This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH: PR target/44072] Replace "cmp r0, -1" by "adds r0, 1" in thumb2
- From: Carrot Wei <carrot at google dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 12 May 2010 16:43:01 +0800
- Subject: [PATCH: PR target/44072] Replace "cmp r0, -1" by "adds r0, 1" in thumb2
Hi
Both "cmp r0, -1" and "adds r0, 1" have the same effect when used to set
conditions for following branch. But adds with small positive immediate is a
16 bit instruction and cmp with negative immediate is a 32 bit instruction. So
we prefer adds in thumb2.
Thumb1 already has an insn pattern "cbranchsi4_scratch" to do this, this patch
adds the corresponding insn pattern for thumb2.
Test:
Regression tests on arm qemu.
thanks
Guozhi
ChangeLog:
2010-05-12 Wei Guozhi <carrot@google.com>
PR target/44072
* config/arm/thumb2.md (thumb2_cbranchsi4_scratch): New insn pattern.
ChangeLog:
2010-05-12 Wei Guozhi <carrot@google.com>
PR target/44072
* gcc.target/arm/pr44072.c: New testcase.
Index: config/arm/thumb2.md
===================================================================
--- config/arm/thumb2.md (revision 159251)
+++ config/arm/thumb2.md (working copy)
@@ -1516,3 +1516,74 @@
(const_int 8)
(const_int 10)))))]
)
+
+(define_insn "thumb2_cbranchsi4_scratch"
+ [(set (pc) (if_then_else
+ (match_operator 4 "arm_comparison_operator"
+ [(match_operand:SI 1 "s_register_operand" "l,?h,0")
+ (match_operand:SI 2 "thumb1_cmpneg_operand" "Pt,Ps,Ps")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))
+ (clobber (match_scratch:SI 0 "=l,X,l"))]
+ "TARGET_THUMB2"
+ "*
+ if (which_alternative == 1)
+ {
+ output_asm_insn (\"cmp\\t%1, #%n2\", operands);
+ switch (get_attr_length (insn))
+ {
+ case 6: return \"b%d4\\t%l3\";
+ case 8: 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%=:\";
+ }
+ }
+ else
+ {
+ if (which_alternative == 0)
+ output_asm_insn (\"adds\\t%0, %1, #%n2\", operands);
+ else
+ output_asm_insn (\"adds\\t%0, #%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 (symbol_ref ("which_alternative"))
+ (const_int 1))
+ (if_then_else
+ (eq_attr "length" "10")
+ (const_string "yes")
+ (const_string "no"))
+ (if_then_else
+ (eq_attr "length" "8")
+ (const_string "yes")
+ (const_string "no"))))
+ (set (attr "length")
+ (if_then_else
+ (eq (symbol_ref ("which_alternative"))
+ (const_int 1))
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -250))
+ (le (minus (match_dup 3) (pc)) (const_int 256)))
+ (const_int 6)
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
+ (le (minus (match_dup 3) (pc)) (const_int 2048)))
+ (const_int 8)
+ (const_int 10)))
+ (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)))))]
+)
Index: pr44072.c
===================================================================
--- pr44072.c (revision 0)
+++ pr44072.c (revision 0)
@@ -0,0 +1,9 @@
+/* { dg-options "-march=armv7-a -mthumb -Os" } */
+/* { dg-final { scan-assembler "adds" } } */
+
+void foo1();
+void bar5(int x)
+{
+ if (x == -1)
+ foo1();
+}