arm.c (arm_rtx_costs_1, [...]): Adjust costs for comparing a constant with small...
authorRichard Earnshaw <rearnsha@gcc.gnu.org>
Fri, 24 Oct 2003 09:25:30 +0000 (09:25 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Fri, 24 Oct 2003 09:25:30 +0000 (09:25 +0000)
* arm.c (arm_rtx_costs_1, case TARGET_THUMB): Adjust costs for
comparing a constant with small negative numbers and add costing
for constants in conjunction with AND.
(note_invalid_constants): Tidy previous change.
(thumb_cmp_operand): Tidy.
(thumb_cmpneg_operand): New function.
* arm.h (CONDITIONAL_REGISTER_USAGE): Don't use HI regs if optimizing
for size.
(FIRST_LO_REGNUM, FIRST_HI_REGNUM, LAST_HI_REGNUM): Define.
(PREDICATE_CODES): Add thumb_cmpneg_operand.
* arm.md (cbranchsi4): Convert to define_expand.  Handle comparison
with a negative constant.
(cbranchsi4_insn): Matcher for cbranchsi4.
(cbranchsi4_scratch): Similar, but a scratch is available for
handling negative constants.
(movsi_cbranchsi4): New pattern.
(tstsi3_cbranch): Renamed from andsi3_cbranch_scratch, remove scratch
and use the TST instruction.
(andsi3_cbranch, orrsi3_cbranch, xorsi3_cbranch, cbranchne_decr1)
(addsi3_cbranch, subsi3_cbranch): Ensure that register preferencing
cannot see high regs or memory alternatives.
(bicsi3_cbranch_scratch, bicsi3_cbranch): New patterns.

From-SVN: r72885

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/config/arm/arm.h
gcc/config/arm/arm.md

index 794eb0190d29141fec40fe5a96bac13dfff0a40a..6330e5cb1aec00f0411bdbae5354fa110fbfd0c0 100644 (file)
@@ -1,3 +1,28 @@
+2003-10-24  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm.c (arm_rtx_costs_1, case TARGET_THUMB): Adjust costs for
+       comparing a constant with small negative numbers and add costing
+       for constants in conjunction with AND.
+       (note_invalid_constants): Tidy previous change.
+       (thumb_cmp_operand): Tidy.
+       (thumb_cmpneg_operand): New function.
+       * arm.h (CONDITIONAL_REGISTER_USAGE): Don't use HI regs if optimizing
+       for size.
+       (FIRST_LO_REGNUM, FIRST_HI_REGNUM, LAST_HI_REGNUM): Define.
+       (PREDICATE_CODES): Add thumb_cmpneg_operand.
+       * arm.md (cbranchsi4): Convert to define_expand.  Handle comparison
+       with a negative constant.
+       (cbranchsi4_insn): Matcher for cbranchsi4.
+       (cbranchsi4_scratch): Similar, but a scratch is available for
+       handling negative constants.
+       (movsi_cbranchsi4): New pattern.
+       (tstsi3_cbranch): Renamed from andsi3_cbranch_scratch, remove scratch
+       and use the TST instruction.
+       (andsi3_cbranch, orrsi3_cbranch, xorsi3_cbranch, cbranchne_decr1)
+       (addsi3_cbranch, subsi3_cbranch): Ensure that register preferencing
+       cannot see high regs or memory alternatives.
+       (bicsi3_cbranch_scratch, bicsi3_cbranch): New patterns.
+
 2003-10-24  Richard Earnshaw  <rearnsha@arm.com>
 
        * arm.c (note_invalid_constants): Try to extract the constant
 
 2003-10-22  Jan Hubicka  <jh@suse.cz>
 
-       * dwarf2out.c (dwarf2out_abstract_function): Use DW_AT to check presence of DW_AT_inline.
-       (gen_subprogram_die): Likewise; do not abort instead of emitting DW_AT_not_inline
+       * dwarf2out.c (dwarf2out_abstract_function): Use DW_AT to check
+       presence of DW_AT_inline.
+       (gen_subprogram_die): Likewise; do not abort instead of emitting
+       DW_AT_not_inline.
 
 2003-10-22  Jan Hubicka  <jh@suse.cz>
 
index 2b1bf7a138986abbd0d6b70116a5ecd29cd69431..f127b1d2904e5a9f4a883522fecddc3f31d02f32 100644 (file)
@@ -3131,12 +3131,12 @@ arm_rtx_costs_1 (rtx x, enum rtx_code code, enum rtx_code outer)
                return COSTS_N_INSNS (2);                               
              return COSTS_N_INSNS (3);                         
            }                                                           
