aboutsummaryrefslogtreecommitdiffstats
path: root/toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99379.patch
diff options
context:
space:
mode:
Diffstat (limited to 'toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99379.patch')
-rw-r--r--toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99379.patch2011
1 files changed, 0 insertions, 2011 deletions
diff --git a/toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99379.patch b/toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99379.patch
deleted file mode 100644
index e1e89bf8af..0000000000
--- a/toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99379.patch
+++ /dev/null
@@ -1,2011 +0,0 @@
-2010-08-29 Chung-Lin Tang <cltang@codesourcery.com>
-
- Backport from mainline:
-
- 2010-04-16 Bernd Schmidt <bernds@codesourcery.com>
-
- PR target/41514
- gcc/
- * config/arm/arm.md (cbranchsi4_insn): Renamed from "*cbranchsi4_insn".
- If the previous insn is a cbranchsi4_insn with the same arguments,
- omit the compare instruction.
-
- gcc/testsuite/
- * gcc.target/arm/thumb-comparisons.c: New test.
-
- gcc/
- * config/arm/arm.md (addsi3_cbranch): If destination is a high
- register, inputs must be low registers and we need a low register
- scratch. Handle alternative 2 like alternative 3.
-
- PR target/40603
- gcc/
- * config/arm/arm.md (cbranchqi4): New pattern.
- * config/arm/predicates.md (const0_operand,
- cbranchqi4_comparison_operator): New predicates.
-
- gcc/testsuite/
- * gcc.target/arm/thumb-cbranchqi.c: New test.
-
- 2010-04-27 Bernd Schmidt <bernds@codesourcery.com>
-
- PR target/40657
- gcc/
- * config/arm/arm.c (thumb1_extra_regs_pushed): New function.
- (thumb1_expand_prologue, thumb1_output_function_prologue): Call it
- here to determine which regs to push and how much stack to reserve.
-
- gcc/testsuite/
- * gcc.target/arm/thumb-stackframe.c: New test.
-
- 2010-07-02 Bernd Schmidt <bernds@codesourcery.com>
-
- PR target/42835
- gcc/
- * config/arm/arm-modes.def (CC_NOTB): New mode.
- * config/arm/arm.c (get_arm_condition_code): Handle it.
- * config/arm/thumb2.md (thumb2_compare_scc): Delete pattern.
- * config/arm/arm.md (subsi3_compare0_c): New pattern.
- (compare_scc): Now a define_and_split. Add a number of extra
- splitters before it.
-
- gcc/testsuite/
- * gcc.target/arm/pr42835.c: New test.
-
- PR target/42172
- gcc/
- * config/arm/arm.c (thumb1_rtx_costs): Improve support for SIGN_EXTEND
- and ZERO_EXTEND.
- (arm_rtx_costs_1): Likewise.
- (arm_size_rtx_costs): Use arm_rtx_costs_1 for these codes.
- * config/arm/arm.md (is_arch6): New attribute.
- (zero_extendhisi2, zero_extendqisi2, extendhisi2,
- extendqisi2): Tighten the code somewhat, avoiding invalid
- RTL to occur in the expander patterns.
- (thumb1_zero_extendhisi2): Merge with thumb1_zero_extendhisi2_v6.
- (thumb1_zero_extendhisi2_v6): Delete.
- (thumb1_extendhisi2): Merge with thumb1_extendhisi2_v6.
- (thumb1_extendhisi2_v6): Delete.
- (thumb1_extendqisi2): Merge with thumb1_extendhisi2_v6.
- (thumb1_extendqisi2_v6): Delete.
- (zero_extendhisi2 for register input splitter): New.
- (zero_extendqisi2 for register input splitter): New.
- (thumb1_extendhisi2 for register input splitter): New.
- (extendhisi2 for register input splitter): New.
- (extendqisi2 for register input splitter): New.
- (TARGET_THUMB1 extendqisi2 for memory input splitter): New.
- (arm_zero_extendhisi2): Allow nonimmediate_operand for operand 1,
- and add support for a register alternative requiring a split.
- (thumb1_zero_extendqisi2): Likewise.
- (arm_zero_extendqisi2): Likewise.
- (arm_extendhisi2): Likewise.
- (arm_extendqisi2): Likewise.
-
- gcc/testsuite/
- * gcc.target/arm/pr42172-1.c: New test.
-
- 2010-07-05 Bernd Schmidt <bernds@codesourcery.com>
-
- * config/arm/arm.c (get_arm_condition_code): Remove CC_NOTBmode case.
- * arm-modes.def (CC_NOTB): Don't define.
- * config/arm/arm.md (arm_adddi3): Generate canonical RTL.
- (adddi_sesidi_di, adddi_zesidi_di): Likewise.
- (LTUGEU): New code_iterator.
- (cnb, optab): New corresponding code_attrs.
- (addsi3_carryin_<optab>): Renamed from addsi3_carryin. Change pattern
- to canonical form. Operands 1 and 2 are commutative. Parametrize
- using LTUGEU.
- (addsi3_carryin_shift_<optab>): Likewise.
- (addsi3_carryin_alt2_<optab>): Renamed from addsi3_carryin_alt2.
- Operands 1 and 2 are commutative. Parametrize using LTUGEU.
- (addsi3_carryin_alt1, addsi3_carryin_alt3): Remove.
- (subsi3_compare): Renamed from subsi3_compare0_c. Change CC_NOTB to
- CC.
- (arm_subsi3_insn): Allow constants for operand 0.
- (compare_scc peephole for eq case): New.
- (compare_scc splitters): Change CC_NOTB to CC.
-
- 2010-07-09 Bernd Schmidt <bernds@codesourcery.com>
-
- PR target/40657
- gcc/
- * config/arm/arm.c (thumb1_extra_regs_pushed): New arg FOR_PROLOGUE.
- All callers changed.
- Handle the case when we're called for the epilogue.
- (thumb_unexpanded_epilogue): Use it.
- (thumb1_expand_epilogue): Likewise.
-
- gcc/testsuite/
- * gcc.target/arm/pr40657-1.c: New test.
- * gcc.target/arm/pr40657-2.c: New test.
- * gcc.c-torture/execute/pr40657.c: New test.
-
- gcc/
- * config/arm/arm.md (addsi3_cbranch): Switch alternatives 0 and 1.
-
- * config/arm/arm.md (Thumb-1 ldrsb peephole): New.
-
- * config/arm/arm.md (cbranchqi4): Fix array size.
- (addsi3_cbranch): Also andle alternative 2 like alternative 3 when
- calculating length.
-
- 2010-08-27 Paul Brook <paul@codesourcery.com>
-
- gcc/
-
-=== modified file 'gcc/config/arm/arm-modes.def'
---- old/gcc/config/arm/arm-modes.def 2010-07-29 16:58:56 +0000
-+++ new/gcc/config/arm/arm-modes.def 2010-08-31 10:00:27 +0000
-@@ -34,6 +34,8 @@
- CCFPmode should be used with floating equalities.
- CC_NOOVmode should be used with SImode integer equalities.
- CC_Zmode should be used if only the Z flag is set correctly
-+ CC_Cmode should be used if only the C flag is set correctly, after an
-+ addition.
- CC_Nmode should be used if only the N (sign) flag is set correctly
- CC_CZmode should be used if only the C and Z flags are correct
- (used for DImode unsigned comparisons).
-
-=== modified file 'gcc/config/arm/arm.c'
---- old/gcc/config/arm/arm.c 2010-08-25 16:22:17 +0000
-+++ new/gcc/config/arm/arm.c 2010-08-31 10:00:27 +0000
-@@ -6443,6 +6443,7 @@
- thumb1_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer)
- {
- enum machine_mode mode = GET_MODE (x);
-+ int total;
-
- switch (code)
- {
-@@ -6545,24 +6546,20 @@
- return 14;
- return 2;
-
-+ case SIGN_EXTEND:
- case ZERO_EXTEND:
-- /* XXX still guessing. */
-- switch (GET_MODE (XEXP (x, 0)))
-- {
-- case QImode:
-- return (1 + (mode == DImode ? 4 : 0)
-- + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
--
-- case HImode:
-- return (4 + (mode == DImode ? 4 : 0)
-- + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
--
-- case SImode:
-- return (1 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
--
-- default:
-- return 99;
-- }
-+ total = mode == DImode ? COSTS_N_INSNS (1) : 0;
-+ total += thumb1_rtx_costs (XEXP (x, 0), GET_CODE (XEXP (x, 0)), code);
-+
-+ if (mode == SImode)
-+ return total;
-+
-+ if (arm_arch6)
-+ return total + COSTS_N_INSNS (1);
-+
-+ /* Assume a two-shift sequence. Increase the cost slightly so
-+ we prefer actual shifts over an extend operation. */
-+ return total + 1 + COSTS_N_INSNS (2);
-
- default:
- return 99;
-@@ -7046,44 +7043,39 @@
- return false;
-
- case SIGN_EXTEND:
-- if (GET_MODE_CLASS (mode) == MODE_INT)
-- {
-- *total = 0;
-- if (mode == DImode)
-- *total += COSTS_N_INSNS (1);
--
-- if (GET_MODE (XEXP (x, 0)) != SImode)
-- {
-- if (arm_arch6)
-- {
-- if (GET_CODE (XEXP (x, 0)) != MEM)
-- *total += COSTS_N_INSNS (1);
-- }
-- else if (!arm_arch4 || GET_CODE (XEXP (x, 0)) != MEM)
-- *total += COSTS_N_INSNS (2);
-- }
--
-- return false;
-- }
--
-- /* Fall through */
- case ZERO_EXTEND:
- *total = 0;
- if (GET_MODE_CLASS (mode) == MODE_INT)
- {
-+ rtx op = XEXP (x, 0);
-+ enum machine_mode opmode = GET_MODE (op);
-+
- if (mode == DImode)
- *total += COSTS_N_INSNS (1);
-
-- if (GET_MODE (XEXP (x, 0)) != SImode)
-+ if (opmode != SImode)
- {
-- if (arm_arch6)
-+ if (MEM_P (op))
- {
-- if (GET_CODE (XEXP (x, 0)) != MEM)
-- *total += COSTS_N_INSNS (1);
-+ /* If !arm_arch4, we use one of the extendhisi2_mem
-+ or movhi_bytes patterns for HImode. For a QImode
-+ sign extension, we first zero-extend from memory
-+ and then perform a shift sequence. */
-+ if (!arm_arch4 && (opmode != QImode || code == SIGN_EXTEND))
-+ *total += COSTS_N_INSNS (2);
- }
-- else if (!arm_arch4 || GET_CODE (XEXP (x, 0)) != MEM)
-- *total += COSTS_N_INSNS (GET_MODE (XEXP (x, 0)) == QImode ?
-- 1 : 2);
-+ else if (arm_arch6)
-+ *total += COSTS_N_INSNS (1);
-+
-+ /* We don't have the necessary insn, so we need to perform some
-+ other operation. */
-+ else if (TARGET_ARM && code == ZERO_EXTEND && mode == QImode)
-+ /* An and with constant 255. */
-+ *total += COSTS_N_INSNS (1);
-+ else
-+ /* A shift sequence. Increase costs slightly to avoid
-+ combining two shifts into an extend operation. */
-+ *total += COSTS_N_INSNS (2) + 1;
- }
-
- return false;
-@@ -7333,41 +7325,8 @@
- return false;
-
- case SIGN_EXTEND:
-- *total = 0;
-- if (GET_MODE_SIZE (GET_MODE (XEXP (x, 0))) < 4)
-- {
-- if (!(arm_arch4 && MEM_P (XEXP (x, 0))))
-- *total += COSTS_N_INSNS (arm_arch6 ? 1 : 2);
-- }
-- if (mode == DImode)
-- *total += COSTS_N_INSNS (1);
-- return false;
--
- case ZERO_EXTEND:
-- *total = 0;
-- if (!(arm_arch4 && MEM_P (XEXP (x, 0))))
-- {
-- switch (GET_MODE (XEXP (x, 0)))
-- {
-- case QImode:
-- *total += COSTS_N_INSNS (1);
-- break;
--
-- case HImode:
-- *total += COSTS_N_INSNS (arm_arch6 ? 1 : 2);
--
-- case SImode:
-- break;
--
-- default:
-- *total += COSTS_N_INSNS (2);
-- }
-- }
--
-- if (mode == DImode)
-- *total += COSTS_N_INSNS (1);
--
-- return false;
-+ return arm_rtx_costs_1 (x, outer_code, total, 0);
-
- case CONST_INT:
- if (const_ok_for_arm (INTVAL (x)))
-@@ -16898,11 +16857,11 @@
-
- case CC_Cmode:
- switch (comp_code)
-- {
-- case LTU: return ARM_CS;
-- case GEU: return ARM_CC;
-- default: gcc_unreachable ();
-- }
-+ {
-+ case LTU: return ARM_CS;
-+ case GEU: return ARM_CC;
-+ default: gcc_unreachable ();
-+ }
-
- case CC_CZmode:
- switch (comp_code)
-@@ -20127,6 +20086,81 @@
- #endif
- }
-
-+/* Given the stack offsets and register mask in OFFSETS, decide how
-+ many additional registers to push instead of subtracting a constant
-+ from SP. For epilogues the principle is the same except we use pop.
-+ FOR_PROLOGUE indicates which we're generating. */
-+static int
-+thumb1_extra_regs_pushed (arm_stack_offsets *offsets, bool for_prologue)
-+{
-+ HOST_WIDE_INT amount;
-+ unsigned long live_regs_mask = offsets->saved_regs_mask;
-+ /* Extract a mask of the ones we can give to the Thumb's push/pop
-+ instruction. */
-+ unsigned long l_mask = live_regs_mask & (for_prologue ? 0x40ff : 0xff);
-+ /* Then count how many other high registers will need to be pushed. */
-+ unsigned long high_regs_pushed = bit_count (live_regs_mask & 0x0f00);
-+ int n_free, reg_base;
-+
-+ if (!for_prologue && frame_pointer_needed)
-+ amount = offsets->locals_base - offsets->saved_regs;
-+ else
-+ amount = offsets->outgoing_args - offsets->saved_regs;
-+
-+ /* If the stack frame size is 512 exactly, we can save one load
-+ instruction, which should make this a win even when optimizing
-+ for speed. */
-+ if (!optimize_size && amount != 512)
-+ return 0;
-+
-+ /* Can't do this if there are high registers to push. */
-+ if (high_regs_pushed != 0)
-+ return 0;
-+
-+ /* Shouldn't do it in the prologue if no registers would normally
-+ be pushed at all. In the epilogue, also allow it if we'll have
-+ a pop insn for the PC. */
-+ if (l_mask == 0
-+ && (for_prologue
-+ || TARGET_BACKTRACE
-+ || (live_regs_mask & 1 << LR_REGNUM) == 0
-+ || TARGET_INTERWORK
-+ || crtl->args.pretend_args_size != 0))
-+ return 0;
-+
-+ /* Don't do this if thumb_expand_prologue wants to emit instructions
-+ between the push and the stack frame allocation. */
-+ if (for_prologue
-+ && ((flag_pic && arm_pic_register != INVALID_REGNUM)
-+ || (!frame_pointer_needed && CALLER_INTERWORKING_SLOT_SIZE > 0)))
-+ return 0;
-+
-+ reg_base = 0;
-+ n_free = 0;
-+ if (!for_prologue)
-+ {
-+ reg_base = arm_size_return_regs () / UNITS_PER_WORD;
-+ live_regs_mask >>= reg_base;
-+ }
-+
-+ while (reg_base + n_free < 8 && !(live_regs_mask & 1)
-+ && (for_prologue || call_used_regs[reg_base + n_free]))
-+ {
-+ live_regs_mask >>= 1;
-+ n_free++;
-+ }
-+
-+ if (n_free == 0)
-+ return 0;
-+ gcc_assert (amount / 4 * 4 == amount);
-+
-+ if (amount >= 512 && (amount - n_free * 4) < 512)
-+ return (amount - 508) / 4;
-+ if (amount <= n_free * 4)
-+ return amount / 4;
-+ return 0;
-+}
-+
- /* The bits which aren't usefully expanded as rtl. */
- const char *
- thumb_unexpanded_epilogue (void)
-@@ -20135,6 +20169,7 @@
- int regno;
- unsigned long live_regs_mask = 0;
- int high_regs_pushed = 0;
-+ int extra_pop;
- int had_to_push_lr;
- int size;
-
-@@ -20154,6 +20189,13 @@
- the register is used to hold a return value. */
- size = arm_size_return_regs ();
-
-+ extra_pop = thumb1_extra_regs_pushed (offsets, false);
-+ if (extra_pop > 0)
-+ {
-+ unsigned long extra_mask = (1 << extra_pop) - 1;
-+ live_regs_mask |= extra_mask << (size / UNITS_PER_WORD);
-+ }
-+
- /* The prolog may have pushed some high registers to use as
- work registers. e.g. the testsuite file:
- gcc/testsuite/gcc/gcc.c-torture/execute/complex-2.c
-@@ -20237,7 +20279,9 @@
- live_regs_mask);
-
- /* We have either just popped the return address into the
-- PC or it is was kept in LR for the entire function. */
-+ PC or it is was kept in LR for the entire function.
-+ Note that thumb_pushpop has already called thumb_exit if the
-+ PC was in the list. */
- if (!had_to_push_lr)
- thumb_exit (asm_out_file, LR_REGNUM);
- }
-@@ -20419,6 +20463,7 @@
- stack_pointer_rtx);
-
- amount = offsets->outgoing_args - offsets->saved_regs;
-+ amount -= 4 * thumb1_extra_regs_pushed (offsets, true);
- if (amount)
- {
- if (amount < 512)
-@@ -20503,6 +20548,7 @@
- emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
- amount = offsets->locals_base - offsets->saved_regs;
- }
-+ amount -= 4 * thumb1_extra_regs_pushed (offsets, false);
-
- gcc_assert (amount >= 0);
- if (amount)
-@@ -20723,7 +20769,11 @@
- register. */
- else if ((l_mask & 0xff) != 0
- || (high_regs_pushed == 0 && l_mask))
-- thumb_pushpop (f, l_mask, 1, &cfa_offset, l_mask);
-+ {
-+ unsigned long mask = l_mask;
-+ mask |= (1 << thumb1_extra_regs_pushed (offsets, true)) - 1;
-+ thumb_pushpop (f, mask, 1, &cfa_offset, mask);
-+ }
-
- if (high_regs_pushed)
- {
-
-=== modified file 'gcc/config/arm/arm.md'
---- old/gcc/config/arm/arm.md 2010-08-25 16:22:17 +0000
-+++ new/gcc/config/arm/arm.md 2010-08-31 10:00:27 +0000
-@@ -150,6 +150,9 @@
- ; patterns that share the same RTL in both ARM and Thumb code.
- (define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
-
-+; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
-+(define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
-+
- ;; Operand number of an input operand that is shifted. Zero if the
- ;; given instruction does not shift one of its input operands.
- (define_attr "shift" "" (const_int 0))
-@@ -515,8 +518,8 @@
- (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
- (match_dup 1)))
- (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
-- (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
-- (plus:SI (match_dup 4) (match_dup 5))))]
-+ (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
-+ (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
- "
- {
- operands[3] = gen_highpart (SImode, operands[0]);
-@@ -543,10 +546,10 @@
- (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
- (match_dup 1)))
- (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
-- (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
-- (plus:SI (ashiftrt:SI (match_dup 2)
-+ (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
- (const_int 31))
-- (match_dup 4))))]
-+ (match_dup 4))
-+ (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
- "
- {
- operands[3] = gen_highpart (SImode, operands[0]);
-@@ -572,8 +575,8 @@
- (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
- (match_dup 1)))
- (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
-- (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
-- (plus:SI (match_dup 4) (const_int 0))))]
-+ (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
-+ (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
- "
- {
- operands[3] = gen_highpart (SImode, operands[0]);
-@@ -861,24 +864,38 @@
- [(set_attr "conds" "set")]
- )
-
--(define_insn "*addsi3_carryin"
-- [(set (match_operand:SI 0 "s_register_operand" "=r")
-- (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
-- (plus:SI (match_operand:SI 1 "s_register_operand" "r")
-- (match_operand:SI 2 "arm_rhs_operand" "rI"))))]
-- "TARGET_32BIT"
-- "adc%?\\t%0, %1, %2"
-- [(set_attr "conds" "use")]
--)
--
--(define_insn "*addsi3_carryin_shift"
-- [(set (match_operand:SI 0 "s_register_operand" "=r")
-- (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
-- (plus:SI
-- (match_operator:SI 2 "shift_operator"
-- [(match_operand:SI 3 "s_register_operand" "r")
-- (match_operand:SI 4 "reg_or_int_operand" "rM")])
-- (match_operand:SI 1 "s_register_operand" "r"))))]
-+(define_code_iterator LTUGEU [ltu geu])
-+(define_code_attr cnb [(ltu "CC_C") (geu "CC")])
-+(define_code_attr optab [(ltu "ltu") (geu "geu")])
-+
-+(define_insn "*addsi3_carryin_<optab>"
-+ [(set (match_operand:SI 0 "s_register_operand" "=r")
-+ (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
-+ (match_operand:SI 2 "arm_rhs_operand" "rI"))
-+ (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
-+ "TARGET_32BIT"
-+ "adc%?\\t%0, %1, %2"
-+ [(set_attr "conds" "use")]
-+)
-+
-+(define_insn "*addsi3_carryin_alt2_<optab>"
-+ [(set (match_operand:SI 0 "s_register_operand" "=r")
-+ (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
-+ (match_operand:SI 1 "s_register_operand" "%r"))
-+ (match_operand:SI 2 "arm_rhs_operand" "rI")))]
-+ "TARGET_32BIT"
-+ "adc%?\\t%0, %1, %2"
-+ [(set_attr "conds" "use")]
-+)
-+
-+(define_insn "*addsi3_carryin_shift_<optab>"
-+ [(set (match_operand:SI 0 "s_register_operand" "=r")
-+ (plus:SI (plus:SI
-+ (match_operator:SI 2 "shift_operator"
-+ [(match_operand:SI 3 "s_register_operand" "r")
-+ (match_operand:SI 4 "reg_or_int_operand" "rM")])
-+ (match_operand:SI 1 "s_register_operand" "r"))
-+ (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
- "TARGET_32BIT"
- "adc%?\\t%0, %1, %3%S2"
- [(set_attr "conds" "use")
-@@ -887,36 +904,6 @@
- (const_string "alu_shift_reg")))]
- )
-
--(define_insn "*addsi3_carryin_alt1"
-- [(set (match_operand:SI 0 "s_register_operand" "=r")
-- (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
-- (match_operand:SI 2 "arm_rhs_operand" "rI"))
-- (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
-- "TARGET_32BIT"
-- "adc%?\\t%0, %1, %2"
-- [(set_attr "conds" "use")]
--)
--
--(define_insn "*addsi3_carryin_alt2"
-- [(set (match_operand:SI 0 "s_register_operand" "=r")
-- (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
-- (match_operand:SI 1 "s_register_operand" "r"))
-- (match_operand:SI 2 "arm_rhs_operand" "rI")))]
-- "TARGET_32BIT"
-- "adc%?\\t%0, %1, %2"
-- [(set_attr "conds" "use")]
--)
--
--(define_insn "*addsi3_carryin_alt3"
-- [(set (match_operand:SI 0 "s_register_operand" "=r")
-- (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
-- (match_operand:SI 2 "arm_rhs_operand" "rI"))
-- (match_operand:SI 1 "s_register_operand" "r")))]
-- "TARGET_32BIT"
-- "adc%?\\t%0, %1, %2"
-- [(set_attr "conds" "use")]
--)
--
- (define_expand "incscc"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (plus:SI (match_operator:SI 2 "arm_comparison_operator"
-@@ -1116,24 +1103,27 @@
-
- ; ??? Check Thumb-2 split length
- (define_insn_and_split "*arm_subsi3_insn"
-- [(set (match_operand:SI 0 "s_register_operand" "=r,rk,r")
-- (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,!k,?n")
-- (match_operand:SI 2 "s_register_operand" "r, r, r")))]
-+ [(set (match_operand:SI 0 "s_register_operand" "=r,r,rk,r,r")
-+ (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,r,!k,?n,r")
-+ (match_operand:SI 2 "reg_or_int_operand" "r,rI, r, r,?n")))]
- "TARGET_32BIT"
- "@
- rsb%?\\t%0, %2, %1
- sub%?\\t%0, %1, %2
-+ sub%?\\t%0, %1, %2
-+ #
- #"
-- "TARGET_32BIT
-- && GET_CODE (operands[1]) == CONST_INT
-- && !const_ok_for_arm (INTVAL (operands[1]))"
-+ "&& ((GET_CODE (operands[1]) == CONST_INT
-+ && !const_ok_for_arm (INTVAL (operands[1])))
-+ || (GET_CODE (operands[2]) == CONST_INT
-+ && !const_ok_for_arm (INTVAL (operands[2]))))"
- [(clobber (const_int 0))]
- "
- arm_split_constant (MINUS, SImode, curr_insn,
- INTVAL (operands[1]), operands[0], operands[2], 0);
- DONE;
- "
-- [(set_attr "length" "4,4,16")
-+ [(set_attr "length" "4,4,4,16,16")
- (set_attr "predicable" "yes")]
- )
-
-@@ -1165,6 +1155,19 @@
- [(set_attr "conds" "set")]
- )
-
-+(define_insn "*subsi3_compare"
-+ [(set (reg:CC CC_REGNUM)
-+ (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,I")
-+ (match_operand:SI 2 "arm_rhs_operand" "rI,r")))
-+ (set (match_operand:SI 0 "s_register_operand" "=r,r")
-+ (minus:SI (match_dup 1) (match_dup 2)))]
-+ "TARGET_32BIT"
-+ "@
-+ sub%.\\t%0, %1, %2
-+ rsb%.\\t%0, %2, %1"
-+ [(set_attr "conds" "set")]
-+)
-+
- (define_expand "decscc"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
-@@ -4050,93 +4053,46 @@
- )
-
- (define_expand "zero_extendhisi2"
-- [(set (match_dup 2)
-- (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
-- (const_int 16)))
-- (set (match_operand:SI 0 "s_register_operand" "")
-- (lshiftrt:SI (match_dup 2) (const_int 16)))]
-+ [(set (match_operand:SI 0 "s_register_operand" "")
-+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
- "TARGET_EITHER"
-- "
-- {
-- if ((TARGET_THUMB1 || arm_arch4) && GET_CODE (operands[1]) == MEM)
-- {
-- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
-- gen_rtx_ZERO_EXTEND (SImode, operands[1])));
-- DONE;
-- }
--
-- if (TARGET_ARM && GET_CODE (operands[1]) == MEM)
-- {
-- emit_insn (gen_movhi_bytes (operands[0], operands[1]));
-- DONE;
-- }
--
-- if (!s_register_operand (operands[1], HImode))
-- operands[1] = copy_to_mode_reg (HImode, operands[1]);
--
-- if (arm_arch6)
-- {
-- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
-- gen_rtx_ZERO_EXTEND (SImode, operands[1])));
-- DONE;
-- }
--
-- operands[1] = gen_lowpart (SImode, operands[1]);
-- operands[2] = gen_reg_rtx (SImode);
-- }"
--)
-+{
-+ if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
-+ {
-+ emit_insn (gen_movhi_bytes (operands[0], operands[1]));
-+ DONE;
-+ }
-+ if (!arm_arch6 && !MEM_P (operands[1]))
-+ {
-+ rtx t = gen_lowpart (SImode, operands[1]);
-+ rtx tmp = gen_reg_rtx (SImode);
-+ emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
-+ emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
-+ DONE;
-+ }
-+})
-+
-+(define_split
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (zero_extend:SI (match_operand:HI 1 "register_operand" "l,m")))]
-+ "!TARGET_THUMB2 && !arm_arch6"
-+ [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
-+ (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
-+{
-+ operands[2] = gen_lowpart (SImode, operands[1]);
-+})
-
- (define_insn "*thumb1_zero_extendhisi2"
-- [(set (match_operand:SI 0 "register_operand" "=l")
-- (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
-- "TARGET_THUMB1 && !arm_arch6"
-- "*
-- rtx mem = XEXP (operands[1], 0);
--
-- if (GET_CODE (mem) == CONST)
-- mem = XEXP (mem, 0);
--
-- if (GET_CODE (mem) == LABEL_REF)
-- return \"ldr\\t%0, %1\";
--
-- if (GET_CODE (mem) == PLUS)
-- {
-- rtx a = XEXP (mem, 0);
-- rtx b = XEXP (mem, 1);
--
-- /* This can happen due to bugs in reload. */
-- if (GET_CODE (a) == REG && REGNO (a) == SP_REGNUM)
-- {
-- rtx ops[2];
-- ops[0] = operands[0];
-- ops[1] = a;
--
-- output_asm_insn (\"mov %0, %1\", ops);
--
-- XEXP (mem, 0) = operands[0];
-- }
--
-- else if ( GET_CODE (a) == LABEL_REF
-- && GET_CODE (b) == CONST_INT)
-- return \"ldr\\t%0, %1\";
-- }
--
-- return \"ldrh\\t%0, %1\";
-- "
-- [(set_attr "length" "4")
-- (set_attr "type" "load_byte")
-- (set_attr "pool_range" "60")]
--)
--
--(define_insn "*thumb1_zero_extendhisi2_v6"
- [(set (match_operand:SI 0 "register_operand" "=l,l")
- (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))]
-- "TARGET_THUMB1 && arm_arch6"
-+ "TARGET_THUMB1"
- "*
- rtx mem;
-
-- if (which_alternative == 0)
-+ if (which_alternative == 0 && arm_arch6)
- return \"uxth\\t%0, %1\";
-+ if (which_alternative == 0)
-+ return \"#\";
-
- mem = XEXP (operands[1], 0);
-
-@@ -4170,20 +4126,25 @@
-
- return \"ldrh\\t%0, %1\";
- "
-- [(set_attr "length" "2,4")
-+ [(set_attr_alternative "length"
-+ [(if_then_else (eq_attr "is_arch6" "yes")
-+ (const_int 2) (const_int 4))
-+ (const_int 4)])
- (set_attr "type" "alu_shift,load_byte")
- (set_attr "pool_range" "*,60")]
- )
-
- (define_insn "*arm_zero_extendhisi2"
-- [(set (match_operand:SI 0 "s_register_operand" "=r")
-- (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
-+ [(set (match_operand:SI 0 "s_register_operand" "=r,r")
-+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
- "TARGET_ARM && arm_arch4 && !arm_arch6"
-- "ldr%(h%)\\t%0, %1"
-- [(set_attr "type" "load_byte")
-+ "@
-+ #
-+ ldr%(h%)\\t%0, %1"
-+ [(set_attr "type" "alu_shift,load_byte")
- (set_attr "predicable" "yes")
-- (set_attr "pool_range" "256")
-- (set_attr "neg_pool_range" "244")]
-+ (set_attr "pool_range" "*,256")
-+ (set_attr "neg_pool_range" "*,244")]
- )
-
- (define_insn "*arm_zero_extendhisi2_v6"
-@@ -4213,50 +4174,49 @@
- [(set (match_operand:SI 0 "s_register_operand" "")
- (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
- "TARGET_EITHER"
-- "
-- if (!arm_arch6 && GET_CODE (operands[1]) != MEM)
-- {
-- if (TARGET_ARM)
-- {
-- emit_insn (gen_andsi3 (operands[0],
-- gen_lowpart (SImode, operands[1]),
-- GEN_INT (255)));
-- }
-- else /* TARGET_THUMB */
-- {
-- rtx temp = gen_reg_rtx (SImode);
-- rtx ops[3];
--
-- operands[1] = copy_to_mode_reg (QImode, operands[1]);
-- operands[1] = gen_lowpart (SImode, operands[1]);
--
-- ops[0] = temp;
-- ops[1] = operands[1];
-- ops[2] = GEN_INT (24);
--
-- emit_insn (gen_rtx_SET (VOIDmode, ops[0],
-- gen_rtx_ASHIFT (SImode, ops[1], ops[2])));
--
-- ops[0] = operands[0];
-- ops[1] = temp;
-- ops[2] = GEN_INT (24);
--
-- emit_insn (gen_rtx_SET (VOIDmode, ops[0],
-- gen_rtx_LSHIFTRT (SImode, ops[1], ops[2])));
-- }
-- DONE;
-- }
-- "
--)
-+{
-+ if (TARGET_ARM && !arm_arch6 && GET_CODE (operands[1]) != MEM)
-+ {
-+ emit_insn (gen_andsi3 (operands[0],
-+ gen_lowpart (SImode, operands[1]),
-+ GEN_INT (255)));
-+ DONE;
-+ }
-+ if (!arm_arch6 && !MEM_P (operands[1]))
-+ {
-+ rtx t = gen_lowpart (SImode, operands[1]);
-+ rtx tmp = gen_reg_rtx (SImode);
-+ emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
-+ emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
-+ DONE;
-+ }
-+})
-+
-+(define_split
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
-+ "!arm_arch6"
-+ [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
-+ (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
-+{
-+ operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
-+ if (TARGET_ARM)
-+ {
-+ emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
-+ DONE;
-+ }
-+})
-
- (define_insn "*thumb1_zero_extendqisi2"
-- [(set (match_operand:SI 0 "register_operand" "=l")
-- (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
-+ [(set (match_operand:SI 0 "register_operand" "=l,l")
-+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
- "TARGET_THUMB1 && !arm_arch6"
-- "ldrb\\t%0, %1"
-- [(set_attr "length" "2")
-- (set_attr "type" "load_byte")
-- (set_attr "pool_range" "32")]
-+ "@
-+ #
-+ ldrb\\t%0, %1"
-+ [(set_attr "length" "4,2")
-+ (set_attr "type" "alu_shift,load_byte")
-+ (set_attr "pool_range" "*,32")]
- )
-
- (define_insn "*thumb1_zero_extendqisi2_v6"
-@@ -4272,14 +4232,17 @@
- )
-
- (define_insn "*arm_zero_extendqisi2"
-- [(set (match_operand:SI 0 "s_register_operand" "=r")
-- (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
-+ [(set (match_operand:SI 0 "s_register_operand" "=r,r")
-+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
- "TARGET_ARM && !arm_arch6"
-- "ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
-- [(set_attr "type" "load_byte")
-+ "@
-+ #
-+ ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
-+ [(set_attr "length" "8,4")
-+ (set_attr "type" "alu_shift,load_byte")
- (set_attr "predicable" "yes")
-- (set_attr "pool_range" "4096")
-- (set_attr "neg_pool_range" "4084")]
-+ (set_attr "pool_range" "*,4096")
-+ (set_attr "neg_pool_range" "*,4084")]
- )
-
- (define_insn "*arm_zero_extendqisi2_v6"
-@@ -4358,108 +4321,42 @@
- )
-
- (define_expand "extendhisi2"
-- [(set (match_dup 2)
-- (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
-- (const_int 16)))
-- (set (match_operand:SI 0 "s_register_operand" "")
-- (ashiftrt:SI (match_dup 2)
-- (const_int 16)))]
-+ [(set (match_operand:SI 0 "s_register_operand" "")
-+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
- "TARGET_EITHER"
-- "
-- {
-- if (GET_CODE (operands[1]) == MEM)
-- {
-- if (TARGET_THUMB1)
-- {
-- emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
-- DONE;
-- }
-- else if (arm_arch4)
-- {
-- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
-- gen_rtx_SIGN_EXTEND (SImode, operands[1])));
-- DONE;
-- }
-- }
--
-- if (TARGET_ARM && GET_CODE (operands[1]) == MEM)
-- {
-- emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
-- DONE;
-- }
--
-- if (!s_register_operand (operands[1], HImode))
-- operands[1] = copy_to_mode_reg (HImode, operands[1]);
--
-- if (arm_arch6)
-- {
-- if (TARGET_THUMB1)
-- emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
-- else
-- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
-- gen_rtx_SIGN_EXTEND (SImode, operands[1])));
--
-- DONE;
-- }
--
-- operands[1] = gen_lowpart (SImode, operands[1]);
-- operands[2] = gen_reg_rtx (SImode);
-- }"
--)
--
--(define_insn "thumb1_extendhisi2"
-- [(set (match_operand:SI 0 "register_operand" "=l")
-- (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))
-- (clobber (match_scratch:SI 2 "=&l"))]
-- "TARGET_THUMB1 && !arm_arch6"
-- "*
-- {
-- rtx ops[4];
-- rtx mem = XEXP (operands[1], 0);
--
-- /* This code used to try to use 'V', and fix the address only if it was
-- offsettable, but this fails for e.g. REG+48 because 48 is outside the
-- range of QImode offsets, and offsettable_address_p does a QImode
-- address check. */
--
-- if (GET_CODE (mem) == CONST)
-- mem = XEXP (mem, 0);
--
-- if (GET_CODE (mem) == LABEL_REF)
-- return \"ldr\\t%0, %1\";
--
-- if (GET_CODE (mem) == PLUS)
-- {
-- rtx a = XEXP (mem, 0);
-- rtx b = XEXP (mem, 1);
--
-- if (GET_CODE (a) == LABEL_REF
-- && GET_CODE (b) == CONST_INT)
-- return \"ldr\\t%0, %1\";
--
-- if (GET_CODE (b) == REG)
-- return \"ldrsh\\t%0, %1\";
--
-- ops[1] = a;
-- ops[2] = b;
-- }
-- else
-- {
-- ops[1] = mem;
-- ops[2] = const0_rtx;
-- }
--
-- gcc_assert (GET_CODE (ops[1]) == REG);
--
-- ops[0] = operands[0];
-- ops[3] = operands[2];
-- output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
-- return \"\";
-- }"
-- [(set_attr "length" "4")
-- (set_attr "type" "load_byte")
-- (set_attr "pool_range" "1020")]
--)
-+{
-+ if (TARGET_THUMB1)
-+ {
-+ emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
-+ DONE;
-+ }
-+ if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
-+ {
-+ emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
-+ DONE;
-+ }
-+
-+ if (!arm_arch6 && !MEM_P (operands[1]))
-+ {
-+ rtx t = gen_lowpart (SImode, operands[1]);
-+ rtx tmp = gen_reg_rtx (SImode);
-+ emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
-+ emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
-+ DONE;
-+ }
-+})
-+
-+(define_split
-+ [(parallel
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
-+ (clobber (match_scratch:SI 2 ""))])]
-+ "!arm_arch6"
-+ [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
-+ (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
-+{
-+ operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
-+})
-
- ;; We used to have an early-clobber on the scratch register here.
- ;; However, there's a bug somewhere in reload which means that this
-@@ -4468,16 +4365,18 @@
- ;; we try to verify the operands. Fortunately, we don't really need
- ;; the early-clobber: we can always use operand 0 if operand 2
- ;; overlaps the address.
--(define_insn "*thumb1_extendhisi2_insn_v6"
-+(define_insn "thumb1_extendhisi2"
- [(set (match_operand:SI 0 "register_operand" "=l,l")
- (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))
- (clobber (match_scratch:SI 2 "=X,l"))]
-- "TARGET_THUMB1 && arm_arch6"
-+ "TARGET_THUMB1"
- "*
- {
- rtx ops[4];
- rtx mem;
-
-+ if (which_alternative == 0 && !arm_arch6)
-+ return \"#\";
- if (which_alternative == 0)
- return \"sxth\\t%0, %1\";
-
-@@ -4525,7 +4424,10 @@
- output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
- return \"\";
- }"
-- [(set_attr "length" "2,4")
-+ [(set_attr_alternative "length"
-+ [(if_then_else (eq_attr "is_arch6" "yes")
-+ (const_int 2) (const_int 4))
-+ (const_int 4)])
- (set_attr "type" "alu_shift,load_byte")
- (set_attr "pool_range" "*,1020")]
- )
-@@ -4566,15 +4468,28 @@
- }"
- )
-
-+(define_split
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
-+ "!arm_arch6"
-+ [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
-+ (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
-+{
-+ operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
-+})
-+
- (define_insn "*arm_extendhisi2"
-- [(set (match_operand:SI 0 "s_register_operand" "=r")
-- (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
-+ [(set (match_operand:SI 0 "s_register_operand" "=r,r")
-+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
- "TARGET_ARM && arm_arch4 && !arm_arch6"
-- "ldr%(sh%)\\t%0, %1"
-- [(set_attr "type" "load_byte")
-+ "@
-+ #
-+ ldr%(sh%)\\t%0, %1"
-+ [(set_attr "length" "8,4")
-+ (set_attr "type" "alu_shift,load_byte")
- (set_attr "predicable" "yes")
-- (set_attr "pool_range" "256")
-- (set_attr "neg_pool_range" "244")]
-+ (set_attr "pool_range" "*,256")
-+ (set_attr "neg_pool_range" "*,244")]
- )
-
- ;; ??? Check Thumb-2 pool range
-@@ -4636,46 +4551,45 @@
- )
-
- (define_expand "extendqisi2"
-- [(set (match_dup 2)
-- (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
-- (const_int 24)))
-- (set (match_operand:SI 0 "s_register_operand" "")
-- (ashiftrt:SI (match_dup 2)
-- (const_int 24)))]
-+ [(set (match_operand:SI 0 "s_register_operand" "")
-+ (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
- "TARGET_EITHER"
-- "
-- {
-- if ((TARGET_THUMB || arm_arch4) && GET_CODE (operands[1]) == MEM)
-- {
-- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
-- gen_rtx_SIGN_EXTEND (SImode, operands[1])));
-- DONE;
-- }
--
-- if (!s_register_operand (operands[1], QImode))
-- operands[1] = copy_to_mode_reg (QImode, operands[1]);
--
-- if (arm_arch6)
-- {
-- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
-- gen_rtx_SIGN_EXTEND (SImode, operands[1])));
-- DONE;
-- }
--
-- operands[1] = gen_lowpart (SImode, operands[1]);
-- operands[2] = gen_reg_rtx (SImode);
-- }"
--)
-+{
-+ if (!arm_arch4 && MEM_P (operands[1]))
-+ operands[1] = copy_to_mode_reg (QImode, operands[1]);
-+
-+ if (!arm_arch6 && !MEM_P (operands[1]))
-+ {
-+ rtx t = gen_lowpart (SImode, operands[1]);
-+ rtx tmp = gen_reg_rtx (SImode);
-+ emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
-+ emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
-+ DONE;
-+ }
-+})
-+
-+(define_split
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
-+ "!arm_arch6"
-+ [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
-+ (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
-+{
-+ operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
-+})
-
- (define_insn "*arm_extendqisi"
-- [(set (match_operand:SI 0 "s_register_operand" "=r")
-- (sign_extend:SI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
-+ [(set (match_operand:SI 0 "s_register_operand" "=r,r")
-+ (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
- "TARGET_ARM && arm_arch4 && !arm_arch6"
-- "ldr%(sb%)\\t%0, %1"
-- [(set_attr "type" "load_byte")
-+ "@
-+ #
-+ ldr%(sb%)\\t%0, %1"
-+ [(set_attr "length" "8,4")
-+ (set_attr "type" "alu_shift,load_byte")
- (set_attr "predicable" "yes")
-- (set_attr "pool_range" "256")
-- (set_attr "neg_pool_range" "244")]
-+ (set_attr "pool_range" "*,256")
-+ (set_attr "neg_pool_range" "*,244")]
- )
-
- (define_insn "*arm_extendqisi_v6"
-@@ -4703,162 +4617,103 @@
- (set_attr "predicable" "yes")]
- )
-
--(define_insn "*thumb1_extendqisi2"
-- [(set (match_operand:SI 0 "register_operand" "=l,l")
-- (sign_extend:SI (match_operand:QI 1 "memory_operand" "V,m")))]
-- "TARGET_THUMB1 && !arm_arch6"
-- "*
-- {
-- rtx ops[3];
-- rtx mem = XEXP (operands[1], 0);
--
-- if (GET_CODE (mem) == CONST)
-- mem = XEXP (mem, 0);
--
-- if (GET_CODE (mem) == LABEL_REF)
-- return \"ldr\\t%0, %1\";
--
-- if (GET_CODE (mem) == PLUS
-- && GET_CODE (XEXP (mem, 0)) == LABEL_REF)
-- return \"ldr\\t%0, %1\";
--
-- if (which_alternative == 0)
-- return \"ldrsb\\t%0, %1\";
--
-- ops[0] = operands[0];
--
-- if (GET_CODE (mem) == PLUS)
-- {
-- rtx a = XEXP (mem, 0);
-- rtx b = XEXP (mem, 1);
--
-- ops[1] = a;
-- ops[2] = b;
--
-- if (GET_CODE (a) == REG)
-- {
-- if (GET_CODE (b) == REG)
-- output_asm_insn (\"ldrsb\\t%0, [%1, %2]\", ops);
-- else if (REGNO (a) == REGNO (ops[0]))
-- {
-- output_asm_insn (\"ldrb\\t%0, [%1, %2]\", ops);
-- output_asm_insn (\"lsl\\t%0, %0, #24\", ops);
-- output_asm_insn (\"asr\\t%0, %0, #24\", ops);
-- }
-- else
-- output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
-- }
-- else
-- {
-- gcc_assert (GET_CODE (b) == REG);
-- if (REGNO (b) == REGNO (ops[0]))
-- {
-- output_asm_insn (\"ldrb\\t%0, [%2, %1]\", ops);
-- output_asm_insn (\"lsl\\t%0, %0, #24\", ops);
-- output_asm_insn (\"asr\\t%0, %0, #24\", ops);
-- }
-- else
-- output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
-- }
-- }
-- else if (GET_CODE (mem) == REG && REGNO (ops[0]) == REGNO (mem))
-- {
-- output_asm_insn (\"ldrb\\t%0, [%0, #0]\", ops);
-- output_asm_insn (\"lsl\\t%0, %0, #24\", ops);
-- output_asm_insn (\"asr\\t%0, %0, #24\", ops);
-- }
-- else
-- {
-- ops[1] = mem;
-- ops[2] = const0_rtx;
--
-- output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
-- }
-- return \"\";
-- }"
-- [(set_attr "length" "2,6")
-- (set_attr "type" "load_byte,load_byte")
-- (set_attr "pool_range" "32,32")]
--)
--
--(define_insn "*thumb1_extendqisi2_v6"
-+(define_split
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (sign_extend:SI (match_operand:QI 1 "memory_operand" "")))]
-+ "TARGET_THUMB1 && reload_completed"
-+ [(set (match_dup 0) (match_dup 2))
-+ (set (match_dup 0) (sign_extend:SI (match_dup 3)))]
-+{
-+ rtx addr = XEXP (operands[1], 0);
-+
-+ if (GET_CODE (addr) == CONST)
-+ addr = XEXP (addr, 0);
-+
-+ if (GET_CODE (addr) == PLUS
-+ && REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1)))
-+ /* No split necessary. */
-+ FAIL;
-+
-+ if (GET_CODE (addr) == PLUS
-+ && !REG_P (XEXP (addr, 0)) && !REG_P (XEXP (addr, 1)))
-+ FAIL;
-+
-+ if (reg_overlap_mentioned_p (operands[0], addr))
-+ {
-+ rtx t = gen_lowpart (QImode, operands[0]);
-+ emit_move_insn (t, operands[1]);
-+ emit_insn (gen_thumb1_extendqisi2 (operands[0], t));
-+ DONE;
-+ }
-+
-+ if (REG_P (addr))
-+ {
-+ addr = gen_rtx_PLUS (Pmode, addr, operands[0]);
-+ operands[2] = const0_rtx;
-+ }
-+ else if (GET_CODE (addr) != PLUS)
-+ FAIL;
-+ else if (REG_P (XEXP (addr, 0)))
-+ {
-+ operands[2] = XEXP (addr, 1);
-+ addr = gen_rtx_PLUS (Pmode, XEXP (addr, 0), operands[0]);
-+ }
-+ else
-+ {
-+ operands[2] = XEXP (addr, 0);
-+ addr = gen_rtx_PLUS (Pmode, XEXP (addr, 1), operands[0]);
-+ }
-+
-+ operands[3] = change_address (operands[1], QImode, addr);
-+})
-+
-+(define_peephole2
-+ [(set (match_operand:SI 0 "register_operand" "")
-+ (plus:SI (match_dup 0) (match_operand 1 "const_int_operand")))
-+ (set (match_operand:SI 2 "register_operand" "") (const_int 0))
-+ (set (match_operand:SI 3 "register_operand" "")
-+ (sign_extend:SI (match_operand:QI 4 "memory_operand" "")))]
-+ "TARGET_THUMB1
-+ && GET_CODE (XEXP (operands[4], 0)) == PLUS
-+ && rtx_equal_p (operands[0], XEXP (XEXP (operands[4], 0), 0))
-+ && rtx_equal_p (operands[2], XEXP (XEXP (operands[4], 0), 1))
-+ && (peep2_reg_dead_p (3, operands[0])
-+ || rtx_equal_p (operands[0], operands[3]))
-+ && (peep2_reg_dead_p (3, operands[2])
-+ || rtx_equal_p (operands[2], operands[3]))"
-+ [(set (match_dup 2) (match_dup 1))
-+ (set (match_dup 3) (sign_extend:SI (match_dup 4)))]
-+{
-+ rtx addr = gen_rtx_PLUS (Pmode, operands[0], operands[2]);
-+ operands[4] = change_address (operands[4], QImode, addr);
-+})
-+
-+(define_insn "thumb1_extendqisi2"
- [(set (match_operand:SI 0 "register_operand" "=l,l,l")
- (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,V,m")))]
-- "TARGET_THUMB1 && arm_arch6"
-- "*
-- {
-- rtx ops[3];
-- rtx mem;
--
-- if (which_alternative == 0)
-- return \"sxtb\\t%0, %1\";
--
-- mem = XEXP (operands[1], 0);
--
-- if (GET_CODE (mem) == CONST)
-- mem = XEXP (mem, 0);
--
-- if (GET_CODE (mem) == LABEL_REF)
-- return \"ldr\\t%0, %1\";
--
-- if (GET_CODE (mem) == PLUS
-- && GET_CODE (XEXP (mem, 0)) == LABEL_REF)
-- return \"ldr\\t%0, %1\";
--
-- if (which_alternative == 0)
-- return \"ldrsb\\t%0, %1\";
--
-- ops[0] = operands[0];
--
-- if (GET_CODE (mem) == PLUS)
-- {
-- rtx a = XEXP (mem, 0);
-- rtx b = XEXP (mem, 1);
--
-- ops[1] = a;
-- ops[2] = b;
--
-- if (GET_CODE (a) == REG)
-- {
-- if (GET_CODE (b) == REG)
-- output_asm_insn (\"ldrsb\\t%0, [%1, %2]\", ops);
-- else if (REGNO (a) == REGNO (ops[0]))
-- {
-- output_asm_insn (\"ldrb\\t%0, [%1, %2]\", ops);
-- output_asm_insn (\"sxtb\\t%0, %0\", ops);
-- }
-- else
-- output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
-- }
-- else
-- {
-- gcc_assert (GET_CODE (b) == REG);
-- if (REGNO (b) == REGNO (ops[0]))
-- {
-- output_asm_insn (\"ldrb\\t%0, [%2, %1]\", ops);
-- output_asm_insn (\"sxtb\\t%0, %0\", ops);
-- }
-- else
-- output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
-- }
-- }
-- else if (GET_CODE (mem) == REG && REGNO (ops[0]) == REGNO (mem))
-- {
-- output_asm_insn (\"ldrb\\t%0, [%0, #0]\", ops);
-- output_asm_insn (\"sxtb\\t%0, %0\", ops);
-- }
-- else
-- {
-- ops[1] = mem;
-- ops[2] = const0_rtx;
--
-- output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
-- }
-- return \"\";
-- }"
-- [(set_attr "length" "2,2,4")
-- (set_attr "type" "alu_shift,load_byte,load_byte")
-- (set_attr "pool_range" "*,32,32")]
-+ "TARGET_THUMB1"
-+{
-+ rtx addr;
-+
-+ if (which_alternative == 0 && arm_arch6)
-+ return "sxtb\\t%0, %1";
-+ if (which_alternative == 0)
-+ return "#";
-+
-+ addr = XEXP (operands[1], 0);
-+ if (GET_CODE (addr) == PLUS
-+ && REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1)))
-+ return "ldrsb\\t%0, %1";
-+
-+ return "#";
-+}
-+ [(set_attr_alternative "length"
-+ [(if_then_else (eq_attr "is_arch6" "yes")
-+ (const_int 2) (const_int 4))
-+ (const_int 2)
-+ (if_then_else (eq_attr "is_arch6" "yes")
-+ (const_int 4) (const_int 6))])
-+ (set_attr "type" "alu_shift,load_byte,load_byte")]
- )
-
- (define_expand "extendsfdf2"
-@@ -6784,6 +6639,30 @@
- operands[2] = force_reg (SImode, operands[2]);
- ")
-
-+;; A pattern to recognize a special situation and optimize for it.
-+;; On the thumb, zero-extension from memory is preferrable to sign-extension
-+;; due to the available addressing modes. Hence, convert a signed comparison
-+;; with zero into an unsigned comparison with 127 if possible.
-+(define_expand "cbranchqi4"
-+ [(set (pc) (if_then_else
-+ (match_operator 0 "lt_ge_comparison_operator"
-+ [(match_operand:QI 1 "memory_operand" "")
-+ (match_operand:QI 2 "const0_operand" "")])
-+ (label_ref (match_operand 3 "" ""))
-+ (pc)))]
-+ "TARGET_THUMB1"
-+{
-+ rtx xops[4];
-+ xops[1] = gen_reg_rtx (SImode);
-+ emit_insn (gen_zero_extendqisi2 (xops[1], operands[1]));
-+ xops[2] = GEN_INT (127);
-+ xops[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]) == GE ? LEU : GTU,
-+ VOIDmode, xops[1], xops[2]);
-+ xops[3] = operands[3];
-+ emit_insn (gen_cbranchsi4 (xops[0], xops[1], xops[2], xops[3]));
-+ DONE;
-+})
-+
- (define_expand "cbranchsf4"
- [(set (pc) (if_then_else
- (match_operator 0 "arm_comparison_operator"
-@@ -6849,7 +6728,7 @@
- }"
- )
-
--(define_insn "*cbranchsi4_insn"
-+(define_insn "cbranchsi4_insn"
- [(set (pc) (if_then_else
- (match_operator 0 "arm_comparison_operator"
- [(match_operand:SI 1 "s_register_operand" "l,*h")
-@@ -6858,7 +6737,20 @@
- (pc)))]
- "TARGET_THUMB1"
- "*
-- output_asm_insn (\"cmp\\t%1, %2\", operands);
-+ rtx t = prev_nonnote_insn (insn);
-+ if (t != NULL_RTX
-+ && INSN_P (t)
-+ && INSN_CODE (t) == CODE_FOR_cbranchsi4_insn)
-+ {
-+ t = XEXP (SET_SRC (PATTERN (t)), 0);
-+ if (!rtx_equal_p (XEXP (t, 0), operands[1])
-+ || !rtx_equal_p (XEXP (t, 1), operands[2]))
-+ t = NULL_RTX;
-+ }
-+ else
-+ t = NULL_RTX;
-+ if (t == NULL_RTX)
-+ output_asm_insn (\"cmp\\t%1, %2\", operands);
-
- switch (get_attr_length (insn))
- {
-@@ -7674,15 +7566,15 @@
- (if_then_else
- (match_operator 4 "arm_comparison_operator"
- [(plus:SI
-- (match_operand:SI 2 "s_register_operand" "%l,0,*0,1,1,1")
-- (match_operand:SI 3 "reg_or_int_operand" "lL,IJ,*r,lIJ,lIJ,lIJ"))
-+ (match_operand:SI 2 "s_register_operand" "%0,l,*l,1,1,1")
-+ (match_operand:SI 3 "reg_or_int_operand" "IJ,lL,*l,lIJ,lIJ,lIJ"))
- (const_int 0)])
- (label_ref (match_operand 5 "" ""))
- (pc)))
- (set
- (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m")
- (plus:SI (match_dup 2) (match_dup 3)))
-- (clobber (match_scratch:SI 1 "=X,X,X,l,&l,&l"))]
-+ (clobber (match_scratch:SI 1 "=X,X,l,l,&l,&l"))]
- "TARGET_THUMB1
- && (GET_CODE (operands[4]) == EQ
- || GET_CODE (operands[4]) == NE
-@@ -7692,8 +7584,7 @@
- {
- rtx cond[3];
-
--
-- cond[0] = (which_alternative < 3) ? operands[0] : operands[1];
-+ cond[0] = (which_alternative < 2) ? operands[0] : operands[1];
- cond[1] = operands[2];
- cond[2] = operands[3];
-
-@@ -7702,13 +7593,13 @@
- else
- output_asm_insn (\"add\\t%0, %1, %2\", cond);
-
-- if (which_alternative >= 3
-+ if (which_alternative >= 2
- && which_alternative < 4)
- output_asm_insn (\"mov\\t%0, %1\", operands);
- else if (which_alternative >= 4)
- output_asm_insn (\"str\\t%1, %0\", operands);
-
-- switch (get_attr_length (insn) - ((which_alternative >= 3) ? 2 : 0))
-+ switch (get_attr_length (insn) - ((which_alternative >= 2) ? 2 : 0))
- {
- case 4:
- return \"b%d4\\t%l5\";
-@@ -7722,7 +7613,7 @@
- [(set (attr "far_jump")
- (if_then_else
- (ior (and (lt (symbol_ref ("which_alternative"))
-- (const_int 3))
-+ (const_int 2))
- (eq_attr "length" "8"))
- (eq_attr "length" "10"))
- (const_string "yes")
-@@ -7730,7 +7621,7 @@
- (set (attr "length")
- (if_then_else
- (lt (symbol_ref ("which_alternative"))
-- (const_int 3))
-+ (const_int 2))
- (if_then_else
- (and (ge (minus (match_dup 5) (pc)) (const_int -250))
- (le (minus (match_dup 5) (pc)) (const_int 256)))
-@@ -9483,41 +9374,117 @@
- (set_attr "length" "4,8")]
- )
-
--(define_insn "*compare_scc"
-+; A series of splitters for the compare_scc pattern below. Note that
-+; order is important.
-+(define_split
-+ [(set (match_operand:SI 0 "s_register_operand" "")
-+ (lt:SI (match_operand:SI 1 "s_register_operand" "")
-+ (const_int 0)))
-+ (clobber (reg:CC CC_REGNUM))]
-+ "TARGET_32BIT && reload_completed"
-+ [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
-+
-+(define_split
-+ [(set (match_operand:SI 0 "s_register_operand" "")
-+ (ge:SI (match_operand:SI 1 "s_register_operand" "")
-+ (const_int 0)))
-+ (clobber (reg:CC CC_REGNUM))]
-+ "TARGET_32BIT && reload_completed"
-+ [(set (match_dup 0) (not:SI (match_dup 1)))
-+ (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
-+
-+(define_split
-+ [(set (match_operand:SI 0 "s_register_operand" "")
-+ (eq:SI (match_operand:SI 1 "s_register_operand" "")
-+ (const_int 0)))
-+ (clobber (reg:CC CC_REGNUM))]
-+ "TARGET_32BIT && reload_completed"
-+ [(parallel
-+ [(set (reg:CC CC_REGNUM)
-+ (compare:CC (const_int 1) (match_dup 1)))
-+ (set (match_dup 0)
-+ (minus:SI (const_int 1) (match_dup 1)))])
-+ (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
-+ (set (match_dup 0) (const_int 0)))])
-+
-+(define_split
-+ [(set (match_operand:SI 0 "s_register_operand" "")
-+ (ne:SI (match_operand:SI 1 "s_register_operand" "")
-+ (match_operand:SI 2 "const_int_operand" "")))
-+ (clobber (reg:CC CC_REGNUM))]
-+ "TARGET_32BIT && reload_completed"
-+ [(parallel
-+ [(set (reg:CC CC_REGNUM)
-+ (compare:CC (match_dup 1) (match_dup 2)))
-+ (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
-+ (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
-+ (set (match_dup 0) (const_int 1)))]
-+{
-+ operands[3] = GEN_INT (-INTVAL (operands[2]));
-+})
-+
-+(define_split
-+ [(set (match_operand:SI 0 "s_register_operand" "")
-+ (ne:SI (match_operand:SI 1 "s_register_operand" "")
-+ (match_operand:SI 2 "arm_add_operand" "")))
-+ (clobber (reg:CC CC_REGNUM))]
-+ "TARGET_32BIT && reload_completed"
-+ [(parallel
-+ [(set (reg:CC_NOOV CC_REGNUM)
-+ (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
-+ (const_int 0)))
-+ (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
-+ (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
-+ (set (match_dup 0) (const_int 1)))])
-+
-+(define_insn_and_split "*compare_scc"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (match_operator:SI 1 "arm_comparison_operator"
- [(match_operand:SI 2 "s_register_operand" "r,r")
- (match_operand:SI 3 "arm_add_operand" "rI,L")]))
- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_ARM"
-- "*
-- if (operands[3] == const0_rtx)
-- {
-- if (GET_CODE (operands[1]) == LT)
-- return \"mov\\t%0, %2, lsr #31\";
--
-- if (GET_CODE (operands[1]) == GE)
-- return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
--
-- if (GET_CODE (operands[1]) == EQ)
-- return \"rsbs\\t%0, %2, #1\;movcc\\t%0, #0\";
-- }
--
-- if (GET_CODE (operands[1]) == NE)
-- {
-- if (which_alternative == 1)
-- return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
-- return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
-- }
-- if (which_alternative == 1)
-- output_asm_insn (\"cmn\\t%2, #%n3\", operands);
-- else
-- output_asm_insn (\"cmp\\t%2, %3\", operands);
-- return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
-- "
-- [(set_attr "conds" "clob")
-- (set_attr "length" "12")]
--)
-+ "TARGET_32BIT"
-+ "#"
-+ "&& reload_completed"
-+ [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
-+ (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
-+ (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
-+{
-+ rtx tmp1;
-+ enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
-+ operands[2], operands[3]);
-+ enum rtx_code rc = GET_CODE (operands[1]);
-+
-+ tmp1 = gen_rtx_REG (mode, CC_REGNUM);
-+
-+ operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
-+ if (mode == CCFPmode || mode == CCFPEmode)
-+ rc = reverse_condition_maybe_unordered (rc);
-+ else
-+ rc = reverse_condition (rc);
-+ operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
-+})
-+
-+;; Attempt to improve the sequence generated by the compare_scc splitters
-+;; not to use conditional execution.
-+(define_peephole2
-+ [(set (reg:CC CC_REGNUM)
-+ (compare:CC (match_operand:SI 1 "register_operand" "")
-+ (match_operand:SI 2 "arm_rhs_operand" "")))
-+ (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
-+ (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
-+ (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
-+ (set (match_dup 0) (const_int 1)))
-+ (match_scratch:SI 3 "r")]
-+ "TARGET_32BIT"
-+ [(set (match_dup 3) (minus:SI (match_dup 1) (match_dup 2)))
-+ (parallel
-+ [(set (reg:CC CC_REGNUM)
-+ (compare:CC (const_int 0) (match_dup 3)))
-+ (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
-+ (set (match_dup 0)
-+ (plus:SI (plus:SI (match_dup 0) (match_dup 3))
-+ (geu:SI (reg:CC CC_REGNUM) (const_int 0))))])
-
- (define_insn "*cond_move"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
-
-=== modified file 'gcc/config/arm/predicates.md'
---- old/gcc/config/arm/predicates.md 2010-08-31 09:40:16 +0000
-+++ new/gcc/config/arm/predicates.md 2010-08-31 10:00:27 +0000
-@@ -115,6 +115,10 @@
- (and (match_code "const_int")
- (match_test "const_ok_for_arm (~INTVAL (op))")))
-
-+(define_predicate "const0_operand"
-+ (and (match_code "const_int")
-+ (match_test "INTVAL (op) == 0")))
-+
- ;; Something valid on the RHS of an ARM data-processing instruction
- (define_predicate "arm_rhs_operand"
- (ior (match_operand 0 "s_register_operand")
-@@ -233,6 +237,9 @@
- && (TARGET_FPA || TARGET_VFP)")
- (match_code "unordered,ordered,unlt,unle,unge,ungt"))))
-
-+(define_special_predicate "lt_ge_comparison_operator"
-+ (match_code "lt,ge"))
-+
- (define_special_predicate "minmax_operator"
- (and (match_code "smin,smax,umin,umax")
- (match_test "mode == GET_MODE (op)")))
-
-=== modified file 'gcc/config/arm/thumb2.md'
---- old/gcc/config/arm/thumb2.md 2010-08-31 09:40:16 +0000
-+++ new/gcc/config/arm/thumb2.md 2010-08-31 10:00:27 +0000
-@@ -599,42 +599,6 @@
- (set_attr "length" "6,10")]
- )
-
--(define_insn "*thumb2_compare_scc"
-- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
-- (match_operator:SI 1 "arm_comparison_operator"
-- [(match_operand:SI 2 "s_register_operand" "r,r")
-- (match_operand:SI 3 "arm_add_operand" "rI,L")]))
-- (clobber (reg:CC CC_REGNUM))]
-- "TARGET_THUMB2"
-- "*
-- if (operands[3] == const0_rtx)
-- {
-- if (GET_CODE (operands[1]) == LT)
-- return \"lsr\\t%0, %2, #31\";
--
-- if (GET_CODE (operands[1]) == GE)
-- return \"mvn\\t%0, %2\;lsr\\t%0, %0, #31\";
--
-- if (GET_CODE (operands[1]) == EQ)
-- return \"rsbs\\t%0, %2, #1\;it\\tcc\;movcc\\t%0, #0\";
-- }
--
-- if (GET_CODE (operands[1]) == NE)
-- {
-- if (which_alternative == 1)
-- return \"adds\\t%0, %2, #%n3\;it\\tne\;movne\\t%0, #1\";
-- return \"subs\\t%0, %2, %3\;it\\tne\;movne\\t%0, #1\";
-- }
-- if (which_alternative == 1)
-- output_asm_insn (\"cmn\\t%2, #%n3\", operands);
-- else
-- output_asm_insn (\"cmp\\t%2, %3\", operands);
-- return \"ite\\t%D1\;mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
-- "
-- [(set_attr "conds" "clob")
-- (set_attr "length" "14")]
--)
--
- (define_insn "*thumb2_cond_move"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
- (if_then_else:SI (match_operator 3 "equality_operator"
-
-=== added file 'gcc/testsuite/gcc.c-torture/execute/pr40657.c'
---- old/gcc/testsuite/gcc.c-torture/execute/pr40657.c 1970-01-01 00:00:00 +0000
-+++ new/gcc/testsuite/gcc.c-torture/execute/pr40657.c 2010-08-31 10:00:27 +0000
-@@ -0,0 +1,23 @@
-+/* Verify that that Thumb-1 epilogue size optimization does not clobber the
-+ return value. */
-+
-+long long v = 0x123456789abc;
-+
-+__attribute__((noinline)) void bar (int *x)
-+{
-+ asm volatile ("" : "=m" (x) ::);
-+}
-+
-+__attribute__((noinline)) long long foo()
-+{
-+ int x;
-+ bar(&x);
-+ return v;
-+}
-+
-+int main ()
-+{
-+ if (foo () != v)
-+ abort ();
-+ exit (0);
-+}
-
-=== added file 'gcc/testsuite/gcc.target/arm/pr40657-1.c'
---- old/gcc/testsuite/gcc.target/arm/pr40657-1.c 1970-01-01 00:00:00 +0000
-+++ new/gcc/testsuite/gcc.target/arm/pr40657-1.c 2010-08-31 10:00:27 +0000
-@@ -0,0 +1,13 @@
-+/* { dg-options "-Os -march=armv5te -mthumb" } */
-+/* { dg-require-effective-target arm_thumb1_ok } */
-+/* { dg-final { scan-assembler "pop.*r1.*pc" } } */
-+/* { dg-final { scan-assembler-not "sub\[\\t \]*sp,\[\\t \]*sp" } } */
-+/* { dg-final { scan-assembler-not "add\[\\t \]*sp,\[\\t \]*sp" } } */
-+
-+extern void bar(int*);
-+int foo()
-+{
-+ int x;
-+ bar(&x);
-+ return x;
-+}
-
-=== added file 'gcc/testsuite/gcc.target/arm/pr40657-2.c'
---- old/gcc/testsuite/gcc.target/arm/pr40657-2.c 1970-01-01 00:00:00 +0000
-+++ new/gcc/testsuite/gcc.target/arm/pr40657-2.c 2010-08-31 10:00:27 +0000
-@@ -0,0 +1,20 @@
-+/* { dg-options "-Os -march=armv4t -mthumb" } */
-+/* { dg-require-effective-target arm_thumb1_ok } */
-+/* { dg-final { scan-assembler-not "sub\[\\t \]*sp,\[\\t \]*sp" } } */
-+/* { dg-final { scan-assembler-not "add\[\\t \]*sp,\[\\t \]*sp" } } */
-+
-+/* Here, we test that if there's a pop of r[4567] in the epilogue,
-+ add sp,sp,#12 is removed and replaced by three additional pops
-+ of lower-numbered regs. */
-+
-+extern void bar(int*);
-+
-+int t1, t2, t3, t4, t5;
-+int foo()
-+{
-+ int i,j,k,x = 0;
-+ for (i = 0; i < t1; i++)
-+ for (j = 0; j < t2; j++)
-+ bar(&x);
-+ return x;
-+}
-
-=== added file 'gcc/testsuite/gcc.target/arm/pr42172-1.c'
---- old/gcc/testsuite/gcc.target/arm/pr42172-1.c 1970-01-01 00:00:00 +0000
-+++ new/gcc/testsuite/gcc.target/arm/pr42172-1.c 2010-08-31 10:00:27 +0000
-@@ -0,0 +1,19 @@
-+/* { dg-options "-O2" } */
-+
-+struct A {
-+ unsigned int f1 : 3;
-+ unsigned int f2 : 3;
-+ unsigned int f3 : 1;
-+ unsigned int f4 : 1;
-+
-+};
-+
-+void init_A (struct A *this)
-+{
-+ this->f1 = 0;
-+ this->f2 = 1;
-+ this->f3 = 0;
-+ this->f4 = 0;
-+}
-+
-+/* { dg-final { scan-assembler-times "ldr" 1 } } */
-
-=== added file 'gcc/testsuite/gcc.target/arm/pr42835.c'
---- old/gcc/testsuite/gcc.target/arm/pr42835.c 1970-01-01 00:00:00 +0000
-+++ new/gcc/testsuite/gcc.target/arm/pr42835.c 2010-08-31 10:00:27 +0000
-@@ -0,0 +1,12 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mthumb -Os" } */
-+/* { dg-require-effective-target arm_thumb2_ok } */
-+
-+int foo(int *p, int i)
-+{
-+ return( (i < 0 && *p == 1)
-+ || (i > 0 && *p == 2) );
-+}
-+
-+/* { dg-final { scan-assembler-times "movne\[\\t \]*r.,\[\\t \]*#" 1 } } */
-+/* { dg-final { scan-assembler-times "moveq\[\\t \]*r.,\[\\t \]*#" 1 } } */
-
-=== added file 'gcc/testsuite/gcc.target/arm/thumb-cbranchqi.c'
---- old/gcc/testsuite/gcc.target/arm/thumb-cbranchqi.c 1970-01-01 00:00:00 +0000
-+++ new/gcc/testsuite/gcc.target/arm/thumb-cbranchqi.c 2010-08-31 10:00:27 +0000
-@@ -0,0 +1,15 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mthumb -Os" } */
-+/* { dg-require-effective-target arm_thumb1_ok } */
-+
-+int ldrb(unsigned char* p)
-+{
-+ if (p[8] <= 0x7F)
-+ return 2;
-+ else
-+ return 5;
-+}
-+
-+
-+/* { dg-final { scan-assembler "127" } } */
-+/* { dg-final { scan-assembler "bhi" } } */
-
-=== added file 'gcc/testsuite/gcc.target/arm/thumb-comparisons.c'
---- old/gcc/testsuite/gcc.target/arm/thumb-comparisons.c 1970-01-01 00:00:00 +0000
-+++ new/gcc/testsuite/gcc.target/arm/thumb-comparisons.c 2010-08-31 10:00:27 +0000
-@@ -0,0 +1,18 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mthumb -Os" } */
-+/* { dg-require-effective-target arm_thumb1_ok } */
-+
-+int foo(char ch)
-+{
-+ switch (ch) {
-+ case '-':
-+ case '?':
-+ case '/':
-+ case 99:
-+ return 1;
-+ default:
-+ return 0;
-+ }
-+}
-+
-+/* { dg-final { scan-assembler-times "cmp\[\\t \]*r.,\[\\t \]*#63" 1 } } */
-
-=== added file 'gcc/testsuite/gcc.target/arm/thumb-stackframe.c'
---- old/gcc/testsuite/gcc.target/arm/thumb-stackframe.c 1970-01-01 00:00:00 +0000
-+++ new/gcc/testsuite/gcc.target/arm/thumb-stackframe.c 2010-08-31 10:00:27 +0000
-@@ -0,0 +1,13 @@
-+/* { dg-do compile } */
-+/* { dg-options "-mthumb -Os" } */
-+/* { dg-require-effective-target arm_thumb1_ok } */
-+
-+extern void bar(int*);
-+int foo()
-+{
-+ int x;
-+ bar(&x);
-+ return x;
-+}
-+
-+/* { dg-final { scan-assembler-not "sub\[\\t \]*sp,\[\\t \]*sp," } } */
-