@@ -38,6 +38,7 @@ extern bool cris_constant_index_p (const_rtx);
extern bool cris_base_p (const_rtx, bool);
extern bool cris_base_or_autoincr_p (const_rtx, bool);
extern bool cris_bdap_index_p (const_rtx, bool);
+extern void cris_reduce_compare (rtx *, rtx *, rtx *);
extern bool cris_biap_index_p (const_rtx, bool);
extern bool cris_legitimate_address_p (machine_mode, rtx, bool);
extern bool cris_store_multiple_op_p (rtx);
@@ -3053,6 +3053,63 @@ cris_split_movdx (rtx *operands)
return val;
}
+/* Try to change a comparison against a constant to be against zero, and
+ an unsigned compare against zero to be an equality test. Beware:
+ only valid for compares of integer-type operands. Also, note that we
+ don't use operand 0 at the moment. */
+
+void
+cris_reduce_compare (rtx *relp, rtx *, rtx *op1p)
+{
+ rtx op1 = *op1p;
+ rtx_code code = GET_CODE (*relp);
+
+ /* Code lifted mostly from emit_store_flag_1. */
+ switch (code)
+ {
+ case LT:
+ if (op1 == const1_rtx)
+ code = LE;
+ break;
+ case LE:
+ if (op1 == constm1_rtx)
+ code = LT;
+ break;
+ case GE:
+ if (op1 == const1_rtx)
+ code = GT;
+ break;
+ case GT:
+ if (op1 == constm1_rtx)
+ code = GE;
+ break;
+ case GEU:
+ if (op1 == const1_rtx)
+ code = NE;
+ break;
+ case LTU:
+ if (op1 == const1_rtx)
+ code = EQ;
+ break;
+ case GTU:
+ if (op1 == const0_rtx)
+ code = NE;
+ break;
+ case LEU:
+ if (op1 == const0_rtx)
+ code = EQ;
+ break;
+ default:
+ break;
+ }
+
+ if (code != GET_CODE (*relp))
+ {
+ *op1p = const0_rtx;
+ PUT_CODE (*relp, code);
+ }
+}
+
/* The expander for the prologue pattern name. */
void
@@ -3539,7 +3539,7 @@ (define_expand "cbranch<mode>4"
(label_ref (match_operand 3 "" ""))
(pc)))]
""
- "")
+ "cris_reduce_compare (&operands[0], &operands[1], &operands[2]);")
(define_expand "cbranchdi4"
[(set (cc0)
@@ -3552,6 +3552,7 @@ (define_expand "cbranchdi4"
(pc)))]
""
{
+ cris_reduce_compare (&operands[0], &operands[1], &operands[2]);
if (TARGET_V32 && !REG_P (operands[1]))
operands[1] = force_reg (DImode, operands[1]);
if (TARGET_V32 && MEM_P (operands[2]))
@@ -3652,6 +3653,7 @@ (define_expand "cstoredi4"
[(cc0) (const_int 0)]))]
""
{
+ cris_reduce_compare (&operands[1], &operands[2], &operands[3]);
if (TARGET_V32 && !REG_P (operands[2]))
operands[2] = force_reg (DImode, operands[2]);
if (TARGET_V32 && MEM_P (operands[3]))
@@ -3666,7 +3668,7 @@ (define_expand "cstore<mode>4"
(match_operator:SI 1 "ordered_comparison_operator"
[(cc0) (const_int 0)]))]
""
- "")
+ "cris_reduce_compare (&operands[1], &operands[2], &operands[3]);")
;; Like bCC, we have to check the overflow bit for
;; signed conditions.