arm.h (ARM_REGNO_OK_FOR_BASE_P, [...]): New macros.
* arm.h (ARM_REGNO_OK_FOR_BASE_P, THUMB_REGNO_MODE_OK_FOR_BASE_P): New macros. (REGNO_MODE_OK_FOR_BASE_P): Define in terms of above. (REGNO_OK_FOR_FOR_BASE_P): Delete. (ARM_REG_OK_FOR_BASE_P, THUMB_REG_MODE_OK_FOR_BASE_P): New macros for both strict and non-strict uses. (REG_MODE_OK_FOR_BASE_P): Define in terms of above. (ARM_REG_OK_FOR_INDEX_P, THUMB_REG_OK_FOR_INDEX_P): New macros. (REG_OK_FOR_INDEX_P): Define in terms of above. (REG_OK_FOR_BASE_P): Delete. (REG_OK_FOR_PRE_POST_P): Delete. (ARM_BASE_REGISTER_RTX_P): Renamed from BASE_REGISTER_RTX_P. (ARM_INDEX_REGISTER_RTX_P): Renamed from INDEX_REGISTER_RTX_P. (ARM_GO_IF_LEGITIMATE_INDEX): Renamed from GO_IF_LEGITIMATE_INDEX. (THUMB_LEGITIMATE_OFFSET): Renamed from LEGITIMATE_OFFSET. (ARM_GO_IF_LEGITIMATE_ADDRESS): Adjust for name changes. Use ARM specific variants rather than general ones. Use ARM_REG_OK_FOR_BASE_P in pre/post increment cases. (THUMB_GO_IF_LEGITIMATE_ADDRESS): Similarly for Thumb. (ARM_LEGITIMIZE_ADDRESS): Similarly. (THUMB_LEGITIMIZE_RELOAD_ADDRESS): Similarly. * arm.c (legitimate_pic_address): Similarly. From-SVN: r37954
This commit is contained in:
parent
4eb191f350
commit
f1008e52f1
|
@ -1,3 +1,28 @@
|
|||
2000-12-02 Richard Earnshaw <rearnsha@arm.com>
|
||||
|
||||
* arm.h (ARM_REGNO_OK_FOR_BASE_P, THUMB_REGNO_MODE_OK_FOR_BASE_P): New
|
||||
macros.
|
||||
(REGNO_MODE_OK_FOR_BASE_P): Define in terms of above.
|
||||
(REGNO_OK_FOR_FOR_BASE_P): Delete.
|
||||
(ARM_REG_OK_FOR_BASE_P, THUMB_REG_MODE_OK_FOR_BASE_P): New macros for
|
||||
both strict and non-strict uses.
|
||||
(REG_MODE_OK_FOR_BASE_P): Define in terms of above.
|
||||
(ARM_REG_OK_FOR_INDEX_P, THUMB_REG_OK_FOR_INDEX_P): New macros.
|
||||
(REG_OK_FOR_INDEX_P): Define in terms of above.
|
||||
(REG_OK_FOR_BASE_P): Delete.
|
||||
(REG_OK_FOR_PRE_POST_P): Delete.
|
||||
(ARM_BASE_REGISTER_RTX_P): Renamed from BASE_REGISTER_RTX_P.
|
||||
(ARM_INDEX_REGISTER_RTX_P): Renamed from INDEX_REGISTER_RTX_P.
|
||||
(ARM_GO_IF_LEGITIMATE_INDEX): Renamed from GO_IF_LEGITIMATE_INDEX.
|
||||
(THUMB_LEGITIMATE_OFFSET): Renamed from LEGITIMATE_OFFSET.
|
||||
(ARM_GO_IF_LEGITIMATE_ADDRESS): Adjust for name changes. Use ARM
|
||||
specific variants rather than general ones. Use ARM_REG_OK_FOR_BASE_P
|
||||
in pre/post increment cases.
|
||||
(THUMB_GO_IF_LEGITIMATE_ADDRESS): Similarly for Thumb.
|
||||
(ARM_LEGITIMIZE_ADDRESS): Similarly.
|
||||
(THUMB_LEGITIMIZE_RELOAD_ADDRESS): Similarly.
|
||||
* arm.c (legitimate_pic_address): Similarly.
|
||||
|
||||
2000-12-02 Neil Booth <neilb@earthling.net>
|
||||
|
||||
* tradcpp.c (struct answer, parse_assertion, parse_answer,
|
||||
|
|
|
@ -1967,7 +1967,7 @@ legitimize_pic_address (orig, mode, reg)
|
|||
{
|
||||
/* The base register doesn't really matter, we only want to
|
||||
test the index for the appropriate mode. */
|
||||
GO_IF_LEGITIMATE_INDEX (mode, 0, offset, win);
|
||||
ARM_GO_IF_LEGITIMATE_INDEX (mode, 0, offset, win);
|
||||
|
||||
if (!no_new_pseudos)
|
||||
offset = force_reg (Pmode, offset);
|
||||
|
|
|
@ -1269,7 +1269,7 @@ enum reg_class
|
|||
&& GET_CODE (XEXP (X, 0)) == REG \
|
||||
&& XEXP (X, 0) == stack_pointer_rtx \
|
||||
&& GET_CODE (XEXP (X, 1)) == CONST_INT \
|
||||
&& ! LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1)))) \
|
||||
&& ! THUMB_LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1)))) \
|
||||
{ \
|
||||
rtx orig_X = X; \
|
||||
X = copy_rtx (X); \
|
||||
|
@ -1781,23 +1781,23 @@ typedef struct
|
|||
((R TEST VALUE) || ((unsigned) reg_renumber[R] TEST VALUE))
|
||||
|
||||
/* On the ARM, don't allow the pc to be used. */
|
||||
#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \
|
||||
(TARGET_THUMB ? \
|
||||
( TEST_REGNO (REGNO, <=, LAST_LO_REGNUM) \
|
||||
|| (GET_MODE_SIZE (MODE) >= 4 \
|
||||
&& TEST_REGNO (REGNO, ==, STACK_POINTER_REGNUM))) \
|
||||
:( \
|
||||
TEST_REGNO (REGNO, <, PC_REGNUM) \
|
||||
|| TEST_REGNO (REGNO, ==, FRAME_POINTER_REGNUM) \
|
||||
|| TEST_REGNO (REGNO, ==, ARG_POINTER_REGNUM)))
|
||||
#define ARM_REGNO_OK_FOR_BASE_P(REGNO) \
|
||||
(TEST_REGNO (REGNO, <, PC_REGNUM) \
|
||||
|| TEST_REGNO (REGNO, ==, FRAME_POINTER_REGNUM) \
|
||||
|| TEST_REGNO (REGNO, ==, ARG_POINTER_REGNUM))
|
||||
|
||||
/* This is like REGNO_MODE_OF_FOR_BASE_P, except that in Thumb mode
|
||||
the stack pointer is always acceptable, hence the passing of SImode */
|
||||
#define REGNO_OK_FOR_BASE_P(REGNO) \
|
||||
REGNO_MODE_OK_FOR_BASE_P (REGNO, SImode)
|
||||
#define THUMB_REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \
|
||||
(TEST_REGNO (REGNO, <=, LAST_LO_REGNUM) \
|
||||
|| (GET_MODE_SIZE (MODE) >= 4 \
|
||||
&& TEST_REGNO (REGNO, ==, STACK_POINTER_REGNUM)))
|
||||
|
||||
/* We play tricks with REGNO_MODE_OK... here, so that for ARM the macros
|
||||
are the same, but for Thumb only registers 0 - 7 are OK. */
|
||||
#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \
|
||||
(TARGET_THUMB \
|
||||
? THUMB_REGNO_MODE_OK_FOR_BASE_P (REGNO, MODE) \
|
||||
: ARM_REGNO_OK_FOR_BASE_P (REGNO))
|
||||
|
||||
/* For ARM code, we don't care about the mode, but for Thumb, the index
|
||||
must be suitable for use in a QImode load. */
|
||||
#define REGNO_OK_FOR_INDEX_P(REGNO) \
|
||||
REGNO_MODE_OK_FOR_BASE_P (REGNO, QImode)
|
||||
|
||||
|
@ -1928,48 +1928,51 @@ typedef struct
|
|||
The symbol REG_OK_STRICT causes the latter definition to be used. */
|
||||
#ifndef REG_OK_STRICT
|
||||
|
||||
#define REG_MODE_OK_FOR_BASE_P(X, MODE) \
|
||||
(TARGET_THUMB ? \
|
||||
( REGNO (X) <= LAST_LO_REGNUM \
|
||||
|| REGNO (X) >= FIRST_PSEUDO_REGISTER \
|
||||
|| (GET_MODE_SIZE (MODE) >= 4 \
|
||||
&& (REGNO (X) == STACK_POINTER_REGNUM \
|
||||
|| (X) == hard_frame_pointer_rtx \
|
||||
|| (X) == arg_pointer_rtx))) \
|
||||
:( \
|
||||
REGNO (X) <= LAST_ARM_REGNUM \
|
||||
|| REGNO (X) >= FIRST_PSEUDO_REGISTER \
|
||||
|| REGNO (X) == FRAME_POINTER_REGNUM \
|
||||
|| REGNO (X) == ARG_POINTER_REGNUM))
|
||||
#define ARM_REG_OK_FOR_BASE_P(X) \
|
||||
(REGNO (X) <= LAST_ARM_REGNUM \
|
||||
|| REGNO (X) >= FIRST_PSEUDO_REGISTER \
|
||||
|| REGNO (X) == FRAME_POINTER_REGNUM \
|
||||
|| REGNO (X) == ARG_POINTER_REGNUM)
|
||||
|
||||
/* Nonzero if X is a hard reg that can be used as a base reg
|
||||
or if it is a pseudo reg. */
|
||||
#define REG_OK_FOR_BASE_P(X) \
|
||||
REG_MODE_OK_FOR_BASE_P (X, SImode)
|
||||
#define THUMB_REG_MODE_OK_FOR_BASE_P(X, MODE) \
|
||||
(REGNO (X) <= LAST_LO_REGNUM \
|
||||
|| REGNO (X) >= FIRST_PSEUDO_REGISTER \
|
||||
|| (GET_MODE_SIZE (MODE) >= 4 \
|
||||
&& (REGNO (X) == STACK_POINTER_REGNUM \
|
||||
|| (X) == hard_frame_pointer_rtx \
|
||||
|| (X) == arg_pointer_rtx)))
|
||||
|
||||
#else /* REG_OK_STRICT */
|
||||
|
||||
#define ARM_REG_OK_FOR_BASE_P(X) \
|
||||
ARM_REGNO_OK_FOR_BASE_P (REGNO (X))
|
||||
|
||||
#define THUMB_REG_MODE_OK_FOR_BASE_P(X, MODE) \
|
||||
THUMB_REGNO_MODE_OK_FOR_BASE_P (REGNO (X), MODE)
|
||||
|
||||
#endif /* REG_OK_STRICT */
|
||||
|
||||
/* Now define some helpers in terms of the above. */
|
||||
|
||||
#define REG_MODE_OK_FOR_BASE_P(X, MODE) \
|
||||
(TARGET_THUMB \
|
||||
? THUMB_REG_MODE_OK_FOR_BASE_P (X, MODE) \
|
||||
: ARM_REG_OK_FOR_BASE_P (X))
|
||||
|
||||
#define ARM_REG_OK_FOR_INDEX_P(X) ARM_REG_OK_FOR_BASE_P (X)
|
||||
|
||||
/* For Thumb, a valid index register is anything that can be used in
|
||||
a byte load instruction. */
|
||||
#define THUMB_REG_OK_FOR_INDEX_P(X) THUMB_REG_MODE_OK_FOR_BASE_P (X, QImode)
|
||||
|
||||
/* Nonzero if X is a hard reg that can be used as an index
|
||||
or if it is a pseudo reg. On the Thumb, the stack pointer
|
||||
is not suitable. */
|
||||
#define REG_OK_FOR_INDEX_P(X) \
|
||||
REG_MODE_OK_FOR_BASE_P (X, QImode)
|
||||
#define REG_OK_FOR_INDEX_P(X) \
|
||||
(TARGET_THUMB \
|
||||
? THUMB_REG_OK_FOR_INDEX_P (X) \
|
||||
: ARM_REG_OK_FOR_INDEX_P (X))
|
||||
|
||||
/* Just like REG_OK_FOR_BASE_P except that we also allow the PC. */
|
||||
#define REG_OK_FOR_PRE_POST_P(X) \
|
||||
(REG_OK_FOR_BASE_P (X) || REGNO(X) == PC_REGNUM)
|
||||
|
||||
#else /* REG_OK_STRICT */
|
||||
|
||||
/* Nonzero if X is a hard reg that can be used as a base reg. */
|
||||
#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
|
||||
|
||||
/* Nonzero if X is a hard reg that can be used as an index. */
|
||||
#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
|
||||
|
||||
/* Just like REG_OK_FOR_BASE_P except that we also allow the PC. */
|
||||
#define REG_OK_FOR_PRE_POST_P(X) \
|
||||
(REG_OK_FOR_BASE_P (X) || TEST_REGNO (REGNO (X), ==, PC_REGNUM))
|
||||
|
||||
#endif /* REG_OK_STRICT */
|
||||
|
||||
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
|
||||
that is a valid memory address for an instruction.
|
||||
|
@ -1979,132 +1982,135 @@ typedef struct
|
|||
The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS. */
|
||||
|
||||
/* --------------------------------arm version----------------------------- */
|
||||
#define BASE_REGISTER_RTX_P(X) \
|
||||
(GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X))
|
||||
#define ARM_BASE_REGISTER_RTX_P(X) \
|
||||
(GET_CODE (X) == REG && ARM_REG_OK_FOR_BASE_P (X))
|
||||
|
||||
#define INDEX_REGISTER_RTX_P(X) \
|
||||
(GET_CODE (X) == REG && REG_OK_FOR_INDEX_P (X))
|
||||
#define ARM_INDEX_REGISTER_RTX_P(X) \
|
||||
(GET_CODE (X) == REG && ARM_REG_OK_FOR_INDEX_P (X))
|
||||
|
||||
/* A C statement (sans semicolon) to jump to LABEL for legitimate index RTXs
|
||||
used by the macro GO_IF_LEGITIMATE_ADDRESS. Floating point indices can
|
||||
only be small constants. */
|
||||
#define GO_IF_LEGITIMATE_INDEX(MODE, BASE_REGNO, INDEX, LABEL) \
|
||||
do \
|
||||
{ \
|
||||
HOST_WIDE_INT range; \
|
||||
enum rtx_code code = GET_CODE (INDEX); \
|
||||
\
|
||||
if (TARGET_HARD_FLOAT && GET_MODE_CLASS (MODE) == MODE_FLOAT) \
|
||||
{ \
|
||||
if (code == CONST_INT && INTVAL (INDEX) < 1024 \
|
||||
&& INTVAL (INDEX) > -1024 \
|
||||
&& (INTVAL (INDEX) & 3) == 0) \
|
||||
goto LABEL; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
if (INDEX_REGISTER_RTX_P (INDEX) && GET_MODE_SIZE (MODE) <= 4) \
|
||||
goto LABEL; \
|
||||
if (GET_MODE_SIZE (MODE) <= 4 && code == MULT \
|
||||
&& (! arm_arch4 || (MODE) != HImode)) \
|
||||
{ \
|
||||
rtx xiop0 = XEXP (INDEX, 0); \
|
||||
rtx xiop1 = XEXP (INDEX, 1); \
|
||||
if (INDEX_REGISTER_RTX_P (xiop0) \
|
||||
&& power_of_two_operand (xiop1, SImode)) \
|
||||
goto LABEL; \
|
||||
if (INDEX_REGISTER_RTX_P (xiop1) \
|
||||
&& power_of_two_operand (xiop0, SImode)) \
|
||||
goto LABEL; \
|
||||
} \
|
||||
if (GET_MODE_SIZE (MODE) <= 4 \
|
||||
&& (code == LSHIFTRT || code == ASHIFTRT \
|
||||
|| code == ASHIFT || code == ROTATERT) \
|
||||
&& (! arm_arch4 || (MODE) != HImode)) \
|
||||
{ \
|
||||
rtx op = XEXP (INDEX, 1); \
|
||||
if (INDEX_REGISTER_RTX_P (XEXP (INDEX, 0)) \
|
||||
&& GET_CODE (op) == CONST_INT && INTVAL (op) > 0 \
|
||||
&& INTVAL (op) <= 31) \
|
||||
goto LABEL; \
|
||||
} \
|
||||
/* NASTY: Since this limits the addressing of unsigned byte loads */ \
|
||||
range = ((MODE) == HImode || (MODE) == QImode) \
|
||||
? (arm_arch4 ? 256 : 4095) : 4096; \
|
||||
if (code == CONST_INT && INTVAL (INDEX) < range \
|
||||
&& INTVAL (INDEX) > -range) \
|
||||
goto LABEL; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Jump to LABEL if X is a valid address RTX. This must also take
|
||||
REG_OK_STRICT into account when deciding about valid registers, but it uses
|
||||
the above macros so we are in luck. Allow REG, REG+REG, REG+INDEX,
|
||||
INDEX+REG, REG-INDEX, and non floating SYMBOL_REF to the constant pool.
|
||||
Allow REG-only and AUTINC-REG if handling TImode or HImode. Other symbol
|
||||
refs must be forced though a static cell to ensure addressability. */
|
||||
#define ARM_GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
|
||||
{ \
|
||||
if (BASE_REGISTER_RTX_P (X)) \
|
||||
goto LABEL; \
|
||||
else if ((GET_CODE (X) == POST_INC || GET_CODE (X) == PRE_DEC) \
|
||||
&& GET_CODE (XEXP (X, 0)) == REG \
|
||||
&& REG_OK_FOR_PRE_POST_P (XEXP (X, 0))) \
|
||||
goto LABEL; \
|
||||
else if (GET_MODE_SIZE (MODE) >= 4 && reload_completed \
|
||||
&& (GET_CODE (X) == LABEL_REF \
|
||||
|| (GET_CODE (X) == CONST \
|
||||
&& GET_CODE (XEXP ((X), 0)) == PLUS \
|
||||
&& GET_CODE (XEXP (XEXP ((X), 0), 0)) == LABEL_REF \
|
||||
&& GET_CODE (XEXP (XEXP ((X), 0), 1)) == CONST_INT)))\
|
||||
goto LABEL; \
|
||||
else if ((MODE) == TImode) \
|
||||
; \
|
||||
else if ((MODE) == DImode || (TARGET_SOFT_FLOAT && (MODE) == DFmode)) \
|
||||
{ \
|
||||
if (GET_CODE (X) == PLUS && BASE_REGISTER_RTX_P (XEXP (X, 0)) \
|
||||
&& GET_CODE (XEXP (X, 1)) == CONST_INT) \
|
||||
{ \
|
||||
HOST_WIDE_INT val = INTVAL (XEXP (X, 1)); \
|
||||
if (val == 4 || val == -4 || val == -8) \
|
||||
#define ARM_GO_IF_LEGITIMATE_INDEX(MODE, BASE_REGNO, INDEX, LABEL) \
|
||||
do \
|
||||
{ \
|
||||
HOST_WIDE_INT range; \
|
||||
enum rtx_code code = GET_CODE (INDEX); \
|
||||
\
|
||||
if (TARGET_HARD_FLOAT && GET_MODE_CLASS (MODE) == MODE_FLOAT) \
|
||||
{ \
|
||||
if (code == CONST_INT && INTVAL (INDEX) < 1024 \
|
||||
&& INTVAL (INDEX) > -1024 \
|
||||
&& (INTVAL (INDEX) & 3) == 0) \
|
||||
goto LABEL; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
if (ARM_INDEX_REGISTER_RTX_P (INDEX) \
|
||||
&& GET_MODE_SIZE (MODE) <= 4) \
|
||||
goto LABEL; \
|
||||
if (GET_MODE_SIZE (MODE) <= 4 && code == MULT \
|
||||
&& (! arm_arch4 || (MODE) != HImode)) \
|
||||
{ \
|
||||
rtx xiop0 = XEXP (INDEX, 0); \
|
||||
rtx xiop1 = XEXP (INDEX, 1); \
|
||||
if (ARM_INDEX_REGISTER_RTX_P (xiop0) \
|
||||
&& power_of_two_operand (xiop1, SImode)) \
|
||||
goto LABEL; \
|
||||
if (ARM_INDEX_REGISTER_RTX_P (xiop1) \
|
||||
&& power_of_two_operand (xiop0, SImode)) \
|
||||
goto LABEL; \
|
||||
} \
|
||||
if (GET_MODE_SIZE (MODE) <= 4 \
|
||||
&& (code == LSHIFTRT || code == ASHIFTRT \
|
||||
|| code == ASHIFT || code == ROTATERT) \
|
||||
&& (! arm_arch4 || (MODE) != HImode)) \
|
||||
{ \
|
||||
rtx op = XEXP (INDEX, 1); \
|
||||
if (ARM_INDEX_REGISTER_RTX_P (XEXP (INDEX, 0)) \
|
||||
&& GET_CODE (op) == CONST_INT && INTVAL (op) > 0 \
|
||||
&& INTVAL (op) <= 31) \
|
||||
goto LABEL; \
|
||||
} \
|
||||
/* NASTY: Since this limits the addressing of unsigned \
|
||||
byte loads. */ \
|
||||
range = ((MODE) == HImode || (MODE) == QImode) \
|
||||
? (arm_arch4 ? 256 : 4095) : 4096; \
|
||||
if (code == CONST_INT && INTVAL (INDEX) < range \
|
||||
&& INTVAL (INDEX) > -range) \
|
||||
goto LABEL; \
|
||||
} \
|
||||
} \
|
||||
else if (GET_CODE (X) == PLUS) \
|
||||
{ \
|
||||
rtx xop0 = XEXP (X, 0); \
|
||||
rtx xop1 = XEXP (X, 1); \
|
||||
\
|
||||
if (BASE_REGISTER_RTX_P (xop0)) \
|
||||
GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop0), xop1, LABEL); \
|
||||
else if (BASE_REGISTER_RTX_P (xop1)) \
|
||||
GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop1), xop0, LABEL); \
|
||||
} \
|
||||
/* Reload currently can't handle MINUS, so disable this for now */ \
|
||||
/* else if (GET_CODE (X) == MINUS) \
|
||||
{ \
|
||||
rtx xop0 = XEXP (X,0); \
|
||||
rtx xop1 = XEXP (X,1); \
|
||||
\
|
||||
if (BASE_REGISTER_RTX_P (xop0)) \
|
||||
GO_IF_LEGITIMATE_INDEX (MODE, -1, xop1, LABEL); \
|
||||
} */ \
|
||||
else if (GET_MODE_CLASS (MODE) != MODE_FLOAT \
|
||||
&& GET_CODE (X) == SYMBOL_REF \
|
||||
&& CONSTANT_POOL_ADDRESS_P (X) \
|
||||
&& ! (flag_pic \
|
||||
&& symbol_mentioned_p (get_pool_constant (X)))) \
|
||||
goto LABEL; \
|
||||
else if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_DEC) \
|
||||
&& (GET_MODE_SIZE (MODE) <= 4) \
|
||||
&& GET_CODE (XEXP (X, 0)) == REG \
|
||||
&& REG_OK_FOR_PRE_POST_P (XEXP (X, 0))) \
|
||||
goto LABEL; \
|
||||
while (0)
|
||||
|
||||
/* Jump to LABEL if X is a valid address RTX. This must take
|
||||
REG_OK_STRICT into account when deciding about valid registers.
|
||||
|
||||
Allow REG, REG+REG, REG+INDEX, INDEX+REG, REG-INDEX, and non
|
||||
floating SYMBOL_REF to the constant pool. Allow REG-only and
|
||||
AUTINC-REG if handling TImode or HImode. Other symbol refs must be
|
||||
forced though a static cell to ensure addressability. */
|
||||
#define ARM_GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
|
||||
{ \
|
||||
if (ARM_BASE_REGISTER_RTX_P (X)) \
|
||||
goto LABEL; \
|
||||
else if ((GET_CODE (X) == POST_INC || GET_CODE (X) == PRE_DEC) \
|
||||
&& GET_CODE (XEXP (X, 0)) == REG \
|
||||
&& ARM_REG_OK_FOR_BASE_P (XEXP (X, 0))) \
|
||||
goto LABEL; \
|
||||
else if (GET_MODE_SIZE (MODE) >= 4 && reload_completed \
|
||||
&& (GET_CODE (X) == LABEL_REF \
|
||||
|| (GET_CODE (X) == CONST \
|
||||
&& GET_CODE (XEXP ((X), 0)) == PLUS \
|
||||
&& GET_CODE (XEXP (XEXP ((X), 0), 0)) == LABEL_REF \
|
||||
&& GET_CODE (XEXP (XEXP ((X), 0), 1)) == CONST_INT))) \
|
||||
goto LABEL; \
|
||||
else if ((MODE) == TImode) \
|
||||
; \
|
||||
else if ((MODE) == DImode || (TARGET_SOFT_FLOAT && (MODE) == DFmode)) \
|
||||
{ \
|
||||
if (GET_CODE (X) == PLUS && ARM_BASE_REGISTER_RTX_P (XEXP (X, 0)) \
|
||||
&& GET_CODE (XEXP (X, 1)) == CONST_INT) \
|
||||
{ \
|
||||
HOST_WIDE_INT val = INTVAL (XEXP (X, 1)); \
|
||||
if (val == 4 || val == -4 || val == -8) \
|
||||
goto LABEL; \
|
||||
} \
|
||||
} \
|
||||
else if (GET_CODE (X) == PLUS) \
|
||||
{ \
|
||||
rtx xop0 = XEXP (X, 0); \
|
||||
rtx xop1 = XEXP (X, 1); \
|
||||
\
|
||||
if (ARM_BASE_REGISTER_RTX_P (xop0)) \
|
||||
ARM_GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop0), xop1, LABEL); \
|
||||
else if (ARM_BASE_REGISTER_RTX_P (xop1)) \
|
||||
ARM_GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop1), xop0, LABEL); \
|
||||
} \
|
||||
/* Reload currently can't handle MINUS, so disable this for now */ \
|
||||
/* else if (GET_CODE (X) == MINUS) \
|
||||
{ \
|
||||
rtx xop0 = XEXP (X,0); \
|
||||
rtx xop1 = XEXP (X,1); \
|
||||
\
|
||||
if (ARM_BASE_REGISTER_RTX_P (xop0)) \
|
||||
ARM_GO_IF_LEGITIMATE_INDEX (MODE, -1, xop1, LABEL); \
|
||||
} */ \
|
||||
else if (GET_MODE_CLASS (MODE) != MODE_FLOAT \
|
||||
&& GET_CODE (X) == SYMBOL_REF \
|
||||
&& CONSTANT_POOL_ADDRESS_P (X) \
|
||||
&& ! (flag_pic \
|
||||
&& symbol_mentioned_p (get_pool_constant (X)))) \
|
||||
goto LABEL; \
|
||||
else if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_DEC) \
|
||||
&& (GET_MODE_SIZE (MODE) <= 4) \
|
||||
&& GET_CODE (XEXP (X, 0)) == REG \
|
||||
&& ARM_REG_OK_FOR_BASE_P (XEXP (X, 0))) \
|
||||
goto LABEL; \
|
||||
}
|
||||
|
||||
/* ---------------------thumb version----------------------------------*/
|
||||
#define LEGITIMATE_OFFSET(MODE, VAL) \
|
||||
#define THUMB_LEGITIMATE_OFFSET(MODE, VAL) \
|
||||
(GET_MODE_SIZE (MODE) == 1 ? ((unsigned HOST_WIDE_INT) (VAL) < 32) \
|
||||
: GET_MODE_SIZE (MODE) == 2 ? ((unsigned HOST_WIDE_INT) (VAL) < 64 \
|
||||
&& ((VAL) & 1) == 0) \
|
||||
|
@ -2123,9 +2129,9 @@ typedef struct
|
|||
better ways to solve some of these problems. */
|
||||
|
||||
/* Although it is not incorrect, we don't accept QImode and HImode
|
||||
addresses based on the frame pointer or arg pointer until the reload pass starts.
|
||||
This is so that eliminating such addresses into stack based ones
|
||||
won't produce impossible code. */
|
||||
addresses based on the frame pointer or arg pointer until the
|
||||
reload pass starts. This is so that eliminating such addresses
|
||||
into stack based ones won't produce impossible code. */
|
||||
#define THUMB_GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN) \
|
||||
{ \
|
||||
/* ??? Not clear if this is right. Experiment. */ \
|
||||
|
@ -2139,7 +2145,8 @@ typedef struct
|
|||
|| reg_mentioned_p (virtual_stack_vars_rtx, X))) \
|
||||
; \
|
||||
/* Accept any base register. SP only in SImode or larger. */ \
|
||||
else if (GET_CODE (X) == REG && REG_MODE_OK_FOR_BASE_P (X, MODE)) \
|
||||
else if (GET_CODE (X) == REG \
|
||||
&& THUMB_REG_MODE_OK_FOR_BASE_P (X, MODE)) \
|
||||
goto WIN; \
|
||||
/* This is PC relative data before MACHINE_DEPENDENT_REORG runs. */ \
|
||||
else if (GET_MODE_SIZE (MODE) >= 4 && CONSTANT_P (X) \
|
||||
|
@ -2156,7 +2163,7 @@ typedef struct
|
|||
/* Post-inc indexing only supported for SImode and larger. */ \
|
||||
else if (GET_CODE (X) == POST_INC && GET_MODE_SIZE (MODE) >= 4 \
|
||||
&& GET_CODE (XEXP (X, 0)) == REG \
|
||||
&& REG_OK_FOR_INDEX_P (XEXP (X, 0))) \
|
||||
&& THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0))) \
|
||||
goto WIN; \
|
||||
else if (GET_CODE (X) == PLUS) \
|
||||
{ \
|
||||
|
@ -2171,15 +2178,15 @@ typedef struct
|
|||
&& XEXP (X, 1) != frame_pointer_rtx \
|
||||
&& XEXP (X, 0) != virtual_stack_vars_rtx \
|
||||
&& XEXP (X, 1) != virtual_stack_vars_rtx \
|
||||
&& REG_OK_FOR_INDEX_P (XEXP (X, 0)) \
|
||||
&& REG_OK_FOR_INDEX_P (XEXP (X, 1))) \
|
||||
&& THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0)) \
|
||||
&& THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 1))) \
|
||||
goto WIN; \
|
||||
/* REG+const has 5-7 bit offset for non-SP registers. */ \
|
||||
else if (GET_CODE (XEXP (X, 0)) == REG \
|
||||
&& (REG_OK_FOR_INDEX_P (XEXP (X, 0)) \
|
||||
&& (THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0)) \
|
||||
|| XEXP (X, 0) == arg_pointer_rtx) \
|
||||
&& GET_CODE (XEXP (X, 1)) == CONST_INT \
|
||||
&& LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1)))) \
|
||||
&& THUMB_LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1)))) \
|
||||
goto WIN; \
|
||||
/* REG+const has 10 bit offset for SP, but only SImode and \
|
||||
larger is supported. */ \
|
||||
|
@ -2243,7 +2250,8 @@ typedef struct
|
|||
xop0 = force_reg (SImode, xop0); \
|
||||
if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1)) \
|
||||
xop1 = force_reg (SImode, xop1); \
|
||||
if (BASE_REGISTER_RTX_P (xop0) && GET_CODE (xop1) == CONST_INT) \
|
||||
if (ARM_BASE_REGISTER_RTX_P (xop0) \
|
||||
&& GET_CODE (xop1) == CONST_INT) \
|
||||
{ \
|
||||
HOST_WIDE_INT n, low_n; \
|
||||
rtx base_reg, val; \
|
||||
|
|
Loading…
Reference in New Issue