arm.c (arm_legtimize_address): New function.

* arm.c (arm_legtimize_address): New function.
* arm-protos.h (arm_legtimize_address): Add prototype.
* arm.h (ARM_LEGITIMIZE_ADDRESS): Use arm_legitimize_address.
(LEGITIMIZE_ADDRESS, THUMB_LEGITIMIZE_ADDRESS): Wrap with
do ... while (0)

From-SVN: r62091
This commit is contained in:
Richard Earnshaw 2003-01-29 16:50:34 +00:00 committed by Richard Earnshaw
parent 0680c8fb90
commit ccf4d51284
4 changed files with 114 additions and 84 deletions

View File

@ -1,3 +1,11 @@
2003-01-29 Richard Earnshaw <rearnsha@arm.com>
* arm.c (arm_legtimize_address): New function.
* arm-protos.h (arm_legtimize_address): Add prototype.
* arm.h (ARM_LEGITIMIZE_ADDRESS): Use arm_legitimize_address.
(LEGITIMIZE_ADDRESS, THUMB_LEGITIMIZE_ADDRESS): Wrap with
do ... while (0)
2003-01-29 Joel Sherrill <joel@OARcorp.com>
* gthr-rtems.h: Define __GTHREAD_MUTEX_INIT. Apparently no code

View File

@ -57,6 +57,7 @@ extern int thumb_legitimate_address_p PARAMS ((enum machine_mode, rtx,
int));
extern int thumb_legitimate_offset_p PARAMS ((enum machine_mode,
HOST_WIDE_INT));
extern rtx arm_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
extern int const_double_rtx_ok_for_fpu PARAMS ((rtx));
extern int neg_const_double_rtx_ok_for_fpu PARAMS ((rtx));

View File

@ -2905,6 +2905,91 @@ thumb_legitimate_offset_p (mode, val)
}
}
/* Try machine-dependent ways of modifying an illegitimate address
to be legitimate. If we find one, return the new, valid address. */
rtx
arm_legitimize_address (x, orig_x, mode)
rtx x;
rtx orig_x;
enum machine_mode mode;
{
if (GET_CODE (x) == PLUS)
{
rtx xop0 = XEXP (x, 0);
rtx xop1 = XEXP (x, 1);
if (CONSTANT_P (xop0) && !symbol_mentioned_p (xop0))
xop0 = force_reg (SImode, xop0);
if (CONSTANT_P (xop1) && !symbol_mentioned_p (xop1))
xop1 = force_reg (SImode, xop1);
if (ARM_BASE_REGISTER_RTX_P (xop0)
&& GET_CODE (xop1) == CONST_INT)
{
HOST_WIDE_INT n, low_n;
rtx base_reg, val;
n = INTVAL (xop1);
if (mode == DImode || (TARGET_SOFT_FLOAT && mode == DFmode))
{
low_n = n & 0x0f;
n &= ~0x0f;
if (low_n > 4)
{
n += 16;
low_n -= 16;
}
}
else
{
low_n = ((mode) == TImode ? 0
: n >= 0 ? (n & 0xfff) : -((-n) & 0xfff));
n -= low_n;
}
base_reg = gen_reg_rtx (SImode);
val = force_operand (gen_rtx_PLUS (SImode, xop0,
GEN_INT (n)), NULL_RTX);
emit_move_insn (base_reg, val);
x = (low_n == 0 ? base_reg
: gen_rtx_PLUS (SImode, base_reg, GEN_INT (low_n)));
}
else if (xop0 != XEXP (x, 0) || xop1 != XEXP (x, 1))
x = gen_rtx_PLUS (SImode, xop0, xop1);
}
/* XXX We don't allow MINUS any more -- see comment in
arm_legitimate_address_p (). */
else if (GET_CODE (x) == MINUS)
{
rtx xop0 = XEXP (x, 0);
rtx xop1 = XEXP (x, 1);
if (CONSTANT_P (xop0))
xop0 = force_reg (SImode, xop0);
if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1))
xop1 = force_reg (SImode, xop1);
if (xop0 != XEXP (x, 0) || xop1 != XEXP (x, 1))
x = gen_rtx_MINUS (SImode, xop0, xop1);
}
if (flag_pic)
{
/* We need to find and carefully transform any SYMBOL and LABEL
references; so go back to the original address expression. */
rtx new_x = legitimize_pic_address (orig_x, mode, NULL_RTX);
if (new_x != orig_x)
x = new_x;
}
return x;
}
#define REG_OR_SUBREG_REG(X) \

