mirror of git://gcc.gnu.org/git/gcc.git
arm.c (arm_legitimate_index_p): Limit iWMMXt addressing modes to LDRD for DImode.
2007-03-01 Paul Brook <paul@codesourcery.com> * config/arm/arm.c (arm_legitimate_index_p): Limit iWMMXt addressing modes to LDRD for DImode. (output_move_double): Fixup out of range ldrd/strd. (vfp_secondary_reload_class): Rename... (coproc_secondary_reload_class): ... to this. Add wb argument. * config/arm/arm.h (SECONDARY_OUTPUT_RELOAD_CLASS): Use coproc_secondary_reload_class for CLASS_IWMMXT. (SECONDARY_INPUT_RELOAD_CLASS): Ditto. * arm-protos.h (coproc_secondary_reload_class): Update prototype. From-SVN: r122437
This commit is contained in:
parent
2711355fbc
commit
fe2d934b4b
|
@ -1,3 +1,15 @@
|
||||||
|
2007-03-01 Paul Brook <paul@codesourcery.com>
|
||||||
|
|
||||||
|
* config/arm/arm.c (arm_legitimate_index_p): Limit iWMMXt addressing
|
||||||
|
modes to LDRD for DImode.
|
||||||
|
(output_move_double): Fixup out of range ldrd/strd.
|
||||||
|
(vfp_secondary_reload_class): Rename...
|
||||||
|
(coproc_secondary_reload_class): ... to this. Add wb argument.
|
||||||
|
* config/arm/arm.h (SECONDARY_OUTPUT_RELOAD_CLASS): Use
|
||||||
|
coproc_secondary_reload_class for CLASS_IWMMXT.
|
||||||
|
(SECONDARY_INPUT_RELOAD_CLASS): Ditto.
|
||||||
|
* arm-protos.h (coproc_secondary_reload_class): Update prototype.
|
||||||
|
|
||||||
2007-03-01 Zdenek Dvorak <dvorakz@suse.cz>
|
2007-03-01 Zdenek Dvorak <dvorakz@suse.cz>
|
||||||
|
|
||||||
* tree-ssa-loop-prefetch.c (determine_unroll_factor): Bound the unroll
|
* tree-ssa-loop-prefetch.c (determine_unroll_factor): Bound the unroll
|
||||||
|
|
|
@ -68,7 +68,8 @@ extern rtx thumb_legitimize_reload_address (rtx *, enum machine_mode, int, int,
|
||||||
int);
|
int);
|
||||||
extern int arm_const_double_rtx (rtx);
|
extern int arm_const_double_rtx (rtx);
|
||||||
extern int neg_const_double_rtx_ok_for_fpa (rtx);
|
extern int neg_const_double_rtx_ok_for_fpa (rtx);
|
||||||
extern enum reg_class vfp_secondary_reload_class (enum machine_mode, rtx);
|
extern enum reg_class coproc_secondary_reload_class (enum machine_mode, rtx,
|
||||||
|
bool);
|
||||||
extern bool arm_tls_referenced_p (rtx);
|
extern bool arm_tls_referenced_p (rtx);
|
||||||
|
|
||||||
extern int cirrus_memory_offset (rtx);
|
extern int cirrus_memory_offset (rtx);
|
||||||
|
|
|
@ -3922,10 +3922,15 @@ thumb2_legitimate_index_p (enum machine_mode mode, rtx index, int strict_p)
|
||||||
&& (INTVAL (index) & 3) == 0);
|
&& (INTVAL (index) & 3) == 0);
|
||||||
|
|
||||||
if (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (mode))
|
if (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (mode))
|
||||||
return (code == CONST_INT
|
{
|
||||||
&& INTVAL (index) < 1024
|
/* For DImode assume values will usually live in core regs
|
||||||
&& INTVAL (index) > -1024
|
and only allow LDRD addressing modes. */
|
||||||
&& (INTVAL (index) & 3) == 0);
|
if (!TARGET_LDRD || mode != DImode)
|
||||||
|
return (code == CONST_INT
|
||||||
|
&& INTVAL (index) < 1024
|
||||||
|
&& INTVAL (index) > -1024
|
||||||
|
&& (INTVAL (index) & 3) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (arm_address_register_rtx_p (index, strict_p)
|
if (arm_address_register_rtx_p (index, strict_p)
|
||||||
&& (GET_MODE_SIZE (mode) <= 4))
|
&& (GET_MODE_SIZE (mode) <= 4))
|
||||||
|
@ -5764,12 +5769,12 @@ arm_eliminable_register (rtx x)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return GENERAL_REGS if a scratch register required to reload x to/from
|
/* Return GENERAL_REGS if a scratch register required to reload x to/from
|
||||||
VFP registers. Otherwise return NO_REGS. */
|
coprocessor registers. Otherwise return NO_REGS. */
|
||||||
|
|
||||||
enum reg_class
|
enum reg_class
|
||||||
vfp_secondary_reload_class (enum machine_mode mode, rtx x)
|
coproc_secondary_reload_class (enum machine_mode mode, rtx x, bool wb)
|
||||||
{
|
{
|
||||||
if (arm_coproc_mem_operand (x, FALSE) || s_register_operand (x, mode))
|
if (arm_coproc_mem_operand (x, wb) || s_register_operand (x, mode))
|
||||||
return NO_REGS;
|
return NO_REGS;
|
||||||
|
|
||||||
return GENERAL_REGS;
|
return GENERAL_REGS;
|
||||||
|
@ -9146,12 +9151,37 @@ output_move_double (rtx *operands)
|
||||||
output_asm_insn ("ldr%(d%)\t%0, [%1] @split", otherops);
|
output_asm_insn ("ldr%(d%)\t%0, [%1] @split", otherops);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
output_asm_insn ("ldr%(d%)\t%0, [%1, %2]!", otherops);
|
{
|
||||||
|
/* IWMMXT allows offsets larger than ldrd can handle,
|
||||||
|
fix these up with a pair of ldr. */
|
||||||
|
if (GET_CODE (otherops[2]) == CONST_INT
|
||||||
|
&& (INTVAL(otherops[2]) <= -256
|
||||||
|
|| INTVAL(otherops[2]) >= 256))
|
||||||
|
{
|
||||||
|
output_asm_insn ("ldr%?\t%0, [%1, %2]!", otherops);
|
||||||
|
otherops[0] = gen_rtx_REG (SImode, 1 + reg0);
|
||||||
|
output_asm_insn ("ldr%?\t%0, [%1, #4]", otherops);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
output_asm_insn ("ldr%(d%)\t%0, [%1, %2]!", otherops);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* We only allow constant increments, so this is safe. */
|
/* IWMMXT allows offsets larger than ldrd can handle,
|
||||||
output_asm_insn ("ldr%(d%)\t%0, [%1], %2", otherops);
|
fix these up with a pair of ldr. */
|
||||||
|
if (GET_CODE (otherops[2]) == CONST_INT
|
||||||
|
&& (INTVAL(otherops[2]) <= -256
|
||||||
|
|| INTVAL(otherops[2]) >= 256))
|
||||||
|
{
|
||||||
|
otherops[0] = gen_rtx_REG (SImode, 1 + reg0);
|
||||||
|
output_asm_insn ("ldr%?\t%0, [%1, #4]", otherops);
|
||||||
|
otherops[0] = operands[0];
|
||||||
|
output_asm_insn ("ldr%?\t%0, [%1], %2", otherops);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* We only allow constant increments, so this is safe. */
|
||||||
|
output_asm_insn ("ldr%(d%)\t%0, [%1], %2", otherops);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -9289,7 +9319,29 @@ output_move_double (rtx *operands)
|
||||||
otherops[1] = XEXP (XEXP (XEXP (operands[0], 0), 1), 0);
|
otherops[1] = XEXP (XEXP (XEXP (operands[0], 0), 1), 0);
|
||||||
otherops[2] = XEXP (XEXP (XEXP (operands[0], 0), 1), 1);
|
otherops[2] = XEXP (XEXP (XEXP (operands[0], 0), 1), 1);
|
||||||
|
|
||||||
if (GET_CODE (XEXP (operands[0], 0)) == PRE_MODIFY)
|
/* IWMMXT allows offsets larger than ldrd can handle,
|
||||||
|
fix these up with a pair of ldr. */
|
||||||
|
if (GET_CODE (otherops[2]) == CONST_INT
|
||||||
|
&& (INTVAL(otherops[2]) <= -256
|
||||||
|
|| INTVAL(otherops[2]) >= 256))
|
||||||
|
{
|
||||||
|
rtx reg1;
|
||||||
|
reg1 = gen_rtx_REG (SImode, 1 + REGNO (operands[1]));
|
||||||
|
if (GET_CODE (XEXP (operands[0], 0)) == PRE_MODIFY)
|
||||||
|
{
|
||||||
|
output_asm_insn ("ldr%?\t%0, [%1, %2]!", otherops);
|
||||||
|
otherops[0] = reg1;
|
||||||
|
output_asm_insn ("ldr%?\t%0, [%1, #4]", otherops);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
otherops[0] = reg1;
|
||||||
|
output_asm_insn ("ldr%?\t%0, [%1, #4]", otherops);
|
||||||
|
otherops[0] = operands[1];
|
||||||
|
output_asm_insn ("ldr%?\t%0, [%1], %2", otherops);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (GET_CODE (XEXP (operands[0], 0)) == PRE_MODIFY)
|
||||||
output_asm_insn ("str%(d%)\t%0, [%1, %2]!", otherops);
|
output_asm_insn ("str%(d%)\t%0, [%1, %2]!", otherops);
|
||||||
else
|
else
|
||||||
output_asm_insn ("str%(d%)\t%0, [%1], %2", otherops);
|
output_asm_insn ("str%(d%)\t%0, [%1], %2", otherops);
|
||||||
|
|
|
@ -1121,10 +1121,12 @@ enum reg_class
|
||||||
or out of a register in CLASS in MODE. If it can be done directly,
|
or out of a register in CLASS in MODE. If it can be done directly,
|
||||||
NO_REGS is returned. */
|
NO_REGS is returned. */
|
||||||
#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \
|
#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \
|
||||||
/* Restrict which direct reloads are allowed for VFP regs. */ \
|
/* Restrict which direct reloads are allowed for VFP/iWMMXt regs. */ \
|
||||||
((TARGET_VFP && TARGET_HARD_FLOAT \
|
((TARGET_VFP && TARGET_HARD_FLOAT \
|
||||||
&& (CLASS) == VFP_REGS) \
|
&& (CLASS) == VFP_REGS) \
|
||||||
? vfp_secondary_reload_class (MODE, X) \
|
? coproc_secondary_reload_class (MODE, X, FALSE) \
|
||||||
|
: (TARGET_IWMMXT && (CLASS) == IWMMXT_REGS) \
|
||||||
|
? coproc_secondary_reload_class (MODE, X, TRUE) \
|
||||||
: TARGET_32BIT \
|
: TARGET_32BIT \
|
||||||
? (((MODE) == HImode && ! arm_arch4 && true_regnum (X) == -1) \
|
? (((MODE) == HImode && ! arm_arch4 && true_regnum (X) == -1) \
|
||||||
? GENERAL_REGS : NO_REGS) \
|
? GENERAL_REGS : NO_REGS) \
|
||||||
|
@ -1132,10 +1134,12 @@ enum reg_class
|
||||||
|
|
||||||
/* If we need to load shorts byte-at-a-time, then we need a scratch. */
|
/* If we need to load shorts byte-at-a-time, then we need a scratch. */
|
||||||
#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \
|
#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \
|
||||||
/* Restrict which direct reloads are allowed for VFP regs. */ \
|
/* Restrict which direct reloads are allowed for VFP/iWMMXt regs. */ \
|
||||||
((TARGET_VFP && TARGET_HARD_FLOAT \
|
((TARGET_VFP && TARGET_HARD_FLOAT \
|
||||||
&& (CLASS) == VFP_REGS) \
|
&& (CLASS) == VFP_REGS) \
|
||||||
? vfp_secondary_reload_class (MODE, X) : \
|
? coproc_secondary_reload_class (MODE, X, FALSE) : \
|
||||||
|
(TARGET_IWMMXT && (CLASS) == IWMMXT_REGS) ? \
|
||||||
|
coproc_secondary_reload_class (MODE, X, TRUE) : \
|
||||||
/* Cannot load constants into Cirrus registers. */ \
|
/* Cannot load constants into Cirrus registers. */ \
|
||||||
(TARGET_MAVERICK && TARGET_HARD_FLOAT \
|
(TARGET_MAVERICK && TARGET_HARD_FLOAT \
|
||||||
&& (CLASS) == CIRRUS_REGS \
|
&& (CLASS) == CIRRUS_REGS \
|
||||||
|
|
Loading…
Reference in New Issue