mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-06 14:50:24 +08:00
s390.c: (s390_cc_modes_compatible): Move before "s390_emit_compare".
2005-07-13 Adrian Strae�tling <straetling@de.ibm.com> * config/s390/s390.c: (s390_cc_modes_compatible): Move before "s390_emit_compare". Add handling of CCZ1mode. (s390_canonicalize_comparison): Simplify cascaded EQ, NE. (390_emit_compare): Use "s390_cc_modes_compatible" for mode checking. (s390_branch_condition_mask): Add CCZ1mode handling. * config/s390/s390.md: ("seq", "*seq"): New pattern. ("sync_compare_and_swap_cc<mode>", "*sync_compare_and_swap_cc<mode>"): Use CCZ1mode instead of CCZmode. * config/s390/s390-modes.def: Add CCZ1mode. Comment new mode. From-SVN: r101990
This commit is contained in:
parent
ccbdc0d46e
commit
6995045258
@ -1,3 +1,16 @@
|
||||
2005-07-13 Adrian Strae½tling <straetling@de.ibm.com>
|
||||
|
||||
* config/s390/s390.c: (s390_cc_modes_compatible): Move before
|
||||
"s390_emit_compare". Add handling of CCZ1mode.
|
||||
(s390_canonicalize_comparison): Simplify cascaded EQ, NE.
|
||||
(390_emit_compare): Use "s390_cc_modes_compatible" for mode
|
||||
checking.
|
||||
(s390_branch_condition_mask): Add CCZ1mode handling.
|
||||
* config/s390/s390.md: ("seq", "*seq"): New pattern.
|
||||
("sync_compare_and_swap_cc<mode>", "*sync_compare_and_swap_cc<mode>"):
|
||||
Use CCZ1mode instead of CCZmode.
|
||||
* config/s390/s390-modes.def: Add CCZ1mode. Comment new mode.
|
||||
|
||||
2006-07-13 Adrian Strae½tling <straetling@de.ibm.com>
|
||||
|
||||
* config/s390/s390.md: ("cmpstrsi", "*cmpstr<mode>"): New
|
||||
|
@ -35,6 +35,7 @@ Condition Codes
|
||||
Check for zero
|
||||
|
||||
CCZ: EQ NE NE NE
|
||||
CCZ1: EQ NE (CS)
|
||||
|
||||
Unsigned compares
|
||||
|
||||
@ -146,10 +147,17 @@ 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.
|
||||
|
||||
CCZ1
|
||||
|
||||
The compare and swap instructions sets the condition code to 0/1 if the
|
||||
operands were equal/unequal. The CCZ1 mode ensures the result can be
|
||||
effectively placed into a register.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
CC_MODE (CCZ);
|
||||
CC_MODE (CCZ1);
|
||||
CC_MODE (CCA);
|
||||
CC_MODE (CCAP);
|
||||
CC_MODE (CCAN);
|
||||
|
@ -272,6 +272,41 @@ s390_set_has_landing_pad_p (bool value)
|
||||
cfun->machine->has_landing_pad_p = value;
|
||||
}
|
||||
|
||||
/* If two condition code modes are compatible, return a condition code
|
||||
mode which is compatible with both. Otherwise, return
|
||||
VOIDmode. */
|
||||
|
||||
static enum machine_mode
|
||||
s390_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
|
||||
{
|
||||
if (m1 == m2)
|
||||
return m1;
|
||||
|
||||
switch (m1)
|
||||
{
|
||||
case CCZmode:
|
||||
if (m2 == CCUmode || m2 == CCTmode || m2 == CCZ1mode
|
||||
|| m2 == CCSmode || m2 == CCSRmode || m2 == CCURmode)
|
||||
return m2;
|
||||
return VOIDmode;
|
||||
|
||||
case CCSmode:
|
||||
case CCUmode:
|
||||
case CCTmode:
|
||||
case CCSRmode:
|
||||
case CCURmode:
|
||||
case CCZ1mode:
|
||||
if (m2 == CCZmode)
|
||||
return m1;
|
||||
|
||||
return VOIDmode;
|
||||
|
||||
default:
|
||||
return VOIDmode;
|
||||
}
|
||||
return VOIDmode;
|
||||
}
|
||||
|
||||
/* Return true if SET either doesn't set the CC register, or else
|
||||
the source and destination have matching CC modes and that
|
||||
CC mode is at least as constrained as REQ_MODE. */
|
||||
@ -612,6 +647,23 @@ s390_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
|
||||
*code = new_code;
|
||||
}
|
||||
}
|
||||
|
||||
/* Simplify cascaded EQ, NE with const0_rtx. */
|
||||
if ((*code == NE || *code == EQ)
|
||||
&& (GET_CODE (*op0) == EQ || GET_CODE (*op0) == NE)
|
||||
&& GET_MODE (*op0) == SImode
|
||||
&& GET_MODE (XEXP (*op0, 0)) == CCZ1mode
|
||||
&& REG_P (XEXP (*op0, 0))
|
||||
&& XEXP (*op0, 1) == const0_rtx
|
||||
&& *op1 == const0_rtx)
|
||||
{
|
||||
if ((*code == EQ && GET_CODE (*op0) == NE)
|
||||
|| (*code == NE && GET_CODE (*op0) == EQ))
|
||||
*code = EQ;
|
||||
else
|
||||
*code = NE;
|
||||
*op0 = XEXP (*op0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Emit a compare instruction suitable to implement the comparison
|
||||
@ -625,8 +677,10 @@ s390_emit_compare (enum rtx_code code, rtx op0, rtx op1)
|
||||
rtx ret = NULL_RTX;
|
||||
|
||||
/* Do not output a redundant compare instruction if a compare_and_swap
|
||||
pattern already computed the result and the machine modes match. */
|
||||
if (s390_compare_emitted && GET_MODE (s390_compare_emitted) == mode)
|
||||
pattern already computed the result and the machine modes are compatible. */
|
||||
if (s390_compare_emitted
|
||||
&& (s390_cc_modes_compatible (GET_MODE (s390_compare_emitted), mode)
|
||||
== GET_MODE (s390_compare_emitted)))
|
||||
ret = gen_rtx_fmt_ee (code, VOIDmode, s390_compare_emitted, const0_rtx);
|
||||
else
|
||||
{
|
||||
@ -673,6 +727,7 @@ s390_branch_condition_mask (rtx code)
|
||||
switch (GET_MODE (XEXP (code, 0)))
|
||||
{
|
||||
case CCZmode:
|
||||
case CCZ1mode:
|
||||
switch (GET_CODE (code))
|
||||
{
|
||||
case EQ: return CC0;
|
||||
@ -7910,40 +7965,6 @@ s390_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* If two condition code modes are compatible, return a condition code
|
||||
mode which is compatible with both. Otherwise, return
|
||||
VOIDmode. */
|
||||
|
||||
static enum machine_mode
|
||||
s390_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
|
||||
{
|
||||
if (m1 == m2)
|
||||
return m1;
|
||||
|
||||
switch (m1)
|
||||
{
|
||||
case CCZmode:
|
||||
if (m2 == CCUmode || m2 == CCTmode
|
||||
|| m2 == CCSmode || m2 == CCSRmode || m2 == CCURmode)
|
||||
return m2;
|
||||
return VOIDmode;
|
||||
|
||||
case CCSmode:
|
||||
case CCUmode:
|
||||
case CCTmode:
|
||||
case CCSRmode:
|
||||
case CCURmode:
|
||||
if (m2 == CCZmode)
|
||||
return m1;
|
||||
|
||||
return VOIDmode;
|
||||
|
||||
default:
|
||||
return VOIDmode;
|
||||
}
|
||||
return VOIDmode;
|
||||
}
|
||||
|
||||
/* This function is used by the call expanders of the machine description.
|
||||
It emits the call insn itself together with the necessary operations
|
||||
to adjust the target address and returns the emitted insn.
|
||||
|
@ -3973,6 +3973,34 @@
|
||||
"if (!s390_expand_addcc (<CODE>, s390_compare_op0, s390_compare_op1,
|
||||
operands[0], const0_rtx, const1_rtx)) FAIL; DONE;")
|
||||
|
||||
(define_expand "seq"
|
||||
[(parallel
|
||||
[(set (match_operand:SI 0 "register_operand" "=d")
|
||||
(match_dup 1))
|
||||
(clobber (reg:CC CC_REGNUM))])
|
||||
(parallel
|
||||
[(set (match_dup 0) (xor:SI (match_dup 0) (const_int 1)))
|
||||
(clobber (reg:CC CC_REGNUM))])]
|
||||
""
|
||||
{
|
||||
if (!s390_compare_emitted || GET_MODE (s390_compare_emitted) != CCZ1mode)
|
||||
FAIL;
|
||||
operands[1] = s390_emit_compare (NE, s390_compare_op0, s390_compare_op1);
|
||||
PUT_MODE (operands[1], SImode);
|
||||
})
|
||||
|
||||
(define_insn_and_split "*sne"
|
||||
[(set (match_operand:SI 0 "register_operand" "=d")
|
||||
(ne:SI (match_operand:CCZ1 1 "register_operand" "0")
|
||||
(const_int 0)))
|
||||
(clobber (reg:CC CC_REGNUM))]
|
||||
""
|
||||
"#"
|
||||
"reload_completed"
|
||||
[(parallel
|
||||
[(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 28)))
|
||||
(clobber (reg:CC CC_REGNUM))])])
|
||||
|
||||
|
||||
;;
|
||||
;;- Multiply instructions.
|
||||
@ -6797,10 +6825,10 @@
|
||||
(match_operand:GPR 3 "register_operand" "")]
|
||||
UNSPECV_CAS))
|
||||
(set (match_dup 4)
|
||||
(compare:CCZ (match_dup 1) (match_dup 2)))])]
|
||||
(compare:CCZ1 (match_dup 1) (match_dup 2)))])]
|
||||
""
|
||||
{
|
||||
operands[4] = gen_rtx_REG (CCZmode, CC_REGNUM);
|
||||
operands[4] = gen_rtx_REG (CCZ1mode, CC_REGNUM);
|
||||
s390_compare_op0 = operands[1];
|
||||
s390_compare_op1 = operands[2];
|
||||
s390_compare_emitted = operands[4];
|
||||
@ -6815,8 +6843,8 @@
|
||||
(match_operand:GPR 2 "register_operand" "0")
|
||||
(match_operand:GPR 3 "register_operand" "r")]
|
||||
UNSPECV_CAS))
|
||||
(set (reg:CCZ CC_REGNUM)
|
||||
(compare:CCZ (match_dup 1) (match_dup 2)))]
|
||||
(set (reg:CCZ1 CC_REGNUM)
|
||||
(compare:CCZ1 (match_dup 1) (match_dup 2)))]
|
||||
""
|
||||
"cs<g>\t%0,%3,%S1"
|
||||
[(set_attr "op_type" "RS<E>")
|
||||
|
Loading…
Reference in New Issue
Block a user