OSDN Git Service

* config/arm/thumb2.md (thumb2_tlobits_cbranch): New insn pattern.
authorcarrot <carrot@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 10 May 2010 07:26:04 +0000 (07:26 +0000)
committercarrot <carrot@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 10 May 2010 07:26:04 +0000 (07:26 +0000)
* gcc.target/arm/pr42879.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159212 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/arm/thumb2.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/pr42879.c [new file with mode: 0644]

index 5f79292..76e6ea6 100644 (file)
@@ -1,3 +1,8 @@
+2010-05-10  Wei Guozhi  <carrot@google.com>
+
+       PR target/42879
+       * config/arm/thumb2.md (thumb2_tlobits_cbranch): New insn pattern.
+
 2010-05-09  Joseph Myers  <joseph@codesourcery.com>
 
        PR c/10676
index 3e2c3da..9b80752 100644 (file)
   [(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]));
+
+      output_asm_insn (\"lsls\\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 e801b1f..5ee636f 100644 (file)
@@ -1,3 +1,8 @@
+2010-05-10  Wei Guozhi  <carrot@google.com>
+
+       PR target/42879
+       * gcc.target/arm/pr42879.c: New testcase.
+
 2010-05-09  Joseph Myers  <joseph@codesourcery.com>
 
        PR c/44051
diff --git a/gcc/testsuite/gcc.target/arm/pr42879.c b/gcc/testsuite/gcc.target/arm/pr42879.c
new file mode 100644 (file)
index 0000000..02af72c
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-options "-march=armv7-a -mthumb -Os" }  */
+/* { dg-final { scan-assembler "lsls" } } */
+
+struct A
+{
+  int v:1;
+};
+
+int bar();
+int foo(struct A* p)
+{
+  if (p->v)
+    return 1;
+  return bar();
+}