]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
final.c (final_scan_insn): Call CC_STATUS_INIT unconditionally.
authorBernd Schmidt <bernds@codesourcery.com>
Mon, 2 Aug 2010 09:51:39 +0000 (09:51 +0000)
committerBernd Schmidt <bernds@gcc.gnu.org>
Mon, 2 Aug 2010 09:51:39 +0000 (09:51 +0000)
* final.c (final_scan_insn): Call CC_STATUS_INIT unconditionally.
* config/arm/arm.c (thumb1_code): New variable.
(arm_override_options): Set it.
(thumb1_final_prescan_insn): Keep track of condition code status.
(arm_adjust_cost): For Thumb, try to keep cc-setting insns next to
jumps that depend on them.
* config/arm/arm.h (thumb1_code): Declare variable.
(struct machine_function): Guard with #ifndef GENERATOR_FILE.  Add
members thumb1_cc_insn, thumb1_cc_op0, thumb1_cc_op1 and
thumb1_cc_mode.
(CC_STATUS_INIT): New macro.
* config/arm/constraints.md (Pd): New constraint.
* config/arm/predicates.md (noov_comparison_operator): New predicate.
* config/arm/arm.md (is_thumb1): New define_attr.
(conds): Set default to "clob" when generating Thumb1 code.
(thumb1_bicsi3): Renamed from bicsi3.  All uses changed.  Condition
code are set.  Use two-operand assembly syntax.
(thumb1_subsi3_insn): Condition codes are set.  Now a properly named
pattern.
(thumb1_andsi3_insn, thumb1_iorsi3_insn, thumb1_xorsi3_insn): Condition
codes are set.  Use two-operand assembly syntax.
(zero_extendhisi splitter): Remove constraints.
(thumb1_movsi_insn, thumb1_movhi_insn, thumb1_movqi_insn, thumb1_movhf,
thumb1_movsf_insn): Set conds attribute as appropriate.
(cbranchsi4_insn): Use condition code status from struct
machine_function to determine whether the comparison can be eliminated.
Discourage the alternative using high registers.
(movsi_cbranchsi4, andsi3_cbranch, orrsi3_cbranch_scratch,
orrsi3_cbranch, xorsi3_cbranch_scratch, xorsi3_cbranch,
bicsi3_cbranch_scratch, bicsi3_cbranch, subsi3_cbranch_scratch,
subsi3_cbranch): Delete.
(movsi_cbranchsi4 peepholes): Rewrite to generate a sequence of
one subtract and one cbranch insn.

From-SVN: r162813

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/config/arm/arm.h
gcc/config/arm/arm.md
gcc/config/arm/constraints.md
gcc/config/arm/predicates.md
gcc/final.c

index 31348a411b08d0d76f123359b059044cb272dee2..fb365750c465eb62ea308072c9d39a11508821dc 100644 (file)
@@ -3,6 +3,40 @@
        * postreload.c (reload_cse_simplify_operands): Take attribute enabled
        into account.
 
+       * final.c (final_scan_insn): Call CC_STATUS_INIT unconditionally.
+       * config/arm/arm.c (thumb1_code): New variable.
+       (arm_override_options): Set it.
+       (thumb1_final_prescan_insn): Keep track of condition code status.
+       (arm_adjust_cost): For Thumb, try to keep cc-setting insns next to
+       jumps that depend on them.
+       * config/arm/arm.h (thumb1_code): Declare variable.
+       (struct machine_function): Guard with #ifndef GENERATOR_FILE.  Add
+       members thumb1_cc_insn, thumb1_cc_op0, thumb1_cc_op1 and
+       thumb1_cc_mode.
+       (CC_STATUS_INIT): New macro.
+       * config/arm/constraints.md (Pd): New constraint.
+       * config/arm/predicates.md (noov_comparison_operator): New predicate.
+       * config/arm/arm.md (is_thumb1): New define_attr.
+       (conds): Set default to "clob" when generating Thumb1 code.
+       (thumb1_bicsi3): Renamed from bicsi3.  All uses changed.  Condition
+       code are set.  Use two-operand assembly syntax.
+       (thumb1_subsi3_insn): Condition codes are set.  Now a properly named
+       pattern.
+       (thumb1_andsi3_insn, thumb1_iorsi3_insn, thumb1_xorsi3_insn): Condition
+       codes are set.  Use two-operand assembly syntax.
+       (zero_extendhisi splitter): Remove constraints.
+       (thumb1_movsi_insn, thumb1_movhi_insn, thumb1_movqi_insn, thumb1_movhf,
+       thumb1_movsf_insn): Set conds attribute as appropriate.
+       (cbranchsi4_insn): Use condition code status from struct
+       machine_function to determine whether the comparison can be eliminated.
+       Discourage the alternative using high registers.
+       (movsi_cbranchsi4, andsi3_cbranch, orrsi3_cbranch_scratch,
+       orrsi3_cbranch, xorsi3_cbranch_scratch, xorsi3_cbranch,
+       bicsi3_cbranch_scratch, bicsi3_cbranch, subsi3_cbranch_scratch,
+       subsi3_cbranch): Delete.
+       (movsi_cbranchsi4 peepholes): Rewrite to generate a sequence of
+       one subtract and one cbranch insn.
+
 2010-08-02  Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
 
        * config/arm/arm.c (COSTS_N_INSNS): Remove definition.
index 23bc81023c068001a17d2c188eb9e5611a26c686..d22ded39b33f8030d64b9a6769cd869024af46b4 100644 (file)
@@ -687,6 +687,9 @@ int arm_tune_cortex_a9 = 0;
 /* Nonzero if generating Thumb instructions.  */
 int thumb_code = 0;
 
+/* Nonzero if generating Thumb-1 instructions.  */
+int thumb1_code = 0;
+
 /* Nonzero if we should define __THUMB_INTERWORK__ in the
    preprocessor.
    XXX This is a bit of a hack, it's intended to help work around
@@ -718,6 +721,7 @@ enum arm_pcs arm_pcs_default;
 int arm_ccfsm_state;
 /* arm_current_cc is also used for Thumb-2 cond_exec blocks.  */
 enum arm_cond_code arm_current_cc;
