This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PING] [PATCH: PR target/42879] Replace "tst r3, 1" with "lsls r3, r3, 31" in thumb2
- From: Carrot Wei <carrot at google dot com>
- To: Richard Earnshaw <rearnsha at arm dot com>, gcc-patches at gcc dot gnu dot org
- Date: Sat, 1 May 2010 13:15:59 +0800
- Subject: Re: [PING] [PATCH: PR target/42879] Replace "tst r3, 1" with "lsls r3, r3, 31" in thumb2
- References: <v2v7587b291004252333m996ec418ud68882ac032145a1@mail.gmail.com> <t2u7587b291004272044yf40b4b35q9b1de75567b0b659@mail.gmail.com> <w2i7587b291004282052o926e254dqc142cf3af8ddd11e@mail.gmail.com> <1272538531.28096.21.camel@e102346-lin.cambridge.arm.com> <j2r7587b291004292231x85bf7ab4t98129fbb14eec6e4@mail.gmail.com> <1272616057.28096.29.camel@e102346-lin.cambridge.arm.com>
On Fri, Apr 30, 2010 at 4:27 PM, Richard Earnshaw <rearnsha@arm.com> wrote:
>> Since only when both registers are LO_REGS, then the lsls will be
>> encoded as 16bit. Otherwise it is 32 bit, no better than current tst
>> instruction.
>>
>
> Except that at the time the pattern is generated we don't know whether
> or not HI or LO regs will be used (since this is in combine and we are
> still using pseudos).
>
>> With this patch should it fall back to tst instruction when there are HI_REGS?
>
> So your pattern needs to handle the fall-back case as well, when we want
> to generate TST rather than LSLS (note you can use 'X' as a constraint
> for the output in this case to say that you don't need a register).
>
According to your suggestion, I added a new insn pattern to handle it on thumb2.
It passed the regression tests on arm qemu.
ChangeLog:
2010-05-01 Wei Guozhi <carrot@google.com>
PR target/42879
* config/arm/thumb2.md (thumb2_tlobits_cbranch): New insn pattern.
ChangeLog:
2010-05-01 Wei Guozhi <carrot@google.com>
PR target/42879
* gcc.target/arm/pr42879.c: New testcase.
Index: config/arm/thumb2.md
===================================================================
--- config/arm/thumb2.md (revision 158917)
+++ config/arm/thumb2.md (working copy)
@@ -1442,3 +1442,80 @@
[(set_attr "length" "4,4,16")
(set_attr "predicable" "yes")]
)
+
+(define_insn "*thumb2_tlobits_cbranch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 0 "equality_operator"
+ [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l,?h")
+ (match_operand:SI 2 "const_int_operand" "i,i")
+ (const_int 0))
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))
+ (clobber (match_scratch:SI 4 "=l,X"))]
+ "TARGET_THUMB2"
+ "*
+ {
+ if (which_alternative == 0)
+ {
+ rtx op[3];
+ op[0] = operands[4];
+ op[1] = operands[1];
+ op[2] = GEN_INT (32 - INTVAL (operands[2]));
+
+ if (TARGET_UNIFIED_ASM)
+ output_asm_insn (\"lsls\\t%0, %1, %2\", op);
+ else
+ output_asm_insn (\"lsl\\t%0, %1, %2\", op);
+ 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%=:\";
+ }
+ }
+ else
+ {
+ rtx op[2];
+ op[0] = operands[1];
+ op[1] = GEN_INT ((1 << INTVAL (operands[2])) - 1);
+
+ output_asm_insn (\"tst\\t%0, %1\", op);
+ switch (get_attr_length (insn))
+ {
+ case 6: return \"b%d0\\t%l3\";
+ case 8: 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
+ (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
+ (le (minus (match_dup 3) (pc)) (const_int 2048)))
+ (const_string "no")
+ (const_string "yes")))
+ (set (attr "length")
+ (if_then_else
+ (eq (symbol_ref ("which_alternative"))
+ (const_int 0))
+ (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)))
+ (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)))))]
+)
Index: testsuite/gcc.target/arm/pr42879.c
===================================================================
--- testsuite/gcc.target/arm/pr42879.c (revision 0)
+++ testsuite/gcc.target/arm/pr42879.c (revision 0)
@@ -0,0 +1,15 @@
+/* { dg-options "-march=armv7-a -mthumb -Os" } */
+/* { dg-final { scan-assembler "lsl" } } */
+
+struct A
+{
+ int v:1;
+};
+
+int bar();
+int foo(struct A* p)
+{
+ if (p->v)
+ return 1;
+ return bar();
+}