This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[cond-optab] Convert mcore
- From: Paolo Bonzini <bonzini at gnu dot org>
- To: <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 26 Mar 2009 04:35:49 -0400
- Subject: [cond-optab] Convert mcore
mcore's main simplification stems from consolidating the generation of
the compare instruction into a single routine, instead of having separate
functions for 1) legitimizing a comparison 2) synthesizing the CC register
for the comparison.
Paolo
2009-03-24 Paolo Bonzini <bonzini@gnu.org>
* config/mcore/mcore-protos.h (arch_compare_op0, arch_compare_op1,
mcore_modify_comparison, mcore_gen_compare_reg): Remove.
(mcore_gen_compare): New.
* config/mcore/mcore.c (arch_compare_op0, arch_compare_op1): Delete.
(mcore_modify_comparison, mcore_gen_compare_reg): Fold into...
(mcore_gen_compare): ... this.
* config/mcore/mcore.md (cmpsi, bCC, sCC): Remove.
(cbranchsi4, cstoresi4): New, using mcore_gen_compare.
(stack probe pattern): Use cbranchsi4.
Index: gcc/config/mcore/mcore-protos.h
===================================================================
--- gcc/config/mcore/mcore-protos.h (branch cond-optab)
+++ gcc/config/mcore/mcore-protos.h (working copy)
@@ -46,21 +46,17 @@ extern rtx mcore_function_value
#ifdef RTX_CODE
-extern GTY(()) rtx arch_compare_op0;
-extern GTY(()) rtx arch_compare_op1;
-
extern const char * mcore_output_bclri (rtx, int);
extern const char * mcore_output_bseti (rtx, int);
extern const char * mcore_output_cmov (rtx *, int, const char *);
extern char * mcore_output_call (rtx *, int);
extern int mcore_is_dead (rtx, rtx);
extern int mcore_expand_insv (rtx *);
-extern int mcore_modify_comparison (RTX_CODE);
extern bool mcore_expand_block_move (rtx *);
extern const char * mcore_output_andn (rtx, rtx *);
extern void mcore_print_operand_address (FILE *, rtx);
extern void mcore_print_operand (FILE *, rtx, int);
-extern rtx mcore_gen_compare_reg (RTX_CODE);
+extern bool mcore_gen_compare (RTX_CODE, rtx, rtx);
extern int mcore_symbolic_address_p (rtx);
extern bool mcore_r15_operand_p (rtx);
extern enum reg_class mcore_secondary_reload_class (enum reg_class, enum machine_mode, rtx);
Index: gcc/config/mcore/mcore.c
===================================================================
--- gcc/config/mcore/mcore.c (branch cond-optab)
+++ gcc/config/mcore/mcore.c (working copy)
@@ -57,11 +57,6 @@ long mcore_current_compilation_timesta
/* Global variables for machine-dependent things. */
-/* Saved operands from the last compare to use when we generate an scc
- or bcc insn. */
-rtx arch_compare_op0;
-rtx arch_compare_op1;
-
/* Provides the class number of the smallest class containing
reg number. */
const int regno_reg_class[FIRST_PSEUDO_REGISTER] =
@@ -519,26 +514,36 @@ mcore_rtx_costs (rtx x, int code, int ou
}
}
-/* Check to see if a comparison against a constant can be made more efficient
- by incrementing/decrementing the constant to get one that is more efficient
- to load. */
+/* Prepare the operands for a comparison. Return whether the branch/setcc
+ should reverse the operands. */
-int
-mcore_modify_comparison (enum rtx_code code)
+bool
+mcore_gen_compare (enum rtx_code code, rtx op0, rtx op1)
{
- rtx op1 = arch_compare_op1;
-
+ rtx cc_reg = gen_rtx_REG (CCmode, CC_REG);
+ bool invert;
+
if (GET_CODE (op1) == CONST_INT)
{
HOST_WIDE_INT val = INTVAL (op1);
switch (code)
{
+ case GTU:
+ /* Unsigned > 0 is the same as != 0; everything else is converted
+ below to LEU (reversed cmphs). */
+ if (val == 0)
+ code = NE;
+ break;
+
+ /* Check whether (LE A imm) can become (LT A imm + 1),
+ or (GT A imm) can become (GE A imm + 1). */
+ case GT:
case LE:
if (CONST_OK_FOR_J (val + 1))
{
- arch_compare_op1 = GEN_INT (val + 1);
- return 1;
+ op1 = GEN_INT (val + 1);
+ code = code == LE ? LT : GE;
}
break;
@@ -546,28 +551,18 @@ mcore_modify_comparison (enum rtx_code c
break;
}
}
-
- return 0;
-}
-
-/* Prepare the operands for a comparison. */
-
-rtx
-mcore_gen_compare_reg (enum rtx_code code)
-{
- rtx op0 = arch_compare_op0;
- rtx op1 = arch_compare_op1;
- rtx cc_reg = gen_rtx_REG (CCmode, CC_REG);
-
+
if (CONSTANT_P (op1) && GET_CODE (op1) != CONST_INT)
op1 = force_reg (SImode, op1);
/* cmpnei: 0-31 (K immediate)
cmplti: 1-32 (J immediate, 0 using btsti x,31). */
+ invert = false;
switch (code)
{
case EQ: /* Use inverted condition, cmpne. */
code = NE;
+ invert = true;
/* Drop through. */
case NE: /* Use normal condition, cmpne. */
@@ -577,6 +572,7 @@ mcore_gen_compare_reg (enum rtx_code cod
case LE: /* Use inverted condition, reversed cmplt. */
code = GT;
+ invert = true;
/* Drop through. */
case GT: /* Use normal condition, reversed cmplt. */
@@ -586,6 +582,7 @@ mcore_gen_compare_reg (enum rtx_code cod
case GE: /* Use inverted condition, cmplt. */
code = LT;
+ invert = true;
/* Drop through. */
case LT: /* Use normal condition, cmplt. */
@@ -597,13 +594,10 @@ mcore_gen_compare_reg (enum rtx_code cod
break;
case GTU: /* Use inverted condition, cmple. */
- /* Unsigned > 0 is the same as != 0, but we need to invert the
- condition, so we want to set code = EQ. This cannot be done
- however, as the mcore does not support such a test. Instead
- we cope with this case in the "bgtu" pattern itself so we
- should never reach this point. */
+ /* We coped with unsigned > 0 above. */
gcc_assert (GET_CODE (op1) != CONST_INT || INTVAL (op1) != 0);
code = LEU;
+ invert = true;
/* Drop through. */
case LEU: /* Use normal condition, reversed cmphs. */
@@ -613,6 +607,7 @@ mcore_gen_compare_reg (enum rtx_code cod
case LTU: /* Use inverted condition, cmphs. */
code = GEU;
+ invert = true;
/* Drop through. */
case GEU: /* Use normal condition, cmphs. */
@@ -624,9 +619,10 @@ mcore_gen_compare_reg (enum rtx_code cod
break;
}
- emit_insn (gen_rtx_SET (VOIDmode, cc_reg, gen_rtx_fmt_ee (code, CCmode, op0, op1)));
-
- return cc_reg;
+ emit_insn (gen_rtx_SET (VOIDmode,
+ cc_reg,
+ gen_rtx_fmt_ee (code, CCmode, op0, op1)));
+ return invert;
}
int
Index: gcc/config/mcore/mcore.md
===================================================================
--- gcc/config/mcore/mcore.md (branch cond-optab)
+++ gcc/config/mcore/mcore.md (working copy)
@@ -303,22 +303,6 @@
""
"cmphs %1,%0")
-;; We save the compare operands in the cmpxx patterns and use them when
-;; we generate the branch.
-
-;; We accept constants here, in case we can modify them to ones which
-;; are more efficient to load. E.g. change 'x <= 62' to 'x < 63'.
-
-(define_expand "cmpsi"
- [(set (reg:CC 17) (compare:CC (match_operand:SI 0 "mcore_compare_operand" "")
- (match_operand:SI 1 "nonmemory_operand" "")))]
- ""
- "
-{ arch_compare_op0 = operands[0];
- arch_compare_op1 = operands[1];
- DONE;
-}")
-
;; -------------------------------------------------------------------------
;; Logical operations
;; -------------------------------------------------------------------------
@@ -1479,6 +1463,10 @@
;; Define the real conditional branch instructions.
;; ------------------------------------------------------------------------
+;; At top-level, condition test are eq/ne, because we
+;; are comparing against the condition register (which
+;; has the result of the true relational test
+
(define_insn "branch_true"
[(set (pc) (if_then_else (ne (reg:CC 17) (const_int 0))
(label_ref (match_operand 0 "" ""))
@@ -1513,189 +1501,28 @@
;; Conditional branch insns
-;; At top-level, condition test are eq/ne, because we
-;; are comparing against the condition register (which
-;; has the result of the true relational test
-
-; There is no beq compare, so we reverse the branch arms.
-
-(define_expand "beq"
- [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (EQ);
-}")
-
-(define_expand "bne"
- [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (NE);
-}")
-
-; check whether (GT A imm) can become (LE A imm) with the branch reversed.
-; if so, emit a (LT A imm + 1) in place of the (LE A imm). BRC
-
-(define_expand "bgt"
- [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (mcore_modify_comparison (LE))
- {
- emit_jump_insn (gen_reverse_blt (operands[0]));
- DONE;
- }
- operands[1] = mcore_gen_compare_reg (GT);
-}")
-
-; There is no ble compare, so we reverse the branch arms.
-; reversed the condition and branch arms for ble -- the check_dbra_loop()
-; transformation assumes that ble uses a branch-true with the label as
-; as the target. BRC
-
-; check whether (LE A imm) can become (LT A imm + 1).
-
-(define_expand "ble"
- [(set (pc) (if_then_else (eq (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (mcore_modify_comparison (LE))
- {
- emit_jump_insn (gen_blt (operands[0]));
- DONE;
- }
- operands[1] = mcore_gen_compare_reg (LE);
-}")
-
-; make generating a reversed blt simple
-(define_expand "reverse_blt"
- [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (LT);
-}")
-
-(define_expand "blt"
- [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (LT);
-}")
-
-; There is no bge compare, so we reverse the branch arms.
-
-(define_expand "bge"
- [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (GE);
-}")
-
-; There is no gtu compare, so we reverse the branch arms
-
-;(define_expand "bgtu"
-; [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
-; (pc)
-; (label_ref (match_operand 0 "" ""))))]
-; ""
-; "
-;{
-; if (GET_CODE (arch_compare_op1) == CONST_INT
-; && INTVAL (arch_compare_op1) == 0)
-; operands[1] = mcore_gen_compare_reg (NE);
-; else
-; { if (mcore_modify_comparison (GTU))
-; {
-; emit_jump_insn (gen_bgeu (operands[0]));
-; DONE;
-; }
-; operands[1] = mcore_gen_compare_reg (LEU);
-; }
-;}")
-
-(define_expand "bgtu"
- [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "
-{
- if (GET_CODE (arch_compare_op1) == CONST_INT
- && INTVAL (arch_compare_op1) == 0)
- {
- /* The inverse of '> 0' for an unsigned test is
- '== 0' but we do not have such an instruction available.
- Instead we must reverse the branch (back to the normal
- ordering) and test '!= 0'. */
-
- operands[1] = mcore_gen_compare_reg (NE);
-
- emit_jump_insn (gen_rtx_SET (VOIDmode,
- pc_rtx,
- gen_rtx_IF_THEN_ELSE (VOIDmode,
- gen_rtx_NE (VOIDmode,
- operands[1],
- const0_rtx),
- gen_rtx_LABEL_REF (VOIDmode,operands[0]),
- pc_rtx)));
- DONE;
- }
- operands[1] = mcore_gen_compare_reg (GTU);
-}")
-
-
-(define_expand "bleu"
- [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
+(define_expand "cbranchsi4"
+ [(set (pc)
+ (if_then_else (match_operator:SI 0 "ordered_comparison_operator"
+ [(match_operand:SI 1 "mcore_compare_operand")
+ (match_operand:SI 2 "nonmemory_operand")])
+ (label_ref (match_operand 3 ""))
+ (pc)))]
""
"
{
- operands[1] = mcore_gen_compare_reg (LEU);
-}")
+ bool invert;
+ invert = mcore_gen_compare (GET_CODE (operands[0]),
+ operands[1], operands[2]);
-; There is no bltu compare, so we reverse the branch arms
-(define_expand "bltu"
- [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (LTU);
+ if (invert)
+ emit_jump_insn (gen_branch_false (operands[3]));
+ else
+ emit_jump_insn (gen_branch_true (operands[3]));
+ DONE;
}")
-(define_expand "bgeu"
- [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (GEU);
-}")
;; ------------------------------------------------------------------------
;; Jump and linkage insns
@@ -1853,118 +1680,23 @@
(set (match_dup 0) (eq:SI (reg:CC 17) (const_int 0)))])
-(define_expand "seq"
- [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
- (eq:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (NE);
-}")
-
-(define_expand "sne"
- [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
- (ne:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (NE);
-}")
-
-(define_expand "slt"
- [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
- (ne:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (LT);
-}")
-
-; make generating a LT with the comparison reversed easy. BRC
-(define_expand "reverse_slt"
+(define_expand "cstoresi4"
[(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
- (eq:SI (match_dup 1) (const_int 0)))]
+ (match_operator:SI 1 "ordered_comparison_operator"
+ [(match_operand:SI 2 "mcore_compare_operand" "")
+ (match_operand:SI 3 "nonmemory_operand" "")]))]
""
"
{
- operands[1] = mcore_gen_compare_reg (LT);
-}")
-
-(define_expand "sge"
- [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
- (eq:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (LT);
-}")
-
-; check whether (GT A imm) can become (LE A imm) with the comparison
-; reversed. if so, emit a (LT A imm + 1) in place of the (LE A imm). BRC
+ bool invert;
+ invert = mcore_gen_compare (GET_CODE (operands[1]),
+ operands[2], operands[3]);
-(define_expand "sgt"
- [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
- (ne:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- if (mcore_modify_comparison (LE))
- {
- emit_insn (gen_reverse_slt (operands[0]));
- DONE;
- }
-
- operands[1] = mcore_gen_compare_reg (GT);
-}")
-
-(define_expand "sle"
- [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
- (eq:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- if (mcore_modify_comparison (LE))
- {
- emit_insn (gen_slt (operands[0]));
- DONE;
- }
- operands[1] = mcore_gen_compare_reg (GT);
-}")
-
-(define_expand "sltu"
- [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
- (eq:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (GEU);
-}")
-
-(define_expand "sgeu"
- [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
- (ne:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (GEU);
-}")
-
-(define_expand "sgtu"
- [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
- (eq:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (LEU);
-}")
-
-(define_expand "sleu"
- [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
- (ne:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (LEU);
+ if (invert)
+ emit_insn (gen_mvcv (operands[0]));
+ else
+ emit_insn (gen_mvc (operands[0]));
+ DONE;
}")
(define_insn "incscc"
@@ -3308,7 +3040,7 @@
rtx loop_label = gen_label_rtx ();
rtx step = gen_reg_rtx (Pmode);
rtx tmp = gen_reg_rtx (Pmode);
- rtx memref;
+ rtx test, memref;
#if 1
emit_insn (gen_movsi (tmp, operands[1]));
@@ -3317,8 +3049,8 @@
if (GET_CODE (operands[1]) != CONST_INT)
{
out_label = gen_label_rtx ();
- emit_insn (gen_cmpsi (step, tmp)); /* quick out */
- emit_jump_insn (gen_bgeu (out_label));
+ test = gen_rtx_GEU (VOIDmode, step, tmp); /* quick out */
+ emit_jump_insn (gen_cbranchsi4 (test, step, tmp, out_label));
}
/* Run a loop that steps it incrementally. */
@@ -3332,8 +3064,8 @@
emit_insn(gen_subsi3(tmp, tmp, step));
/* Loop condition -- going back up. */
- emit_insn (gen_cmpsi (step, tmp));
- emit_jump_insn (gen_bltu (loop_label));
+ test = gen_rtx_LTU (VOIDmode, step, tmp);
+ emit_jump_insn (gen_cbranchsi4 (test, step, tmp, loop_label));
if (out_label)
emit_label (out_label);