+
 rtx arm_target_insn;
 int arm_target_label;
 /* The number of conditionally executed insns, including the current insn.  */
@@ -1572,7 +1576,8 @@ arm_override_options (void)
 
   arm_ld_sched = (tune_flags & FL_LDSCHED) != 0;
   arm_tune_strongarm = (tune_flags & FL_STRONG) != 0;
-  thumb_code = (TARGET_ARM == 0);
+  thumb_code = TARGET_ARM == 0;
+  thumb1_code = TARGET_THUMB1 != 0;
   arm_tune_wbuf = (tune_flags & FL_WBUF) != 0;
   arm_tune_xscale = (tune_flags & FL_XSCALE) != 0;
   arm_arch_iwmmxt = (insn_flags & FL_IWMMXT) != 0;
@@ -7682,12 +7687,26 @@ arm_address_cost (rtx x, bool speed ATTRIBUTE_UNUSED)
 {
   return TARGET_32BIT ? arm_arm_address_cost (x) : arm_thumb_address_cost (x);
 }
-
+/* This function implements the target macro TARGET_SCHED_ADJUST_COST.
+   It corrects the value of COST based on the relationship between
+   INSN and DEP through the dependence LINK.  It returns the new
+   value.  */
+  
 static int
 arm_adjust_cost (rtx insn, rtx link, rtx dep, int cost)
 {
   rtx i_pat, d_pat;
 
+  /* When generating Thumb-1 code, we want to place flag-setting operations
+     close to a conditional branch which depends on them, so that we can
+     omit the comparison.  */
+  if (TARGET_THUMB1
+      && REG_NOTE_KIND (link) == 0
+      && recog_memoized (insn) == CODE_FOR_cbranchsi4_insn
+      && recog_memoized (dep) >= 0
+      && get_attr_conds (dep) == CONDS_SET)
+    return 0;
+
   /* Some true dependencies can have a higher cost depending
      on precisely how certain input operands are used.  */
   if (arm_tune_xscale
@@ -19474,14 +19493,45 @@ thumb_exit (FILE *f, int reg_containing_return_addr)
   /* Return to caller.  */
   asm_fprintf (f, "\tbx\t%r\n", reg_containing_return_addr);
 }
-
 \f
+/* Scan INSN just before assembler is output for it.
+   For Thumb-1, we track the status of the condition codes; this
+   information is used in the cbranchsi4_insn pattern.  */
 void
 thumb1_final_prescan_insn (rtx insn)
 {
   if (flag_print_asm_name)
     asm_fprintf (asm_out_file, "%@ 0x%04x\n",
                 INSN_ADDRESSES (INSN_UID (insn)));
+  /* Don't overwrite the previous setter when we get to a cbranch.  */
+  if (INSN_CODE (insn) != CODE_FOR_cbranchsi4_insn)
+    {
+      enum attr_conds conds;
+
+      if (cfun->machine->thumb1_cc_insn)
+       {
+         if (modified_in_p (cfun->machine->thumb1_cc_op0, insn)
+             || modified_in_p (cfun->machine->thumb1_cc_op1, insn))
+           CC_STATUS_INIT;
+       }
+      conds = get_attr_conds (insn);
+      if (conds == CONDS_SET)
+       {
+         rtx set = single_set (insn);
+         cfun->machine->thumb1_cc_insn = insn;
+         cfun->machine->thumb1_cc_op0 = SET_DEST (set);
+         cfun->machine->thumb1_cc_op1 = const0_rtx;
+         cfun->machine->thumb1_cc_mode = CC_NOOVmode;
+         if (INSN_CODE (insn) == CODE_FOR_thumb1_subsi3_insn)
+           {
+             rtx src1 = XEXP (SET_SRC (set), 1);
+             if (src1 == const0_rtx)
+               cfun->machine->thumb1_cc_mode = CCmode;
+           }
+       }
+      else if (conds != CONDS_NOCOND)
+       cfun->machine->thumb1_cc_insn = NULL_RTX;
+    }
 }
 
 int
index 8c6d249a837ca481c7aea3016ee78cbfe13fa0c2..e90f1d3cbdd4f47172f92f3207fe7dbc31fa9e9e 100644 (file)
@@ -412,9 +412,12 @@ extern int arm_arch7em;
 /* Nonzero if this chip can benefit from load scheduling.  */
 extern int arm_ld_sched;
 
-/* Nonzero if generating thumb code.  */
+/* Nonzero if generating Thumb code, either Thumb-1 or Thumb-2.  */
 extern int thumb_code;
 
+/* Nonzero if generating Thumb-1 code.  */
+extern int thumb1_code;
+
 /* Nonzero if this chip is a StrongARM.  */
 extern int arm_tune_strongarm;
 
@@ -1593,6 +1596,7 @@ typedef struct GTY(()) arm_stack_offsets
 }
 arm_stack_offsets;
 
+#ifndef GENERATOR_FILE
 /* A C structure for machine-specific, per-function data.
    This is added to the cfun structure.  */
 typedef struct GTY(()) machine_function
@@ -1623,8 +1627,16 @@ typedef struct GTY(()) machine_function
   /* Set to 1 when a return insn is output, this means that the epilogue
      is not needed.  */
   int return_used_this_function;
+  /* When outputting Thumb-1 code, record the last insn that provides
+     information about condition codes, and the comparison operands.  */
+  rtx thumb1_cc_insn;
+  rtx thumb1_cc_op0;
+  rtx thumb1_cc_op1;
+  /* Also record the CC mode that is supported.  */
+  enum machine_mode thumb1_cc_mode;
 }
 machine_function;
+#endif
 
 /* As in the machine_function, a global set of call-via labels, for code 
    that is in text_section.  */
