aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/arm/thumb2.md
diff options
context:
space:
mode:
authorWei Guozhi <carrot@google.com>2010-05-10 07:26:04 +0000
committerWei Guozhi <carrot@gcc.gnu.org>2010-05-10 07:26:04 +0000
commit333b67a9f16208485c0f76edea0b4ecaddd0c8e6 (patch)
tree7a6ad5a80b4bd6bc27c3ac904a1b2fe1a259dc03 /gcc/config/arm/thumb2.md
parent4af3ff4194e5dc832c7c5b1a352eb9beff23e60a (diff)
downloadgcc-333b67a9f16208485c0f76edea0b4ecaddd0c8e6.zip
gcc-333b67a9f16208485c0f76edea0b4ecaddd0c8e6.tar.gz
gcc-333b67a9f16208485c0f76edea0b4ecaddd0c8e6.tar.bz2
thumb2.md (thumb2_tlobits_cbranch): New insn pattern.
* config/arm/thumb2.md (thumb2_tlobits_cbranch): New insn pattern. * gcc.target/arm/pr42879.c: New testcase. From-SVN: r159212
Diffstat (limited to 'gcc/config/arm/thumb2.md')
-rw-r--r--gcc/config/arm/thumb2.md74
1 files changed, 74 insertions, 0 deletions
diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
index 3e2c3da..9b80752 100644
--- a/gcc/config/arm/thumb2.md
+++ b/gcc/config/arm/thumb2.md
@@ -1442,3 +1442,77 @@
[(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)))))]
+)