diff options
author | Andreas Krebbel <krebbel1@de.ibm.com> | 2004-11-30 15:31:12 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@gcc.gnu.org> | 2004-11-30 15:31:12 +0000 |
commit | 00bda9206b27e0c9d5bae355189fe2067ed12750 (patch) | |
tree | 75d3d68bc26017f3db22f4232fa43b375b5a8ad1 /gcc/config | |
parent | 017e0eb94d164300f87adc5759eeffea42d02300 (diff) | |
download | gcc-00bda9206b27e0c9d5bae355189fe2067ed12750.zip gcc-00bda9206b27e0c9d5bae355189fe2067ed12750.tar.gz gcc-00bda9206b27e0c9d5bae355189fe2067ed12750.tar.bz2 |
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
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/s390/s390-modes.def | 121 | ||||
-rw-r--r-- | gcc/config/s390/s390.c | 37 | ||||
-rw-r--r-- | gcc/config/s390/s390.md | 19 |
3 files changed, 154 insertions, 23 deletions
diff --git a/gcc/config/s390/s390-modes.def b/gcc/config/s390/s390-modes.def index dc56eea8..1cb0f19 100644 --- a/gcc/config/s390/s390-modes.def +++ b/gcc/config/s390/s390-modes.def @@ -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); diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index cf0a0115..1526f90 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -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, diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 7e803b9..7672e2b 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -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. ;; |