@@ -2259,6 +2271,9 @@ extern int making_const_table;
 #define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE)  ((VALUE) = 32, 1)
 #define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE)  ((VALUE) = 32, 1)
 \f
+#define CC_STATUS_INIT \
+  do { cfun->machine->thumb1_cc_insn = NULL_RTX; } while (0)
+
 #undef  ASM_APP_OFF
 #define ASM_APP_OFF (TARGET_THUMB1 ? "\t.code\t16\n" : \
                     TARGET_THUMB2 ? "\t.thumb\n" : "")
index 885d6ed81cba14814ce1bfcae98f7c6d342042f9..097defd07425d6f4a2deeae62999b1699d0f30ed 100644 (file)
 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
 
+; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
+(define_attr "is_thumb1" "no,yes" (const (symbol_ref "thumb1_code")))
+
 ;; Operand number of an input operand that is shifted.  Zero if the
 ;; given instruction does not shift one of its input operands.
 (define_attr "shift" "" (const_int 0))
 ;   output of this insn
 
 (define_attr "conds" "use,set,clob,unconditional,nocond"
-       (if_then_else (eq_attr "type" "call")
+       (if_then_else
+        (ior (eq_attr "is_thumb1" "yes")
+             (eq_attr "type" "call"))
         (const_string "clob")
         (if_then_else (eq_attr "neon_type" "none")
          (const_string "nocond")
   "
 )
 
-(define_insn "*thumb1_subsi3_insn"
+(define_insn "thumb1_subsi3_insn"
   [(set (match_operand:SI           0 "register_operand" "=l")
        (minus:SI (match_operand:SI 1 "register_operand" "l")
-                 (match_operand:SI 2 "register_operand" "l")))]
+                 (match_operand:SI 2 "reg_or_int_operand" "lPd")))]
   "TARGET_THUMB1"
   "sub\\t%0, %1, %2"
-  [(set_attr "length" "2")]
-)
+  [(set_attr "length" "2")
+   (set_attr "conds" "set")])
 
 ; ??? Check Thumb-2 split length
 (define_insn_and_split "*arm_subsi3_insn"
              operands[2] = force_reg (SImode,
                                       GEN_INT (~INTVAL (operands[2])));
              
-             emit_insn (gen_bicsi3 (operands[0], operands[2], operands[1]));
+             emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
              
              DONE;
            }
        (and:SI (match_operand:SI 1 "register_operand" "%0")
                (match_operand:SI 2 "register_operand" "l")))]
   "TARGET_THUMB1"
-  "and\\t%0, %0, %2"
-  [(set_attr "length" "2")]
-)
+  "and\\t%0, %2"
+  [(set_attr "length" "2")
+   (set_attr "conds" "set")])
 
 (define_insn "*andsi3_compare0"
   [(set (reg:CC_NOOV CC_REGNUM)
   [(set_attr "predicable" "yes")]
 )
 
-(define_insn "bicsi3"
+(define_insn "thumb1_bicsi3"
   [(set (match_operand:SI                 0 "register_operand" "=l")
        (and:SI (not:SI (match_operand:SI 1 "register_operand" "l"))
                (match_operand:SI         2 "register_operand" "0")))]
   "TARGET_THUMB1"
-  "bic\\t%0, %0, %1"
-  [(set_attr "length" "2")]
-)
+  "bic\\t%0, %1"
+  [(set_attr "length" "2")
+   (set_attr "conds" "set")])
 
 (define_insn "andsi_not_shiftsi_si"
   [(set (match_operand:SI 0 "s_register_operand" "=r")
    (set_attr "predicable" "yes")]
 )
 
-(define_insn "*thumb1_iorsi3"
+(define_insn "*thumb1_iorsi3_insn"
   [(set (match_operand:SI         0 "register_operand" "=l")
        (ior:SI (match_operand:SI 1 "register_operand" "%0")
                (match_operand:SI 2 "register_operand" "l")))]
   "TARGET_THUMB1"
-  "orr\\t%0, %0, %2"
-  [(set_attr "length" "2")]
-)
+  "orr\\t%0, %2"
+  [(set_attr "length" "2")
+   (set_attr "conds" "set")])
 
 (define_peephole2
   [(match_scratch:SI 3 "r")
   [(set_attr "predicable" "yes")]
 )
 
-(define_insn "*thumb1_xorsi3"
+(define_insn "*thumb1_xorsi3_insn"
   [(set (match_operand:SI         0 "register_operand" "=l")
        (xor:SI (match_operand:SI 1 "register_operand" "%0")
                (match_operand:SI 2 "register_operand" "l")))]
   "TARGET_THUMB1"
-  "eor\\t%0, %0, %2"
-  [(set_attr "length" "2")]
-)
+  "eor\\t%0, %2"
+  [(set_attr "length" "2")
+   (set_attr "conds" "set")])
 
 (define_insn "*xorsi3_compare0"
   [(set (reg:CC_NOOV CC_REGNUM)
                   (match_operand:SI 2 "nonmemory_operand" "N,l")))]
   "TARGET_THUMB1"
   "lsl\\t%0, %1, %2"
-  [(set_attr "length" "2")]
-)
+  [(set_attr "length" "2")
+   (set_attr "conds" "set")])
 
 (define_expand "ashrdi3"
   [(set (match_operand:DI              0 "s_register_operand" "")
                     (match_operand:SI 2 "nonmemory_operand" "N,l")))]
   "TARGET_THUMB1"
   "asr\\t%0, %1, %2"
-  [(set_attr "length" "2")]
-)
+  [(set_attr "length" "2")
+   (set_attr "conds" "set")])
 
 (define_expand "lshrdi3"
   [(set (match_operand:DI              0 "s_register_operand" "")
                     (match_operand:SI 2 "nonmemory_operand" "N,l")))]
   "TARGET_THUMB1"
   "lsr\\t%0, %1, %2"
