diff options
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.patch | 2011 |
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," } } */ - |