aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorAndreas Krebbel <krebbel1@de.ibm.com>2004-11-30 15:31:12 +0000
committerUlrich Weigand <uweigand@gcc.gnu.org>2004-11-30 15:31:12 +0000
commit00bda9206b27e0c9d5bae355189fe2067ed12750 (patch)
tree75d3d68bc26017f3db22f4232fa43b375b5a8ad1 /gcc/config
parent017e0eb94d164300f87adc5759eeffea42d02300 (diff)
downloadgcc-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.def121
-rw-r--r--gcc/config/s390/s390.c37
-rw-r--r--gcc/config/s390/s390.md19
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.
;;