s390-modes.def: Added cc modes documentation.

2004-11-30  Andreas Krebbel  <krebbel1@de.ibm.com>

	* config/s390/s390-modes.def: Added cc modes documentation.
	* config/s390/s390.c: (s390_tm_ccmode, s390_select_ccmode,
	s390_expand_addcc): Added cc mode comments.
	* config/s390/s390.md: Removed old cc mode documentation.

From-SVN: r91528
This commit is contained in:
Andreas Krebbel 2004-11-30 15:31:12 +00:00 committed by Ulrich Weigand
parent 017e0eb94d
commit 00bda9206b
4 changed files with 161 additions and 23 deletions

View File

@ -1,3 +1,10 @@
2004-11-30 Andreas Krebbel <krebbel1@de.ibm.com>
* config/s390/s390-modes.def: Added cc modes documentation.
* config/s390/s390.c: (s390_tm_ccmode, s390_select_ccmode,
s390_expand_addcc): Added cc mode comments.
* config/s390/s390.md: Removed old cc mode documentation.
2004-11-30 Mark Dettinger <dettinge@de.ibm.com>
* config/s390/s390.c (struct processor_costs): New data type.

View File

@ -25,6 +25,127 @@ INT_MODE (OI, 32);
/* Add any extra modes needed to represent the condition code. */
/*
Condition Codes
Check for zero
CCZ: EQ NE NE NE
Unsigned compares
CCU: EQ LTU GTU NE (CLG/R, CL/R/Y, CLM/Y, CLI/Y)
CCUR: EQ GTU LTU NE (CLGF/R)
Signed compares
CCS: EQ LT GT UNORDERED (LTGFR, LTGR, LTR, ICM/Y,
LTDBR, LTDR, LTEBR, LTER,
CG/R, C/R/Y, CGHI, CHI,
CDB/R, CD/R, CEB/R, CE/R,
ADB/R, AEB/R, SDB/R, SEB/R,
SRAG, SRA, SRDA)
CCSR: EQ GT LT UNORDERED (CGF/R, CH/Y)
Condition codes resulting from add with overflow
CCA: EQ LT GT Overflow
CCAP: EQ LT GT LT (AGHI, AHI)
CCAN: EQ LT GT GT (AGHI, AHI)
Condition codes of unsigned adds and subs
CCL: EQ NE EQ NE (ALGF/R, ALG/R, AL/R/Y,
ALCG/R, ALC/R,
SLGF/R, SLG/R, SL/R/Y,
SLBG/R, SLB/R)
CCL1: GEU GEU LTU LTU (ALG/R, AL/R/Y)
CCL2: GTU GTU LEU LEU (SLG/R, SL/R/Y)
CCL3: EQ LTU EQ GTU (SLG/R, SL/R/Y)
Test under mask checks
CCT: EQ NE NE NE (ICM/Y, TML, CG/R, CGHI,
C/R/Y, CHI, NG/R, N/R/Y,
OG/R, O/R/Y, XG/R, X/R/Y)
CCT1: NE EQ NE NE (TMH, TML)
CCT2: NE NE EQ NE (TMH, TML)
CCT3: NE NE NE EQ (TMH, TML)
CCA and CCT modes are request only modes. These modes are never returned by
s390_select_cc_mode. They are only intended to match other modes.
Requested mode -> Destination CC register mode
CCS, CCU, CCT, CCSR, CCUR -> CCZ
CCA -> CCAP, CCAN
*** Comments ***
CCAP, CCAN
The CC obtained from add instruction usually can't be used for comparisons
because its coupling with overflow flag. In case of an overflow the
less than/greater than data are lost. Nevertheless a comparison can be done
whenever immediate values are involved because they are known at compile time.
If you know whether the used constant is positive or negative you can predict
the sign of the result even in case of an overflow.
CCT, CCT1, CCT2, CCT3
If bits of an integer masked with an AND instruction are checked, the test under
mask instructions turn out to be very handy for a set of special cases.
The simple cases are checks whether all masked bits are zero or ones:
int a;
if ((a & (16 + 128)) == 0) -> CCT/CCZ
if ((a & (16 + 128)) == 16 + 128) -> CCT3
Using two extra modes makes it possible to do complete checks on two bits of an
integer (This is possible on register operands only. TM does not provide the
information necessary for CCT1 and CCT2 modes.):
int a;
if ((a & (16 + 128)) == 16) -> CCT1
if ((a & (16 + 128)) == 128) -> CCT2
CCSR, CCUR
There are several instructions comparing 32 bit with 64 bit unsigned/signed
values. Such instructions can be considered to have a builtin zero/sign_extend.
The problem is that in the RTL (to be canonical) the zero/sign extended operand
has to be the first one but the machine instructions like it the other way
around. The following both modes can be considered as CCS and CCU modes with
exchanged operands.
CCL1, CCL2
These modes represent the result of overflow checks.
if (a + b < a) -> CCL1 state of the carry bit (CC2 | CC3)
if (a - b > a) -> CCL2 state of the borrow bit (CC0 | CC1)
They are used when multi word numbers are computed dealing one SImode part after
another or whenever manual overflow checks like the examples above are
compiled.
CCL3
A logical subtract instruction sets the borrow bit in case of an overflow.
The resulting condition code of those instructions is represented by the
CCL3 mode. Together with the CCU mode this mode is used for jumpless
implementations of several if-constructs - see s390_expand_addcc for more
details.
*/
CC_MODE (CCZ);
CC_MODE (CCA);
CC_MODE (CCAP);

