mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-15 08:10:28 +08:00
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:
parent
0680c8fb90
commit
ccf4d51284
@ -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
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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) \
|
||||
|
@ -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. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user