summaryrefslogtreecommitdiff
path: root/gcc/config/iq2000
diff options
context:
space:
mode:
authorPaolo Bonzini <bonzini@gnu.org>2009-05-12 09:43:48 +0000
committerPaolo Bonzini <bonzini@gcc.gnu.org>2009-05-12 09:43:48 +0000
commitf90b7a5a7913cc7239cce42f6ca328b9a741b387 (patch)
tree06c940a96a184a178bfadd53e04213225655a68d /gcc/config/iq2000
parentb7a0af68063c79655c561750e9863799bf846cae (diff)
downloadgcc-f90b7a5a7913cc7239cce42f6ca328b9a741b387.tar.gz
Merge cond-optab branch.
From-SVN: r147425
Diffstat (limited to 'gcc/config/iq2000')
-rw-r--r--gcc/config/iq2000/iq2000-protos.h2
-rw-r--r--gcc/config/iq2000/iq2000.c64
-rw-r--r--gcc/config/iq2000/iq2000.h7
-rw-r--r--gcc/config/iq2000/iq2000.md400
-rw-r--r--gcc/config/iq2000/predicates.md8
5 files changed, 40 insertions, 441 deletions
diff --git a/gcc/config/iq2000/iq2000-protos.h b/gcc/config/iq2000/iq2000-protos.h
index 094bcbf2f12..a927452d83c 100644
--- a/gcc/config/iq2000/iq2000-protos.h
+++ b/gcc/config/iq2000/iq2000-protos.h
@@ -41,7 +41,7 @@ extern void print_operand (FILE *, rtx, int);
#ifdef RTX_CODE
extern rtx gen_int_relational (enum rtx_code, rtx, rtx, rtx, int *);
-extern void gen_conditional_branch (rtx *, enum rtx_code);
+extern void gen_conditional_branch (rtx *, enum machine_mode);
#endif
#ifdef TREE_CODE
diff --git a/gcc/config/iq2000/iq2000.c b/gcc/config/iq2000/iq2000.c
index 3b9e1166b27..28bb7a831fe 100644
--- a/gcc/config/iq2000/iq2000.c
+++ b/gcc/config/iq2000/iq2000.c
@@ -118,13 +118,6 @@ enum processor_type iq2000_tune;
/* Which instruction set architecture to use. */
int iq2000_isa;
-/* Cached operands, and operator to compare for use in set/branch/trap
- on condition codes. */
-rtx branch_cmp[2];
-
-/* What type of branch to use. */
-enum cmp_type branch_type;
-
/* Local variables. */
/* The next branch instruction is a branch likely, not branch normal. */
@@ -1010,60 +1003,31 @@ gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1,
The comparison operands are saved away by cmp{si,di,sf,df}. */
void
-gen_conditional_branch (rtx operands[], enum rtx_code test_code)
+gen_conditional_branch (rtx operands[], enum machine_mode mode)
{
- enum cmp_type type = branch_type;
- rtx cmp0 = branch_cmp[0];
- rtx cmp1 = branch_cmp[1];
- enum machine_mode mode;
+ enum rtx_code test_code = GET_CODE (operands[0]);
+ rtx cmp0 = operands[1];
+ rtx cmp1 = operands[2];
rtx reg;
int invert;
rtx label1, label2;
- switch (type)
- {
- case CMP_SI:
- case CMP_DI:
- mode = type == CMP_SI ? SImode : DImode;
- invert = 0;
- reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert);
-
- if (reg)
- {
- cmp0 = reg;
- cmp1 = const0_rtx;
- test_code = NE;
- }
- else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
- /* We don't want to build a comparison against a nonzero
- constant. */
- cmp1 = force_reg (mode, cmp1);
-
- break;
-
- case CMP_SF:
- case CMP_DF:
- reg = gen_reg_rtx (CCmode);
+ invert = 0;
+ reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert);
- /* For cmp0 != cmp1, build cmp0 == cmp1, and test for result == 0. */
- emit_insn (gen_rtx_SET (VOIDmode, reg,
- gen_rtx_fmt_ee (test_code == NE ? EQ : test_code,
- CCmode, cmp0, cmp1)));
-
- test_code = test_code == NE ? EQ : NE;
- mode = CCmode;
+ if (reg)
+ {
cmp0 = reg;
cmp1 = const0_rtx;
- invert = 0;
- break;
-
- default:
- abort_with_insn (gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1),
- "bad test");
+ test_code = NE;
}
+ else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
+ /* We don't want to build a comparison against a nonzero
+ constant. */
+ cmp1 = force_reg (mode, cmp1);
/* Generate the branch. */
- label1 = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
+ label1 = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
label2 = pc_rtx;
if (invert)
diff --git a/gcc/config/iq2000/iq2000.h b/gcc/config/iq2000/iq2000.h
index 30642b2a13f..0664f511bd3 100644
--- a/gcc/config/iq2000/iq2000.h
+++ b/gcc/config/iq2000/iq2000.h
@@ -1001,13 +1001,6 @@ extern enum processor_type iq2000_tune;
/* Which instruction set architecture to use. */
extern int iq2000_isa;
-/* Cached operands, and operator to compare for use in set/branch/trap
- on condition codes. */
-extern rtx branch_cmp[2];
-
-/* What type of branch to use. */
-extern enum cmp_type branch_type;
-
enum iq2000_builtins
{
IQ2000_BUILTIN_ADO16,
diff --git a/gcc/config/iq2000/iq2000.md b/gcc/config/iq2000/iq2000.md
index 919f6a20231..61275f2c671 100644
--- a/gcc/config/iq2000/iq2000.md
+++ b/gcc/config/iq2000/iq2000.md
@@ -989,63 +989,25 @@
;;
;; ....................
;;
-;; COMPARISONS
+;; CONDITIONAL BRANCHES
;;
;; ....................
-;; Flow here is rather complex:
-;;
-;; 1) The cmp{si,di,sf,df} routine is called. It deposits the
-;; arguments into the branch_cmp array, and the type into
-;; branch_type. No RTL is generated.
-;;
-;; 2) The appropriate branch define_expand is called, which then
-;; creates the appropriate RTL for the comparison and branch.
-;; Different CC modes are used, based on what type of branch is
-;; done, so that we can constrain things appropriately. There
-;; are assumptions in the rest of GCC that break if we fold the
-;; operands into the branches for integer operations, and use cc0
-;; for floating point, so we use the fp status register instead.
-;; If needed, an appropriate temporary is created to hold the
-;; of the integer compare.
-
-(define_expand "cmpsi"
- [(set (cc0)
- (compare:CC (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "arith_operand" "")))]
+(define_expand "cbranchsi4"
+ [(set (pc)
+ (if_then_else
+ (match_operator:SI 0 "ordered_comparison_operator"
+ [(match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "reg_or_const_operand")])
+ (label_ref (match_operand:SI 3 ""))
+ (pc)))]
""
"
{
- if (operands[0]) /* avoid unused code message */
- {
- branch_cmp[0] = operands[0];
- branch_cmp[1] = operands[1];
- branch_type = CMP_SI;
- DONE;
- }
+ gen_conditional_branch (operands, SImode);
+ DONE;
}")
-(define_expand "tstsi"
- [(set (cc0)
- (match_operand:SI 0 "register_operand" ""))]
- ""
- "
-{
- if (operands[0]) /* avoid unused code message */
- {
- branch_cmp[0] = operands[0];
- branch_cmp[1] = const0_rtx;
- branch_type = CMP_SI;
- DONE;
- }
-}")
-
-;;
-;; ....................
-;;
-;; CONDITIONAL BRANCHES
-;;
-;; ....................
;; Conditional branches on comparisons with zero.
@@ -1135,166 +1097,6 @@
[(set_attr "type" "branch")
(set_attr "mode" "none")])
-(define_expand "beq"
- [(set (pc)
- (if_then_else (eq:CC (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (operands[0]) /* avoid unused code warning */
- {
- gen_conditional_branch (operands, EQ);
- DONE;
- }
-}")
-
-(define_expand "bne"
- [(set (pc)
- (if_then_else (ne:CC (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (operands[0]) /* avoid unused code warning */
- {
- gen_conditional_branch (operands, NE);
- DONE;
- }
-}")
-
-(define_expand "bgt"
- [(set (pc)
- (if_then_else (gt:CC (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (operands[0]) /* avoid unused code warning */
- {
- gen_conditional_branch (operands, GT);
- DONE;
- }
-}")
-
-(define_expand "bge"
- [(set (pc)
- (if_then_else (ge:CC (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (operands[0]) /* avoid unused code warning */
- {
- gen_conditional_branch (operands, GE);
- DONE;
- }
-}")
-
-(define_expand "blt"
- [(set (pc)
- (if_then_else (lt:CC (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (operands[0]) /* avoid unused code warning */
- {
- gen_conditional_branch (operands, LT);
- DONE;
- }
-}")
-
-(define_expand "ble"
- [(set (pc)
- (if_then_else (le:CC (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (operands[0]) /* avoid unused code warning */
- {
- gen_conditional_branch (operands, LE);
- DONE;
- }
-}")
-
-(define_expand "bgtu"
- [(set (pc)
- (if_then_else (gtu:CC (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (operands[0]) /* avoid unused code warning */
- {
- gen_conditional_branch (operands, GTU);
- DONE;
- }
-}")
-
-(define_expand "bgeu"
- [(set (pc)
- (if_then_else (geu:CC (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (operands[0]) /* avoid unused code warning */
- {
- gen_conditional_branch (operands, GEU);
- DONE;
- }
-}")
-
-
-(define_expand "bltu"
- [(set (pc)
- (if_then_else (ltu:CC (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (operands[0]) /* avoid unused code warning */
- {
- gen_conditional_branch (operands, LTU);
- DONE;
- }
-}")
-
-(define_expand "bleu"
- [(set (pc)
- (if_then_else (leu:CC (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (operands[0]) /* avoid unused code warning */
- {
- gen_conditional_branch (operands, LEU);
- DONE;
- }
-}")
;; Recognize bbi and bbin instructions. These use two unusual template
;; patterns, %Ax and %Px. %Ax outputs an 'i' if operand `x' is a LABEL_REF
@@ -1390,25 +1192,19 @@
;;
;; ....................
-(define_expand "seq"
+(define_expand "cstoresi4"
[(set (match_operand:SI 0 "register_operand" "=d")
- (eq:SI (match_dup 1)
- (match_dup 2)))]
+ (match_operator:SI 1 "ordered_comparison_operator"
+ [(match_operand:SI 2 "register_operand")
+ (match_operand:SI 3 "reg_or_const_operand")]))]
""
"
{
- if (branch_type != CMP_SI && (branch_type != CMP_DI))
- FAIL;
-
- /* Set up operands from compare. */
- operands[1] = branch_cmp[0];
- operands[2] = branch_cmp[1];
-
- gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
+ gen_int_relational (GET_CODE (operands[1]), operands[0],
+ operands[2], operands[3], (int *)0);
DONE;
}")
-
(define_insn "seq_si_zero"
[(set (match_operand:SI 0 "register_operand" "=d")
(eq:SI (match_operand:SI 1 "register_operand" "d")
@@ -1418,24 +1214,6 @@
[(set_attr "type" "arith")
(set_attr "mode" "SI")])
-(define_expand "sne"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (ne:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- if (branch_type != CMP_SI && (branch_type != CMP_DI))
- FAIL;
-
- /* Set up operands from compare. */
- operands[1] = branch_cmp[0];
- operands[2] = branch_cmp[1];
-
- gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
- DONE;
-}")
-
(define_insn "sne_si_zero"
[(set (match_operand:SI 0 "register_operand" "=d")
(ne:SI (match_operand:SI 1 "register_operand" "d")
@@ -1445,24 +1223,6 @@
[(set_attr "type" "arith")
(set_attr "mode" "SI")])
-(define_expand "sgt"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (gt:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- if (branch_type != CMP_SI && (branch_type != CMP_DI))
- FAIL;
-
- /* Set up operands from compare. */
- operands[1] = branch_cmp[0];
- operands[2] = branch_cmp[1];
-
- gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
- DONE;
-}")
-
(define_insn "sgt_si"
[(set (match_operand:SI 0 "register_operand" "=d,=d")
(gt:SI (match_operand:SI 1 "register_operand" "d,d")
@@ -1474,42 +1234,6 @@
[(set_attr "type" "arith,arith")
(set_attr "mode" "SI,SI")])
-(define_expand "sge"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (ge:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- if (branch_type != CMP_SI && (branch_type != CMP_DI))
- FAIL;
-
- /* Set up operands from compare. */
- operands[1] = branch_cmp[0];
- operands[2] = branch_cmp[1];
-
- gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
- DONE;
-}")
-
-(define_expand "slt"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (lt:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- if (branch_type != CMP_SI && (branch_type != CMP_DI))
- FAIL;
-
- /* Set up operands from compare. */
- operands[1] = branch_cmp[0];
- operands[2] = branch_cmp[1];
-
- gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
- DONE;
-}")
-
(define_insn "slt_si"
[(set (match_operand:SI 0 "register_operand" "=d,=d")
(lt:SI (match_operand:SI 1 "register_operand" "d,d")
@@ -1521,24 +1245,6 @@
[(set_attr "type" "arith,arith")
(set_attr "mode" "SI,SI")])
-(define_expand "sle"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (le:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- if (branch_type != CMP_SI && (branch_type != CMP_DI))
- FAIL;
-
- /* Set up operands from compare. */
- operands[1] = branch_cmp[0];
- operands[2] = branch_cmp[1];
-
- gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
- DONE;
-}")
-
(define_insn "sle_si_const"
[(set (match_operand:SI 0 "register_operand" "=d")
(le:SI (match_operand:SI 1 "register_operand" "d")
@@ -1552,24 +1258,6 @@
[(set_attr "type" "arith")
(set_attr "mode" "SI")])
-(define_expand "sgtu"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (gtu:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- if (branch_type != CMP_SI && (branch_type != CMP_DI))
- FAIL;
-
- /* Set up operands from compare. */
- operands[1] = branch_cmp[0];
- operands[2] = branch_cmp[1];
-
- gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
- DONE;
-}")
-
(define_insn "sgtu_si"
[(set (match_operand:SI 0 "register_operand" "=d")
(gtu:SI (match_operand:SI 1 "register_operand" "d")
@@ -1588,42 +1276,6 @@
[(set_attr "type" "arith")
(set_attr "mode" "SI")])
-(define_expand "sgeu"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (geu:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- if (branch_type != CMP_SI && (branch_type != CMP_DI))
- FAIL;
-
- /* Set up operands from compare. */
- operands[1] = branch_cmp[0];
- operands[2] = branch_cmp[1];
-
- gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
- DONE;
-}")
-
-(define_expand "sltu"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (ltu:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- if (branch_type != CMP_SI && (branch_type != CMP_DI))
- FAIL;
-
- /* Set up operands from compare. */
- operands[1] = branch_cmp[0];
- operands[2] = branch_cmp[1];
-
- gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
- DONE;
-}")
-
(define_insn "sltu_si"
[(set (match_operand:SI 0 "register_operand" "=d,=d")
(ltu:SI (match_operand:SI 1 "register_operand" "d,d")
@@ -1635,24 +1287,6 @@
[(set_attr "type" "arith,arith")
(set_attr "mode" "SI,SI")])
-(define_expand "sleu"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (leu:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- if (branch_type != CMP_SI && (branch_type != CMP_DI))
- FAIL;
-
- /* Set up operands from compare. */
- operands[1] = branch_cmp[0];
- operands[2] = branch_cmp[1];
-
- gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
- DONE;
-}")
-
(define_insn "sleu_si_const"
[(set (match_operand:SI 0 "register_operand" "=d")
(leu:SI (match_operand:SI 1 "register_operand" "d")
diff --git a/gcc/config/iq2000/predicates.md b/gcc/config/iq2000/predicates.md
index 53471e455ad..f275090309b 100644
--- a/gcc/config/iq2000/predicates.md
+++ b/gcc/config/iq2000/predicates.md
@@ -41,6 +41,14 @@
return register_operand (op, mode);
})
+;; Return 1 if OP is a register or a constant. gen_int_relational
+;; takes care of forcing out-of-range constants into a register.
+
+(define_predicate "reg_or_const_operand"
+ (ior (match_code "const_int")
+ (and (match_code "reg,subreg")
+ (match_operand 0 "register_operand"))))
+
;; Return 1 if OP is a integer which fits in 16 bits.
(define_predicate "small_int"