@@ -32,7 +32,6 @@ extern void v850_init_expanders (void);
#ifdef RTX_CODE
extern rtx v850_return_addr (int);
extern const char *output_move_single (rtx *);
-extern void notice_update_cc (rtx, rtx_insn *);
extern char * construct_save_jarl (rtx);
extern char * construct_restore_jr (rtx);
#ifdef HAVE_MACHINE_MODES
@@ -68,8 +68,6 @@ data_area_stack_element * data_area_stack = NULL;
function is an interrupt handler. */
static int v850_interrupt_cache_p = FALSE;
-rtx v850_compare_op0, v850_compare_op1;
-
/* Whether current function is an interrupt handler. */
static int v850_interrupt_p = FALSE;
@@ -418,7 +416,9 @@ v850_print_operand (FILE * file, rtx x, int code)
case 'b':
case 'B':
case 'C':
- switch ((code == 'B' || code == 'C')
+ case 'd':
+ case 'D':
+ switch ((code == 'B' || code == 'C' || code == 'D')
? reverse_condition (GET_CODE (x)) : GET_CODE (x))
{
case NE:
@@ -434,7 +434,10 @@ v850_print_operand (FILE * file, rtx x, int code)
fprintf (file, "e");
break;
case GE:
- fprintf (file, "ge");
+ if (code == 'D' || code == 'd')
+ fprintf (file, "p");
+ else
+ fprintf (file, "ge");
break;
case GT:
fprintf (file, "gt");
@@ -443,7 +446,10 @@ v850_print_operand (FILE * file, rtx x, int code)
fprintf (file, "le");
break;
case LT:
- fprintf (file, "lt");
+ if (code == 'D' || code == 'd')
+ fprintf (file, "n");
+ else
+ fprintf (file, "lt");
break;
case GEU:
fprintf (file, "nl");
@@ -905,7 +911,7 @@ output_move_single (rtx * operands)
}
machine_mode
-v850_select_cc_mode (enum rtx_code cond, rtx op0, rtx op1 ATTRIBUTE_UNUSED)
+v850_select_cc_mode (enum rtx_code cond, rtx op0, rtx op1)
{
if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT)
{
@@ -927,11 +933,20 @@ v850_select_cc_mode (enum rtx_code cond, rtx op0, rtx op1 ATTRIBUTE_UNUSED)
gcc_unreachable ();
}
}
+
+ if (op1 == const0_rtx
+ && (cond == EQ || cond == NE || cond == LT || cond == GE)
+ && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
+ || GET_CODE (op0) == NEG || GET_CODE (op0) == AND
+ || GET_CODE (op0) == IOR || GET_CODE (op0) == XOR
+ || GET_CODE (op0) == NOT || GET_CODE (op0) == ASHIFT))
+ return CCNZmode;
+
return CCmode;
}
machine_mode
-v850_gen_float_compare (enum rtx_code cond, machine_mode mode ATTRIBUTE_UNUSED, rtx op0, rtx op1)
+v850_gen_float_compare (enum rtx_code cond, machine_mode mode, rtx op0, rtx op1)
{
if (GET_MODE (op0) == DFmode)
{
@@ -960,7 +975,7 @@ v850_gen_float_compare (enum rtx_code cond, machine_mode mode ATTRIBUTE_UNUSED,
gcc_unreachable ();
}
}
- else if (GET_MODE (v850_compare_op0) == SFmode)
+ else if (mode == SFmode)
{
switch (cond)
{
@@ -993,25 +1008,6 @@ v850_gen_float_compare (enum rtx_code cond, machine_mode mode ATTRIBUTE_UNUSED,
return v850_select_cc_mode (cond, op0, op1);
}
-rtx
-v850_gen_compare (enum rtx_code cond, machine_mode mode, rtx op0, rtx op1)
-{
- if (GET_MODE_CLASS(GET_MODE (op0)) != MODE_FLOAT)
- {
- emit_insn (gen_cmpsi_insn (op0, op1));
- return gen_rtx_fmt_ee (cond, mode, gen_rtx_REG(CCmode, CC_REGNUM), const0_rtx);
- }
- else
- {
- rtx cc_reg;
- mode = v850_gen_float_compare (cond, mode, op0, op1);
- cc_reg = gen_rtx_REG (mode, CC_REGNUM);
- emit_insn (gen_rtx_SET (cc_reg, gen_rtx_REG (mode, FCC_REGNUM)));
-
- return gen_rtx_fmt_ee (cond, mode, cc_reg, const0_rtx);
- }
-}
-
/* Return maximum offset supported for a short EP memory reference of mode
MODE and signedness UNSIGNEDP. */
@@ -1635,7 +1631,7 @@ increment_stack (signed int amount, bool in_prologue)
inc = reg;
}
- inc = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, inc));
+ inc = emit_insn (gen_addsi3_clobber_flags (stack_pointer_rtx, stack_pointer_rtx, inc));
if (in_prologue)
F (inc);
}
@@ -1712,7 +1708,7 @@ expand_prologue (void)
save_all = gen_rtx_PARALLEL
(VOIDmode,
- rtvec_alloc (num_save + 1
+ rtvec_alloc (num_save + 2
+ (TARGET_DISABLE_CALLT ? (TARGET_LONG_CALLS ? 2 : 1) : 0)));
XVECEXP (save_all, 0, 0)
@@ -1731,13 +1727,16 @@ expand_prologue (void)
save_regs[i]);
}
+ XVECEXP (save_all, 0, num_save + 1)
+ = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, CC_REGNUM));
+
if (TARGET_DISABLE_CALLT)
{
- XVECEXP (save_all, 0, num_save + 1)
+ XVECEXP (save_all, 0, num_save + 2)
= gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 10));
if (TARGET_LONG_CALLS)
- XVECEXP (save_all, 0, num_save + 2)
+ XVECEXP (save_all, 0, num_save + 3)
= gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
}
@@ -2330,7 +2329,7 @@ construct_save_jarl (rtx op)
stack_bytes = INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1));
/* Each push will put 4 bytes from the stack.... */
- stack_bytes += (count - (TARGET_LONG_CALLS ? 3 : 2)) * 4;
+ stack_bytes += (count - (TARGET_LONG_CALLS ? 4 : 3)) * 4;
/* Make sure that the amount we are popping either 0 or 16 bytes. */
if (stack_bytes != 0)
@@ -2341,7 +2340,7 @@ construct_save_jarl (rtx op)
/* Now compute the bit mask of registers to push. */
mask = 0;
- for (i = 1; i < count - (TARGET_LONG_CALLS ? 2 : 1); i++)
+ for (i = 1; i < count - (TARGET_LONG_CALLS ? 3 : 2); i++)
{
rtx vector_element = XVECEXP (op, 0, i);
@@ -3325,6 +3324,9 @@ v850_modes_tieable_p (machine_mode mode1, machine_mode mode2)
#undef TARGET_MODES_TIEABLE_P
#define TARGET_MODES_TIEABLE_P v850_modes_tieable_p
+#undef TARGET_FLAGS_REGNUM
+#define TARGET_FLAGS_REGNUM 32
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-v850.h"
@@ -26,9 +26,6 @@
#ifndef GCC_V850_H
#define GCC_V850_H
-extern GTY(()) rtx v850_compare_op0;
-extern GTY(()) rtx v850_compare_op1;
-
#undef LIB_SPEC
#define LIB_SPEC "%{!shared:%{!symbolic:--start-group -lc -lgcc --end-group}}"
@@ -567,8 +564,6 @@ struct cum_arg { int nbytes; };
#define SELECT_CC_MODE(OP, X, Y) v850_select_cc_mode (OP, X, Y)
-#define NOTICE_UPDATE_CC(EXP, INSN)
-
/* Nonzero if access to memory by bytes or half words is no faster
than accessing full words. */
#define SLOW_BYTE_ACCESS 1
@@ -28,6 +28,42 @@
;;
;; One day we'll probably need to handle calls to targets more than 4M
;; away.
+;;
+
+;; Condition codes
+;;
+;; Data movement (load, store, register copy) does not modify condition
+;; codes. But there is no way to add two registers together without
+;; modifying the condition codes.
+;;
+;; So we do not expose the condition codes until after reload. The
+;; general approach is to have a define_insn_and_split for the basic
+;; operation with no condition codes in the pattern (to give the
+;; optimizers maximal freedom). The splitter adds a clobber of the
+;; condition codes after reload. There is a distinct pattern which
+;; sets the condition codes.
+;;
+;; As noted, data movement does not affect condition codes.
+;;
+;; Arithmetic generally set the codes in the expected ways, with mul
+;; instructions being a notable outlier. div instructions generally
+;; do the right thing, except when the output registers are the same
+;; when the flags do not get set. We just assume they're clobbered
+;; for div instructions to avoid MD bloat with marginal benefit
+;;
+;; The bit manipulation instructions (clr1, not1, set1) set condition
+;; codes, but not in a useful way (they're set to the prior status of
+;; the bit). So we just model those as clobbers. tst1 does set the
+;; condition codes in a useful way. We could perhaps do better with
+;; these by noting they only modify the Z flag, it doesn't seem worth
+;; the effort.
+;;
+;; Byte swaps seem to change the condition codes, but I haven't tried
+;; to describe how.
+;;
+;; I have no documentation on the rotate instructions. They likely
+;; set the condition codes, but I've left them as clobbers for now.
+
;; The size of instructions in bytes.
@@ -352,110 +388,90 @@
;; ----------------------------------------------------------------------
(define_insn "*v850_tst1"
- [(set (cc0)
+ [(set (reg:CCZ CC_REGNUM)
(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)))]
- ""
+ "reload_completed"
"tst1 %1,%0"
[(set_attr "length" "4")])
;; This replaces ld.b;sar;andi with tst1;setf nz.
+;; Should there be variants for HI or SI modes?
-(define_split
+(define_insn_and_split ""
[(set (match_operand:SI 0 "register_operand" "")
(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)))])
+ "#"
+ "reload_completed"
+ [(set (reg:CCZ CC_REGNUM) (compare (zero_extract:SI (match_dup 1)
+ (const_int 1)
+ (match_dup 2))
+ (const_int 0)))
+ (set (match_dup 0) (ne:SI (reg:CCZ CC_REGNUM) (const_int 0)))])
(define_expand "cbranchsi4"
- [(set (cc0)
- (compare (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "reg_or_int5_operand" "")))
- (set (pc)
+ [(set (pc)
(if_then_else
- (match_operator 0 "ordered_comparison_operator" [(cc0)
- (const_int 0)])
+ (match_operator 0 "comparison_operator"
+ [(match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "reg_or_int5_operand")])
(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_expand "cmpsi"
- [(set (cc0)
- (compare (match_operand:SI 0 "register_operand" "r,r")
- (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
- ""
- {
- v850_compare_op0 = operands[0];
- v850_compare_op1 = operands[1];
- DONE;
- })
-
(define_insn "cmpsi_insn"
- [(set (cc0)
+ [(set (reg:CC CC_REGNUM)
(compare (match_operand:SI 0 "register_operand" "r,r")
(match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
- ""
- "@
- cmp %1,%0
- cmp %1,%0"
+ "reload_completed"
+ "cmp %1,%0"
[(set_attr "length" "2,2")])
-(define_expand "cbranchsf4"
+(define_insn_and_split "cbranchsf4"
[(set (pc)
(if_then_else (match_operator 0 "ordered_comparison_operator"
- [(match_operand:SF 1 "register_operand")
- (match_operand:SF 2 "register_operand")])
+ [(match_operand:SF 1 "register_operand" "r")
+ (match_operand:SF 2 "register_operand" "r")])
(label_ref (match_operand 3 ""))
- (pc)))
- (clobber (cc0))]
+ (pc)))]
"TARGET_USE_FPU"
-{
- enum rtx_code cond = GET_CODE (operands[0]);
- machine_mode mode;
- rtx fcc_reg;
- rtx cc_reg;
- rtx tmp;
-
- v850_compare_op0 = operands[1];
- v850_compare_op1 = operands[2];
-
- if (GET_MODE_CLASS (GET_MODE (v850_compare_op0)) != MODE_FLOAT)
- FAIL;
-
- mode = v850_gen_float_compare (cond, VOIDmode, v850_compare_op0, v850_compare_op1);
- fcc_reg = gen_rtx_REG (mode, FCC_REGNUM);
- cc_reg = gen_rtx_REG (mode, CC_REGNUM);
- emit_insn (gen_rtx_SET (cc_reg, fcc_reg));
- tmp = gen_rtx_fmt_ee (cond, mode, cc_reg, const0_rtx);
- tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
- gen_rtx_LABEL_REF (VOIDmode, operands[3]), pc_rtx);
- emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
- DONE;
-})
+ "#"
+ "reload_completed"
+ [(set (match_dup 4) (match_dup 5))
+ (set (pc)
+ (if_then_else (match_dup 6)
+ (label_ref (match_dup 3))
+ (pc)))]
+ "{
+ /* This will generate the comparison insn at the start of
+ the sequence and get us the right mode to use for our
+ condition code registers. */
+ enum machine_mode mode
+ = v850_gen_float_compare (GET_CODE (operands[0]),
+ GET_MODE (operands[1]),
+ operands[1], operands[2]);
+ /* We want operands referring to CC_REGNUM and FCC_REGNUM
+ in mode MODE. */
+ operands[4] = gen_rtx_REG (mode, CC_REGNUM);
+ operands[5] = gen_rtx_REG (mode, FCC_REGNUM);
+ if (mode == CC_FPU_NEmode)
+ operands[6] = gen_rtx_NE (mode, operands[4], const0_rtx);
+ else
+ operands[6] = gen_rtx_EQ (mode, operands[4], const0_rtx);
+}")
(define_insn "cstoresf4"
[(set (match_operand:SI 0 "register_operand" "=r")
(match_operator:SI 1 "ordered_comparison_operator"
[(match_operand:SF 2 "register_operand" "r")
- (match_operand:SF 3 "register_operand" "r")]))]
+ (match_operand:SF 3 "register_operand" "r")]))
+ (clobber (reg:CC CC_REGNUM))]
"TARGET_USE_FPU"
{
if (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
@@ -471,44 +487,47 @@
[(set_attr "length" "12")
(set_attr "type" "fpu")])
-(define_expand "cbranchdf4"
+(define_insn_and_split "cbranchdf4"
[(set (pc)
(if_then_else (match_operator 0 "ordered_comparison_operator"
- [(match_operand:DF 1 "even_reg_operand")
- (match_operand:DF 2 "even_reg_operand")])
+ [(match_operand:DF 1 "even_reg_operand" "r")
+ (match_operand:DF 2 "even_reg_operand" "r")])
(label_ref (match_operand 3 ""))
- (pc)))
- (clobber (cc0))]
+ (pc)))]
"TARGET_USE_FPU"
-{
- enum rtx_code cond = GET_CODE (operands[0]);
- machine_mode mode;
- rtx fcc_reg;
- rtx cc_reg;
- rtx tmp;
-
- v850_compare_op0 = operands[1];
- v850_compare_op1 = operands[2];
-
- if (GET_MODE_CLASS (GET_MODE (v850_compare_op0)) != MODE_FLOAT)
- FAIL;
-
- mode = v850_gen_float_compare (cond, VOIDmode, v850_compare_op0, v850_compare_op1);
- fcc_reg = gen_rtx_REG (mode, FCC_REGNUM);
- cc_reg = gen_rtx_REG (mode, CC_REGNUM);
- emit_insn (gen_rtx_SET (cc_reg, fcc_reg));
- tmp = gen_rtx_fmt_ee (cond, mode, cc_reg, const0_rtx);
- tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
- gen_rtx_LABEL_REF (VOIDmode, operands[3]), pc_rtx);
- emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
- DONE;
-})
+ "#"
+ "reload_completed"
+;; How to get the mode here?
+ [(set (match_dup 4) (match_dup 5))
+ (set (pc)
+ (if_then_else (match_dup 6)
+ (label_ref (match_dup 3))
+ (pc)))]
+ "{
+ /* This will generate the comparison insn at the start of
+ the sequence and get us the right mode to use for our
+ condition code registers. */
+ enum machine_mode mode
+ = v850_gen_float_compare (GET_CODE (operands[0]),
+ GET_MODE (operands[1]),
+ operands[1], operands[2]);
+ PUT_MODE (operands[0], mode);
+ /* We want operands referring to CC_REGNUM and FCC_REGNUM
+ in mode MODE. */
+ operands[4] = gen_rtx_REG (mode, CC_REGNUM);
+ operands[5] = gen_rtx_REG (mode, FCC_REGNUM);
+ if (mode == CC_FPU_NEmode)
+ operands[6] = gen_rtx_NE (mode, operands[4], const0_rtx);
+ else
+ operands[6] = gen_rtx_EQ (mode, operands[4], const0_rtx);
+}")
(define_insn "cstoredf4"
[(set (match_operand:SI 0 "register_operand" "=r")
(match_operator:SI 1 "ordered_comparison_operator"
[(match_operand:DF 2 "even_reg_operand" "r")
- (match_operand:DF 3 "even_reg_operand" "r")]))]
+ (match_operand:DF 3 "even_reg_operand" "r")]))
+ (clobber (reg:CC CC_REGNUM))]
"TARGET_USE_FPU"
{
if (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
@@ -524,38 +543,25 @@
[(set_attr "length" "12")
(set_attr "type" "fpu")])
-(define_expand "cmpsf"
- [(set (reg:CC CC_REGNUM)
- (compare (match_operand:SF 0 "register_operand" "r")
- (match_operand:SF 1 "register_operand" "r")))]
- "TARGET_USE_FPU"
- {
- v850_compare_op0 = operands[0];
- v850_compare_op1 = operands[1];
- DONE;
- })
-
-(define_expand "cmpdf"
- [(set (reg:CC CC_REGNUM)
- (compare (match_operand:DF 0 "even_reg_operand" "r")
- (match_operand:DF 1 "even_reg_operand" "r")))]
- "TARGET_USE_FPU"
- {
- v850_compare_op0 = operands[0];
- v850_compare_op1 = operands[1];
- DONE;
- })
-
;; ----------------------------------------------------------------------
;; ADD INSTRUCTIONS
;; ----------------------------------------------------------------------
-(define_insn "addsi3"
+(define_insn_and_split "addsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r")
+ (match_operand:SI 2 "nonmemory_operand" "rJ,K,U")))]
+ ""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC CC_REGNUM))])])
+
+(define_insn "addsi3_clobber_flags"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
(plus:SI (match_operand:SI 1 "register_operand" "%0,r,r")
(match_operand:SI 2 "nonmemory_operand" "rJ,K,U")))
(clobber (reg:CC CC_REGNUM))]
-
""
"@
add %2,%0
@@ -566,8 +572,17 @@
;; ----------------------------------------------------------------------
;; SUBTRACT INSTRUCTIONS
;; ----------------------------------------------------------------------
+(define_insn_and_split "subsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (minus:SI (match_operand:SI 1 "register_operand" "0,r")
+ (match_operand:SI 2 "register_operand" "r,0")))]
+ ""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC CC_REGNUM))])])
-(define_insn "subsi3"
+(define_insn "subsi3_clobber_flags"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(minus:SI (match_operand:SI 1 "register_operand" "0,r")
(match_operand:SI 2 "register_operand" "r,0")))
@@ -578,7 +593,16 @@
subr %1,%0"
[(set_attr "length" "2,2")])
-(define_insn "negsi2"
+(define_insn_and_split "negsi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (neg:SI (match_operand:SI 1 "register_operand" "0")))]
+ ""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (neg:SI (match_dup 1)))
+ (clobber (reg:CC CC_REGNUM))])])
+
+(define_insn "negsi2_clobber_flags"
[(set (match_operand:SI 0 "register_operand" "=r")
(neg:SI (match_operand:SI 1 "register_operand" "0")))
(clobber (reg:CC CC_REGNUM))]
@@ -703,7 +727,7 @@
(match_dup 2)))
(clobber (reg:CC CC_REGNUM))]
"TARGET_V850E_UP"
- "sxh %0\n\tdivh %2,%0,%3"
+ "sxh %0\\n\\tdivh %2,%0,%3"
[(set_attr "length" "6")
(set_attr "type" "div")])
@@ -719,7 +743,7 @@
(match_dup 2)))
(clobber (reg:CC CC_REGNUM))]
"TARGET_V850E_UP"
- "zxh %0\n\tdivhu %2,%0,%3"
+ "zxh %0\\n\\ndivhu %2,%0,%3"
[(set_attr "length" "6")
(set_attr "type" "div")])
@@ -785,12 +809,22 @@
[(set_attr "length" "4")
(set_attr "type" "bit1")])
-(define_insn "andsi3"
+(define_insn_and_split "andsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
+ (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
+ ""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC CC_REGNUM))])])
+
+(define_insn "andsi3_clobber_flags"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
(and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
(match_operand:SI 2 "nonmemory_operand" "r,I,M")))
(clobber (reg:CC CC_REGNUM))]
- ""
+ "reload_completed"
"@
and %2,%0
and %.,%0
@@ -860,7 +894,17 @@
[(set_attr "length" "4")
(set_attr "type" "bit1")])
-(define_insn "iorsi3"
+(define_insn_and_split "iorsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
+ (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
+ ""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC CC_REGNUM))])])
+
+(define_insn "iorsi3_clobber_flags"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
(ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
(match_operand:SI 2 "nonmemory_operand" "r,I,M")))
@@ -935,7 +979,17 @@
[(set_attr "length" "4")
(set_attr "type" "bit1")])
-(define_insn "xorsi3"
+(define_insn_and_split "xorsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
+ (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
+ ""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC CC_REGNUM))])])
+
+(define_insn "xorsi3_clobber_flags"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
(xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
(match_operand:SI 2 "nonmemory_operand" "r,I,M")))
@@ -946,12 +1000,23 @@
xor %.,%0
xori %2,%1,%0"
[(set_attr "length" "2,2,4")])
+
;; ----------------------------------------------------------------------
;; NOT INSTRUCTIONS
;; ----------------------------------------------------------------------
-(define_insn "one_cmplsi2"
+(define_insn_and_split "one_cmplsi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (not:SI (match_operand:SI 1 "register_operand" "r")))]
+ ""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (not:SI (match_dup 1)))
+ (clobber (reg:CC CC_REGNUM))])])
+
+
+(define_insn "one_cmplsi2_clobber_flags"
[(set (match_operand:SI 0 "register_operand" "=r")
(not:SI (match_operand:SI 1 "register_operand" "r")))
(clobber (reg:CC CC_REGNUM))]
@@ -977,7 +1042,8 @@
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
(match_operand:SI 1 "immediate_operand" "n")
(match_operand:SI 2 "immediate_operand" "n"))
- (match_operand:SI 3 "register_operand" "r"))]
+ (match_operand:SI 3 "register_operand" "r"))
+ (clobber (reg:CC CC_REGNUM))]
"TARGET_V850E3V5_UP"
"bins %3, %2, %1, %0"
[(set_attr "length" "4")])
@@ -986,20 +1052,46 @@
;; Scc INSTRUCTIONS
;; -----------------------------------------------------------------
-(define_insn "*setcc"
+(define_insn_and_split "*cbranchsi4_insn"
+ [(set (pc)
+ (if_then_else (match_operator 0 "comparison_operator"
+ [(match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "reg_or_int5_operand" "rJ")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ ""
+ "#"
+ "reload_completed"
+ [(set (reg:CC CC_REGNUM)
+ (compare:CC (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (match_op_dup 0
+ [(reg:CC CC_REGNUM) (const_int 0)])
+ (label_ref (match_dup 3))
+ (pc)))]
+ "")
+
+
+(define_insn_and_split "cstoresi4"
[(set (match_operand:SI 0 "register_operand" "=r")
(match_operator:SI 1 "comparison_operator"
- [(cc0) (const_int 0)]))]
+ [(match_operand:SI 2 "register_operand" "r")
+ (match_operand:SI 3 "reg_or_int5_operand" "rJ")]))]
""
- "setf %c1,%0"
- [(set_attr "length" "4")])
+ "#"
+ "reload_completed"
+ [(set (reg:CC CC_REGNUM)
+ (compare:CC (match_dup 2) (match_dup 3)))
+ (set (match_dup 0) (match_op_dup 1
+ [(reg:CC CC_REGNUM) (const_int 0)]))]
+ "")
-(define_insn "setf_insn"
+(define_insn "*setcc_insn"
[(set (match_operand:SI 0 "register_operand" "=r")
- (match_operator:SI 1 "comparison_operator"
- [(reg:CC CC_REGNUM) (const_int 0)]))]
- ""
- "setf %b1,%0"
+ (match_operator:SI 1 "comparison_operator"
+ [(reg:CC CC_REGNUM) (const_int 0)]))]
+ "reload_completed"
+ "setf %c1,%0"
[(set_attr "length" "4")])
(define_insn "set_z_insn"
@@ -1065,12 +1157,6 @@
}
})
-;; ??? Clobbering the condition codes is overkill.
-
-;; ??? We sometimes emit an unnecessary compare instruction because the
-;; condition codes may have already been set by an earlier instruction,
-;; but we have no code here to avoid the compare if it is unnecessary.
-
(define_insn "movsicc_normal_cc"
[(set (match_operand:SI 0 "register_operand" "=r")
(if_then_else:SI
@@ -1078,7 +1164,7 @@
[(reg:CC CC_REGNUM) (const_int 0)])
(match_operand:SI 2 "reg_or_int5_operand" "rJ")
(match_operand:SI 3 "reg_or_0_operand" "rI")))]
- "(TARGET_V850E_UP)"
+ "reload_completed && (TARGET_V850E_UP)"
"cmov %c1,%2,%z3,%0";
[(set_attr "length" "6")])
@@ -1089,11 +1175,11 @@
[(reg:CC CC_REGNUM) (const_int 0)])
(match_operand:SI 2 "reg_or_0_operand" "rI")
(match_operand:SI 3 "reg_or_int5_operand" "rJ")))]
- "(TARGET_V850E_UP)"
+ "reload_completed && (TARGET_V850E_UP)"
"cmov %C1,%3,%z2,%0"
[(set_attr "length" "6")])
-(define_insn "*movsicc_normal"
+(define_insn_and_split "*movsicc_normal"
[(set (match_operand:SI 0 "register_operand" "=r")
(if_then_else:SI
(match_operator 1 "comparison_operator"
@@ -1102,21 +1188,35 @@
(match_operand:SI 2 "reg_or_int5_operand" "rJ")
(match_operand:SI 3 "reg_or_0_operand" "rI")))]
"(TARGET_V850E_UP)"
- "cmp %5,%4 ; cmov %c1,%2,%z3,%0"
- [(set_attr "length" "6")])
+ "#"
+ "reload_completed"
+ [(set (reg:CC CC_REGNUM)
+ (compare:CC (match_dup 4) (match_dup 5)))
+ (set (match_dup 0)
+ (if_then_else:SI (match_op_dup 1
+ [(reg:CC CC_REGNUM) (const_int 0)])
+ (match_dup 2) (match_dup 3)))])
-(define_insn "*movsicc_reversed"
+
+(define_insn_and_split "*movsicc_reversed"
[(set (match_operand:SI 0 "register_operand" "=r")
(if_then_else:SI
(match_operator 1 "comparison_operator"
[(match_operand:SI 4 "register_operand" "r")
(match_operand:SI 5 "reg_or_int5_operand" "rJ")])
- (match_operand:SI 2 "reg_or_0_operand" "rI")
- (match_operand:SI 3 "reg_or_int5_operand" "rJ")))]
+ (match_operand:SI 2 "reg_or_int5_operand" "rI")
+ (match_operand:SI 3 "reg_or_0_operand" "rJ")))]
"(TARGET_V850E_UP)"
- "cmp %5,%4 ; cmov %C1,%3,%z2,%0"
- [(set_attr "length" "6")])
+ "#"
+ "reload_completed"
+ [(set (reg:CC CC_REGNUM)
+ (compare:CC (match_dup 4) (match_dup 5)))
+ (set (match_dup 0)
+ (if_then_else:SI (match_op_dup 1
+ [(reg:CC CC_REGNUM) (const_int 0)])
+ (match_dup 2) (match_dup 3)))])
+;; We could expose the setting of the condition codes here.
(define_insn "*movsicc_tst1"
[(set (match_operand:SI 0 "register_operand" "=r")
(if_then_else:SI
@@ -1127,11 +1227,13 @@
(match_operand 3 "const_int_operand" "n"))
(const_int 0)])
(match_operand:SI 4 "reg_or_int5_operand" "rJ")
- (match_operand:SI 5 "reg_or_0_operand" "rI")))]
+ (match_operand:SI 5 "reg_or_0_operand" "rI")))
+ (clobber (reg:CC CC_REGNUM))]
"(TARGET_V850E_UP)"
"tst1 %3,%2 ; cmov %c1,%4,%z5,%0"
[(set_attr "length" "8")])
+;; We could expose the setting of the condition codes here.
(define_insn "*movsicc_tst1_reversed"
[(set (match_operand:SI 0 "register_operand" "=r")
(if_then_else:SI
@@ -1142,7 +1244,8 @@
(match_operand 3 "const_int_operand" "n"))
(const_int 0)])
(match_operand:SI 4 "reg_or_0_operand" "rI")
- (match_operand:SI 5 "reg_or_int5_operand" "rJ")))]
+ (match_operand:SI 5 "reg_or_int5_operand" "rJ")))
+ (clobber (reg:CC CC_REGNUM))]
"(TARGET_V850E_UP)"
"tst1 %3,%2 ; cmov %C1,%5,%z4,%0"
[(set_attr "length" "8")])
@@ -1152,6 +1255,9 @@
;; second pattern by subsequent combining. As above, we must include the
;; comparison to avoid input reloads in an insn using cc0.
+;; We could expose the setting of the condition codes here.
+;; However, I haven't seen this pattern used, so I'm not going
+;; to bother.
(define_insn "*sasf"
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI
@@ -1235,7 +1341,8 @@
[(ashift:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "const_int_operand" "n"))
(lshiftrt:SI (match_dup 1)
- (match_operand:SI 3 "const_int_operand" "n"))]))]
+ (match_operand:SI 3 "const_int_operand" "n"))]))
+ (clobber (reg:CC CC_REGNUM))]
"TARGET_V850E3V5_UP && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32)"
"rotl %2, %1, %0"
[(set_attr "length" "4")])
@@ -1246,7 +1353,8 @@
[(lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 3 "const_int_operand" "n"))
(ashift:SI (match_dup 1)
- (match_operand:SI 2 "const_int_operand" "n"))]))]
+ (match_operand:SI 2 "const_int_operand" "n"))]))
+ (clobber (reg:CC CC_REGNUM))]
"TARGET_V850E3V5_UP && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32)"
"rotl %2, %1, %0"
[(set_attr "length" "4")])
@@ -1287,9 +1395,11 @@
}
)
+;; Note the embedded arithmetic. That affects the condition codes!
(define_insn "fix_loop_counter"
[(unspec:SI [(match_operand:SI 0 "register_operand" "+r,!m")
- (clobber (match_scratch:SI 1 "=X,r"))] UNSPEC_LOOP)]
+ (clobber (match_scratch:SI 1 "=X,r"))] UNSPEC_LOOP)
+ (clobber (reg:CC CC_REGNUM))]
"TARGET_V850E3V5_UP && TARGET_LOOP"
{
switch (which_alternative)
@@ -1349,68 +1459,52 @@
;; Conditional jump instructions
-(define_insn "*branch_normal"
+(define_insn_and_split "*cbranchsi4_insn"
[(set (pc)
- (if_then_else (match_operator 1 "comparison_operator"
- [(cc0) (const_int 0)])
- (label_ref (match_operand 0 "" ""))
+ (if_then_else (match_operator 0 "comparison_operator"
+ [(match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "reg_or_int5_operand" "rJ")])
+ (label_ref (match_operand 3 "" ""))
(pc)))]
""
-{
- if (get_attr_length (insn) == 2)
- return "b%b1 %l0";
- if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
- return "b%b1 %l0";
- return "b%B1 .+6 ; jr %l0";
-}
- [(set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 0) (pc)))
- (const_int 256))
- (const_int 2)
- (if_then_else (lt (abs (minus (match_dup 0) (pc)))
- (const_int 65536))
- (const_int 4)
- (const_int 6))))])
+ "#"
+ "reload_completed"
+ [(set (reg:CC CC_REGNUM)
+ (compare:CC (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (match_op_dup 0
+ [(reg:CC CC_REGNUM) (const_int 0)])
+ (label_ref (match_dup 3))
+ (pc)))]
+ "")
-(define_insn "*branch_invert"
+(define_insn "*branch_normal"
[(set (pc)
(if_then_else (match_operator 1 "comparison_operator"
- [(cc0) (const_int 0)])
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
-{
- if (get_attr_length (insn) == 2)
- return "b%B1 %l0";
-
- if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
- return "b%B1 %l0";
-
- return "b%b1 .+6 ; jr %l0";
-}
- [(set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 0) (pc)))
- (const_int 256))
- (const_int 2)
- (if_then_else (lt (abs (minus (match_dup 0) (pc)))
- (const_int 65536))
- (const_int 4)
- (const_int 6))))])
-
-(define_insn "branch_z_normal"
- [(set (pc)
- (if_then_else (match_operand 1 "v850_float_z_comparison_operator" "")
+ [(reg CC_REGNUM) (const_int 0)])
(label_ref (match_operand 0 "" ""))
(pc)))]
- "TARGET_V850E2V3_UP"
+ "reload_completed"
{
+ bool nzmode = GET_MODE (XEXP (operands[1], 0)) == CCNZmode;
if (get_attr_length (insn) == 2)
- return "bz %l0";
-
+ {
+ if (nzmode)
+ return "b%d1 %l0";
+ else
+ return "b%b1 %l0";
+ }
if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
- return "bz %l0";
-
- return "bnz 1f ; jr %l0 ; 1:";
+ {
+ if (nzmode)
+ return "b%d1 %l0";
+ else
+ return "b%b1 %l0";
+ }
+ if (nzmode)
+ return "b%D1 .+6 ; jr %l0";
+ else
+ return "b%B1 .+6 ; jr %l0";
}
[(set (attr "length")
(if_then_else (lt (abs (minus (match_dup 0) (pc)))
@@ -1421,68 +1515,36 @@
(const_int 4)
(const_int 6))))])
-(define_insn "*branch_z_invert"
+(define_insn "*branch_invert"
[(set (pc)
- (if_then_else (match_operand 1 "v850_float_z_comparison_operator" "")
+ (if_then_else (match_operator 1 "comparison_operator"
+ [(reg CC_REGNUM) (const_int 0)])
(pc)
(label_ref (match_operand 0 "" ""))))]
- "TARGET_V850E2V3_UP"
+ "reload_completed"
{
- if (get_attr_length (insn) == 2)
- return "bnz %l0";
-
- if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
- return "bnz %l0";
-
- return "bz 1f ; jr %l0 ; 1:";
-}
- [(set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 0) (pc)))
- (const_int 256))
- (const_int 2)
- (if_then_else (lt (abs (minus (match_dup 0) (pc)))
- (const_int 65536))
- (const_int 4)
- (const_int 6))))])
+ bool nzmode = GET_MODE (XEXP (operands[1], 0)) == CCNZmode;
-(define_insn "branch_nz_normal"
- [(set (pc)
- (if_then_else (match_operand 1 "v850_float_nz_comparison_operator" "")
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- "TARGET_V850E2V3_UP"
-{
if (get_attr_length (insn) == 2)
- return "bnz %l0";
-
- if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
- return "bnz %l0";
-
- return "bz 1f ; jr %l0 ; 1:";
-}
-[(set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 0) (pc)))
- (const_int 256))
- (const_int 2)
- (if_then_else (lt (abs (minus (match_dup 0) (pc)))
- (const_int 65536))
- (const_int 4)
- (const_int 6))))])
-
-(define_insn "*branch_nz_invert"
- [(set (pc)
- (if_then_else (match_operand 1 "v850_float_nz_comparison_operator" "")
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- "TARGET_V850E2V3_UP"
-{
- if (get_attr_length (insn) == 2)
- return "bz %l0";
+ {
+ if (nzmode)
+ return "b%D1 %l0";
+ else
+ return "b%B1 %l0";
+ }
if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
- return "bz %l0";
+ {
+ if (nzmode)
+ return "b%D1 %l0";
+ else
+ return "b%B1 %l0";
+ }
- return "bnz 1f ; jr %l0 ; 1:";
+ if (nzmode)
+ return "b%d1 .+6 ; jr %l0";
+ else
+ return "b%b1 .+6 ; jr %l0";
}
[(set (attr "length")
(if_then_else (lt (abs (minus (match_dup 0) (pc)))
@@ -1602,6 +1664,7 @@
(define_insn "call_internal_short"
[(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
(match_operand:SI 1 "general_operand" "g,g"))
+ (clobber (reg:CC CC_REGNUM))
(clobber (reg:SI 31))]
"! TARGET_LONG_CALLS"
{
@@ -1620,6 +1683,7 @@
(define_insn "call_internal_long"
[(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
(match_operand:SI 1 "general_operand" "g,g"))
+ (clobber (reg:CC CC_REGNUM))
(clobber (reg:SI 31))]
"TARGET_LONG_CALLS"
{
@@ -1668,6 +1732,7 @@
[(set (match_operand 0 "" "=r,r")
(call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
(match_operand:SI 2 "general_operand" "g,g")))
+ (clobber (reg:CC CC_REGNUM))
(clobber (reg:SI 31))]
"! TARGET_LONG_CALLS"
{
@@ -1687,6 +1752,7 @@
[(set (match_operand 0 "" "=r,r")
(call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
(match_operand:SI 2 "general_operand" "g,g")))
+ (clobber (reg:CC CC_REGNUM))
(clobber (reg:SI 31))]
"TARGET_LONG_CALLS"
{
@@ -1719,6 +1785,7 @@
;; EXTEND INSTRUCTIONS
;; ----------------------------------------------------------------------
+;; We only need the CC clobber because of the andi alternative
(define_insn "*zero_extendhisi2_v850e"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
(zero_extend:SI
@@ -1791,8 +1858,7 @@
(define_insn "*extendhisi_insn"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
- (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,Q,m")))
- (clobber (reg:CC CC_REGNUM))]
+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,Q,m")))]
"(TARGET_V850E_UP)"
"@
sxh %0
@@ -1822,8 +1888,7 @@
(define_insn "*extendqisi_insn"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
- (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,Q,m")))
- (clobber (reg:CC CC_REGNUM))]
+ (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,Q,m")))]
"(TARGET_V850E_UP)"
"@
sxb %0
@@ -1853,7 +1918,18 @@
;; SHIFTS
;; ----------------------------------------------------------------------
-(define_insn "ashlsi3"
+(define_insn_and_split "ashlsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (ashift:SI
+ (match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "r,N")))]
+ ""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC CC_REGNUM))])])
+
+(define_insn "ashlsi3_clobber_flags"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(ashift:SI
(match_operand:SI 1 "register_operand" "0,0")
@@ -1865,7 +1941,7 @@
shl %2,%0"
[(set_attr "length" "4,2")])
-(define_insn "ashlsi3_v850e2"
+(define_insn "ashlsi3_v850e2_clobber_flags"
[(set (match_operand:SI 0 "register_operand" "=r")
(ashift:SI
(match_operand:SI 1 "register_operand" "r")
@@ -1875,7 +1951,18 @@
"shl %2,%1,%0"
[(set_attr "length" "4")])
-(define_insn "lshrsi3"
+(define_insn_and_split "lshrsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (lshiftrt:SI
+ (match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "r,N")))]
+ ""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC CC_REGNUM))])])
+
+(define_insn "lshrsi3_clobber_flags"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(lshiftrt:SI
(match_operand:SI 1 "register_operand" "0,0")
@@ -1887,7 +1974,7 @@
shr %2,%0"
[(set_attr "length" "4,2")])
-(define_insn "lshrsi3_v850e2"
+(define_insn "lshrsi3_v850e2_clobber_flags"
[(set (match_operand:SI 0 "register_operand" "=r")
(lshiftrt:SI
(match_operand:SI 1 "register_operand" "r")
@@ -1897,7 +1984,18 @@
"shr %2,%1,%0"
[(set_attr "length" "4")])
-(define_insn "ashrsi3"
+(define_insn_and_split "ashrsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (ashiftrt:SI
+ (match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "r,N")))]
+ ""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC CC_REGNUM))])])
+
+(define_insn "ashrsi3_clobber_flags"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(ashiftrt:SI
(match_operand:SI 1 "register_operand" "0,0")
@@ -1909,7 +2007,7 @@
sar %2,%0"
[(set_attr "length" "4,2")])
-(define_insn "ashrsi3_v850e2"
+(define_insn "ashrsi3_v850e2_clobber_flags"
[(set (match_operand:SI 0 "register_operand" "=r")
(ashiftrt:SI
(match_operand:SI 1 "register_operand" "r")
@@ -2279,6 +2377,8 @@
;; ---------------- special insns
;;
+;; reciprocal
+
;; Generic code demands that the recip and rsqrt named patterns
;; have precisely one operand. So that's what we expose in the
;; expander via the strange UNSPEC. However, those expanders
@@ -2417,7 +2517,7 @@
[(set (reg:CC_FPU_LE FCC_REGNUM)
(compare:CC_FPU_LE (match_operand:SF 0 "register_operand" "r")
(match_operand:SF 1 "register_operand" "r")))]
- "TARGET_USE_FPU"
+ "reload_completed && TARGET_USE_FPU"
"cmpf.s le, %z0, %z1"
[(set_attr "length" "4")
(set_attr "type" "fpu")])
@@ -2426,7 +2526,7 @@
[(set (reg:CC_FPU_LT FCC_REGNUM)
(compare:CC_FPU_LT (match_operand:SF 0 "register_operand" "r")
(match_operand:SF 1 "register_operand" "r")))]
- "TARGET_USE_FPU"
+ "reload_completed && TARGET_USE_FPU"
"cmpf.s lt, %z0, %z1"
[(set_attr "length" "4")
(set_attr "type" "fpu")])
@@ -2435,7 +2535,7 @@
[(set (reg:CC_FPU_GE FCC_REGNUM)
(compare:CC_FPU_GE (match_operand:SF 0 "register_operand" "r")
(match_operand:SF 1 "register_operand" "r")))]
- "TARGET_USE_FPU"
+ "reload_completed && TARGET_USE_FPU"
"cmpf.s le, %z1, %z0"
[(set_attr "length" "4")
(set_attr "type" "fpu")])
@@ -2444,7 +2544,7 @@
[(set (reg:CC_FPU_GT FCC_REGNUM)
(compare:CC_FPU_GT (match_operand:SF 0 "register_operand" "r")
(match_operand:SF 1 "register_operand" "r")))]
- "TARGET_USE_FPU"
+ "reload_completed && TARGET_USE_FPU"
"cmpf.s lt, %z1, %z0"
[(set_attr "length" "4")
(set_attr "type" "fpu")])
@@ -2453,7 +2553,7 @@
[(set (reg:CC_FPU_EQ FCC_REGNUM)
(compare:CC_FPU_EQ (match_operand:SF 0 "register_operand" "r")
(match_operand:SF 1 "register_operand" "r")))]
- "TARGET_USE_FPU"
+ "reload_completed && TARGET_USE_FPU"
"cmpf.s eq, %z0, %z1"
[(set_attr "length" "4")
(set_attr "type" "fpu")])
@@ -2464,7 +2564,7 @@
[(set (reg:CC_FPU_LE FCC_REGNUM)
(compare:CC_FPU_LE (match_operand:DF 0 "even_reg_operand" "r")
(match_operand:DF 1 "even_reg_operand" "r")))]
- "TARGET_USE_FPU"
+ "reload_completed && TARGET_USE_FPU"
"cmpf.d le, %z0, %z1"
[(set_attr "length" "4")
(set_attr "type" "fpu")])
@@ -2473,7 +2573,7 @@
[(set (reg:CC_FPU_LT FCC_REGNUM)
(compare:CC_FPU_LT (match_operand:DF 0 "even_reg_operand" "r")
(match_operand:DF 1 "even_reg_operand" "r")))]
- "TARGET_USE_FPU"
+ "reload_completed && TARGET_USE_FPU"
"cmpf.d lt, %z0, %z1"
[(set_attr "length" "4")
(set_attr "type" "fpu")])
@@ -2482,7 +2582,7 @@
[(set (reg:CC_FPU_GE FCC_REGNUM)
(compare:CC_FPU_GE (match_operand:DF 0 "even_reg_operand" "r")
(match_operand:DF 1 "even_reg_operand" "r")))]
- "TARGET_USE_FPU"
+ "reload_completed && TARGET_USE_FPU"
"cmpf.d le, %z1, %z0"
[(set_attr "length" "4")
(set_attr "type" "fpu")])
@@ -2491,7 +2591,7 @@
[(set (reg:CC_FPU_GT FCC_REGNUM)
(compare:CC_FPU_GT (match_operand:DF 0 "even_reg_operand" "r")
(match_operand:DF 1 "even_reg_operand" "r")))]
- "TARGET_USE_FPU"
+ "reload_completed && TARGET_USE_FPU"
"cmpf.d lt, %z1, %z0"
[(set_attr "length" "4")
(set_attr "type" "fpu")])
@@ -2500,7 +2600,7 @@
[(set (reg:CC_FPU_EQ FCC_REGNUM)
(compare:CC_FPU_EQ (match_operand:DF 0 "even_reg_operand" "r")
(match_operand:DF 1 "even_reg_operand" "r")))]
- "TARGET_USE_FPU"
+ "reload_completed && TARGET_USE_FPU"
"cmpf.d eq, %z0, %z1"
[(set_attr "length" "4")
(set_attr "type" "fpu")])
@@ -2512,7 +2612,8 @@
(define_insn "trfsr"
[(set (match_operand 0 "" "") (match_operand 1 "" ""))]
- "TARGET_USE_FPU
+ "reload_completed
+ && TARGET_USE_FPU
&& GET_MODE(operands[0]) == GET_MODE(operands[1])
&& GET_CODE(operands[0]) == REG && REGNO (operands[0]) == CC_REGNUM
&& GET_CODE(operands[1]) == REG && REGNO (operands[1]) == FCC_REGNUM
@@ -2668,7 +2769,8 @@
;; Initialize an interrupt function. Do not depend on TARGET_PROLOG_FUNCTION.
(define_insn "callt_save_interrupt"
- [(unspec_volatile [(const_int 0)] 2)]
+ [(unspec_volatile [(const_int 0)] 2)
+ (clobber (reg:CC CC_REGNUM))]
"(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
;; The CALLT instruction stores the next address of CALLT to CTPC register
;; without saving its previous value. So if the interrupt handler
@@ -2689,7 +2791,8 @@
[(set_attr "length" "26")])
(define_insn "callt_return_interrupt"
- [(unspec_volatile [(const_int 0)] 3)]
+ [(unspec_volatile [(const_int 0)] 3)
+ (clobber (reg:CC CC_REGNUM))]
"(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
"callt ctoff(__callt_return_interrupt)"
[(set_attr "length" "2")])
@@ -2700,7 +2803,8 @@
(set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 4))
(set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1))
(set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 10))
- (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 11))]
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 11))
+ (clobber (reg:CC CC_REGNUM))]
""
{
if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
@@ -2733,7 +2837,8 @@
(set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
(set (reg:SI 1) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
(set (reg:SI 4) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))
- (set (reg:SI 30) (mem:SI (reg:SI 3)))]
+ (set (reg:SI 30) (mem:SI (reg:SI 3)))
+ (clobber (reg:CC CC_REGNUM))]
""
{
if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
@@ -2763,13 +2868,15 @@
;; insns this complicated.
(define_insn "callt_save_all_interrupt"
- [(unspec_volatile [(const_int 0)] 0)]
+ [(unspec_volatile [(const_int 0)] 0)
+ (clobber (reg:CC CC_REGNUM))]
"(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
"callt ctoff(__callt_save_all_interrupt)"
[(set_attr "length" "2")])
(define_insn "save_all_interrupt"
- [(unspec_volatile [(const_int 0)] 0)]
+ [(unspec_volatile [(const_int 0)] 0)
+ (clobber (reg:CC CC_REGNUM))]
""
{
if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
@@ -2844,10 +2951,12 @@
[(set (attr "length")
(if_then_else (match_test "TARGET_LONG_CALLS")
(const_int 4)
- (const_int 62)))])
+ (const_int 62)
+ ))])
(define_insn "_save_all_interrupt"
- [(unspec_volatile [(const_int 0)] 0)]
+ [(unspec_volatile [(const_int 0)] 0)
+ (clobber (reg:CC CC_REGNUM))]
"TARGET_V850 && ! TARGET_LONG_CALLS"
"jarl __save_all_interrupt,r10"
[(set_attr "length" "4")])
@@ -2859,13 +2968,15 @@
;; insns this complicated.
(define_insn "callt_restore_all_interrupt"
- [(unspec_volatile [(const_int 0)] 1)]
+ [(unspec_volatile [(const_int 0)] 1)
+ (clobber (reg:CC CC_REGNUM))]
"(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
"callt ctoff(__callt_restore_all_interrupt)"
[(set_attr "length" "2")])
(define_insn "restore_all_interrupt"
- [(unspec_volatile [(const_int 0)] 1)]
+ [(unspec_volatile [(const_int 0)] 1)
+ (clobber (reg:CC CC_REGNUM))]
""
{
if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
@@ -2942,7 +3053,8 @@
))])
(define_insn "_restore_all_interrupt"
- [(unspec_volatile [(const_int 0)] 1)]
+ [(unspec_volatile [(const_int 0)] 1)
+ (clobber (reg:CC CC_REGNUM))]
"TARGET_V850 && ! TARGET_LONG_CALLS"
"jarl __restore_all_interrupt,r10"
[(set_attr "length" "4")])