diff options
author | Paolo Bonzini <bonzini@gnu.org> | 2009-05-12 09:43:48 +0000 |
---|---|---|
committer | Paolo Bonzini <bonzini@gcc.gnu.org> | 2009-05-12 09:43:48 +0000 |
commit | f90b7a5a7913cc7239cce42f6ca328b9a741b387 (patch) | |
tree | 06c940a96a184a178bfadd53e04213225655a68d /gcc/config/iq2000 | |
parent | b7a0af68063c79655c561750e9863799bf846cae (diff) | |
download | gcc-f90b7a5a7913cc7239cce42f6ca328b9a741b387.tar.gz |
Merge cond-optab branch.
From-SVN: r147425
Diffstat (limited to 'gcc/config/iq2000')
-rw-r--r-- | gcc/config/iq2000/iq2000-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/iq2000/iq2000.c | 64 | ||||
-rw-r--r-- | gcc/config/iq2000/iq2000.h | 7 | ||||
-rw-r--r-- | gcc/config/iq2000/iq2000.md | 400 | ||||
-rw-r--r-- | gcc/config/iq2000/predicates.md | 8 |
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" |