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:
parent
017e0eb94d
commit
00bda9206b
|
@ -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>
|
2004-11-30 Mark Dettinger <dettinge@de.ibm.com>
|
||||||
|
|
||||||
* config/s390/s390.c (struct processor_costs): New data type.
|
* config/s390/s390.c (struct processor_costs): New data type.
|
||||||
|
|
|
@ -25,6 +25,127 @@ INT_MODE (OI, 32);
|
||||||
|
|
||||||
/* Add any extra modes needed to represent the condition code. */
|
/* 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 (CCZ);
|
||||||
CC_MODE (CCA);
|
CC_MODE (CCA);
|
||||||
CC_MODE (CCAP);
|
CC_MODE (CCAP);
|
||||||
|
|
|
@ -472,15 +472,20 @@ s390_tm_ccmode (rtx op1, rtx op2, int mixed)
|
||||||
if (GET_CODE (op1) != CONST_INT || GET_CODE (op2) != CONST_INT)
|
if (GET_CODE (op1) != CONST_INT || GET_CODE (op2) != CONST_INT)
|
||||||
return VOIDmode;
|
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)
|
if (INTVAL (op2) == 0)
|
||||||
return CCTmode;
|
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))
|
if (INTVAL (op2) == INTVAL (op1))
|
||||||
return CCT3mode;
|
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)
|
if (mixed)
|
||||||
{
|
{
|
||||||
bit1 = exact_log2 (INTVAL (op2));
|
bit1 = exact_log2 (INTVAL (op2));
|
||||||
|
@ -542,9 +547,19 @@ s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
|
||||||
case LT:
|
case LT:
|
||||||
case GE:
|
case GE:
|
||||||
case GT:
|
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)
|
if ((GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
|
||||||
&& GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
|
&& GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
|
||||||
return CCAPmode;
|
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
|
if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
|
||||||
&& CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0, 1)), 'K', "K"))
|
&& 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.
|
/* Expand conditional increment or decrement using alc/slb instructions.
|
||||||
Should generate code setting DST to either SRC or SRC + INCREMENT,
|
Should generate code setting DST to either SRC or SRC + INCREMENT,
|
||||||
depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
|
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
|
bool
|
||||||
s390_expand_addcc (enum rtx_code cmp_code, rtx cmp_op0, rtx cmp_op1,
|
s390_expand_addcc (enum rtx_code cmp_code, rtx cmp_op0, rtx cmp_op1,
|
||||||
|
|
|
@ -228,25 +228,6 @@
|
||||||
;; Pipeline description for z990.
|
;; Pipeline description for z990.
|
||||||
(include "2084.md")
|
(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.
|
;;- Compare instructions.
|
||||||
;;
|
;;
|
||||||
|
|
Loading…
Reference in New Issue