aboutsummaryrefslogtreecommitdiffstats
path: root/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106802.patch
diff options
context:
space:
mode:
Diffstat (limited to 'toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106802.patch')
-rw-r--r--toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106802.patch948
1 files changed, 0 insertions, 948 deletions
diff --git a/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106802.patch b/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106802.patch
deleted file mode 100644
index ade96fdd11..0000000000
--- a/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106802.patch
+++ /dev/null
@@ -1,948 +0,0 @@
-2011-09-12 Andrew Stubbs <ams@codesourcery.com>
-
- Backport from FSF mainline:
-
- 2011-08-30 Andrew Stubbs <ams@codesourcery.com>
-
- gcc/
- * config/arm/arm.c (optimal_immediate_sequence_1): Make b1, b2,
- b3 and b4 unsigned.
-
- 2011-08-30 Andrew Stubbs <ams@codesourcery.com>
-
- gcc/
- * config/arm/arm.c (arm_gen_constant): Set can_negate correctly
- when code is SET.
-
- 2011-08-26 Andrew Stubbs <ams@codesourcery.com>
-
- gcc/
- * config/arm/arm.c (struct four_ints): New type.
- (count_insns_for_constant): Delete function.
- (find_best_start): Delete function.
- (optimal_immediate_sequence): New function.
- (optimal_immediate_sequence_1): New function.
- (arm_gen_constant): Move constant splitting code to
- optimal_immediate_sequence.
- Rewrite constant negation/invertion code.
-
- gcc/testsuite/
- * gcc.target/arm/thumb2-replicated-constant1.c: New file.
- * gcc.target/arm/thumb2-replicated-constant2.c: New file.
- * gcc.target/arm/thumb2-replicated-constant3.c: New file.
- * gcc.target/arm/thumb2-replicated-constant4.c: New file.
-
- 2011-08-26 Andrew Stubbs <ams@codesourcery.com>
-
- gcc/
- * config/arm/arm-protos.h (const_ok_for_op): Add prototype.
- * config/arm/arm.c (const_ok_for_op): Add support for addw/subw.
- Remove prototype. Remove static function type.
- * config/arm/arm.md (*arm_addsi3): Add addw/subw support.
- Add arch attribute.
- * config/arm/constraints.md (Pj, PJ): New constraints.
-
- 2011-04-20 Andrew Stubbs <ams@codesourcery.com>
-
- gcc/
- * config/arm/arm.c (arm_gen_constant): Move mowv support ....
- (const_ok_for_op): ... to here.
-
- 2011-04-20 Andrew Stubbs <ams@codesourcery.com>
-
- gcc/
- * config/arm/arm.c (arm_gen_constant): Remove redundant can_invert.
-
-
-=== modified file 'gcc/config/arm/arm-protos.h'
---- old/gcc/config/arm/arm-protos.h 2011-07-04 14:03:49 +0000
-+++ new/gcc/config/arm/arm-protos.h 2011-08-25 13:26:58 +0000
-@@ -46,6 +46,7 @@
- extern bool arm_small_register_classes_for_mode_p (enum machine_mode);
- extern int arm_hard_regno_mode_ok (unsigned int, enum machine_mode);
- extern int const_ok_for_arm (HOST_WIDE_INT);
-+extern int const_ok_for_op (HOST_WIDE_INT, enum rtx_code);
- extern int arm_split_constant (RTX_CODE, enum machine_mode, rtx,
- HOST_WIDE_INT, rtx, rtx, int);
- extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, rtx *, rtx *);
-
-=== modified file 'gcc/config/arm/arm.c'
---- old/gcc/config/arm/arm.c 2011-08-24 17:35:16 +0000
-+++ new/gcc/config/arm/arm.c 2011-09-06 12:57:56 +0000
-@@ -63,6 +63,11 @@
-
- void (*arm_lang_output_object_attributes_hook)(void);
-
-+struct four_ints
-+{
-+ int i[4];
-+};
-+
- /* Forward function declarations. */
- static bool arm_needs_doubleword_align (enum machine_mode, const_tree);
- static int arm_compute_static_chain_stack_bytes (void);
-@@ -81,7 +86,6 @@
- static bool arm_legitimate_address_p (enum machine_mode, rtx, bool);
- static int thumb_far_jump_used_p (void);
- static bool thumb_force_lr_save (void);
--static int const_ok_for_op (HOST_WIDE_INT, enum rtx_code);
- static rtx emit_sfm (int, int);
- static unsigned arm_size_return_regs (void);
- static bool arm_assemble_integer (rtx, unsigned int, int);
-@@ -129,7 +133,13 @@
- static int arm_comp_type_attributes (const_tree, const_tree);
- static void arm_set_default_type_attributes (tree);
- static int arm_adjust_cost (rtx, rtx, rtx, int);
--static int count_insns_for_constant (HOST_WIDE_INT, int);
-+static int optimal_immediate_sequence (enum rtx_code code,
-+ unsigned HOST_WIDE_INT val,
-+ struct four_ints *return_sequence);
-+static int optimal_immediate_sequence_1 (enum rtx_code code,
-+ unsigned HOST_WIDE_INT val,
-+ struct four_ints *return_sequence,
-+ int i);
- static int arm_get_strip_length (int);
- static bool arm_function_ok_for_sibcall (tree, tree);
- static enum machine_mode arm_promote_function_mode (const_tree,
-@@ -2525,7 +2535,7 @@
- }
-
- /* Return true if I is a valid constant for the operation CODE. */
--static int
-+int
- const_ok_for_op (HOST_WIDE_INT i, enum rtx_code code)
- {
- if (const_ok_for_arm (i))
-@@ -2533,7 +2543,21 @@
-
- switch (code)
- {
-+ case SET:
-+ /* See if we can use movw. */
-+ if (arm_arch_thumb2 && (i & 0xffff0000) == 0)
-+ return 1;
-+ else
-+ return 0;
-+
- case PLUS:
-+ /* See if we can use addw or subw. */
-+ if (TARGET_THUMB2
-+ && ((i & 0xfffff000) == 0
-+ || ((-i) & 0xfffff000) == 0))
-+ return 1;
-+ /* else fall through. */
-+
- case COMPARE:
- case EQ:
- case NE:
-@@ -2649,68 +2673,41 @@
- 1);
- }
-
--/* Return the number of instructions required to synthesize the given
-- constant, if we start emitting them from bit-position I. */
--static int
--count_insns_for_constant (HOST_WIDE_INT remainder, int i)
--{
-- HOST_WIDE_INT temp1;
-- int step_size = TARGET_ARM ? 2 : 1;
-- int num_insns = 0;
--
-- gcc_assert (TARGET_ARM || i == 0);
--
-- do
-- {
-- int end;
--
-- if (i <= 0)
-- i += 32;
-- if (remainder & (((1 << step_size) - 1) << (i - step_size)))
-- {
-- end = i - 8;
-- if (end < 0)
-- end += 32;
-- temp1 = remainder & ((0x0ff << end)
-- | ((i < end) ? (0xff >> (32 - end)) : 0));
-- remainder &= ~temp1;
-- num_insns++;
-- i -= 8 - step_size;
-- }
-- i -= step_size;
-- } while (remainder);
-- return num_insns;
--}
--
--static int
--find_best_start (unsigned HOST_WIDE_INT remainder)
-+/* Return a sequence of integers, in RETURN_SEQUENCE that fit into
-+ ARM/THUMB2 immediates, and add up to VAL.
-+ Thr function return value gives the number of insns required. */
-+static int
-+optimal_immediate_sequence (enum rtx_code code, unsigned HOST_WIDE_INT val,
-+ struct four_ints *return_sequence)
- {
- int best_consecutive_zeros = 0;
- int i;
- int best_start = 0;
-+ int insns1, insns2;
-+ struct four_ints tmp_sequence;
-
- /* If we aren't targetting ARM, the best place to start is always at
-- the bottom. */
-- if (! TARGET_ARM)
-- return 0;
--
-- for (i = 0; i < 32; i += 2)
-+ the bottom, otherwise look more closely. */
-+ if (TARGET_ARM)
- {
-- int consecutive_zeros = 0;
--
-- if (!(remainder & (3 << i)))
-+ for (i = 0; i < 32; i += 2)
- {
-- while ((i < 32) && !(remainder & (3 << i)))
-- {
-- consecutive_zeros += 2;
-- i += 2;
-- }
-- if (consecutive_zeros > best_consecutive_zeros)
-- {
-- best_consecutive_zeros = consecutive_zeros;
-- best_start = i - consecutive_zeros;
-- }
-- i -= 2;
-+ int consecutive_zeros = 0;
-+
-+ if (!(val & (3 << i)))
-+ {
-+ while ((i < 32) && !(val & (3 << i)))
-+ {
-+ consecutive_zeros += 2;
-+ i += 2;
-+ }
-+ if (consecutive_zeros > best_consecutive_zeros)
-+ {
-+ best_consecutive_zeros = consecutive_zeros;
-+ best_start = i - consecutive_zeros;
-+ }
-+ i -= 2;
-+ }
- }
- }
-
-@@ -2737,13 +2734,161 @@
- the constant starting from `best_start', and also starting from
- zero (i.e. with bit 31 first to be output). If `best_start' doesn't
- yield a shorter sequence, we may as well use zero. */
-+ insns1 = optimal_immediate_sequence_1 (code, val, return_sequence, best_start);
- if (best_start != 0
-- && ((((unsigned HOST_WIDE_INT) 1) << best_start) < remainder)
-- && (count_insns_for_constant (remainder, 0) <=
-- count_insns_for_constant (remainder, best_start)))
-- best_start = 0;
--
-- return best_start;
-+ && ((((unsigned HOST_WIDE_INT) 1) << best_start) < val))
-+ {
-+ insns2 = optimal_immediate_sequence_1 (code, val, &tmp_sequence, 0);
-+ if (insns2 <= insns1)
-+ {
-+ *return_sequence = tmp_sequence;
-+ insns1 = insns2;
-+ }
-+ }
-+
-+ return insns1;
-+}
-+
-+/* As for optimal_immediate_sequence, but starting at bit-position I. */
-+static int
-+optimal_immediate_sequence_1 (enum rtx_code code, unsigned HOST_WIDE_INT val,
-+ struct four_ints *return_sequence, int i)
-+{
-+ int remainder = val & 0xffffffff;
-+ int insns = 0;
-+
-+ /* Try and find a way of doing the job in either two or three
-+ instructions.
-+
-+ In ARM mode we can use 8-bit constants, rotated to any 2-bit aligned
-+ location. We start at position I. This may be the MSB, or
-+ optimial_immediate_sequence may have positioned it at the largest block
-+ of zeros that are aligned on a 2-bit boundary. We then fill up the temps,
-+ wrapping around to the top of the word when we drop off the bottom.
-+ In the worst case this code should produce no more than four insns.
-+
-+ In Thumb2 mode, we can use 32/16-bit replicated constants, and 8-bit
-+ constants, shifted to any arbitrary location. We should always start
-+ at the MSB. */
-+ do
-+ {
-+ int end;
-+ unsigned int b1, b2, b3, b4;
-+ unsigned HOST_WIDE_INT result;
-+ int loc;
-+
-+ gcc_assert (insns < 4);
-+
-+ if (i <= 0)
-+ i += 32;
-+
-+ /* First, find the next normal 12/8-bit shifted/rotated immediate. */
-+ if (remainder & ((TARGET_ARM ? (3 << (i - 2)) : (1 << (i - 1)))))
-+ {
-+ loc = i;
-+ if (i <= 12 && TARGET_THUMB2 && code == PLUS)
-+ /* We can use addw/subw for the last 12 bits. */
-+ result = remainder;
-+ else
-+ {
-+ /* Use an 8-bit shifted/rotated immediate. */
-+ end = i - 8;
-+ if (end < 0)
-+ end += 32;
-+ result = remainder & ((0x0ff << end)
-+ | ((i < end) ? (0xff >> (32 - end))
-+ : 0));
-+ i -= 8;
-+ }
-+ }
-+ else
-+ {
-+ /* Arm allows rotates by a multiple of two. Thumb-2 allows
-+ arbitrary shifts. */
-+ i -= TARGET_ARM ? 2 : 1;
-+ continue;
-+ }
-+
-+ /* Next, see if we can do a better job with a thumb2 replicated
-+ constant.
-+
-+ We do it this way around to catch the cases like 0x01F001E0 where
-+ two 8-bit immediates would work, but a replicated constant would
-+ make it worse.
-+
-+ TODO: 16-bit constants that don't clear all the bits, but still win.
-+ TODO: Arithmetic splitting for set/add/sub, rather than bitwise. */
-+ if (TARGET_THUMB2)
-+ {
-+ b1 = (remainder & 0xff000000) >> 24;
-+ b2 = (remainder & 0x00ff0000) >> 16;
-+ b3 = (remainder & 0x0000ff00) >> 8;
-+ b4 = remainder & 0xff;
-+
-+ if (loc > 24)
-+ {
-+ /* The 8-bit immediate already found clears b1 (and maybe b2),
-+ but must leave b3 and b4 alone. */
-+
-+ /* First try to find a 32-bit replicated constant that clears
-+ almost everything. We can assume that we can't do it in one,
-+ or else we wouldn't be here. */
-+ unsigned int tmp = b1 & b2 & b3 & b4;
-+ unsigned int tmp2 = tmp + (tmp << 8) + (tmp << 16)
-+ + (tmp << 24);
-+ unsigned int matching_bytes = (tmp == b1) + (tmp == b2)
-+ + (tmp == b3) + (tmp == b4);
-+ if (tmp
-+ && (matching_bytes >= 3
-+ || (matching_bytes == 2
-+ && const_ok_for_op (remainder & ~tmp2, code))))
-+ {
-+ /* At least 3 of the bytes match, and the fourth has at
-+ least as many bits set, or two of the bytes match
-+ and it will only require one more insn to finish. */
-+ result = tmp2;
-+ i = tmp != b1 ? 32
-+ : tmp != b2 ? 24
-+ : tmp != b3 ? 16
-+ : 8;
-+ }
-+
-+ /* Second, try to find a 16-bit replicated constant that can
-+ leave three of the bytes clear. If b2 or b4 is already
-+ zero, then we can. If the 8-bit from above would not
-+ clear b2 anyway, then we still win. */
-+ else if (b1 == b3 && (!b2 || !b4
-+ || (remainder & 0x00ff0000 & ~result)))
-+ {
-+ result = remainder & 0xff00ff00;
-+ i = 24;
-+ }
-+ }
-+ else if (loc > 16)
-+ {
-+ /* The 8-bit immediate already found clears b2 (and maybe b3)
-+ and we don't get here unless b1 is alredy clear, but it will
-+ leave b4 unchanged. */
-+
-+ /* If we can clear b2 and b4 at once, then we win, since the
-+ 8-bits couldn't possibly reach that far. */
-+ if (b2 == b4)
-+ {
-+ result = remainder & 0x00ff00ff;
-+ i = 16;
-+ }
-+ }
-+ }
-+
-+ return_sequence->i[insns++] = result;
-+ remainder &= ~result;
-+
-+ if (code == SET || code == MINUS)
-+ code = PLUS;
-+ }
-+ while (remainder);
-+
-+ return insns;
- }
-
- /* Emit an instruction with the indicated PATTERN. If COND is
-@@ -2760,7 +2905,6 @@
-
- /* As above, but extra parameter GENERATE which, if clear, suppresses
- RTL generation. */
--/* ??? This needs more work for thumb2. */
-
- static int
- arm_gen_constant (enum rtx_code code, enum machine_mode mode, rtx cond,
-@@ -2772,15 +2916,15 @@
- int final_invert = 0;
- int can_negate_initial = 0;
- int i;
-- int num_bits_set = 0;
- int set_sign_bit_copies = 0;
- int clear_sign_bit_copies = 0;
- int clear_zero_bit_copies = 0;
- int set_zero_bit_copies = 0;
-- int insns = 0;
-+ int insns = 0, neg_insns, inv_insns;
- unsigned HOST_WIDE_INT temp1, temp2;
- unsigned HOST_WIDE_INT remainder = val & 0xffffffff;
-- int step_size = TARGET_ARM ? 2 : 1;
-+ struct four_ints *immediates;
-+ struct four_ints pos_immediates, neg_immediates, inv_immediates;
-
- /* Find out which operations are safe for a given CODE. Also do a quick
- check for degenerate cases; these can occur when DImode operations
-@@ -2789,7 +2933,6 @@
- {
- case SET:
- can_invert = 1;
-- can_negate = 1;
- break;
-
- case PLUS:
-@@ -2817,9 +2960,6 @@
- gen_rtx_SET (VOIDmode, target, source));
- return 1;
- }
--
-- if (TARGET_THUMB2)
-- can_invert = 1;
- break;
-
- case AND:
-@@ -2861,6 +3001,7 @@
- gen_rtx_NOT (mode, source)));
- return 1;
- }
-+ final_invert = 1;
- break;
-
- case MINUS:
-@@ -2883,7 +3024,6 @@
- source)));
- return 1;
- }
-- can_negate = 1;
-
- break;
-
-@@ -2892,9 +3032,7 @@
- }
-
- /* If we can do it in one insn get out quickly. */
-- if (const_ok_for_arm (val)
-- || (can_negate_initial && const_ok_for_arm (-val))
-- || (can_invert && const_ok_for_arm (~val)))
-+ if (const_ok_for_op (val, code))
- {
- if (generate)
- emit_constant_insn (cond,
-@@ -2947,15 +3085,6 @@
- switch (code)
- {
- case SET:
-- /* See if we can use movw. */
-- if (arm_arch_thumb2 && (remainder & 0xffff0000) == 0)
-- {
-- if (generate)
-- emit_constant_insn (cond, gen_rtx_SET (VOIDmode, target,
-- GEN_INT (val)));
-- return 1;
-- }
--
- /* See if we can do this by sign_extending a constant that is known
- to be negative. This is a good, way of doing it, since the shift
- may well merge into a subsequent insn. */
-@@ -3306,121 +3435,97 @@
- break;
- }
-
-- for (i = 0; i < 32; i++)
-- if (remainder & (1 << i))
-- num_bits_set++;
--
-- if ((code == AND)
-- || (code != IOR && can_invert && num_bits_set > 16))
-- remainder ^= 0xffffffff;
-- else if (code == PLUS && num_bits_set > 16)
-- remainder = (-remainder) & 0xffffffff;
--
-- /* For XOR, if more than half the bits are set and there's a sequence
-- of more than 8 consecutive ones in the pattern then we can XOR by the
-- inverted constant and then invert the final result; this may save an
-- instruction and might also lead to the final mvn being merged with
-- some other operation. */
-- else if (code == XOR && num_bits_set > 16
-- && (count_insns_for_constant (remainder ^ 0xffffffff,
-- find_best_start
-- (remainder ^ 0xffffffff))
-- < count_insns_for_constant (remainder,
-- find_best_start (remainder))))
-- {
-- remainder ^= 0xffffffff;
-- final_invert = 1;
-+ /* Calculate what the instruction sequences would be if we generated it
-+ normally, negated, or inverted. */
-+ if (code == AND)
-+ /* AND cannot be split into multiple insns, so invert and use BIC. */
-+ insns = 99;
-+ else
-+ insns = optimal_immediate_sequence (code, remainder, &pos_immediates);
-+
-+ if (can_negate)
-+ neg_insns = optimal_immediate_sequence (code, (-remainder) & 0xffffffff,
-+ &neg_immediates);
-+ else
-+ neg_insns = 99;
-+
-+ if (can_invert || final_invert)
-+ inv_insns = optimal_immediate_sequence (code, remainder ^ 0xffffffff,
-+ &inv_immediates);
-+ else
-+ inv_insns = 99;
-+
-+ immediates = &pos_immediates;
-+
-+ /* Is the negated immediate sequence more efficient? */
-+ if (neg_insns < insns && neg_insns <= inv_insns)
-+ {
-+ insns = neg_insns;
-+ immediates = &neg_immediates;
-+ }
-+ else
-+ can_negate = 0;
-+
-+ /* Is the inverted immediate sequence more efficient?
-+ We must allow for an extra NOT instruction for XOR operations, although
-+ there is some chance that the final 'mvn' will get optimized later. */
-+ if ((inv_insns + 1) < insns || (!final_invert && inv_insns < insns))
-+ {
-+ insns = inv_insns;
-+ immediates = &inv_immediates;
- }
- else
- {
- can_invert = 0;
-- can_negate = 0;
-+ final_invert = 0;
- }
-
-- /* Now try and find a way of doing the job in either two or three
-- instructions.
-- We start by looking for the largest block of zeros that are aligned on
-- a 2-bit boundary, we then fill up the temps, wrapping around to the
-- top of the word when we drop off the bottom.
-- In the worst case this code should produce no more than four insns.
-- Thumb-2 constants are shifted, not rotated, so the MSB is always the
-- best place to start. */
--
-- /* ??? Use thumb2 replicated constants when the high and low halfwords are
-- the same. */
-- {
-- /* Now start emitting the insns. */
-- i = find_best_start (remainder);
-- do
-- {
-- int end;
--
-- if (i <= 0)
-- i += 32;
-- if (remainder & (3 << (i - 2)))
-- {
-- end = i - 8;
-- if (end < 0)
-- end += 32;
-- temp1 = remainder & ((0x0ff << end)
-- | ((i < end) ? (0xff >> (32 - end)) : 0));
-- remainder &= ~temp1;
--
-- if (generate)
-- {
-- rtx new_src, temp1_rtx;
--
-- if (code == SET || code == MINUS)
-- {
-- new_src = (subtargets ? gen_reg_rtx (mode) : target);
-- if (can_invert && code != MINUS)
-- temp1 = ~temp1;
-- }
-- else
-- {
-- if ((final_invert || remainder) && subtargets)
-- new_src = gen_reg_rtx (mode);
-- else
-- new_src = target;
-- if (can_invert)
-- temp1 = ~temp1;
-- else if (can_negate)
-- temp1 = -temp1;
-- }
--
-- temp1 = trunc_int_for_mode (temp1, mode);
-- temp1_rtx = GEN_INT (temp1);
--
-- if (code == SET)
-- ;
-- else if (code == MINUS)
-- temp1_rtx = gen_rtx_MINUS (mode, temp1_rtx, source);
-- else
-- temp1_rtx = gen_rtx_fmt_ee (code, mode, source, temp1_rtx);
--
-- emit_constant_insn (cond,
-- gen_rtx_SET (VOIDmode, new_src,
-- temp1_rtx));
-- source = new_src;
-- }
--
-- if (code == SET)
-- {
-- can_invert = 0;
-- code = PLUS;
-- }
-- else if (code == MINUS)
-+ /* Now output the chosen sequence as instructions. */
-+ if (generate)
-+ {
-+ for (i = 0; i < insns; i++)
-+ {
-+ rtx new_src, temp1_rtx;
-+
-+ temp1 = immediates->i[i];
-+
-+ if (code == SET || code == MINUS)
-+ new_src = (subtargets ? gen_reg_rtx (mode) : target);
-+ else if ((final_invert || i < (insns - 1)) && subtargets)
-+ new_src = gen_reg_rtx (mode);
-+ else
-+ new_src = target;
-+
-+ if (can_invert)
-+ temp1 = ~temp1;
-+ else if (can_negate)
-+ temp1 = -temp1;
-+
-+ temp1 = trunc_int_for_mode (temp1, mode);
-+ temp1_rtx = GEN_INT (temp1);
-+
-+ if (code == SET)
-+ ;
-+ else if (code == MINUS)
-+ temp1_rtx = gen_rtx_MINUS (mode, temp1_rtx, source);
-+ else
-+ temp1_rtx = gen_rtx_fmt_ee (code, mode, source, temp1_rtx);
-+
-+ emit_constant_insn (cond,
-+ gen_rtx_SET (VOIDmode, new_src,
-+ temp1_rtx));
-+ source = new_src;
-+
-+ if (code == SET)
-+ {
-+ can_negate = can_invert;
-+ can_invert = 0;
- code = PLUS;
--
-- insns++;
-- i -= 8 - step_size;
-- }
-- /* Arm allows rotates by a multiple of two. Thumb-2 allows arbitrary
-- shifts. */
-- i -= step_size;
-- }
-- while (remainder);
-- }
-+ }
-+ else if (code == MINUS)
-+ code = PLUS;
-+ }
-+ }
-
- if (final_invert)
- {
-
-=== modified file 'gcc/config/arm/arm.md'
---- old/gcc/config/arm/arm.md 2011-08-25 11:42:09 +0000
-+++ new/gcc/config/arm/arm.md 2011-08-25 13:26:58 +0000
-@@ -701,21 +701,24 @@
- ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
- ;; put the duplicated register first, and not try the commutative version.
- (define_insn_and_split "*arm_addsi3"
-- [(set (match_operand:SI 0 "s_register_operand" "=r, k,r,r, k,r")
-- (plus:SI (match_operand:SI 1 "s_register_operand" "%rk,k,r,rk,k,rk")
-- (match_operand:SI 2 "reg_or_int_operand" "rI,rI,k,L, L,?n")))]
-+ [(set (match_operand:SI 0 "s_register_operand" "=r, k,r,r, k, r, k,r, k, r")
-+ (plus:SI (match_operand:SI 1 "s_register_operand" "%rk,k,r,rk,k, rk,k,rk,k, rk")
-+ (match_operand:SI 2 "reg_or_int_operand" "rI,rI,k,Pj,Pj,L, L,PJ,PJ,?n")))]
- "TARGET_32BIT"
- "@
- add%?\\t%0, %1, %2
- add%?\\t%0, %1, %2
- add%?\\t%0, %2, %1
-- sub%?\\t%0, %1, #%n2
-- sub%?\\t%0, %1, #%n2
-+ addw%?\\t%0, %1, %2
-+ addw%?\\t%0, %1, %2
-+ sub%?\\t%0, %1, #%n2
-+ sub%?\\t%0, %1, #%n2
-+ subw%?\\t%0, %1, #%n2
-+ subw%?\\t%0, %1, #%n2
- #"
- "TARGET_32BIT
- && GET_CODE (operands[2]) == CONST_INT
-- && !(const_ok_for_arm (INTVAL (operands[2]))
-- || const_ok_for_arm (-INTVAL (operands[2])))
-+ && !const_ok_for_op (INTVAL (operands[2]), PLUS)
- && (reload_completed || !arm_eliminable_register (operands[1]))"
- [(clobber (const_int 0))]
- "
-@@ -724,8 +727,9 @@
- operands[1], 0);
- DONE;
- "
-- [(set_attr "length" "4,4,4,4,4,16")
-- (set_attr "predicable" "yes")]
-+ [(set_attr "length" "4,4,4,4,4,4,4,4,4,16")
-+ (set_attr "predicable" "yes")
-+ (set_attr "arch" "*,*,*,t2,t2,*,*,t2,t2,*")]
- )
-
- (define_insn_and_split "*thumb1_addsi3"
-
-=== modified file 'gcc/config/arm/constraints.md'
---- old/gcc/config/arm/constraints.md 2011-01-03 20:52:22 +0000
-+++ new/gcc/config/arm/constraints.md 2011-08-25 13:26:58 +0000
-@@ -31,7 +31,7 @@
- ;; The following multi-letter normal constraints have been used:
- ;; in ARM/Thumb-2 state: Da, Db, Dc, Dn, Dl, DL, Dv, Dy, Di, Dz
- ;; in Thumb-1 state: Pa, Pb, Pc, Pd
--;; in Thumb-2 state: Ps, Pt, Pu, Pv, Pw, Px
-+;; in Thumb-2 state: Pj, PJ, Ps, Pt, Pu, Pv, Pw, Px
-
- ;; The following memory constraints have been used:
- ;; in ARM/Thumb-2 state: Q, Ut, Uv, Uy, Un, Um, Us
-@@ -74,6 +74,18 @@
- (and (match_code "const_int")
- (match_test "(ival & 0xffff0000) == 0")))))
-
-+(define_constraint "Pj"
-+ "@internal A 12-bit constant suitable for an ADDW or SUBW instruction. (Thumb-2)"
-+ (and (match_code "const_int")
-+ (and (match_test "TARGET_THUMB2")
-+ (match_test "(ival & 0xfffff000) == 0"))))
-+
-+(define_constraint "PJ"
-+ "@internal A constant that satisfies the Pj constrant if negated."
-+ (and (match_code "const_int")
-+ (and (match_test "TARGET_THUMB2")
-+ (match_test "((-ival) & 0xfffff000) == 0"))))
-+
- (define_register_constraint "k" "STACK_REG"
- "@internal The stack register.")
-
-
-=== added file 'gcc/testsuite/gcc.target/arm/thumb2-replicated-constant1.c'
---- old/gcc/testsuite/gcc.target/arm/thumb2-replicated-constant1.c 1970-01-01 00:00:00 +0000
-+++ new/gcc/testsuite/gcc.target/arm/thumb2-replicated-constant1.c 2011-08-25 13:31:00 +0000
-@@ -0,0 +1,27 @@
-+/* Ensure simple replicated constant immediates work. */
-+/* { dg-options "-mthumb -O2" } */
-+/* { dg-require-effective-target arm_thumb2_ok } */
-+
-+int
-+foo1 (int a)
-+{
-+ return a + 0xfefefefe;
-+}
-+
-+/* { dg-final { scan-assembler "add.*#-16843010" } } */
-+
-+int
-+foo2 (int a)
-+{
-+ return a - 0xab00ab00;
-+}
-+
-+/* { dg-final { scan-assembler "sub.*#-1426019584" } } */
-+
-+int
-+foo3 (int a)
-+{
-+ return a & 0x00cd00cd;
-+}
-+
-+/* { dg-final { scan-assembler "and.*#13435085" } } */
-
-=== added file 'gcc/testsuite/gcc.target/arm/thumb2-replicated-constant2.c'
---- old/gcc/testsuite/gcc.target/arm/thumb2-replicated-constant2.c 1970-01-01 00:00:00 +0000
-+++ new/gcc/testsuite/gcc.target/arm/thumb2-replicated-constant2.c 2011-08-25 13:31:00 +0000
-@@ -0,0 +1,75 @@
-+/* Ensure split constants can use replicated patterns. */
-+/* { dg-options "-mthumb -O2" } */
-+/* { dg-require-effective-target arm_thumb2_ok } */
-+
-+int
-+foo1 (int a)
-+{
-+ return a + 0xfe00fe01;
-+}
-+
-+/* { dg-final { scan-assembler "add.*#-33489408" } } */
-+/* { dg-final { scan-assembler "add.*#1" } } */
-+
-+int
-+foo2 (int a)
-+{
-+ return a + 0xdd01dd00;
-+}
-+
-+/* { dg-final { scan-assembler "add.*#-587145984" } } */
-+/* { dg-final { scan-assembler "add.*#65536" } } */
-+
-+int
-+foo3 (int a)
-+{
-+ return a + 0x00443344;
-+}
-+
-+/* { dg-final { scan-assembler "add.*#4456516" } } */
-+/* { dg-final { scan-assembler "add.*#13056" } } */
-+
-+int
-+foo4 (int a)
-+{
-+ return a + 0x77330033;
-+}
-+
-+/* { dg-final { scan-assembler "add.*#1996488704" } } */
-+/* { dg-final { scan-assembler "add.*#3342387" } } */
-+
-+int
-+foo5 (int a)
-+{
-+ return a + 0x11221122;
-+}
-+
-+/* { dg-final { scan-assembler "add.*#285217024" } } */
-+/* { dg-final { scan-assembler "add.*#2228258" } } */
-+
-+int
-+foo6 (int a)
-+{
-+ return a + 0x66666677;
-+}
-+
-+/* { dg-final { scan-assembler "add.*#1717986918" } } */
-+/* { dg-final { scan-assembler "add.*#17" } } */
-+
-+int
-+foo7 (int a)
-+{
-+ return a + 0x99888888;
-+}
-+
-+/* { dg-final { scan-assembler "add.*#-2004318072" } } */
-+/* { dg-final { scan-assembler "add.*#285212672" } } */
-+
-+int
-+foo8 (int a)
-+{
-+ return a + 0xdddddfff;
-+}
-+
-+/* { dg-final { scan-assembler "add.*#-572662307" } } */
-+/* { dg-final { scan-assembler "addw.*#546" } } */
-
-=== added file 'gcc/testsuite/gcc.target/arm/thumb2-replicated-constant3.c'
---- old/gcc/testsuite/gcc.target/arm/thumb2-replicated-constant3.c 1970-01-01 00:00:00 +0000
-+++ new/gcc/testsuite/gcc.target/arm/thumb2-replicated-constant3.c 2011-08-25 13:31:00 +0000
-@@ -0,0 +1,28 @@
-+/* Ensure negated/inverted replicated constant immediates work. */
-+/* { dg-options "-mthumb -O2" } */
-+/* { dg-require-effective-target arm_thumb2_ok } */
-+
-+int
-+foo1 (int a)
-+{
-+ return a | 0xffffff00;
-+}
-+
-+/* { dg-final { scan-assembler "orn.*#255" } } */
-+
-+int
-+foo2 (int a)
-+{
-+ return a & 0xffeeffee;
-+}
-+
-+/* { dg-final { scan-assembler "bic.*#1114129" } } */
-+
-+int
-+foo3 (int a)
-+{
-+ return a & 0xaaaaaa00;
-+}
-+
-+/* { dg-final { scan-assembler "and.*#-1431655766" } } */
-+/* { dg-final { scan-assembler "bic.*#170" } } */
-
-=== added file 'gcc/testsuite/gcc.target/arm/thumb2-replicated-constant4.c'
---- old/gcc/testsuite/gcc.target/arm/thumb2-replicated-constant4.c 1970-01-01 00:00:00 +0000
-+++ new/gcc/testsuite/gcc.target/arm/thumb2-replicated-constant4.c 2011-08-25 13:31:00 +0000
-@@ -0,0 +1,22 @@
-+/* Ensure replicated constants don't make things worse. */
-+/* { dg-options "-mthumb -O2" } */
-+/* { dg-require-effective-target arm_thumb2_ok } */
-+
-+int
-+foo1 (int a)
-+{
-+ /* It might be tempting to use 0x01000100, but it wouldn't help. */
-+ return a + 0x01f001e0;
-+}
-+
-+/* { dg-final { scan-assembler "add.*#32505856" } } */
-+/* { dg-final { scan-assembler "add.*#480" } } */
-+
-+int
-+foo2 (int a)
-+{
-+ return a + 0x0f100e10;
-+}
-+
-+/* { dg-final { scan-assembler "add.*#252706816" } } */
-+/* { dg-final { scan-assembler "add.*#3600" } } */
-