diff --git a/gcc/config/v850/v850-protos.h b/gcc/config/v850/v850-protos.h
index e8ff280..ca99703 100644
--- a/gcc/config/v850/v850-protos.h
+++ b/gcc/config/v850/v850-protos.h
@@ -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
diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c
index e184718..cb2debf 100644
--- a/gcc/config/v850/v850.c
+++ b/gcc/config/v850/v850.c
@@ -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"
diff --git a/gcc/config/v850/v850.h b/gcc/config/v850/v850.h
index 96bddc2..04d226a 100644
--- a/gcc/config/v850/v850.h
+++ b/gcc/config/v850/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
diff --git a/gcc/config/v850/v850.md b/gcc/config/v850/v850.md
index 0fad9ea..3cfec74 100644
--- a/gcc/config/v850/v850.md
+++ b/gcc/config/v850/v850.md
@@ -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")])
