arm.c (arm_legitimize_reload_address): New.

* config/arm/arm.c (arm_legitimize_reload_address): New.
	* config/arm/arm.h (ARM_LEGITIMIZE_RELOAD_ADDRESS): Use
	arm_legitimize_reload_address.
	* config/arm/arm-protos.h (arm_legitimize_reload_address):
	Declare.

From-SVN: r169386
This commit is contained in:
Jie Zhang 2011-01-29 03:20:57 +00:00 committed by Jie Zhang
parent 9b798ac5b8
commit 0cd98787c2
4 changed files with 68 additions and 47 deletions

View file

@ -1,3 +1,11 @@
2011-01-29 Jie Zhang <jie@codesourcery.com>
* config/arm/arm.c (arm_legitimize_reload_address): New.
* config/arm/arm.h (ARM_LEGITIMIZE_RELOAD_ADDRESS): Use
arm_legitimize_reload_address.
* config/arm/arm-protos.h (arm_legitimize_reload_address):
Declare.
2011-01-28 Ian Lance Taylor <iant@google.com>
* godump.c (go_define): Ignore macros whose definitions include

View file

@ -54,6 +54,8 @@ extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
extern rtx legitimize_tls_address (rtx, rtx);
extern int arm_legitimate_address_outer_p (enum machine_mode, rtx, RTX_CODE, int);
extern int thumb_legitimate_offset_p (enum machine_mode, HOST_WIDE_INT);
extern bool arm_legitimize_reload_address (rtx *, enum machine_mode, int, int,
int);
extern rtx thumb_legitimize_reload_address (rtx *, enum machine_mode, int, int,
int);
extern int arm_const_double_rtx (rtx);

View file

@ -6392,6 +6392,62 @@ thumb_legitimize_address (rtx x, rtx orig_x, enum machine_mode mode)
return x;
}
bool
arm_legitimize_reload_address (rtx *p,
enum machine_mode mode,
int opnum, int type,
int ind_levels ATTRIBUTE_UNUSED)
{
if (GET_CODE (*p) == PLUS
&& GET_CODE (XEXP (*p, 0)) == REG
&& ARM_REGNO_OK_FOR_BASE_P (REGNO (XEXP (*p, 0)))
&& GET_CODE (XEXP (*p, 1)) == CONST_INT)
{
HOST_WIDE_INT val = INTVAL (XEXP (*p, 1));
HOST_WIDE_INT low, high;
if (mode == DImode || (mode == DFmode && TARGET_SOFT_FLOAT))
low = ((val & 0xf) ^ 0x8) - 0x8;
else if (TARGET_MAVERICK && TARGET_HARD_FLOAT)
/* Need to be careful, -256 is not a valid offset. */
low = val >= 0 ? (val & 0xff) : -((-val) & 0xff);
else if (mode == SImode
|| (mode == SFmode && TARGET_SOFT_FLOAT)
|| ((mode == HImode || mode == QImode) && ! arm_arch4))
/* Need to be careful, -4096 is not a valid offset. */
low = val >= 0 ? (val & 0xfff) : -((-val) & 0xfff);
else if ((mode == HImode || mode == QImode) && arm_arch4)
/* Need to be careful, -256 is not a valid offset. */
low = val >= 0 ? (val & 0xff) : -((-val) & 0xff);
else if (GET_MODE_CLASS (mode) == MODE_FLOAT
&& TARGET_HARD_FLOAT && TARGET_FPA)
/* Need to be careful, -1024 is not a valid offset. */
low = val >= 0 ? (val & 0x3ff) : -((-val) & 0x3ff);
else
return false;
high = ((((val - low) & (unsigned HOST_WIDE_INT) 0xffffffff)
^ (unsigned HOST_WIDE_INT) 0x80000000)
- (unsigned HOST_WIDE_INT) 0x80000000);
/* Check for overflow or zero */
if (low == 0 || high == 0 || (high + low != val))
return false;
/* Reload the high part into a base reg; leave the low part
in the mem. */
*p = gen_rtx_PLUS (GET_MODE (*p),
gen_rtx_PLUS (GET_MODE (*p), XEXP (*p, 0),
GEN_INT (high)),
GEN_INT (low));
push_reload (XEXP (*p, 0), NULL_RTX, &XEXP (*p, 0), NULL,
MODE_BASE_REG_CLASS (mode), GET_MODE (*p),
VOIDmode, 0, 0, opnum, (enum reload_type) type);
return true;
}
return false;
}
rtx
thumb_legitimize_reload_address (rtx *x_p,
enum machine_mode mode,

View file

@ -1273,53 +1273,8 @@ enum reg_class
#define ARM_LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, IND, WIN) \
do \
{ \
if (GET_CODE (X) == PLUS \
&& GET_CODE (XEXP (X, 0)) == REG \
&& REGNO (XEXP (X, 0)) < FIRST_PSEUDO_REGISTER \
&& REG_MODE_OK_FOR_BASE_P (XEXP (X, 0), MODE) \
&& GET_CODE (XEXP (X, 1)) == CONST_INT) \
{ \
HOST_WIDE_INT val = INTVAL (XEXP (X, 1)); \
HOST_WIDE_INT low, high; \
\
if (MODE == DImode || (MODE == DFmode && TARGET_SOFT_FLOAT)) \
low = ((val & 0xf) ^ 0x8) - 0x8; \
else if (TARGET_MAVERICK && TARGET_HARD_FLOAT) \
/* Need to be careful, -256 is not a valid offset. */ \
low = val >= 0 ? (val & 0xff) : -((-val) & 0xff); \
else if (MODE == SImode \
|| (MODE == SFmode && TARGET_SOFT_FLOAT) \
|| ((MODE == HImode || MODE == QImode) && ! arm_arch4)) \
/* Need to be careful, -4096 is not a valid offset. */ \
low = val >= 0 ? (val & 0xfff) : -((-val) & 0xfff); \
else if ((MODE == HImode || MODE == QImode) && arm_arch4) \
/* Need to be careful, -256 is not a valid offset. */ \
low = val >= 0 ? (val & 0xff) : -((-val) & 0xff); \
else if (GET_MODE_CLASS (MODE) == MODE_FLOAT \
&& TARGET_HARD_FLOAT && TARGET_FPA) \
/* Need to be careful, -1024 is not a valid offset. */ \
low = val >= 0 ? (val & 0x3ff) : -((-val) & 0x3ff); \
else \
break; \
\
high = ((((val - low) & (unsigned HOST_WIDE_INT) 0xffffffff) \
^ (unsigned HOST_WIDE_INT) 0x80000000) \
- (unsigned HOST_WIDE_INT) 0x80000000); \
/* Check for overflow or zero */ \
if (low == 0 || high == 0 || (high + low != val)) \
break; \
\
/* Reload the high part into a base reg; leave the low part \
in the mem. */ \
X = gen_rtx_PLUS (GET_MODE (X), \
gen_rtx_PLUS (GET_MODE (X), XEXP (X, 0), \
GEN_INT (high)), \
GEN_INT (low)); \
push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL, \
MODE_BASE_REG_CLASS (MODE), GET_MODE (X), \
VOIDmode, 0, 0, OPNUM, TYPE); \
goto WIN; \
} \
if (arm_legitimize_reload_address (&X, MODE, OPNUM, TYPE, IND)) \
goto WIN; \
} \
while (0)