View File

@ -1964,92 +1964,28 @@ typedef struct
/* Try machine-dependent ways of modifying an illegitimate address
to be legitimate. If we find one, return the new, valid address.
This macro is used in only one place: `memory_address' in explow.c.
to be legitimate. If we find one, return the new, valid address. */
#define ARM_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
do { \
X = arm_legitimize_address (X, OLDX, MODE); \
\
if (memory_address_p (MODE, X)) \
goto WIN; \
} while (0)
OLDX is the address as it was before break_out_memory_refs was called.
In some cases it is useful to look at this to decide what needs to be done.
#define THUMB_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
do { \
if (flag_pic) \
(X) = legitimize_pic_address (OLDX, MODE, NULL_RTX); \
} while (0)
MODE and WIN are passed so that this macro can use
GO_IF_LEGITIMATE_ADDRESS.
It is always safe for this macro to do nothing. It exists to recognize
opportunities to optimize the output.
On the ARM, try to convert [REG, #BIGCONST]
into ADD BASE, REG, #UPPERCONST and [BASE, #VALIDCONST],
where VALIDCONST == 0 in case of TImode. */
#define ARM_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
{ \
if (GET_CODE (X) == PLUS) \
{ \
rtx xop0 = XEXP (X, 0); \
rtx xop1 = XEXP (X, 1); \
\
if (CONSTANT_P (xop0) && ! symbol_mentioned_p (xop0)) \
xop0 = force_reg (SImode, xop0); \
if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1)) \
xop1 = force_reg (SImode, xop1); \
if (ARM_BASE_REGISTER_RTX_P (xop0) \
&& GET_CODE (xop1) == CONST_INT) \
{ \
HOST_WIDE_INT n, low_n; \
rtx base_reg, val; \
n = INTVAL (xop1); \
\
if (MODE == DImode || (TARGET_SOFT_FLOAT && MODE == DFmode)) \
{ \
low_n = n & 0x0f; \
n &= ~0x0f; \
if (low_n > 4) \
{ \
n += 16; \
low_n -= 16; \
} \
} \
else \
{ \
low_n = ((MODE) == TImode ? 0 \
: n >= 0 ? (n & 0xfff) : -((-n) & 0xfff)); \
n -= low_n; \
} \
base_reg = gen_reg_rtx (SImode); \
val = force_operand (gen_rtx_PLUS (SImode, xop0, \
GEN_INT (n)), NULL_RTX); \
emit_move_insn (base_reg, val); \
(X) = (low_n == 0 ? base_reg \
: gen_rtx_PLUS (SImode, base_reg, GEN_INT (low_n))); \
} \
else if (xop0 != XEXP (X, 0) || xop1 != XEXP (x, 1)) \
(X) = gen_rtx_PLUS (SImode, xop0, xop1); \
} \
else if (GET_CODE (X) == MINUS) \
{ \
rtx xop0 = XEXP (X, 0); \
rtx xop1 = XEXP (X, 1); \
\
if (CONSTANT_P (xop0)) \
xop0 = force_reg (SImode, xop0); \
if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1)) \
xop1 = force_reg (SImode, xop1); \
if (xop0 != XEXP (X, 0) || xop1 != XEXP (X, 1)) \
(X) = gen_rtx_MINUS (SImode, xop0, xop1); \
} \
if (flag_pic) \
(X) = legitimize_pic_address (OLDX, MODE, NULL_RTX); \
if (memory_address_p (MODE, X)) \
goto WIN; \
}
#define THUMB_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
if (flag_pic) \
(X) = legitimize_pic_address (OLDX, MODE, NULL_RTX);
#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
if (TARGET_ARM) \
ARM_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN) \
else \
THUMB_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN)
#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
do { \
if (TARGET_ARM) \
ARM_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN); \
else \
THUMB_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN); \
} while (0)
/* Go to LABEL if ADDR (a legitimate address expression)
has an effect that depends on the machine mode it is used for. */