-         else if (outer == PLUS                                        
+         else if ((outer == PLUS || outer == COMPARE)
                   && INTVAL (x) < 256 && INTVAL (x) > -256)            
-           return 0;                                                   
-         else if (outer == COMPARE                                     
-                  && (unsigned HOST_WIDE_INT) INTVAL (x) < 256)        
-           return 0;                                                   
+           return 0;
+         else if (outer == AND
+                  && INTVAL (x) < 256 && INTVAL (x) >= -256)
+           return COSTS_N_INSNS (1);
          else if (outer == ASHIFT || outer == ASHIFTRT         
                   || outer == LSHIFTRT)                                
            return 0;                                                   
@@ -6903,13 +6903,11 @@ note_invalid_constants (rtx insn, HOST_WIDE_INT address, int do_pushes)
                     us here.  Lets just hope that we can use the 
                     constant pool value directly.  */
                  if (op == cop)
-                   op = get_pool_constant (XEXP (op, 0));
-                 else
-                   op = cop;
+                   cop = get_pool_constant (XEXP (op, 0));
 
                  push_minipool_fix (insn, address,
                                     recog_data.operand_loc[opno],
-                                    recog_data.operand_mode[opno], op);
+                                    recog_data.operand_mode[opno], cop);
                }
 
              result = true;
@@ -12647,10 +12645,19 @@ int
 thumb_cmp_operand (rtx op, enum machine_mode mode)
 {
   return ((GET_CODE (op) == CONST_INT
-          && (unsigned HOST_WIDE_INT) (INTVAL (op)) < 256)
+          && INTVAL (op) < 256
+          && INTVAL (op) >= 0)
          || s_register_operand (op, mode));
 }
 
+int
+thumb_cmpneg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+  return (GET_CODE (op) == CONST_INT
+         && INTVAL (op) < 0
+         && INTVAL (op) > -256);
+}
+
 /* Return TRUE if a result can be stored in OP without clobbering the
    condition code register.  Prior to reload we only accept a
    register.  After reload we have to be able to handle memory as
index f757ead07e1be18d0df1eca28075ecce0d7c4f8c..0cb1562e636fb3372123bb650892c2756d69fa95 100644 (file)
@@ -949,6 +949,16 @@ extern const char * structure_size_string;
        fixed_regs[regno] = call_used_regs[regno] = 1;          \
     }                                                          \
                                                                \
+  if (TARGET_THUMB && optimize_size)                           \
+    {                                                          \
+      /* When optimizing for size, it's better not to use      \
+        the HI regs, because of the overhead of stacking       \
+        them. */                                               \
+      for (regno = FIRST_HI_REGNUM;                            \
+          regno <= LAST_HI_REGNUM; ++regno)                    \
+       fixed_regs[regno] = call_used_regs[regno] = 1;          \
+    }                                                          \
+                                                               \
   if (TARGET_CIRRUS)                                           \
     {                                                          \
       for (regno = FIRST_ARM_FP_REGNUM;                                \
@@ -1055,8 +1065,11 @@ extern const char * structure_size_string;
 /* The number of the last argument register.  */
 #define LAST_ARG_REGNUM        ARG_REGISTER (NUM_ARG_REGS)
 
-/* The number of the last "lo" register (thumb).  */
+/* The numbers of the Thumb register ranges.  */
+#define FIRST_LO_REGNUM        0
 #define LAST_LO_REGNUM         7
+#define FIRST_HI_REGNUM                8
+#define LAST_HI_REGNUM         11
 
 /* The register that holds the return address in exception handlers.  */
 #define EXCEPTION_LR_REGNUM    2
@@ -2693,6 +2706,7 @@ extern int making_const_table;
   {"reg_or_int_operand", {SUBREG, REG, CONST_INT}},                    \
   {"index_operand",      {SUBREG, REG, CONST_INT}},                    \
   {"thumb_cmp_operand",  {SUBREG, REG, CONST_INT}},                    \
+  {"thumb_cmpneg_operand", {CONST_INT}},                               \
   {"thumb_cbrch_target_operand", {SUBREG, REG, MEM}},                  \
   {"offsettable_memory_operand", {MEM}},                               \
   {"bad_signed_byte_operand", {MEM}},                                  \
index c4ef68d937e06c856e787ecfaff44f171d5e5b5a..9a693a839d0836637e698312e8e6ecd881a403d9 100644 (file)
 ;; For a 'b'       pos_range = 2046, neg_range = -2048 giving (-2040->2048).
 ;; For a 'b<cond>' pos_range = 254,  neg_range = -256  giving (-250 ->256).
 
-(define_insn "cbranchsi4"
-  [(set (pc)
-       (if_then_else
-           (match_operator                    0 "arm_comparison_operator"
-                           [(match_operand:SI 1 "register_operand"   "l,r")
-                            (match_operand:SI 2 "nonmemory_operand" "rI,r")])
-           (label_ref       (match_operand    3 "" ""))
-           (pc)))]
+(define_expand "cbranchsi4"
+  [(set (pc) (if_then_else
+             (match_operator 0 "arm_comparison_operator"
+              [(match_operand:SI 1 "s_register_operand" "")
+               (match_operand:SI 2 "nonmemory_operand" "")])
+             (label_ref (match_operand 3 "" ""))
+             (pc)))]
+  "TARGET_THUMB"
+  "
+  if (thumb_cmpneg_operand (operands[2], SImode))
+    {
+      emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
+                                             operands[3], operands[0]));
+      DONE;
+    }
+  if (!thumb_cmp_operand (operands[2], SImode))
+    operands[2] = force_reg (SImode, operands[2]);
+  ")
+
+(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 2 "thumb_cmp_operand" "lI*h,*r")])
+             (label_ref (match_operand 3 "" ""))
+             (pc)))]
   "TARGET_THUMB"
   "*
   output_asm_insn (\"cmp\\t%1, %2\", operands);
+
   switch (get_attr_length (insn))
     {
     case 4:  return \"b%d0\\t%l3\";
                (const_int 8))))]
 )
 
