This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] S/390: cc modes documentation


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 ----


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]