diff options
Diffstat (limited to 'gcc/config/arc')
-rw-r--r-- | gcc/config/arc/arc.c | 17 | ||||
-rw-r--r-- | gcc/config/arc/arc.h | 5 | ||||
-rw-r--r-- | gcc/config/arc/arc.md | 337 |
3 files changed, 41 insertions, 318 deletions
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c index 3f81f61..1f456b6 100644 --- a/gcc/config/arc/arc.c +++ b/gcc/config/arc/arc.c @@ -49,10 +49,6 @@ int arc_cpu_type; cpu (or NULL). */ const char *arc_mangle_cpu; -/* Save the operands last given to a compare for use when we - generate a scc or bcc insn. */ -rtx arc_compare_op0, arc_compare_op1; - /* Name of text, data, and rodata sections used in varasm.c. */ const char *arc_text_section; const char *arc_data_section; @@ -729,21 +725,14 @@ proper_comparison_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) /* Misc. utilities. */ -/* X and Y are two things to compare using CODE. Emit the compare insn and - return the rtx for the cc reg in the proper mode. */ +/* X and Y are two things to compare using CODE. Return the rtx + for the cc reg in the proper mode. */ rtx gen_compare_reg (enum rtx_code code, rtx x, rtx y) { enum machine_mode mode = SELECT_CC_MODE (code, x, y); - rtx cc_reg; - - cc_reg = gen_rtx_REG (mode, 61); - - emit_insn (gen_rtx_SET (VOIDmode, cc_reg, - gen_rtx_COMPARE (mode, x, y))); - - return cc_reg; + return gen_rtx_REG (mode, 61); } /* Return 1 if VALUE, a const_double, will fit in a limm (4 byte number). diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h index db6829b..4153ad6 100644 --- a/gcc/config/arc/arc.h +++ b/gcc/config/arc/arc.h @@ -1067,11 +1067,6 @@ do { if ((LOG) != 0) fprintf (FILE, "\t.align %d\n", 1 << (LOG)); } while (0) /* ??? Not defined in tm.texi. */ #define SETJMP_VIA_SAVE_AREA -/* Define the information needed to generate branch and scc insns. This is - stored from the compare operation. Note that we can't use "rtx" here - since it hasn't been defined! */ -extern struct rtx_def *arc_compare_op0, *arc_compare_op1; - /* ARC function types. */ enum arc_function_type { ARC_FUNCTION_UNKNOWN, ARC_FUNCTION_NORMAL, diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md index b67984ba..09e47da 100644 --- a/gcc/config/arc/arc.md +++ b/gcc/config/arc/arc.md @@ -585,29 +585,11 @@ " { enum rtx_code code = GET_CODE (operands[1]); - rtx ccreg - = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1), - 61); - - operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); + rtx cc_reg = gen_compare_reg (code, XEXP (operands[1], 0), + XEXP (operands[1], 1)); + operands[1] = gen_rtx_fmt_ee (code, VOIDmode, cc_reg, const0_rtx); }") -;(define_expand "movdicc" -; [(set (match_operand:DI 0 "register_operand" "") -; (if_then_else:DI (match_operand 1 "comparison_operator" "") -; (match_operand:DI 2 "nonmemory_operand" "") -; (match_operand:DI 3 "register_operand" "")))] -; "0 /* ??? this would work better if we had cmpdi */" -; " -;{ -; enum rtx_code code = GET_CODE (operands[1]); -; rtx ccreg -; = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1), -; 61); -; -; operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); -;}") - (define_expand "movsfcc" [(set (match_operand:SF 0 "register_operand" "") (if_then_else:SF (match_operand 1 "comparison_operator" "") @@ -617,29 +599,11 @@ " { enum rtx_code code = GET_CODE (operands[1]); - rtx ccreg - = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1), - 61); - - operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); + rtx cc_reg = gen_compare_reg (code, XEXP (operands[1], 0), + XEXP (operands[1], 1)); + operands[1] = gen_rtx_fmt_ee (code, VOIDmode, cc_reg, const0_rtx); }") -;(define_expand "movdfcc" -; [(set (match_operand:DF 0 "register_operand" "") -; (if_then_else:DF (match_operand 1 "comparison_operator" "") -; (match_operand:DF 2 "nonmemory_operand" "") -; (match_operand:DF 3 "register_operand" "")))] -; "0 /* ??? can generate less efficient code if constants involved */" -; " -;{ -; enum rtx_code code = GET_CODE (operands[1]); -; rtx ccreg -; = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1), -; 61); -; -; operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); -;}") - (define_insn "*movsicc_insn" [(set (match_operand:SI 0 "register_operand" "=r") (if_then_else:SI (match_operand 1 "comparison_operator" "") @@ -649,32 +613,6 @@ "mov.%d1 %0,%S2" [(set_attr "type" "cmove")]) -; ??? This doesn't properly handle constants. -;(define_insn "*movdicc_insn" -; [(set (match_operand:DI 0 "register_operand" "=r,r") -; (if_then_else:DI (match_operand 1 "comparison_operator" "") -; (match_operand:DI 2 "nonmemory_operand" "r,Ji") -; (match_operand:DI 3 "register_operand" "0,0")))] -; "0" -; "* -;{ -; switch (which_alternative) -; { -; case 0 : -; /* We normally copy the low-numbered register first. However, if -; the first register operand 0 is the same as the second register of -; operand 1, we must copy in the opposite order. */ -; if (REGNO (operands[0]) == REGNO (operands[2]) + 1) -; return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\"; -; else -; return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\"; -; case 1 : -; return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\"; -; } -;}" -; [(set_attr "type" "cmove,cmove") -; (set_attr "length" "2,4")]) - (define_insn "*movsfcc_insn" [(set (match_operand:SF 0 "register_operand" "=r,r") (if_then_else:SF (match_operand 1 "comparison_operator" "") @@ -686,30 +624,6 @@ mov.%d1 %0,%2 ; %A2" [(set_attr "type" "cmove,cmove")]) -;(define_insn "*movdfcc_insn" -; [(set (match_operand:DF 0 "register_operand" "=r,r") -; (if_then_else:DF (match_operand 1 "comparison_operator" "") -; (match_operand:DF 2 "nonmemory_operand" "r,E") -; (match_operand:DF 3 "register_operand" "0,0")))] -; "0" -; "* -;{ -; switch (which_alternative) -; { -; case 0 : -; /* We normally copy the low-numbered register first. However, if -; the first register operand 0 is the same as the second register of -; operand 1, we must copy in the opposite order. */ -; if (REGNO (operands[0]) == REGNO (operands[2]) + 1) -; return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\"; -; else -; return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\"; -; case 1 : -; return \"mov.%d1 %0,%L2\;mov.%d1 %R0,%H2 ; %A2\"; -; } -;}" -; [(set_attr "type" "cmove,cmove") -; (set_attr "length" "2,4")]) ;; Zero extension instructions. ;; ??? We don't support volatile memrefs here, but I'm not sure why. @@ -1156,22 +1070,6 @@ ;; Compare instructions. ;; This controls RTL generation and register allocation. -;; We generate RTL for comparisons and branches by having the cmpxx -;; patterns store away the operands. Then, the scc and bcc patterns -;; emit RTL for both the compare and the branch. - -(define_expand "cmpsi" - [(set (reg:CC 61) - (compare:CC (match_operand:SI 0 "register_operand" "") - (match_operand:SI 1 "nonmemory_operand" "")))] - "" - " -{ - arc_compare_op0 = operands[0]; - arc_compare_op1 = operands[1]; - DONE; -}") - ;; ??? We may be able to relax this a bit by adding a new constant 'K' for 0. ;; This assumes sub.f 0,symbol,0 is a valid insn. ;; Note that "sub.f 0,r0,1" is an 8 byte insn. To avoid unnecessarily @@ -1211,96 +1109,25 @@ sub.f 0,%0,%1" [(set_attr "type" "compare,compare,compare")]) -;; Next come the scc insns. - -(define_expand "seq" - [(set (match_operand:SI 0 "register_operand" "=r") - (eq:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1); -}") +;; Next come the scc insn and its expander. -(define_expand "sne" - [(set (match_operand:SI 0 "register_operand" "=r") - (ne:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1); -}") - -(define_expand "sgt" - [(set (match_operand:SI 0 "register_operand" "=r") - (gt:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1); -}") - -(define_expand "sle" - [(set (match_operand:SI 0 "register_operand" "=r") - (le:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1); -}") - -(define_expand "sge" - [(set (match_operand:SI 0 "register_operand" "=r") - (ge:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1); -}") - -(define_expand "slt" - [(set (match_operand:SI 0 "register_operand" "=r") - (lt:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1); -}") - -(define_expand "sgtu" - [(set (match_operand:SI 0 "register_operand" "=r") - (gtu:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1); -}") - -(define_expand "sleu" - [(set (match_operand:SI 0 "register_operand" "=r") - (leu:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1); -}") - -(define_expand "sgeu" - [(set (match_operand:SI 0 "register_operand" "=r") - (geu:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1); -}") - -(define_expand "sltu" - [(set (match_operand:SI 0 "register_operand" "=r") - (ltu:SI (match_dup 1) (const_int 0)))] +(define_expand "cstoresi4" + [(set (match_dup 4) + (match_op_dup 5 + [(match_operand:SI 2 "register_operand" "") + (match_operand:SI 3 "nonmemory_operand" "")])) + (set (match_operand:SI 0 "register_operand") + (match_operator:SI 1 "ordered_comparison_operator" + [(match_dup 4) + (const_int 0)]))] "" " { - operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1); + operands[4] = gen_compare_reg (GET_CODE (operands[1]), + operands[2], operands[3]); + operands[5] = gen_rtx_fmt_ee (COMPARE, + GET_MODE (operands[4]), + operands[2], operands[3]); }") (define_insn "*scc_insn" @@ -1332,114 +1159,26 @@ ;; These control RTL generation for conditional jump insns -(define_expand "beq" - [(set (pc) - (if_then_else (eq (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1); -}") - -(define_expand "bne" - [(set (pc) - (if_then_else (ne (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1); -}") - -(define_expand "bgt" - [(set (pc) - (if_then_else (gt (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1); -}") - -(define_expand "ble" - [(set (pc) - (if_then_else (le (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1); -}") - -(define_expand "bge" - [(set (pc) - (if_then_else (ge (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1); -}") - -(define_expand "blt" - [(set (pc) - (if_then_else (lt (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1); -}") - -(define_expand "bgtu" - [(set (pc) - (if_then_else (gtu (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1); -}") - -(define_expand "bleu" - [(set (pc) - (if_then_else (leu (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1); -}") - -(define_expand "bgeu" - [(set (pc) - (if_then_else (geu (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1); -}") - -(define_expand "bltu" - [(set (pc) - (if_then_else (ltu (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] +(define_expand "cbranchsi4" + [(set (match_dup 4) + (match_op_dup 5 + [(match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "nonmemory_operand" "")])) + (set (pc) + (if_then_else + (match_operator 0 "ordered_comparison_operator" + [(match_dup 4) + (const_int 0)]) + (label_ref (match_operand 3 "" "")) + (pc)))] "" " { - operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1); + operands[4] = gen_compare_reg (GET_CODE (operands[0]), + operands[1], operands[2]); + operands[5] = gen_rtx_fmt_ee (COMPARE, + GET_MODE (operands[4]), + operands[1], operands[2]); }") ;; Now match both normal and inverted jump. |