+(define_insn "cbranchsi4_scratch"
+  [(set (pc) (if_then_else
+             (match_operator 4 "arm_comparison_operator"
+              [(match_operand:SI 1 "s_register_operand" "l,0")
+               (match_operand:SI 2 "thumb_cmpneg_operand" "L,J")])
+             (label_ref (match_operand 3 "" ""))
+             (pc)))
+   (clobber (match_scratch:SI 0 "=l,l"))]
+  "TARGET_THUMB"
+  "*
+  output_asm_insn (\"add\\t%0, %1, #%n2\", 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 "*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_THUMB"
+  "*{
+  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)))))]
+)
+
 (define_insn "*negated_cbranchsi4"
   [(set (pc)
        (if_then_else
-        (match_operator             0 "arm_comparison_operator"
-         [(match_operand:SI         1 "register_operand"  "l")
-          (neg:SI (match_operand:SI 2 "nonmemory_operand" "l"))])
-        (label_ref (match_operand   3 "" ""))
+        (match_operator 0 "arm_comparison_operator"
+         [(match_operand:SI 1 "s_register_operand" "l")
+          (neg:SI (match_operand:SI 2 "s_register_operand" "l"))])
+        (label_ref (match_operand 3 "" ""))
         (pc)))]
   "TARGET_THUMB"
   "*
                (const_int 8))))]
 )
   
-(define_insn "*andsi3_cbranch_scratch"
+(define_insn "*tstsi3_cbranch"
   [(set (pc)
        (if_then_else
-        (match_operator 4 "equality_operator"
-         [(and:SI (match_operand:SI 1 "s_register_operand" "%0")
-                  (match_operand:SI 2 "s_register_operand" "l"))
+        (match_operator 3 "equality_operator"
+         [(and:SI (match_operand:SI 0 "s_register_operand" "%l")
+                  (match_operand:SI 1 "s_register_operand" "l"))
           (const_int 0)])
-        (label_ref (match_operand 3 "" ""))
-        (pc)))
-   (clobber (match_scratch:SI 0 "=l"))]
+        (label_ref (match_operand 2 "" ""))
+        (pc)))]
   "TARGET_THUMB"
   "*
   {
-  output_asm_insn (\"and\\t%0, %2\", operands);
+  output_asm_insn (\"tst\\t%0, %1\", 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%=:\";
+    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")
             (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)))
+           (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 3) (pc)) (const_int -2040))
-                    (le (minus (match_dup 3) (pc)) (const_int 2048)))
+               (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))))]
 )
           (const_int 0)])
         (label_ref (match_operand 4 "" ""))
         (pc)))
-   (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,?h,?m,?m")
+   (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_THUMB"
           (const_int 0)])
         (label_ref (match_operand 4 "" ""))
         (pc)))
-   (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,?h,?m,?m")
+   (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_THUMB"
           (const_int 0)])
         (label_ref (match_operand 4 "" ""))
         (pc)))
-   (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,?h,?m,?m")
+   (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_THUMB"
           (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_THUMB"
+  "*
+  {
+  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"))
+                  (match_operand:SI 2 "s_register_operand" "0,1,1,1"))
+          (const_int 0)])
+        (label_ref (match_operand 4 "" ""))
+        (pc)))
+   (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
+       (and:SI (not:SI (match_dup 3)) (match_dup 2)))
+   (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
+  "TARGET_THUMB"
+  "*
+  {
+  if (which_alternative == 0)
+    output_asm_insn (\"bic\\t%0, %3\", operands);
+  else if (which_alternative == 1)
+    {
+      output_asm_insn (\"bic\\t%1, %3\", operands);
+      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 0)])
                      (label_ref (match_operand 4 "" ""))
                      (pc)))
-   (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,?h,?m,?m")
+   (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
        (plus:SI (match_dup 2) (const_int -1)))
    (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
   "TARGET_THUMB"
           (const_int 0)])
         (label_ref (match_operand 5 "" ""))
         (pc)))
-   (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,?h,?m,?m")
-       (plus:SI (match_dup 2) (match_dup 3)))
+   (set
+    (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m")
+    (plus:SI (match_dup 2) (match_dup 3)))
    (clobber (match_scratch:SI 1 "=X,X,X,l,&l,&l"))]
   "TARGET_THUMB
    && (GET_CODE (operands[4]) == EQ
           (const_int 0)])
         (label_ref (match_operand 5 "" ""))
         (pc)))
-   (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,?h,?m,?m")
+   (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_THUMB