diff options
Diffstat (limited to 'gcc/config/v850')
-rw-r--r-- | gcc/config/v850/v850.c | 5 | ||||
-rw-r--r-- | gcc/config/v850/v850.md | 302 |
2 files changed, 62 insertions, 245 deletions
diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c index a562202..f9e8a7d 100644 --- a/gcc/config/v850/v850.c +++ b/gcc/config/v850/v850.c @@ -464,6 +464,11 @@ v850_rtx_costs (rtx x, *total = 20; return true; + case ZERO_EXTRACT: + if (outer_code == COMPARE) + *total = 0; + return false; + default: return false; } diff --git a/gcc/config/v850/v850.md b/gcc/config/v850/v850.md index dad3cdd..69c8d88 100644 --- a/gcc/config/v850/v850.md +++ b/gcc/config/v850/v850.md @@ -227,9 +227,11 @@ ;; ---------------------------------------------------------------------- (define_insn "*v850_tst1" - [(set (cc0) (zero_extract:SI (match_operand:QI 0 "memory_operand" "m") - (const_int 1) - (match_operand:QI 1 "const_int_operand" "n")))] + [(set (cc0) + (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "m") + (const_int 1) + (match_operand:QI 1 "const_int_operand" "n")) + (const_int 0)))] "" "tst1 %1,%0" [(set_attr "length" "4") @@ -237,37 +239,52 @@ ;; This replaces ld.b;sar;andi with tst1;setf nz. -;; ??? The zero_extract sets the Z bit to the opposite of what one would -;; expect. This perhaps should be wrapped in a (eq: X (const_int 0)). - (define_split [(set (match_operand:SI 0 "register_operand" "") - (zero_extract:SI (match_operand:QI 1 "memory_operand" "") - (const_int 1) - (match_operand 2 "const_int_operand" "")))] - "" - [(set (cc0) (zero_extract:SI (match_dup 1) - (const_int 1) - (match_dup 2))) + (compare (zero_extract:SI (match_operand:QI 1 "memory_operand" "") + (const_int 1) + (match_operand 2 "const_int_operand" "")) + (const_int 0)))] + "" + [(set (cc0) (compare (zero_extract:SI (match_dup 1) + (const_int 1) + (match_dup 2)) + (const_int 0))) (set (match_dup 0) (ne:SI (cc0) (const_int 0)))]) -(define_insn "tstsi" - [(set (cc0) (match_operand:SI 0 "register_operand" "r"))] - "" - "cmp %.,%0" - [(set_attr "length" "2") - (set_attr "cc" "set_znv")]) +(define_expand "cbranchsi4" + [(set (cc0) + (compare (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "reg_or_int5_operand" ""))) + (set (pc) + (if_then_else + (match_operator 0 "ordered_comparison_operator" [(cc0) + (const_int 0)]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "") + +(define_expand "cstoresi4" + [(set (cc0) + (compare (match_operand:SI 2 "register_operand" "") + (match_operand:SI 3 "reg_or_int5_operand" ""))) + (set (match_operand:SI 0 "register_operand") + (match_operator:SI 1 "ordered_comparison_operator" [(cc0) + (const_int 0)]))] + "") -(define_insn "cmpsi" +(define_insn "*cmpsi" [(set (cc0) - (compare (match_operand:SI 0 "register_operand" "r,r") - (match_operand:SI 1 "reg_or_int5_operand" "r,J")))] + (compare (match_operand:SI 0 "register_operand" "r,r,r") + (match_operand:SI 1 "reg_or_int5_operand" "r,I,J")))] "" "@ cmp %1,%0 + cmp %.,%0 cmp %1,%0" - [(set_attr "length" "2,2") - (set_attr "cc" "compare")]) + [(set_attr "length" "2,2,2") + (set_attr "cc" "compare,set_znv,compare")]) + ;; ---------------------------------------------------------------------- ;; ADD INSTRUCTIONS @@ -688,110 +705,25 @@ ;; Scc INSTRUCTIONS ;; ----------------------------------------------------------------- -(define_insn "sle" - [(set (match_operand:SI 0 "register_operand" "=r") - (le:SI (cc0) (const_int 0)))] - "" - "* -{ - if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) - return 0; - - return \"setf le,%0\"; -}" - [(set_attr "length" "4") - (set_attr "cc" "none_0hit")]) - -(define_insn "sleu" - [(set (match_operand:SI 0 "register_operand" "=r") - (leu:SI (cc0) (const_int 0)))] - "" - "setf nh,%0" - [(set_attr "length" "4") - (set_attr "cc" "none_0hit")]) - -(define_insn "sge" - [(set (match_operand:SI 0 "register_operand" "=r") - (ge:SI (cc0) (const_int 0)))] - "" - "* -{ - if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) - return 0; - - return \"setf ge,%0\"; -}" - [(set_attr "length" "4") - (set_attr "cc" "none_0hit")]) - -(define_insn "sgeu" +(define_insn "*setcc" [(set (match_operand:SI 0 "register_operand" "=r") - (geu:SI (cc0) (const_int 0)))] - "" - "setf nl,%0" - [(set_attr "length" "4") - (set_attr "cc" "none_0hit")]) - -(define_insn "slt" - [(set (match_operand:SI 0 "register_operand" "=r") - (lt:SI (cc0) (const_int 0)))] - "" - "* -{ - if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) - return 0; - - return \"setf lt,%0\"; -}" - [(set_attr "length" "4") - (set_attr "cc" "none_0hit")]) - -(define_insn "sltu" - [(set (match_operand:SI 0 "register_operand" "=r") - (ltu:SI (cc0) (const_int 0)))] - "" - "setf l,%0" - [(set_attr "length" "4") - (set_attr "cc" "none_0hit")]) - -(define_insn "sgt" - [(set (match_operand:SI 0 "register_operand" "=r") - (gt:SI (cc0) (const_int 0)))] + (match_operator:SI 1 "comparison_operator" + [(cc0) (const_int 0)]))] "" "* { - if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) + if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0 + && (GET_CODE (operands[1]) == GT + || GET_CODE (operands[1]) == GE + || GET_CODE (operands[1]) == LE + || GET_CODE (operands[1]) == LT)) return 0; - return \"setf gt,%0\"; + return \"setf %c1,%0\"; }" [(set_attr "length" "4") (set_attr "cc" "none_0hit")]) -(define_insn "sgtu" - [(set (match_operand:SI 0 "register_operand" "=r") - (gtu:SI (cc0) (const_int 0)))] - "" - "setf h,%0" - [(set_attr "length" "4") - (set_attr "cc" "none_0hit")]) - -(define_insn "seq" - [(set (match_operand:SI 0 "register_operand" "=r") - (eq:SI (cc0) (const_int 0)))] - "" - "setf z,%0" - [(set_attr "length" "4") - (set_attr "cc" "none_0hit")]) - -(define_insn "sne" - [(set (match_operand:SI 0 "register_operand" "=r") - (ne:SI (cc0) (const_int 0)))] - "" - "setf nz,%0" - [(set_attr "length" "4") - (set_attr "cc" "none_0hit")]) - ;; ---------------------------------------------------------------------- ;; CONDITIONAL MOVE INSTRUCTIONS ;; ---------------------------------------------------------------------- @@ -800,25 +732,15 @@ ;; hide the fact that this instruction uses cc0. We do so by including the ;; compare instruction inside it. -;; ??? This is very ugly. The right way to do this is to modify cmpsi so -;; that it doesn't emit RTL, and then modify the bcc/scc patterns so that -;; they emit RTL for the compare instruction. Unfortunately, this requires -;; lots of changes that will be hard to sanitize. So for now, cmpsi still -;; emits RTL, and I get the compare operands here from the previous insn. - (define_expand "movsicc" [(set (match_operand:SI 0 "register_operand" "=r") (if_then_else:SI - (match_operator 1 "comparison_operator" - [(match_dup 4) (match_dup 5)]) + (match_operand 1 "comparison_operator") (match_operand:SI 2 "reg_or_const_operand" "rJ") (match_operand:SI 3 "reg_or_const_operand" "rI")))] "TARGET_V850E" " { - rtx insn = get_last_insn_anywhere (); - rtx src; - if ( (GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT)) { @@ -845,28 +767,6 @@ if (GET_CODE (operands[3]) != REG) operands[3] = copy_to_mode_reg (SImode, operands[3]); } - gcc_assert (GET_CODE (insn) == INSN - && GET_CODE (PATTERN (insn)) == SET - && SET_DEST (PATTERN (insn)) == cc0_rtx); - - src = SET_SRC (PATTERN (insn)); - - switch (GET_CODE (src)) - { - case COMPARE: - operands[4] = XEXP (src, 0); - operands[5] = XEXP (src, 1); - break; - - case REG: - case SUBREG: - operands[4] = src; - operands[5] = const0_rtx; - break; - - default: - gcc_unreachable (); - } }") ;; ??? Clobbering the condition codes is overkill. @@ -1037,96 +937,6 @@ ;; Conditional jump instructions -(define_expand "ble" - [(set (pc) - (if_then_else (le (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bleu" - [(set (pc) - (if_then_else (leu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bge" - [(set (pc) - (if_then_else (ge (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bgeu" - [(set (pc) - (if_then_else (geu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "blt" - [(set (pc) - (if_then_else (lt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bltu" - [(set (pc) - (if_then_else (ltu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bgt" - [(set (pc) - (if_then_else (gt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bgtu" - [(set (pc) - (if_then_else (gtu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "beq" - [(set (pc) - (if_then_else (eq (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bne" - [(set (pc) - (if_then_else (ne (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - (define_insn "*branch_normal" [(set (pc) (if_then_else (match_operator 1 "comparison_operator" @@ -1241,14 +1051,16 @@ { rtx reg = gen_reg_rtx (SImode); rtx tableaddress = gen_reg_rtx (SImode); + rtx test; rtx mem; /* Subtract the lower bound from the index. */ emit_insn (gen_subsi3 (reg, operands[0], operands[1])); - /* Compare the result against the number of table entries. */ - emit_insn (gen_cmpsi (reg, operands[2])); - /* Branch to the default label if out of range of the table. */ - emit_jump_insn (gen_bgtu (operands[4])); + + /* Compare the result against the number of table entries; + branch to the default label if out of range of the table. */ + test = gen_rtx_fmt_ee (GTU, VOIDmode, reg, operands[2]); + emit_jump_insn (gen_cbranchsi4 (test, reg, operands[2], operands[4])); /* Shift index for the table array access. */ emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1))); |