View File

@ -472,15 +472,20 @@ s390_tm_ccmode (rtx op1, rtx op2, int mixed)
if (GET_CODE (op1) != CONST_INT || GET_CODE (op2) != CONST_INT)
return VOIDmode;
/* Selected bits all zero: CC0. */
/* Selected bits all zero: CC0.
e.g.: int a; if ((a & (16 + 128)) == 0) */
if (INTVAL (op2) == 0)
return CCTmode;
/* Selected bits all one: CC3. */
/* Selected bits all one: CC3.
e.g.: int a; if ((a & (16 + 128)) == 16 + 128) */
if (INTVAL (op2) == INTVAL (op1))
return CCT3mode;
/* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. */
/* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. e.g.:
int a;
if ((a & (16 + 128)) == 16) -> CCT1
if ((a & (16 + 128)) == 128) -> CCT2 */
if (mixed)
{
bit1 = exact_log2 (INTVAL (op2));
@ -542,9 +547,19 @@ s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
case LT:
case GE:
case GT:
/* The only overflow condition of NEG and ABS happens when
-INT_MAX is used as parameter, which stays negative. So
we have an overflow from a positive value to a negative.
Using CCAP mode the resulting cc can be used for comparisons. */
if ((GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
&& GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
return CCAPmode;
/* If constants are involved in an add instruction it is possible to use
the resulting cc for comparisons with zero. Knowing the sign of the
constant the overflow behaviour gets predictable. e.g.:
int a, b; if ((b = a + c) > 0)
with c as a constant value: c < 0 -> CCAN and c >= 0 -> CCAP */
if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
&& CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0, 1)), 'K', "K"))
{
@ -3772,7 +3787,21 @@ s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
/* Expand conditional increment or decrement using alc/slb instructions.
Should generate code setting DST to either SRC or SRC + INCREMENT,
depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
Returns true if successful, false otherwise. */
Returns true if successful, false otherwise.
That makes it possible to implement some if-constructs without jumps e.g.:
(borrow = CC0 | CC1 and carry = CC2 | CC3)
unsigned int a, b, c;
if (a < b) c++; -> CCU b > a -> CC2; c += carry;
if (a < b) c--; -> CCL3 a - b -> borrow; c -= borrow;
if (a <= b) c++; -> CCL3 b - a -> borrow; c += carry;
if (a <= b) c--; -> CCU a <= b -> borrow; c -= borrow;
Checks for EQ and NE with a nonzero value need an additional xor e.g.:
if (a == b) c++; -> CCL3 a ^= b; 0 - a -> borrow; c += carry;
if (a == b) c--; -> CCU a ^= b; a <= 0 -> CC0 | CC1; c -= borrow;
if (a != b) c++; -> CCU a ^= b; a > 0 -> CC2; c += carry;
if (a != b) c--; -> CCL3 a ^= b; 0 - a -> borrow; c -= borrow; */
bool
s390_expand_addcc (enum rtx_code cmp_code, rtx cmp_op0, rtx cmp_op1,

View File

@ -228,25 +228,6 @@
;; Pipeline description for z990.
(include "2084.md")
;;
;; Condition Codes
;;
;
; CCL: Zero Nonzero Zero Nonzero (AL, ALR, SL, SLR, N, NC, NI, NR, O, OC, OI, OR, X, XC, XI, XR)
; CCA: Zero <Zero >Zero Overflow (A, AR, AH, AHI, S, SR, SH, SHI, LTR, LCR, LNR, LPR, SLA, SLDA, SLA, SRDA)
; CCU: Equal ULess UGreater -- (CL, CLR, CLI, CLM)
; CCS: Equal SLess SGreater -- (C, CR, CH, CHI, ICM)
; CCT: Zero Mixed Mixed Ones (TM, TMH, TML)
; CCZ -> CCL / CCZ1
; CCZ1 -> CCA/CCU/CCS/CCT
; CCS -> CCA
; String: CLC, CLCL, CLCLE, CLST, CUSE, MVCL, MVCLE, MVPG, MVST, SRST
; Clobber: CKSM, CFC, CS, CDS, CUUTF, CUTFU, PLO, SPM, STCK, STCKE, TS, TRT, TRE, UPT
;;
;;- Compare instructions.
;;