diff options
author | Wei Guozhi <carrot@google.com> | 2010-05-10 07:26:04 +0000 |
---|---|---|
committer | Wei Guozhi <carrot@gcc.gnu.org> | 2010-05-10 07:26:04 +0000 |
commit | 333b67a9f16208485c0f76edea0b4ecaddd0c8e6 (patch) | |
tree | 7a6ad5a80b4bd6bc27c3ac904a1b2fe1a259dc03 /gcc/config/arm/thumb2.md | |
parent | 4af3ff4194e5dc832c7c5b1a352eb9beff23e60a (diff) | |
download | gcc-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.md | 74 |
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)))))] +) |