[arm] Cleanup dead code - old support for DImode comparisons
Now that all the major patterns for DImode have been converted to early expansion, we can safely clean up some dead code for the old way of handling DImode. * config/arm/arm-modes.def (CC_NCV, CC_CZ): Delete CC modes. * config/arm/arm.c (arm_select_cc_mode): Remove old selection code for DImode operands. (arm_gen_dicompare_reg): Remove unreachable expansion code. (maybe_get_arm_condition_code): Remove support for CC_CZmode and CC_NCVmode. * config/arm/arm.md (arm_cmpdi_insn): Delete. (arm_cmpdi_unsigned): Delete. From-SVN: r277181
This commit is contained in:
parent
af74bfeee1
commit
f9f6247d14
@ -1,3 +1,14 @@
|
||||
2019-10-18 Richard Earnshaw <rearnsha@arm.com>
|
||||
|
||||
* config/arm/arm-modes.def (CC_NCV, CC_CZ): Delete CC modes.
|
||||
* config/arm/arm.c (arm_select_cc_mode): Remove old selection code
|
||||
for DImode operands.
|
||||
(arm_gen_dicompare_reg): Remove unreachable expansion code.
|
||||
(maybe_get_arm_condition_code): Remove support for CC_CZmode and
|
||||
CC_NCVmode.
|
||||
* config/arm/arm.md (arm_cmpdi_insn): Delete.
|
||||
(arm_cmpdi_unsigned): Delete.
|
||||
|
||||
2019-10-18 Richard Earnshaw <rearnsha@arm.com>
|
||||
|
||||
* config/arm/arm.c (arm_const_double_prefer_rsbs_rsc): New function.
|
||||
|
@ -36,12 +36,9 @@ ADJUST_FLOAT_FORMAT (HF, ((arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE)
|
||||
CC_Nmode should be used if only the N (sign) flag is set correctly
|
||||
CC_NVmode should be used if only the N and V bits are set correctly,
|
||||
(used for signed comparisons when the carry is propagated in).
|
||||
CC_CZmode should be used if only the C and Z flags are correct
|
||||
(used for DImode unsigned comparisons).
|
||||
CC_RSBmode should be used where the comparison is set by an RSB immediate,
|
||||
or NEG instruction. The form of the comparison for (const - reg) will
|
||||
be (COMPARE (not (reg)) (~const)).
|
||||
CC_NCVmode should be used if only the N, C, and V flags are correct
|
||||
CC_Bmode should be used if only the C flag is correct after a subtract
|
||||
(eg after an unsigned borrow with carry-in propagation).
|
||||
(used for DImode signed comparisons).
|
||||
@ -49,8 +46,6 @@ ADJUST_FLOAT_FORMAT (HF, ((arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE)
|
||||
|
||||
CC_MODE (CC_NOOV);
|
||||
CC_MODE (CC_Z);
|
||||
CC_MODE (CC_CZ);
|
||||
CC_MODE (CC_NCV);
|
||||
CC_MODE (CC_NV);
|
||||
CC_MODE (CC_SWP);
|
||||
CC_MODE (CC_RSB);
|
||||
|
@ -15403,56 +15403,6 @@ arm_select_cc_mode (enum rtx_code op, rtx x, rtx y)
|
||||
|| arm_borrow_operation (y, DImode)))
|
||||
return CC_Bmode;
|
||||
|
||||
if (GET_MODE (x) == DImode || GET_MODE (y) == DImode)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case EQ:
|
||||
case NE:
|
||||
/* A DImode comparison against zero can be implemented by
|
||||
or'ing the two halves together. We can also handle
|
||||
immediates where one word of that value is zero by
|
||||
subtracting the non-zero word from the corresponding word
|
||||
in the other register and then ORRing it with the other
|
||||
word. */
|
||||
if (CONST_INT_P (y)
|
||||
&& ((UINTVAL (y) & 0xffffffff) == 0
|
||||
|| (UINTVAL (y) >> 32) == 0))
|
||||
return CC_Zmode;
|
||||
|
||||
/* We can do an equality test in three Thumb instructions. */
|
||||
if (!TARGET_32BIT)
|
||||
return CC_Zmode;
|
||||
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case LTU:
|
||||
case LEU:
|
||||
case GTU:
|
||||
case GEU:
|
||||
/* DImode unsigned comparisons can be implemented by cmp +
|
||||
cmpeq without a scratch register. Not worth doing in
|
||||
Thumb-2. */
|
||||
if (TARGET_32BIT)
|
||||
return CC_CZmode;
|
||||
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case LT:
|
||||
case LE:
|
||||
case GT:
|
||||
case GE:
|
||||
/* DImode signed and unsigned comparisons can be implemented
|
||||
by cmp + sbcs with a scratch register, but that does not
|
||||
set the Z flag - we must reverse GT/LE/GTU/LEU. */
|
||||
gcc_assert (op != EQ && op != NE);
|
||||
return CC_NCVmode;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
|
||||
if (GET_MODE_CLASS (GET_MODE (x)) == MODE_CC)
|
||||
return GET_MODE (x);
|
||||
|
||||
@ -15673,81 +15623,8 @@ arm_gen_dicompare_reg (rtx_code code, rtx x, rtx y, rtx scratch)
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
/* We might have X as a constant, Y as a register because of the predicates
|
||||
used for cmpdi. If so, force X to a register here. */
|
||||
if (!REG_P (x))
|
||||
x = force_reg (DImode, x);
|
||||
|
||||
mode = SELECT_CC_MODE (code, x, y);
|
||||
cc_reg = gen_rtx_REG (mode, CC_REGNUM);
|
||||
|
||||
if (mode != CC_CZmode)
|
||||
{
|
||||
rtx clobber, set;
|
||||
|
||||
/* To compare two non-zero values for equality, XOR them and
|
||||
then compare against zero. Not used for ARM mode; there
|
||||
CC_CZmode is cheaper. */
|
||||
if (mode == CC_Zmode)
|
||||
{
|
||||
mode = CC_NOOVmode;
|
||||
PUT_MODE (cc_reg, mode);
|
||||
if (y != const0_rtx)
|
||||
{
|
||||
gcc_assert (CONST_INT_P (y));
|
||||
rtx xlo, xhi, ylo, yhi;
|
||||
arm_decompose_di_binop (x, y, &xlo, &xhi, &ylo, &yhi);
|
||||
if (!scratch)
|
||||
scratch = gen_reg_rtx (SImode);
|
||||
if (ylo == const0_rtx)
|
||||
{
|
||||
yhi = gen_int_mode (-INTVAL (yhi), SImode);
|
||||
if (!arm_add_operand (yhi, SImode))
|
||||
yhi = force_reg (SImode, yhi);
|
||||
emit_insn (gen_addsi3 (scratch, xhi, yhi));
|
||||
y = xlo;
|
||||
}
|
||||
else
|
||||
{
|
||||
gcc_assert (yhi == const0_rtx);
|
||||
ylo = gen_int_mode (-INTVAL (ylo), SImode);
|
||||
if (!arm_add_operand (ylo, SImode))
|
||||
ylo = force_reg (SImode, ylo);
|
||||
emit_insn (gen_addsi3 (scratch, xlo, ylo));
|
||||
y = xhi;
|
||||
}
|
||||
x = gen_rtx_IOR (SImode, scratch, y);
|
||||
y = const0_rtx;
|
||||
}
|
||||
else
|
||||
x = gen_rtx_IOR (SImode, gen_lowpart (SImode, x),
|
||||
gen_highpart (SImode, x));
|
||||
}
|
||||
else if (!cmpdi_operand (y, mode))
|
||||
y = force_reg (DImode, y);
|
||||
|
||||
/* A scratch register is required. */
|
||||
if (reload_completed)
|
||||
gcc_assert (scratch != NULL && GET_MODE (scratch) == SImode);
|
||||
else
|
||||
scratch = gen_rtx_SCRATCH (SImode);
|
||||
|
||||
clobber = gen_rtx_CLOBBER (VOIDmode, scratch);
|
||||
set = gen_rtx_SET (cc_reg, gen_rtx_COMPARE (mode, x, y));
|
||||
emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, clobber)));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!cmpdi_operand (y, mode))
|
||||
y = force_reg (DImode, y);
|
||||
|
||||
emit_set_insn (cc_reg, gen_rtx_COMPARE (mode, x, y));
|
||||
}
|
||||
|
||||
return cc_reg;
|
||||
}
|
||||
|
||||
/* X and Y are two things to compare using CODE. Emit the compare insn and
|
||||
@ -24051,28 +23928,6 @@ maybe_get_arm_condition_code (rtx comparison)
|
||||
default: return ARM_NV;
|
||||
}
|
||||
|
||||
case E_CC_CZmode:
|
||||
switch (comp_code)
|
||||
{
|
||||
case NE: return ARM_NE;
|
||||
case EQ: return ARM_EQ;
|
||||
case GEU: return ARM_CS;
|
||||
case GTU: return ARM_HI;
|
||||
case LEU: return ARM_LS;
|
||||
case LTU: return ARM_CC;
|
||||
default: return ARM_NV;
|
||||
}
|
||||
|
||||
case E_CC_NCVmode:
|
||||
switch (comp_code)
|
||||
{
|
||||
case GE: return ARM_GE;
|
||||
case LT: return ARM_LT;
|
||||
case GEU: return ARM_CS;
|
||||
case LTU: return ARM_CC;
|
||||
default: return ARM_NV;
|
||||
}
|
||||
|
||||
case E_CC_NVmode:
|
||||
switch (comp_code)
|
||||
{
|
||||
|
@ -6545,51 +6545,6 @@
|
||||
(set_attr "predicable" "yes")]
|
||||
)
|
||||
|
||||
;; DImode comparisons. The generic code generates branches that
|
||||
;; if-conversion cannot reduce to a conditional compare, so we do
|
||||
;; that directly.
|
||||
|
||||
(define_insn "*arm_cmpdi_insn"
|
||||
[(set (reg:CC_NCV CC_REGNUM)
|
||||
(compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
|
||||
(match_operand:DI 1 "arm_di_operand" "rDi")))
|
||||
(clobber (match_scratch:SI 2 "=r"))]
|
||||
"TARGET_32BIT"
|
||||
"cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
|
||||
[(set_attr "conds" "set")
|
||||
(set_attr "length" "8")
|
||||
(set_attr "type" "multiple")]
|
||||
)
|
||||
|
||||
(define_insn_and_split "*arm_cmpdi_unsigned"
|
||||
[(set (reg:CC_CZ CC_REGNUM)
|
||||
(compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
|
||||
(match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
|
||||
|
||||
"TARGET_32BIT"
|
||||
"#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
|
||||
"&& reload_completed"
|
||||
[(set (reg:CC CC_REGNUM)
|
||||
(compare:CC (match_dup 2) (match_dup 3)))
|
||||
(cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
|
||||
(set (reg:CC CC_REGNUM)
|
||||
(compare:CC (match_dup 0) (match_dup 1))))]
|
||||
{
|
||||
operands[2] = gen_highpart (SImode, operands[0]);
|
||||
operands[0] = gen_lowpart (SImode, operands[0]);
|
||||
if (CONST_INT_P (operands[1]))
|
||||
operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
|
||||
else
|
||||
operands[3] = gen_highpart (SImode, operands[1]);
|
||||
operands[1] = gen_lowpart (SImode, operands[1]);
|
||||
}
|
||||
[(set_attr "conds" "set")
|
||||
(set_attr "enabled_for_short_it" "yes,yes,no,*")
|
||||
(set_attr "arch" "t2,t2,t2,a")
|
||||
(set_attr "length" "6,6,10,8")
|
||||
(set_attr "type" "multiple")]
|
||||
)
|
||||
|
||||
; This insn allows redundant compares to be removed by cse, nothing should
|
||||
; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
|
||||
; is deleted later on. The match_dup will match the mode here, so that
|
||||
|
Loading…
Reference in New Issue
Block a user