-  [(set_attr "length" "2")]
-)
+  [(set_attr "length" "2")
+   (set_attr "conds" "set")])
 
 (define_expand "rotlsi3"
   [(set (match_operand:SI              0 "s_register_operand" "")
 
 (define_split
   [(set (match_operand:SI 0 "register_operand" "")
-       (zero_extend:SI (match_operand:HI 1 "register_operand" "l,m")))]
+       (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
   "!TARGET_THUMB2 && !arm_arch6"
   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
    mov\\t%0, %1"
   [(set_attr "length" "2,2,4,4,2,2,2,2,2")
    (set_attr "type" "*,*,*,*,load1,store1,load1,store1,*")
-   (set_attr "pool_range" "*,*,*,*,*,*,1020,*,*")]
-)
+   (set_attr "pool_range" "*,*,*,*,*,*,1020,*,*")
+   (set_attr "conds" "set,clob,*,*,nocond,nocond,nocond,nocond,nocond")])
 
 (define_split 
   [(set (match_operand:SI 0 "register_operand" "")
       return \"ldrh    %0, %1\";
     }"
   [(set_attr "length" "2,4,2,2,2,2")
-   (set_attr "type" "*,load1,store1,*,*,*")]
-)
+   (set_attr "type" "*,load1,store1,*,*,*")
+   (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")])
 
 
 (define_expand "movhi_bytes"
    mov\\t%0, %1"
   [(set_attr "length" "2")
    (set_attr "type" "*,load1,store1,*,*,*")
-   (set_attr "pool_range" "*,32,*,*,*,*")]
-)
+   (set_attr "pool_range" "*,32,*,*,*,*")
+   (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")])
 
 ;; HFmode moves
 (define_expand "movhf"
   "
   [(set_attr "length" "2")
    (set_attr "type" "*,load1,store1,*,*")
-   (set_attr "pool_range" "*,1020,*,*,*")]
-)
+   (set_attr "pool_range" "*,1020,*,*,*")
+   (set_attr "conds" "clob,nocond,nocond,nocond,nocond")])
 
 (define_expand "movsf"
   [(set (match_operand:SF 0 "general_operand" "")
    mov\\t%0, %1"
   [(set_attr "length" "2")
    (set_attr "type" "*,load1,store1,load1,store1,*,*")
-   (set_attr "pool_range" "*,*,*,1020,*,*,*")]
+   (set_attr "pool_range" "*,*,*,1020,*,*,*")
+   (set_attr "conds" "clob,nocond,nocond,nocond,nocond,nocond,nocond")]
 )
 
 (define_expand "movdf"
 (define_insn "cbranchsi4_insn"
   [(set (pc) (if_then_else
              (match_operator 0 "arm_comparison_operator"
-              [(match_operand:SI 1 "s_register_operand" "l,*h")
+              [(match_operand:SI 1 "s_register_operand" "l,l*h")
                (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r")])
              (label_ref (match_operand 3 "" ""))
              (pc)))]
   "TARGET_THUMB1"
-  "*
-  rtx t = prev_nonnote_insn (insn);
-  if (t != NULL_RTX
-      && INSN_P (t)
-      && INSN_CODE (t) == CODE_FOR_cbranchsi4_insn)
+{
+  rtx t = cfun->machine->thumb1_cc_insn;
+  if (t != NULL_RTX)
     {
-      t = XEXP (SET_SRC (PATTERN (t)), 0);
-      if (!rtx_equal_p (XEXP (t, 0), operands[1])
-         || !rtx_equal_p (XEXP (t, 1), operands[2]))
+      if (!rtx_equal_p (cfun->machine->thumb1_cc_op0, operands[1])
+         || !rtx_equal_p (cfun->machine->thumb1_cc_op1, operands[2]))
+       t = NULL_RTX;
+      if (cfun->machine->thumb1_cc_mode == CC_NOOVmode)
+       {
+         if (!noov_comparison_operator (operands[0], VOIDmode))
+           t = NULL_RTX;
+       }
+      else if (cfun->machine->thumb1_cc_mode != CCmode)
        t = NULL_RTX;
     }
-  else
-    t = NULL_RTX;
   if (t == NULL_RTX)
-    output_asm_insn (\"cmp\\t%1, %2\", operands);
+    {
+      output_asm_insn ("cmp\t%1, %2", operands);
+      cfun->machine->thumb1_cc_insn = insn;
+      cfun->machine->thumb1_cc_op0 = operands[1];
+      cfun->machine->thumb1_cc_op1 = operands[2];
+      cfun->machine->thumb1_cc_mode = CCmode;
+    }
+  else
+    /* Ensure we emit the right type of condition code on the jump.  */
+    XEXP (operands[0], 0) = gen_rtx_REG (cfun->machine->thumb1_cc_mode,
+                                        CC_REGNUM);
 
   switch (get_attr_length (insn))
     {
     case 6:  return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
     default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
     }
-  "
+}
   [(set (attr "far_jump")
         (if_then_else
            (eq_attr "length" "8")
                (const_int 8))))]
 )
 
-(define_insn "*movsi_cbranchsi4"
-  [(set (pc)
-       (if_then_else
-        (match_operator 3 "arm_comparison_operator"
-         [(match_operand:SI 1 "s_register_operand" "0,l,l,l")
-          (const_int 0)])
-        (label_ref (match_operand 2 "" ""))
-        (pc)))
-   (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*h,*m")
-       (match_dup 1))]
-  "TARGET_THUMB1"
-  "*{
-  if (which_alternative == 0)
-    output_asm_insn (\"cmp\t%0, #0\", operands);
-  else if (which_alternative == 1)
-    output_asm_insn (\"sub\t%0, %1, #0\", operands);
-  else
-    {
-      output_asm_insn (\"cmp\t%1, #0\", operands);
-      if (which_alternative == 2)
-       output_asm_insn (\"mov\t%0, %1\", operands);
-      else
-       output_asm_insn (\"str\t%1, %0\", operands);
-    }
-  switch (get_attr_length (insn) - ((which_alternative > 1) ? 2 : 0))
-    {
-    case 4:  return \"b%d3\\t%l2\";
-    case 6:  return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
-    default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
-    }
-  }"
-  [(set (attr "far_jump")
-        (if_then_else
-           (ior (and (gt (symbol_ref ("which_alternative"))
-                         (const_int 1))
-                     (eq_attr "length" "8"))
-                (eq_attr "length" "10"))
-           (const_string "yes")
-            (const_string "no")))
-   (set (attr "length")
-     (if_then_else
-       (le (symbol_ref ("which_alternative"))
-                      (const_int 1))
-       (if_then_else
-        (and (ge (minus (match_dup 2) (pc)) (const_int -250))
-             (le (minus (match_dup 2) (pc)) (const_int 256)))
-        (const_int 4)
-        (if_then_else
-          (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
-               (le (minus (match_dup 2) (pc)) (const_int 2048)))
-          (const_int 6)
-          (const_int 8)))
-       (if_then_else
-        (and (ge (minus (match_dup 2) (pc)) (const_int -248))
-             (le (minus (match_dup 2) (pc)) (const_int 256)))
-        (const_int 6)
-        (if_then_else
-          (and (ge (minus (match_dup 2) (pc)) (const_int -2038))
-               (le (minus (match_dup 2) (pc)) (const_int 2048)))
-          (const_int 8)
-          (const_int 10)))))]
-)
-
+;; Two peepholes to generate subtract of 0 instead of a move if the
+;; condition codes will be useful.
 (define_peephole2
   [(set (match_operand:SI 0 "low_register_operand" "")
        (match_operand:SI 1 "low_register_operand" ""))
                      (label_ref (match_operand 3 "" ""))
                      (pc)))]
   "TARGET_THUMB1"
-  [(parallel
-    [(set (pc)
-       (if_then_else (match_op_dup 2 [(match_dup 1) (const_int 0)])
+  [(set (match_dup 0) (minus:SI (match_dup 1) (const_int 0)))
+   (set (pc)
+       (if_then_else (match_op_dup 2 [(match_dup 0) (const_int 0)])
                      (label_ref (match_dup 3))
-                     (pc)))
-     (set (match_dup 0) (match_dup 1))])]
-  ""
-)
+                     (pc)))]
+  "")
 
 ;; Sigh!  This variant shouldn't be needed, but combine often fails to
 ;; merge cases like this because the op1 is a hard register in
                      (label_ref (match_operand 3 "" ""))
                      (pc)))]
   "TARGET_THUMB1"
-  [(parallel
-    [(set (pc)
-       (if_then_else (match_op_dup 2 [(match_dup 1) (const_int 0)])
+  [(set (match_dup 0) (minus:SI (match_dup 1) (const_int 0)))
+   (set (pc)
+       (if_then_else (match_op_dup 2 [(match_dup 0) (const_int 0)])
                      (label_ref (match_dup 3))
-                     (pc)))
-     (set (match_dup 0) (match_dup 1))])]
-  ""
-)
+                     (pc)))]
+  "")
 
 (define_insn "*negated_cbranchsi4"
   [(set (pc)
                (const_int 6)
                (const_int 8))))]
 )
-  
+
 (define_insn "*tstsi3_cbranch"
   [(set (pc)
        (if_then_else
                (const_int 8))))]
 )
   
-(define_insn "*andsi3_cbranch"
-  [(set (pc)
-       (if_then_else
-        (match_operator 5 "equality_operator"
-         [(and:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
-                  (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
-          (const_int 0)])
-        (label_ref (match_operand 4 "" ""))
-        (pc)))
-   (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
-       (and:SI (match_dup 2) (match_dup 3)))
-   (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
-  "TARGET_THUMB1"
-  "*
-  {
-  if (which_alternative == 0)
-    output_asm_insn (\"and\\t%0, %3\", operands);
-  else if (which_alternative == 1)
-    {
-      output_asm_insn (\"and\\t%1, %3\", operands);
-      output_asm_insn (\"mov\\t%0, %1\", operands);
-    }
-  else
-    {
-      output_asm_insn (\"and\\t%1, %3\", operands);
-      output_asm_insn (\"str\\t%1, %0\", operands);
-    }
-
-  switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
-    {
-    case 4:  return \"b%d5\\t%l4\";
-    case 6:  return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
-    default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
-    }
-  }"
-  [(set (attr "far_jump")
-        (if_then_else
-           (ior (and (eq (symbol_ref ("which_alternative"))
-                         (const_int 0))
-                     (eq_attr "length" "8"))
-                (eq_attr "length" "10"))
-           (const_string "yes")
-            (const_string "no")))
-   (set (attr "length")
-     (if_then_else
-       (eq (symbol_ref ("which_alternative"))
-                      (const_int 0))
-       (if_then_else
-        (and (ge (minus (match_dup 4) (pc)) (const_int -250))
-             (le (minus (match_dup 4) (pc)) (const_int 256)))
-        (const_int 4)
-        (if_then_else
-          (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
-               (le (minus (match_dup 4) (pc)) (const_int 2048)))
-          (const_int 6)
-          (const_int 8)))
-       (if_then_else
-        (and (ge (minus (match_dup 4) (pc)) (const_int -248))
-             (le (minus (match_dup 4) (pc)) (const_int 256)))
-        (const_int 6)
-        (if_then_else
-          (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
-               (le (minus (match_dup 4) (pc)) (const_int 2048)))
-          (const_int 8)
-          (const_int 10)))))]
-)
-
-(define_insn "*orrsi3_cbranch_scratch"
-  [(set (pc)
-       (if_then_else
-        (match_operator 4 "equality_operator"
-         [(ior:SI (match_operand:SI 1 "s_register_operand" "%0")
-                  (match_operand:SI 2 "s_register_operand" "l"))
-          (const_int 0)])
-        (label_ref (match_operand 3 "" ""))
-        (pc)))
-   (clobber (match_scratch:SI 0 "=l"))]
-  "TARGET_THUMB1"
-  "*
-  {
-  output_asm_insn (\"orr\\t%0, %2\", operands);
-  switch (get_attr_length (insn))
-    {
-    case 4:  return \"b%d4\\t%l3\";
-    case 6:  return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
-    default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
-    }
-  }"
-  [(set (attr "far_jump")
-        (if_then_else
-           (eq_attr "length" "8")
-           (const_string "yes")
-            (const_string "no")))
-   (set (attr "length") 
-        (if_then_else
-           (and (ge (minus (match_dup 3) (pc)) (const_int -250))
-                (le (minus (match_dup 3) (pc)) (const_int 256)))
-           (const_int 4)
-           (if_then_else
-               (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
-                    (le (minus (match_dup 3) (pc)) (const_int 2048)))
-               (const_int 6)
-               (const_int 8))))]
-)
-  
-(define_insn "*orrsi3_cbranch"
-  [(set (pc)
-       (if_then_else
-        (match_operator 5 "equality_operator"
-         [(ior:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
-                  (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
-          (const_int 0)])
-        (label_ref (match_operand 4 "" ""))
-        (pc)))
-   (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
-       (ior:SI (match_dup 2) (match_dup 3)))
-   (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
-  "TARGET_THUMB1"
-  "*
-  {
-  if (which_alternative == 0)
-    output_asm_insn (\"orr\\t%0, %3\", operands);
-  else if (which_alternative == 1)
-    {
-      output_asm_insn (\"orr\\t%1, %3\", operands);
-      output_asm_insn (\"mov\\t%0, %1\", operands);
-    }
-  else
-    {
-      output_asm_insn (\"orr\\t%1, %3\", operands);
-      output_asm_insn (\"str\\t%1, %0\", operands);
-    }
-
-  switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
-    {
-    case 4:  return \"b%d5\\t%l4\";
-    case 6:  return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
-    default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
-    }
-  }"
-  [(set (attr "far_jump")
-        (if_then_else
-           (ior (and (eq (symbol_ref ("which_alternative"))
-                         (const_int 0))
-                     (eq_attr "length" "8"))
-                (eq_attr "length" "10"))
-           (const_string "yes")
-            (const_string "no")))
-   (set (attr "length")
-     (if_then_else
-       (eq (symbol_ref ("which_alternative"))
-                      (const_int 0))
-       (if_then_else
-        (and (ge (minus (match_dup 4) (pc)) (const_int -250))
-             (le (minus (match_dup 4) (pc)) (const_int 256)))
-        (const_int 4)
-        (if_then_else
-          (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
-               (le (minus (match_dup 4) (pc)) (const_int 2048)))
-          (const_int 6)
-          (const_int 8)))
-       (if_then_else
-        (and (ge (minus (match_dup 4) (pc)) (const_int -248))
-             (le (minus (match_dup 4) (pc)) (const_int 256)))
-        (const_int 6)
-        (if_then_else
-          (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
-               (le (minus (match_dup 4) (pc)) (const_int 2048)))
-          (const_int 8)
-          (const_int 10)))))]
-)
-
-(define_insn "*xorsi3_cbranch_scratch"
-  [(set (pc)
-       (if_then_else
-        (match_operator 4 "equality_operator"
-         [(xor:SI (match_operand:SI 1 "s_register_operand" "%0")
-                  (match_operand:SI 2 "s_register_operand" "l"))
-          (const_int 0)])
-        (label_ref (match_operand 3 "" ""))
-        (pc)))
-   (clobber (match_scratch:SI 0 "=l"))]
-  "TARGET_THUMB1"
-  "*
-  {
-  output_asm_insn (\"eor\\t%0, %2\", operands);
-  switch (get_attr_length (insn))
-    {
-    case 4:  return \"b%d4\\t%l3\";
-    case 6:  return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
-    default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
-    }
-  }"
-  [(set (attr "far_jump")
-        (if_then_else
-           (eq_attr "length" "8")
-           (const_string "yes")
-            (const_string "no")))
-   (set (attr "length") 
-        (if_then_else
-           (and (ge (minus (match_dup 3) (pc)) (const_int -250))
-                (le (minus (match_dup 3) (pc)) (const_int 256)))
-           (const_int 4)
-           (if_then_else
-               (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
-                    (le (minus (match_dup 3) (pc)) (const_int 2048)))
-               (const_int 6)
-               (const_int 8))))]
-)
-  
-(define_insn "*xorsi3_cbranch"
-  [(set (pc)
-       (if_then_else
-        (match_operator 5 "equality_operator"
-         [(xor:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
-                  (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
-          (const_int 0)])
-        (label_ref (match_operand 4 "" ""))
-        (pc)))
-   (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
-       (xor:SI (match_dup 2) (match_dup 3)))
-   (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
-  "TARGET_THUMB1"
-  "*
-  {
-  if (which_alternative == 0)
-    output_asm_insn (\"eor\\t%0, %3\", operands);
-  else if (which_alternative == 1)
-    {
-      output_asm_insn (\"eor\\t%1, %3\", operands);
-      output_asm_insn (\"mov\\t%0, %1\", operands);
-    }
-  else
-    {
-      output_asm_insn (\"eor\\t%1, %3\", operands);
-      output_asm_insn (\"str\\t%1, %0\", operands);
-    }
-
-  switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
-    {
-    case 4:  return \"b%d5\\t%l4\";
-    case 6:  return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
-    default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
-    }
-  }"
-  [(set (attr "far_jump")
-        (if_then_else
-           (ior (and (eq (symbol_ref ("which_alternative"))
-                         (const_int 0))
-                     (eq_attr "length" "8"))
-                (eq_attr "length" "10"))
-           (const_string "yes")
-            (const_string "no")))
-   (set (attr "length")
-     (if_then_else
-       (eq (symbol_ref ("which_alternative"))
-                      (const_int 0))
-       (if_then_else
-        (and (ge (minus (match_dup 4) (pc)) (const_int -250))
-             (le (minus (match_dup 4) (pc)) (const_int 256)))
-        (const_int 4)
-        (if_then_else
-          (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
-               (le (minus (match_dup 4) (pc)) (const_int 2048)))
-          (const_int 6)
-          (const_int 8)))
-       (if_then_else
-        (and (ge (minus (match_dup 4) (pc)) (const_int -248))
-             (le (minus (match_dup 4) (pc)) (const_int 256)))
-        (const_int 6)
-        (if_then_else
-          (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
-               (le (minus (match_dup 4) (pc)) (const_int 2048)))
-          (const_int 8)
-          (const_int 10)))))]
-)
-
-(define_insn "*bicsi3_cbranch_scratch"
-  [(set (pc)
-       (if_then_else
-        (match_operator 4 "equality_operator"
-         [(and:SI (not:SI (match_operand:SI 2 "s_register_operand" "l"))
-                  (match_operand:SI 1 "s_register_operand" "0"))
-          (const_int 0)])
-        (label_ref (match_operand 3 "" ""))
-        (pc)))
-   (clobber (match_scratch:SI 0 "=l"))]
-  "TARGET_THUMB1"
-  "*
-  {
-  output_asm_insn (\"bic\\t%0, %2\", operands);
-  switch (get_attr_length (insn))
-    {
-    case 4:  return \"b%d4\\t%l3\";
-    case 6:  return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
-    default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
-    }
-  }"
-  [(set (attr "far_jump")
-        (if_then_else
-           (eq_attr "length" "8")
-           (const_string "yes")
-            (const_string "no")))
-   (set (attr "length") 
-        (if_then_else
-           (and (ge (minus (match_dup 3) (pc)) (const_int -250))
-                (le (minus (match_dup 3) (pc)) (const_int 256)))
-           (const_int 4)
-           (if_then_else
-               (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
-                    (le (minus (match_dup 3) (pc)) (const_int 2048)))
-               (const_int 6)
-               (const_int 8))))]
-)
-  
-(define_insn "*bicsi3_cbranch"
-  [(set (pc)
-       (if_then_else
-        (match_operator 5 "equality_operator"
-         [(and:SI (not:SI (match_operand:SI 3 "s_register_operand" "l,l,l,l,l"))
-                  (match_operand:SI 2 "s_register_operand" "0,1,1,1,1"))
-          (const_int 0)])
-        (label_ref (match_operand 4 "" ""))
-        (pc)))
-   (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=!l,l,*?h,*?m,*?m")
-       (and:SI (not:SI (match_dup 3)) (match_dup 2)))
-   (clobber (match_scratch:SI 1 "=X,l,l,&l,&l"))]
-  "TARGET_THUMB1"
-  "*
-  {
-  if (which_alternative == 0)
-    output_asm_insn (\"bic\\t%0, %3\", operands);
-  else if (which_alternative <= 2)
-    {
-      output_asm_insn (\"bic\\t%1, %3\", operands);
-      /* It's ok if OP0 is a lo-reg, even though the mov will set the
-        conditions again, since we're only testing for equality.  */
-      output_asm_insn (\"mov\\t%0, %1\", operands);
-    }
-  else
-    {
-      output_asm_insn (\"bic\\t%1, %3\", operands);
-      output_asm_insn (\"str\\t%1, %0\", operands);
-    }
-
-  switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
-    {
-    case 4:  return \"b%d5\\t%l4\";
-    case 6:  return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
-    default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
-    }
-  }"
-  [(set (attr "far_jump")
-        (if_then_else
-           (ior (and (eq (symbol_ref ("which_alternative"))
-                         (const_int 0))
-                     (eq_attr "length" "8"))
-                (eq_attr "length" "10"))
-           (const_string "yes")
-            (const_string "no")))
-   (set (attr "length")
-     (if_then_else
-       (eq (symbol_ref ("which_alternative"))
-                      (const_int 0))
-       (if_then_else
-        (and (ge (minus (match_dup 4) (pc)) (const_int -250))
-             (le (minus (match_dup 4) (pc)) (const_int 256)))
-        (const_int 4)
-        (if_then_else
-          (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
-               (le (minus (match_dup 4) (pc)) (const_int 2048)))
-          (const_int 6)
-          (const_int 8)))
-       (if_then_else
-        (and (ge (minus (match_dup 4) (pc)) (const_int -248))
-             (le (minus (match_dup 4) (pc)) (const_int 256)))
-        (const_int 6)
-        (if_then_else
-          (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
-               (le (minus (match_dup 4) (pc)) (const_int 2048)))
-          (const_int 8)
-          (const_int 10)))))]
-)
-
 (define_insn "*cbranchne_decr1"
   [(set (pc)
        (if_then_else (match_operator 3 "equality_operator"
           (const_int 8))))]
 )
 
-(define_insn "*subsi3_cbranch"
-  [(set (pc)
-       (if_then_else
-        (match_operator 4 "arm_comparison_operator"
-         [(minus:SI
-           (match_operand:SI 2 "s_register_operand" "l,l,1,l")
-           (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
-          (const_int 0)])
-        (label_ref (match_operand 5 "" ""))
-        (pc)))
-   (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
-       (minus:SI (match_dup 2) (match_dup 3)))
-   (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
-  "TARGET_THUMB1
-   && (GET_CODE (operands[4]) == EQ
-       || GET_CODE (operands[4]) == NE
-       || GET_CODE (operands[4]) == GE
-       || GET_CODE (operands[4]) == LT)"
-  "*
-   {
-     if (which_alternative == 0)
-       output_asm_insn (\"sub\\t%0, %2, %3\", operands);
-     else if (which_alternative == 1)
-       {
-        /* We must provide an alternative for a hi reg because reload 
-           cannot handle output reloads on a jump instruction, but we
-           can't subtract into that.  Fortunately a mov from lo to hi
-           does not clobber the condition codes.  */
-        output_asm_insn (\"sub\\t%1, %2, %3\", operands);
-        output_asm_insn (\"mov\\t%0, %1\", operands);
-       }
-     else
-       {
-        /* Similarly, but the target is memory.  */
-        output_asm_insn (\"sub\\t%1, %2, %3\", operands);
-        output_asm_insn (\"str\\t%1, %0\", operands);
-       }
-
-     switch (get_attr_length (insn) - ((which_alternative != 0) ? 2 : 0))
-       {
-        case 4:
-          return \"b%d4\\t%l5\";
-        case 6:
-          return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
-        default:
-          return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
-       }
-   }
-  "
-  [(set (attr "far_jump")
-        (if_then_else
-           (ior (and (eq (symbol_ref ("which_alternative"))
-                         (const_int 0))
-                     (eq_attr "length" "8"))
-                (eq_attr "length" "10"))
-           (const_string "yes")
-            (const_string "no")))
-   (set (attr "length")
-     (if_then_else
-       (eq (symbol_ref ("which_alternative"))
-                      (const_int 0))
-       (if_then_else
-        (and (ge (minus (match_dup 5) (pc)) (const_int -250))
-             (le (minus (match_dup 5) (pc)) (const_int 256)))
-        (const_int 4)
-        (if_then_else
-          (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
-               (le (minus (match_dup 5) (pc)) (const_int 2048)))
-          (const_int 6)
-          (const_int 8)))
-       (if_then_else
-        (and (ge (minus (match_dup 5) (pc)) (const_int -248))
-             (le (minus (match_dup 5) (pc)) (const_int 256)))
-        (const_int 6)
-        (if_then_else
-          (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
-               (le (minus (match_dup 5) (pc)) (const_int 2048)))
-          (const_int 8)
-          (const_int 10)))))]
-)
-
-(define_insn "*subsi3_cbranch_scratch"
-  [(set (pc)
-       (if_then_else
-        (match_operator 0 "arm_comparison_operator"
-         [(minus:SI (match_operand:SI 1 "register_operand" "l")
-                    (match_operand:SI 2 "nonmemory_operand" "l"))
-          (const_int 0)])
-        (label_ref (match_operand 3 "" ""))
-        (pc)))]
-  "TARGET_THUMB1
-   && (GET_CODE (operands[0]) == EQ
-       || GET_CODE (operands[0]) == NE
-       || GET_CODE (operands[0]) == GE
-       || GET_CODE (operands[0]) == LT)"
-  "*
-  output_asm_insn (\"cmp\\t%1, %2\", operands);
-  switch (get_attr_length (insn))
-    {
-    case 4:  return \"b%d0\\t%l3\";
-    case 6:  return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
-    default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
-    }
-  "
-  [(set (attr "far_jump")
-        (if_then_else
-           (eq_attr "length" "8")
-           (const_string "yes")
-            (const_string "no")))
-   (set (attr "length") 
-        (if_then_else
-           (and (ge (minus (match_dup 3) (pc)) (const_int -250))
-                (le (minus (match_dup 3) (pc)) (const_int 256)))
-           (const_int 4)
-           (if_then_else
-               (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
-                    (le (minus (match_dup 3) (pc)) (const_int 2048)))
-               (const_int 6)
-               (const_int 8))))]
-)
 
 ;; Comparison and test insns
 
index ee6b6256b3234288f4dedd1a594de84690e26cb6..9ee681ca07289c8aa8b2ecd1a5693b45bf7dda35 100644 (file)
@@ -30,7 +30,7 @@
 
 ;; The following multi-letter normal constraints have been used:
 ;; in ARM/Thumb-2 state: Da, Db, Dc, Dn, Dl, DL, Dv, Dy, Di
-;; in Thumb-1 state: Pa, Pb, Pc
+;; in Thumb-1 state: Pa, Pb, Pc, Pd
 ;; in Thumb-2 state: Ps, Pt, Pu, Pv, Pw, Px
 
 ;; The following memory constraints have been used:
        (match_test "TARGET_THUMB1
                    && ival > 1020 && ival <= 1275")))
 
+(define_constraint "Pd"
+  "@internal In Thumb-1 state a constant in the range 0 to 7"
+  (and (match_code "const_int")
+       (match_test "TARGET_THUMB1 && ival >= 0 && ival <= 7")))
+
 (define_constraint "Ps"
   "@internal In Thumb-2 state a constant in the range -255 to +255"
   (and (match_code "const_int")
index f53c54fa110e975b569a60b89f47f120654f69bd..89dcb29a25086d511b138c9fc934d7fc8ec1b0d6 100644 (file)
 (define_special_predicate "lt_ge_comparison_operator"
   (match_code "lt,ge"))
 
+(define_special_predicate "noov_comparison_operator"
+  (match_code "lt,ge,eq,ne"))
+
 (define_special_predicate "minmax_operator"
   (and (match_code "smin,smax,umin,umax")
        (match_test "mode == GET_MODE (op)")))
index c35ed7b75a570bc567c0ff3f56293c307b57744d..f1cff3409ade3c62e97253d8340f11d4fff53f0b 100644 (file)
@@ -99,8 +99,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "sdbout.h"
 #endif
 
-/* If we aren't using cc0, CC_STATUS_INIT shouldn't exist.  So define a
-   null default for it to save conditionalization later.  */
+/* Most ports that aren't using cc0 don't need to define CC_STATUS_INIT.
+   So define a null default for it to save conditionalization later.  */
 #ifndef CC_STATUS_INIT
 #define CC_STATUS_INIT
 #endif
@@ -2039,9 +2039,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
 #endif
            }
        }
-#ifdef HAVE_cc0
       CC_STATUS_INIT;
-#endif
 
       if (!DECL_IGNORED_P (current_function_decl) && LABEL_NAME (insn))
        debug_hooks->label (insn);