[oe] [PATCH] gcc-4.5.inc: Revert PR 42172 backport
Eric Bénard
eric at eukrea.com
Tue Dec 14 07:08:30 UTC 2010
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 at gmail.com>
Acked-by: Eric Bénard <eric at 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 } } */
More information about the Openembedded-devel
mailing list