This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] S/390: cc modes documentation
- From: Andreas Krebbel <krebbel1 at de dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 30 Nov 2004 16:00:26 +0100
- Subject: [PATCH] S/390: cc modes documentation
- Organization: IBM Deutschland Entwicklung GmbH
Hi,
this patch modifies the outdated condition code mode
documentation in s390.md and moves it to s390-modes.def.
It is an documentation only patch and is limited to S/390
back end files.
cc1 built on s390
OK?
Bye,
-Andreas-
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.
Index: gcc/config/s390/s390-modes.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390-modes.def,v
retrieving revision 1.7
diff -p -c -r1.7 s390-modes.def
*** gcc/config/s390/s390-modes.def 17 Oct 2004 18:09:46 -0000 1.7
--- gcc/config/s390/s390-modes.def 30 Nov 2004 14:47:33 -0000
*************** INT_MODE (OI, 32);
*** 25,30 ****
--- 25,151 ----
/* 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, BCT/R)
+
+ 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);
Index: gcc/config/s390/s390.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.c,v
retrieving revision 1.205
diff -p -c -r1.205 s390.c
*** gcc/config/s390/s390.c 25 Nov 2004 17:30:25 -0000 1.205
--- gcc/config/s390/s390.c 30 Nov 2004 14:47:34 -0000
*************** s390_tm_ccmode (rtx op1, rtx op2, int mi
*** 417,431 ****
if (GET_CODE (op1) != CONST_INT || GET_CODE (op2) != CONST_INT)
return VOIDmode;
! /* Selected bits all zero: CC0. */
if (INTVAL (op2) == 0)
return CCTmode;
! /* Selected bits all one: CC3. */
if (INTVAL (op2) == INTVAL (op1))
return CCT3mode;
! /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. */
if (mixed)
{
bit1 = exact_log2 (INTVAL (op2));
--- 417,436 ----
if (GET_CODE (op1) != CONST_INT || GET_CODE (op2) != CONST_INT)
return VOIDmode;
! /* 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.
! 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. e.g.:
! int a;
! if ((a & (16 + 128)) == 16) -> CCT1
! if ((a & (16 + 128)) == 128) -> CCT2 */
if (mixed)
{
bit1 = exact_log2 (INTVAL (op2));
*************** s390_select_ccmode (enum rtx_code code,
*** 487,495 ****
--- 492,510 ----
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"))
{
*************** s390_expand_cmpmem (rtx target, rtx op0,
*** 3677,3683 ****
/* 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. */
bool
s390_expand_addcc (enum rtx_code cmp_code, rtx cmp_op0, rtx cmp_op1,
--- 3692,3712 ----
/* 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.
!
! 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,
Index: gcc/config/s390/s390.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.md,v
retrieving revision 1.148
diff -p -c -r1.148 s390.md
*** gcc/config/s390/s390.md 23 Nov 2004 19:36:22 -0000 1.148
--- gcc/config/s390/s390.md 30 Nov 2004 14:47:35 -0000
***************
*** 228,252 ****
;; 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.
;;
--- 228,233 ----