* [PATCH] gcc-4.5.inc: Revert PR 42172 backport
@ 2010-12-14 0:01 Khem Raj
2010-12-14 7:08 ` Eric Bénard
2010-12-14 12:39 ` Martin Jansa
0 siblings, 2 replies; 3+ messages in thread
From: Khem Raj @ 2010-12-14 0:01 UTC (permalink / raw)
To: openembedded-devel
* This fixes the gcc ICE as seen compiling samba
Signed-off-by: Khem Raj <raj.khem@gmail.com>
---
recipes/gcc/gcc-4.5.inc | 3 +-
recipes/gcc/gcc-4.5/gcc-revert-pr42172.patch | 989 ++++++++++++++++++++++++++
2 files changed, 991 insertions(+), 1 deletions(-)
create mode 100644 recipes/gcc/gcc-4.5/gcc-revert-pr42172.patch
diff --git a/recipes/gcc/gcc-4.5.inc b/recipes/gcc/gcc-4.5.inc
index df462e0..1116331 100644
--- a/recipes/gcc/gcc-4.5.inc
+++ b/recipes/gcc/gcc-4.5.inc
@@ -8,7 +8,7 @@ DEPENDS = "mpfr gmp libmpc libelf"
NATIVEDEPS = "mpfr-native gmp-native libmpc-native"
-INC_PR = "r24"
+INC_PR = "r25"
SRCREV = "167449"
PV = "4.5"
@@ -137,6 +137,7 @@ SRC_URI = "svn://gcc.gnu.org/svn/gcc/branches;module=${BRANCH} \
file://linaro/gcc-4.5-linaro-r99419.patch \
file://linaro/gcc-4.5-linaro-r99420.patch \
file://gcc-scalar-widening-pr45847.patch \
+ file://gcc-revert-pr42172.patch \
"
SRC_URI_append_mips64 = " file://mips64-nomultilib.patch "
diff --git a/recipes/gcc/gcc-4.5/gcc-revert-pr42172.patch b/recipes/gcc/gcc-4.5/gcc-revert-pr42172.patch
new file mode 100644
index 0000000..c49cdf1
--- /dev/null
+++ b/recipes/gcc/gcc-4.5/gcc-revert-pr42172.patch
@@ -0,0 +1,989 @@
+This reverts the fix for pr 42172
+http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42172
+It causes regression in samba compilation for arches below armv7
+-Khem
+
+Index: gcc-4_5-branch/gcc/config/arm/arm.c
+===================================================================
+--- gcc-4_5-branch.orig/gcc/config/arm/arm.c
++++ gcc-4_5-branch/gcc/config/arm/arm.c
+@@ -6420,7 +6420,6 @@ static inline int
+ thumb1_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer)
+ {
+ enum machine_mode mode = GET_MODE (x);
+- int total;
+
+ switch (code)
+ {
+@@ -6523,20 +6522,24 @@ thumb1_rtx_costs (rtx x, enum rtx_code c
+ return 14;
+ return 2;
+
+- case SIGN_EXTEND:
+ case ZERO_EXTEND:
+- 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;
++ /* 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));
+
+- if (arm_arch6)
+- return total + COSTS_N_INSNS (1);
++ case SImode:
++ return (1 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
+
+- /* 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;
++ }
+
+ default:
+ return 99;
+@@ -7020,39 +7023,44 @@ arm_rtx_costs_1 (rtx x, enum rtx_code ou
+ 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 (opmode != SImode)
++ if (GET_MODE (XEXP (x, 0)) != SImode)
+ {
+- if (MEM_P (op))
++ if (arm_arch6)
+ {
+- /* 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);
++ if (GET_CODE (XEXP (x, 0)) != MEM)
++ *total += COSTS_N_INSNS (1);
+ }
+- 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;
++ else if (!arm_arch4 || GET_CODE (XEXP (x, 0)) != MEM)
++ *total += COSTS_N_INSNS (GET_MODE (XEXP (x, 0)) == QImode ?
++ 1 : 2);
+ }
+
+ return false;
+@@ -7302,8 +7310,41 @@ arm_size_rtx_costs (rtx x, enum rtx_code
+ 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:
+- return arm_rtx_costs_1 (x, outer_code, total, 0);
++ *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;
+
+ case CONST_INT:
+ if (const_ok_for_arm (INTVAL (x)))
+Index: gcc-4_5-branch/gcc/config/arm/arm.md
+===================================================================
+--- gcc-4_5-branch.orig/gcc/config/arm/arm.md
++++ gcc-4_5-branch/gcc/config/arm/arm.md
+@@ -156,9 +156,6 @@
+ ; 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))
+@@ -4094,46 +4091,92 @@
+ )
+
+ (define_expand "zero_extendhisi2"
+- [(set (match_operand:SI 0 "s_register_operand" "")
+- (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
++ [(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)))]
+ "TARGET_EITHER"
+-{
+- 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]))
++ "
++ {
++ 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);
++ }"
++)
++
++(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 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;
++ 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\";
+ }
+-})
+
+-(define_split
+- [(set (match_operand:SI 0 "register_operand" "")
+- (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
+- "!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]);
+-})
++ return \"ldrh\\t%0, %1\";
++ "
++ [(set_attr "length" "4")
++ (set_attr "type" "load_byte")
++ (set_attr "pool_range" "60")]
++)
+
+-(define_insn "*thumb1_zero_extendhisi2"
++(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"
++ "TARGET_THUMB1 && arm_arch6"
+ "*
+ rtx mem;
+
+- if (which_alternative == 0 && arm_arch6)
+- return \"uxth\\t%0, %1\";
+ if (which_alternative == 0)
+- return \"#\";
++ return \"uxth\\t%0, %1\";
+
+ mem = XEXP (operands[1], 0);
+
+@@ -4167,25 +4210,20 @@
+
+ return \"ldrh\\t%0, %1\";
+ "
+- [(set_attr_alternative "length"
+- [(if_then_else (eq_attr "is_arch6" "yes")
+- (const_int 2) (const_int 4))
+- (const_int 4)])
++ [(set_attr "length" "2,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,r")
+- (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
++ [(set (match_operand:SI 0 "s_register_operand" "=r")
++ (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
+ "TARGET_ARM && arm_arch4 && !arm_arch6"
+- "@
+- #
+- ldr%(h%)\\t%0, %1"
+- [(set_attr "type" "alu_shift,load_byte")
++ "ldr%(h%)\\t%0, %1"
++ [(set_attr "type" "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"
+@@ -4215,49 +4253,50 @@
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
+ "TARGET_EITHER"
+-{
+- 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]))
++ "
++ if (!arm_arch6 && GET_CODE (operands[1]) != MEM)
+ {
+- 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;
+- }
+-})
++ 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];
+
+-(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)));
++ 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;
+ }
+-})
++ "
++)
+
+ (define_insn "*thumb1_zero_extendqisi2"
+- [(set (match_operand:SI 0 "register_operand" "=l,l")
+- (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
++ [(set (match_operand:SI 0 "register_operand" "=l")
++ (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
+ "TARGET_THUMB1 && !arm_arch6"
+- "@
+- #
+- ldrb\\t%0, %1"
+- [(set_attr "length" "4,2")
+- (set_attr "type" "alu_shift,load_byte")
+- (set_attr "pool_range" "*,32")]
++ "ldrb\\t%0, %1"
++ [(set_attr "length" "2")
++ (set_attr "type" "load_byte")
++ (set_attr "pool_range" "32")]
+ )
+
+ (define_insn "*thumb1_zero_extendqisi2_v6"
+@@ -4273,17 +4312,14 @@
+ )
+
+ (define_insn "*arm_zero_extendqisi2"
+- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
+- (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
++ [(set (match_operand:SI 0 "s_register_operand" "=r")
++ (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
+ "TARGET_ARM && !arm_arch6"
+- "@
+- #
+- ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
+- [(set_attr "length" "8,4")
+- (set_attr "type" "alu_shift,load_byte")
++ "ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
++ [(set_attr "type" "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"
+@@ -4362,42 +4398,108 @@
+ )
+
+ (define_expand "extendhisi2"
+- [(set (match_operand:SI 0 "s_register_operand" "")
+- (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
++ [(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)))]
+ "TARGET_EITHER"
+-{
+- 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 (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 (!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;
+- }
+-})
++ if (TARGET_ARM && GET_CODE (operands[1]) == MEM)
++ {
++ emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
++ 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);
+-})
++ 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")]
++)
+
+ ;; We used to have an early-clobber on the scratch register here.
+ ;; However, there's a bug somewhere in reload which means that this
+@@ -4406,18 +4508,16 @@
+ ;; 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"
++(define_insn "*thumb1_extendhisi2_insn_v6"
+ [(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"
++ "TARGET_THUMB1 && arm_arch6"
+ "*
+ {
+ rtx ops[4];
+ rtx mem;
+
+- if (which_alternative == 0 && !arm_arch6)
+- return \"#\";
+ if (which_alternative == 0)
+ return \"sxth\\t%0, %1\";
+
+@@ -4465,10 +4565,7 @@
+ output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
+ return \"\";
+ }"
+- [(set_attr_alternative "length"
+- [(if_then_else (eq_attr "is_arch6" "yes")
+- (const_int 2) (const_int 4))
+- (const_int 4)])
++ [(set_attr "length" "2,4")
+ (set_attr "type" "alu_shift,load_byte")
+ (set_attr "pool_range" "*,1020")]
+ )
+@@ -4509,28 +4606,15 @@
+ }"
+ )
+
+-(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,r")
+- (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
++ [(set (match_operand:SI 0 "s_register_operand" "=r")
++ (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
+ "TARGET_ARM && arm_arch4 && !arm_arch6"
+- "@
+- #
+- ldr%(sh%)\\t%0, %1"
+- [(set_attr "length" "8,4")
+- (set_attr "type" "alu_shift,load_byte")
++ "ldr%(sh%)\\t%0, %1"
++ [(set_attr "type" "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
+@@ -4592,45 +4676,46 @@
+ )
+
+ (define_expand "extendqisi2"
+- [(set (match_operand:SI 0 "s_register_operand" "")
+- (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
++ [(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)))]
+ "TARGET_EITHER"
+-{
+- if (!arm_arch4 && MEM_P (operands[1]))
+- operands[1] = copy_to_mode_reg (QImode, operands[1]);
++ "
++ {
++ 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 (!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;
+- }
+-})
++ if (!s_register_operand (operands[1], QImode))
++ operands[1] = copy_to_mode_reg (QImode, operands[1]);
+
+-(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);
+-})
++ 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);
++ }"
++)
+
+ (define_insn "*arm_extendqisi"
+- [(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")))]
++ [(set (match_operand:SI 0 "s_register_operand" "=r")
++ (sign_extend:SI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
+ "TARGET_ARM && arm_arch4 && !arm_arch6"
+- "@
+- #
+- ldr%(sb%)\\t%0, %1"
+- [(set_attr "length" "8,4")
+- (set_attr "type" "alu_shift,load_byte")
++ "ldr%(sb%)\\t%0, %1"
++ [(set_attr "type" "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"
+@@ -4658,55 +4743,83 @@
+ (set_attr "predicable" "yes")]
+ )
+
+-(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);
++(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 (addr) == CONST)
+- addr = XEXP (addr, 0);
++ if (GET_CODE (mem) == CONST)
++ mem = XEXP (mem, 0);
+
+- if (GET_CODE (addr) == PLUS
+- && REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1)))
+- /* No split necessary. */
+- FAIL;
++ if (GET_CODE (mem) == LABEL_REF)
++ return \"ldr\\t%0, %1\";
+
+- if (GET_CODE (addr) == PLUS
+- && !REG_P (XEXP (addr, 0)) && !REG_P (XEXP (addr, 1)))
+- FAIL;
++ if (GET_CODE (mem) == PLUS
++ && GET_CODE (XEXP (mem, 0)) == LABEL_REF)
++ return \"ldr\\t%0, %1\";
+
+- 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 (which_alternative == 0)
++ return \"ldrsb\\t%0, %1\";
+
+- 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]);
+- }
++ ops[0] = operands[0];
+
+- operands[3] = change_address (operands[1], QImode, addr);
+-})
++ 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_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
+@@ -4729,32 +4842,83 @@
+ operands[4] = change_address (operands[4], QImode, addr);
+ })
+
+-(define_insn "thumb1_extendqisi2"
++(define_insn "*thumb1_extendqisi2_v6"
+ [(set (match_operand:SI 0 "register_operand" "=l,l,l")
+ (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,V,m")))]
+- "TARGET_THUMB1"
+-{
+- rtx addr;
++ "TARGET_THUMB1 && arm_arch6"
++ "*
++ {
++ rtx ops[3];
++ rtx mem;
+
+- if (which_alternative == 0 && arm_arch6)
+- return "sxtb\\t%0, %1";
+- if (which_alternative == 0)
+- return "#";
++ if (which_alternative == 0)
++ return \"sxtb\\t%0, %1\";
++
++ mem = XEXP (operands[1], 0);
+
+- 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";
++ 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\";
+
+- 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")]
++ 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")]
+ )
+
+ (define_expand "extendsfdf2"
+Index: gcc-4_5-branch/gcc/testsuite/gcc.target/arm/pr42172-1.c
+===================================================================
+--- gcc-4_5-branch.orig/gcc/testsuite/gcc.target/arm/pr42172-1.c
++++ /dev/null
+@@ -1,19 +0,0 @@
+-/* { 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 } } */
--
1.7.1
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH] gcc-4.5.inc: Revert PR 42172 backport
2010-12-14 0:01 [PATCH] gcc-4.5.inc: Revert PR 42172 backport Khem Raj
@ 2010-12-14 7:08 ` Eric Bénard
2010-12-14 12:39 ` Martin Jansa
1 sibling, 0 replies; 3+ messages in thread
From: Eric Bénard @ 2010-12-14 7:08 UTC (permalink / raw)
To: openembedded-devel
On 14/12/2010 01:01, Khem Raj wrote:
> * This fixes the gcc ICE as seen compiling samba
>
> Signed-off-by: Khem Raj<raj.khem@gmail.com>
Acked-by: Eric Bénard <eric@eukrea.com>
> ---
> recipes/gcc/gcc-4.5.inc | 3 +-
> recipes/gcc/gcc-4.5/gcc-revert-pr42172.patch | 989 ++++++++++++++++++++++++++
> 2 files changed, 991 insertions(+), 1 deletions(-)
> create mode 100644 recipes/gcc/gcc-4.5/gcc-revert-pr42172.patch
>
> diff --git a/recipes/gcc/gcc-4.5.inc b/recipes/gcc/gcc-4.5.inc
> index df462e0..1116331 100644
> --- a/recipes/gcc/gcc-4.5.inc
> +++ b/recipes/gcc/gcc-4.5.inc
> @@ -8,7 +8,7 @@ DEPENDS = "mpfr gmp libmpc libelf"
> NATIVEDEPS = "mpfr-native gmp-native libmpc-native"
>
>
> -INC_PR = "r24"
> +INC_PR = "r25"
>
> SRCREV = "167449"
> PV = "4.5"
> @@ -137,6 +137,7 @@ SRC_URI = "svn://gcc.gnu.org/svn/gcc/branches;module=${BRANCH} \
> file://linaro/gcc-4.5-linaro-r99419.patch \
> file://linaro/gcc-4.5-linaro-r99420.patch \
> file://gcc-scalar-widening-pr45847.patch \
> + file://gcc-revert-pr42172.patch \
> "
>
> SRC_URI_append_mips64 = " file://mips64-nomultilib.patch "
> diff --git a/recipes/gcc/gcc-4.5/gcc-revert-pr42172.patch b/recipes/gcc/gcc-4.5/gcc-revert-pr42172.patch
> new file mode 100644
> index 0000000..c49cdf1
> --- /dev/null
> +++ b/recipes/gcc/gcc-4.5/gcc-revert-pr42172.patch
> @@ -0,0 +1,989 @@
> +This reverts the fix for pr 42172
> +http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42172
> +It causes regression in samba compilation for arches below armv7
> +-Khem
> +
> +Index: gcc-4_5-branch/gcc/config/arm/arm.c
> +===================================================================
> +--- gcc-4_5-branch.orig/gcc/config/arm/arm.c
> ++++ gcc-4_5-branch/gcc/config/arm/arm.c
> +@@ -6420,7 +6420,6 @@ static inline int
> + thumb1_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer)
> + {
> + enum machine_mode mode = GET_MODE (x);
> +- int total;
> +
> + switch (code)
> + {
> +@@ -6523,20 +6522,24 @@ thumb1_rtx_costs (rtx x, enum rtx_code c
> + return 14;
> + return 2;
> +
> +- case SIGN_EXTEND:
> + case ZERO_EXTEND:
> +- 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;
> ++ /* 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));
> +
> +- if (arm_arch6)
> +- return total + COSTS_N_INSNS (1);
> ++ case SImode:
> ++ return (1 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
> +
> +- /* 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;
> ++ }
> +
> + default:
> + return 99;
> +@@ -7020,39 +7023,44 @@ arm_rtx_costs_1 (rtx x, enum rtx_code ou
> + 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 (opmode != SImode)
> ++ if (GET_MODE (XEXP (x, 0)) != SImode)
> + {
> +- if (MEM_P (op))
> ++ if (arm_arch6)
> + {
> +- /* 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);
> ++ if (GET_CODE (XEXP (x, 0)) != MEM)
> ++ *total += COSTS_N_INSNS (1);
> + }
> +- 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;
> ++ else if (!arm_arch4 || GET_CODE (XEXP (x, 0)) != MEM)
> ++ *total += COSTS_N_INSNS (GET_MODE (XEXP (x, 0)) == QImode ?
> ++ 1 : 2);
> + }
> +
> + return false;
> +@@ -7302,8 +7310,41 @@ arm_size_rtx_costs (rtx x, enum rtx_code
> + 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:
> +- return arm_rtx_costs_1 (x, outer_code, total, 0);
> ++ *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;
> +
> + case CONST_INT:
> + if (const_ok_for_arm (INTVAL (x)))
> +Index: gcc-4_5-branch/gcc/config/arm/arm.md
> +===================================================================
> +--- gcc-4_5-branch.orig/gcc/config/arm/arm.md
> ++++ gcc-4_5-branch/gcc/config/arm/arm.md
> +@@ -156,9 +156,6 @@
> + ; 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))
> +@@ -4094,46 +4091,92 @@
> + )
> +
> + (define_expand "zero_extendhisi2"
> +- [(set (match_operand:SI 0 "s_register_operand" "")
> +- (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
> ++ [(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)))]
> + "TARGET_EITHER"
> +-{
> +- 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]))
> ++ "
> ++ {
> ++ 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);
> ++ }"
> ++)
> ++
> ++(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 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;
> ++ 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\";
> + }
> +-})
> +
> +-(define_split
> +- [(set (match_operand:SI 0 "register_operand" "")
> +- (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
> +- "!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]);
> +-})
> ++ return \"ldrh\\t%0, %1\";
> ++ "
> ++ [(set_attr "length" "4")
> ++ (set_attr "type" "load_byte")
> ++ (set_attr "pool_range" "60")]
> ++)
> +
> +-(define_insn "*thumb1_zero_extendhisi2"
> ++(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"
> ++ "TARGET_THUMB1&& arm_arch6"
> + "*
> + rtx mem;
> +
> +- if (which_alternative == 0&& arm_arch6)
> +- return \"uxth\\t%0, %1\";
> + if (which_alternative == 0)
> +- return \"#\";
> ++ return \"uxth\\t%0, %1\";
> +
> + mem = XEXP (operands[1], 0);
> +
> +@@ -4167,25 +4210,20 @@
> +
> + return \"ldrh\\t%0, %1\";
> + "
> +- [(set_attr_alternative "length"
> +- [(if_then_else (eq_attr "is_arch6" "yes")
> +- (const_int 2) (const_int 4))
> +- (const_int 4)])
> ++ [(set_attr "length" "2,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,r")
> +- (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
> ++ [(set (match_operand:SI 0 "s_register_operand" "=r")
> ++ (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
> + "TARGET_ARM&& arm_arch4&& !arm_arch6"
> +- "@
> +- #
> +- ldr%(h%)\\t%0, %1"
> +- [(set_attr "type" "alu_shift,load_byte")
> ++ "ldr%(h%)\\t%0, %1"
> ++ [(set_attr "type" "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"
> +@@ -4215,49 +4253,50 @@
> + [(set (match_operand:SI 0 "s_register_operand" "")
> + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
> + "TARGET_EITHER"
> +-{
> +- 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]))
> ++ "
> ++ if (!arm_arch6&& GET_CODE (operands[1]) != MEM)
> + {
> +- 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;
> +- }
> +-})
> ++ 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];
> +
> +-(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)));
> ++ 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;
> + }
> +-})
> ++ "
> ++)
> +
> + (define_insn "*thumb1_zero_extendqisi2"
> +- [(set (match_operand:SI 0 "register_operand" "=l,l")
> +- (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
> ++ [(set (match_operand:SI 0 "register_operand" "=l")
> ++ (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
> + "TARGET_THUMB1&& !arm_arch6"
> +- "@
> +- #
> +- ldrb\\t%0, %1"
> +- [(set_attr "length" "4,2")
> +- (set_attr "type" "alu_shift,load_byte")
> +- (set_attr "pool_range" "*,32")]
> ++ "ldrb\\t%0, %1"
> ++ [(set_attr "length" "2")
> ++ (set_attr "type" "load_byte")
> ++ (set_attr "pool_range" "32")]
> + )
> +
> + (define_insn "*thumb1_zero_extendqisi2_v6"
> +@@ -4273,17 +4312,14 @@
> + )
> +
> + (define_insn "*arm_zero_extendqisi2"
> +- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
> +- (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
> ++ [(set (match_operand:SI 0 "s_register_operand" "=r")
> ++ (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
> + "TARGET_ARM&& !arm_arch6"
> +- "@
> +- #
> +- ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
> +- [(set_attr "length" "8,4")
> +- (set_attr "type" "alu_shift,load_byte")
> ++ "ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
> ++ [(set_attr "type" "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"
> +@@ -4362,42 +4398,108 @@
> + )
> +
> + (define_expand "extendhisi2"
> +- [(set (match_operand:SI 0 "s_register_operand" "")
> +- (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
> ++ [(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)))]
> + "TARGET_EITHER"
> +-{
> +- 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 (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 (!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;
> +- }
> +-})
> ++ if (TARGET_ARM&& GET_CODE (operands[1]) == MEM)
> ++ {
> ++ emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
> ++ 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);
> +-})
> ++ 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")]
> ++)
> +
> + ;; We used to have an early-clobber on the scratch register here.
> + ;; However, there's a bug somewhere in reload which means that this
> +@@ -4406,18 +4508,16 @@
> + ;; 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"
> ++(define_insn "*thumb1_extendhisi2_insn_v6"
> + [(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"
> ++ "TARGET_THUMB1&& arm_arch6"
> + "*
> + {
> + rtx ops[4];
> + rtx mem;
> +
> +- if (which_alternative == 0&& !arm_arch6)
> +- return \"#\";
> + if (which_alternative == 0)
> + return \"sxth\\t%0, %1\";
> +
> +@@ -4465,10 +4565,7 @@
> + output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
> + return \"\";
> + }"
> +- [(set_attr_alternative "length"
> +- [(if_then_else (eq_attr "is_arch6" "yes")
> +- (const_int 2) (const_int 4))
> +- (const_int 4)])
> ++ [(set_attr "length" "2,4")
> + (set_attr "type" "alu_shift,load_byte")
> + (set_attr "pool_range" "*,1020")]
> + )
> +@@ -4509,28 +4606,15 @@
> + }"
> + )
> +
> +-(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,r")
> +- (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
> ++ [(set (match_operand:SI 0 "s_register_operand" "=r")
> ++ (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
> + "TARGET_ARM&& arm_arch4&& !arm_arch6"
> +- "@
> +- #
> +- ldr%(sh%)\\t%0, %1"
> +- [(set_attr "length" "8,4")
> +- (set_attr "type" "alu_shift,load_byte")
> ++ "ldr%(sh%)\\t%0, %1"
> ++ [(set_attr "type" "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
> +@@ -4592,45 +4676,46 @@
> + )
> +
> + (define_expand "extendqisi2"
> +- [(set (match_operand:SI 0 "s_register_operand" "")
> +- (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
> ++ [(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)))]
> + "TARGET_EITHER"
> +-{
> +- if (!arm_arch4&& MEM_P (operands[1]))
> +- operands[1] = copy_to_mode_reg (QImode, operands[1]);
> ++ "
> ++ {
> ++ 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 (!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;
> +- }
> +-})
> ++ if (!s_register_operand (operands[1], QImode))
> ++ operands[1] = copy_to_mode_reg (QImode, operands[1]);
> +
> +-(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);
> +-})
> ++ 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);
> ++ }"
> ++)
> +
> + (define_insn "*arm_extendqisi"
> +- [(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")))]
> ++ [(set (match_operand:SI 0 "s_register_operand" "=r")
> ++ (sign_extend:SI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
> + "TARGET_ARM&& arm_arch4&& !arm_arch6"
> +- "@
> +- #
> +- ldr%(sb%)\\t%0, %1"
> +- [(set_attr "length" "8,4")
> +- (set_attr "type" "alu_shift,load_byte")
> ++ "ldr%(sb%)\\t%0, %1"
> ++ [(set_attr "type" "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"
> +@@ -4658,55 +4743,83 @@
> + (set_attr "predicable" "yes")]
> + )
> +
> +-(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);
> ++(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 (addr) == CONST)
> +- addr = XEXP (addr, 0);
> ++ if (GET_CODE (mem) == CONST)
> ++ mem = XEXP (mem, 0);
> +
> +- if (GET_CODE (addr) == PLUS
> +-&& REG_P (XEXP (addr, 0))&& REG_P (XEXP (addr, 1)))
> +- /* No split necessary. */
> +- FAIL;
> ++ if (GET_CODE (mem) == LABEL_REF)
> ++ return \"ldr\\t%0, %1\";
> +
> +- if (GET_CODE (addr) == PLUS
> +-&& !REG_P (XEXP (addr, 0))&& !REG_P (XEXP (addr, 1)))
> +- FAIL;
> ++ if (GET_CODE (mem) == PLUS
> ++&& GET_CODE (XEXP (mem, 0)) == LABEL_REF)
> ++ return \"ldr\\t%0, %1\";
> +
> +- 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 (which_alternative == 0)
> ++ return \"ldrsb\\t%0, %1\";
> +
> +- 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]);
> +- }
> ++ ops[0] = operands[0];
> +
> +- operands[3] = change_address (operands[1], QImode, addr);
> +-})
> ++ 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_peephole2
> + [(set (match_operand:SI 0 "register_operand" "")
> +@@ -4729,32 +4842,83 @@
> + operands[4] = change_address (operands[4], QImode, addr);
> + })
> +
> +-(define_insn "thumb1_extendqisi2"
> ++(define_insn "*thumb1_extendqisi2_v6"
> + [(set (match_operand:SI 0 "register_operand" "=l,l,l")
> + (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,V,m")))]
> +- "TARGET_THUMB1"
> +-{
> +- rtx addr;
> ++ "TARGET_THUMB1&& arm_arch6"
> ++ "*
> ++ {
> ++ rtx ops[3];
> ++ rtx mem;
> +
> +- if (which_alternative == 0&& arm_arch6)
> +- return "sxtb\\t%0, %1";
> +- if (which_alternative == 0)
> +- return "#";
> ++ if (which_alternative == 0)
> ++ return \"sxtb\\t%0, %1\";
> ++
> ++ mem = XEXP (operands[1], 0);
> +
> +- 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";
> ++ 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\";
> +
> +- 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")]
> ++ 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")]
> + )
> +
> + (define_expand "extendsfdf2"
> +Index: gcc-4_5-branch/gcc/testsuite/gcc.target/arm/pr42172-1.c
> +===================================================================
> +--- gcc-4_5-branch.orig/gcc/testsuite/gcc.target/arm/pr42172-1.c
> ++++ /dev/null
> +@@ -1,19 +0,0 @@
> +-/* { 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 } } */
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] gcc-4.5.inc: Revert PR 42172 backport
2010-12-14 0:01 [PATCH] gcc-4.5.inc: Revert PR 42172 backport Khem Raj
2010-12-14 7:08 ` Eric Bénard
@ 2010-12-14 12:39 ` Martin Jansa
1 sibling, 0 replies; 3+ messages in thread
From: Martin Jansa @ 2010-12-14 12:39 UTC (permalink / raw)
To: openembedded-devel
On Mon, Dec 13, 2010 at 04:01:19PM -0800, Khem Raj wrote:
> * This fixes the gcc ICE as seen compiling samba
>
> Signed-off-by: Khem Raj <raj.khem@gmail.com>
I can confirm that with this and your other samba patch it
compiles now fine on armv4t (om-gta02), Thanks
--
Martin 'JaMa' Jansa jabber: Martin.Jansa@gmail.com
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2010-12-14 12:40 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-12-14 0:01 [PATCH] gcc-4.5.inc: Revert PR 42172 backport Khem Raj
2010-12-14 7:08 ` Eric Bénard
2010-12-14 12:39 ` Martin Jansa
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.