Commit f1008e52 by Richard Earnshaw Committed by Richard Earnshaw

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
parent 4eb191f3
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> 2000-12-02 Neil Booth <neilb@earthling.net>
* tradcpp.c (struct answer, parse_assertion, parse_answer, * tradcpp.c (struct answer, parse_assertion, parse_answer,
......
...@@ -1967,7 +1967,7 @@ legitimize_pic_address (orig, mode, reg) ...@@ -1967,7 +1967,7 @@ legitimize_pic_address (orig, mode, reg)
{ {
/* The base register doesn't really matter, we only want to /* The base register doesn't really matter, we only want to
test the index for the appropriate mode. */ 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) if (!no_new_pseudos)
offset = force_reg (Pmode, offset); offset = force_reg (Pmode, offset);
......
...@@ -1269,7 +1269,7 @@ enum reg_class ...@@ -1269,7 +1269,7 @@ enum reg_class
&& GET_CODE (XEXP (X, 0)) == REG \ && GET_CODE (XEXP (X, 0)) == REG \
&& XEXP (X, 0) == stack_pointer_rtx \ && XEXP (X, 0) == stack_pointer_rtx \
&& GET_CODE (XEXP (X, 1)) == CONST_INT \ && 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; \ rtx orig_X = X; \
X = copy_rtx (X); \ X = copy_rtx (X); \
...@@ -1781,23 +1781,23 @@ typedef struct ...@@ -1781,23 +1781,23 @@ typedef struct
((R TEST VALUE) || ((unsigned) reg_renumber[R] TEST VALUE)) ((R TEST VALUE) || ((unsigned) reg_renumber[R] TEST VALUE))
/* On the ARM, don't allow the pc to be used. */ /* On the ARM, don't allow the pc to be used. */
#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \ #define ARM_REGNO_OK_FOR_BASE_P(REGNO) \
(TARGET_THUMB ? \ (TEST_REGNO (REGNO, <, PC_REGNUM) \
( TEST_REGNO (REGNO, <=, LAST_LO_REGNUM) \ || TEST_REGNO (REGNO, ==, FRAME_POINTER_REGNUM) \
|| (GET_MODE_SIZE (MODE) >= 4 \ || TEST_REGNO (REGNO, ==, ARG_POINTER_REGNUM))
&& TEST_REGNO (REGNO, ==, STACK_POINTER_REGNUM))) \
:( \ #define THUMB_REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \
TEST_REGNO (REGNO, <, PC_REGNUM) \ (TEST_REGNO (REGNO, <=, LAST_LO_REGNUM) \
|| TEST_REGNO (REGNO, ==, FRAME_POINTER_REGNUM) \ || (GET_MODE_SIZE (MODE) >= 4 \
|| TEST_REGNO (REGNO, ==, ARG_POINTER_REGNUM))) && TEST_REGNO (REGNO, ==, STACK_POINTER_REGNUM)))
/* This is like REGNO_MODE_OF_FOR_BASE_P, except that in Thumb mode #define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \
the stack pointer is always acceptable, hence the passing of SImode */ (TARGET_THUMB \
#define REGNO_OK_FOR_BASE_P(REGNO) \ ? THUMB_REGNO_MODE_OK_FOR_BASE_P (REGNO, MODE) \
REGNO_MODE_OK_FOR_BASE_P (REGNO, SImode) : ARM_REGNO_OK_FOR_BASE_P (REGNO))
/* We play tricks with REGNO_MODE_OK... here, so that for ARM the macros /* For ARM code, we don't care about the mode, but for Thumb, the index
are the same, but for Thumb only registers 0 - 7 are OK. */ must be suitable for use in a QImode load. */
#define REGNO_OK_FOR_INDEX_P(REGNO) \ #define REGNO_OK_FOR_INDEX_P(REGNO) \
REGNO_MODE_OK_FOR_BASE_P (REGNO, QImode) REGNO_MODE_OK_FOR_BASE_P (REGNO, QImode)
...@@ -1928,48 +1928,51 @@ typedef struct ...@@ -1928,48 +1928,51 @@ typedef struct
The symbol REG_OK_STRICT causes the latter definition to be used. */ The symbol REG_OK_STRICT causes the latter definition to be used. */
#ifndef REG_OK_STRICT #ifndef REG_OK_STRICT
#define REG_MODE_OK_FOR_BASE_P(X, MODE) \ #define ARM_REG_OK_FOR_BASE_P(X) \
(TARGET_THUMB ? \ (REGNO (X) <= LAST_ARM_REGNUM \
( REGNO (X) <= LAST_LO_REGNUM \ || REGNO (X) >= FIRST_PSEUDO_REGISTER \
|| REGNO (X) >= FIRST_PSEUDO_REGISTER \ || REGNO (X) == FRAME_POINTER_REGNUM \
|| (GET_MODE_SIZE (MODE) >= 4 \ || REGNO (X) == ARG_POINTER_REGNUM)
&& (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))
/* 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)
/* Nonzero if X is a hard reg that can be used as an index #define THUMB_REG_MODE_OK_FOR_BASE_P(X, MODE) \
or if it is a pseudo reg. On the Thumb, the stack pointer (REGNO (X) <= LAST_LO_REGNUM \
is not suitable. */ || REGNO (X) >= FIRST_PSEUDO_REGISTER \
#define REG_OK_FOR_INDEX_P(X) \ || (GET_MODE_SIZE (MODE) >= 4 \
REG_MODE_OK_FOR_BASE_P (X, QImode) && (REGNO (X) == STACK_POINTER_REGNUM \
|| (X) == hard_frame_pointer_rtx \
/* Just like REG_OK_FOR_BASE_P except that we also allow the PC. */ || (X) == arg_pointer_rtx)))
#define REG_OK_FOR_PRE_POST_P(X) \
(REG_OK_FOR_BASE_P (X) || REGNO(X) == PC_REGNUM)
#else /* REG_OK_STRICT */ #else /* REG_OK_STRICT */
/* Nonzero if X is a hard reg that can be used as a base reg. */ #define ARM_REG_OK_FOR_BASE_P(X) \
#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X)) ARM_REGNO_OK_FOR_BASE_P (REGNO (X))
/* Nonzero if X is a hard reg that can be used as an index. */ #define THUMB_REG_MODE_OK_FOR_BASE_P(X, MODE) \
#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X)) THUMB_REGNO_MODE_OK_FOR_BASE_P (REGNO (X), MODE)
/* 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 */ #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) \
(TARGET_THUMB \
? THUMB_REG_OK_FOR_INDEX_P (X) \
: ARM_REG_OK_FOR_INDEX_P (X))
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
that is a valid memory address for an instruction. that is a valid memory address for an instruction.
...@@ -1979,132 +1982,135 @@ typedef struct ...@@ -1979,132 +1982,135 @@ typedef struct
The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS. */ The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS. */
/* --------------------------------arm version----------------------------- */ /* --------------------------------arm version----------------------------- */
#define BASE_REGISTER_RTX_P(X) \ #define ARM_BASE_REGISTER_RTX_P(X) \
(GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) (GET_CODE (X) == REG && ARM_REG_OK_FOR_BASE_P (X))
#define INDEX_REGISTER_RTX_P(X) \ #define ARM_INDEX_REGISTER_RTX_P(X) \
(GET_CODE (X) == REG && REG_OK_FOR_INDEX_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 /* 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 used by the macro GO_IF_LEGITIMATE_ADDRESS. Floating point indices can
only be small constants. */ only be small constants. */
#define GO_IF_LEGITIMATE_INDEX(MODE, BASE_REGNO, INDEX, LABEL) \ #define ARM_GO_IF_LEGITIMATE_INDEX(MODE, BASE_REGNO, INDEX, LABEL) \
do \ 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) \
goto LABEL; \
} \
} \
else if (GET_CODE (X) == PLUS) \
{ \ { \
rtx xop0 = XEXP (X, 0); \ HOST_WIDE_INT range; \
rtx xop1 = XEXP (X, 1); \ enum rtx_code code = GET_CODE (INDEX); \
\ \
if (BASE_REGISTER_RTX_P (xop0)) \ if (TARGET_HARD_FLOAT && GET_MODE_CLASS (MODE) == MODE_FLOAT) \
GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop0), xop1, LABEL); \ { \
else if (BASE_REGISTER_RTX_P (xop1)) \ if (code == CONST_INT && INTVAL (INDEX) < 1024 \
GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop1), xop0, LABEL); \ && 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; \
} \
} \ } \
/* Reload currently can't handle MINUS, so disable this for now */ \ while (0)
/* else if (GET_CODE (X) == MINUS) \
{ \ /* Jump to LABEL if X is a valid address RTX. This must take
rtx xop0 = XEXP (X,0); \ REG_OK_STRICT into account when deciding about valid registers.
rtx xop1 = XEXP (X,1); \
\ Allow REG, REG+REG, REG+INDEX, INDEX+REG, REG-INDEX, and non
if (BASE_REGISTER_RTX_P (xop0)) \ floating SYMBOL_REF to the constant pool. Allow REG-only and
GO_IF_LEGITIMATE_INDEX (MODE, -1, xop1, LABEL); \ AUTINC-REG if handling TImode or HImode. Other symbol refs must be
} */ \ forced though a static cell to ensure addressability. */
else if (GET_MODE_CLASS (MODE) != MODE_FLOAT \ #define ARM_GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
&& GET_CODE (X) == SYMBOL_REF \ { \
&& CONSTANT_POOL_ADDRESS_P (X) \ if (ARM_BASE_REGISTER_RTX_P (X)) \
&& ! (flag_pic \ goto LABEL; \
&& symbol_mentioned_p (get_pool_constant (X)))) \ else if ((GET_CODE (X) == POST_INC || GET_CODE (X) == PRE_DEC) \
goto LABEL; \ && GET_CODE (XEXP (X, 0)) == REG \
else if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_DEC) \ && ARM_REG_OK_FOR_BASE_P (XEXP (X, 0))) \
&& (GET_MODE_SIZE (MODE) <= 4) \ goto LABEL; \
&& GET_CODE (XEXP (X, 0)) == REG \ else if (GET_MODE_SIZE (MODE) >= 4 && reload_completed \
&& REG_OK_FOR_PRE_POST_P (XEXP (X, 0))) \ && (GET_CODE (X) == LABEL_REF \
goto LABEL; \ || (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----------------------------------*/ /* ---------------------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) == 1 ? ((unsigned HOST_WIDE_INT) (VAL) < 32) \
: GET_MODE_SIZE (MODE) == 2 ? ((unsigned HOST_WIDE_INT) (VAL) < 64 \ : GET_MODE_SIZE (MODE) == 2 ? ((unsigned HOST_WIDE_INT) (VAL) < 64 \
&& ((VAL) & 1) == 0) \ && ((VAL) & 1) == 0) \
...@@ -2123,9 +2129,9 @@ typedef struct ...@@ -2123,9 +2129,9 @@ typedef struct
better ways to solve some of these problems. */ better ways to solve some of these problems. */
/* Although it is not incorrect, we don't accept QImode and HImode /* 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. addresses based on the frame pointer or arg pointer until the
This is so that eliminating such addresses into stack based ones reload pass starts. This is so that eliminating such addresses
won't produce impossible code. */ into stack based ones won't produce impossible code. */
#define THUMB_GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN) \ #define THUMB_GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN) \
{ \ { \
/* ??? Not clear if this is right. Experiment. */ \ /* ??? Not clear if this is right. Experiment. */ \
...@@ -2139,7 +2145,8 @@ typedef struct ...@@ -2139,7 +2145,8 @@ typedef struct
|| reg_mentioned_p (virtual_stack_vars_rtx, X))) \ || reg_mentioned_p (virtual_stack_vars_rtx, X))) \
; \ ; \
/* Accept any base register. SP only in SImode or larger. */ \ /* 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; \ goto WIN; \
/* This is PC relative data before MACHINE_DEPENDENT_REORG runs. */ \ /* This is PC relative data before MACHINE_DEPENDENT_REORG runs. */ \
else if (GET_MODE_SIZE (MODE) >= 4 && CONSTANT_P (X) \ else if (GET_MODE_SIZE (MODE) >= 4 && CONSTANT_P (X) \
...@@ -2156,7 +2163,7 @@ typedef struct ...@@ -2156,7 +2163,7 @@ typedef struct
/* Post-inc indexing only supported for SImode and larger. */ \ /* Post-inc indexing only supported for SImode and larger. */ \
else if (GET_CODE (X) == POST_INC && GET_MODE_SIZE (MODE) >= 4 \ else if (GET_CODE (X) == POST_INC && GET_MODE_SIZE (MODE) >= 4 \
&& GET_CODE (XEXP (X, 0)) == REG \ && 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; \ goto WIN; \
else if (GET_CODE (X) == PLUS) \ else if (GET_CODE (X) == PLUS) \
{ \ { \
...@@ -2171,15 +2178,15 @@ typedef struct ...@@ -2171,15 +2178,15 @@ typedef struct
&& XEXP (X, 1) != frame_pointer_rtx \ && XEXP (X, 1) != frame_pointer_rtx \
&& XEXP (X, 0) != virtual_stack_vars_rtx \ && XEXP (X, 0) != virtual_stack_vars_rtx \
&& XEXP (X, 1) != virtual_stack_vars_rtx \ && XEXP (X, 1) != virtual_stack_vars_rtx \
&& REG_OK_FOR_INDEX_P (XEXP (X, 0)) \ && THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0)) \
&& REG_OK_FOR_INDEX_P (XEXP (X, 1))) \ && THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 1))) \
goto WIN; \ goto WIN; \
/* REG+const has 5-7 bit offset for non-SP registers. */ \ /* REG+const has 5-7 bit offset for non-SP registers. */ \
else if (GET_CODE (XEXP (X, 0)) == REG \ 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) \ || XEXP (X, 0) == arg_pointer_rtx) \
&& GET_CODE (XEXP (X, 1)) == CONST_INT \ && GET_CODE (XEXP (X, 1)) == CONST_INT \
&& LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1)))) \ && THUMB_LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1)))) \
goto WIN; \ goto WIN; \
/* REG+const has 10 bit offset for SP, but only SImode and \ /* REG+const has 10 bit offset for SP, but only SImode and \
larger is supported. */ \ larger is supported. */ \
...@@ -2243,7 +2250,8 @@ typedef struct ...@@ -2243,7 +2250,8 @@ typedef struct
xop0 = force_reg (SImode, xop0); \ xop0 = force_reg (SImode, xop0); \
if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1)) \ if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1)) \
xop1 = force_reg (SImode, 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; \ HOST_WIDE_INT n, low_n; \
rtx base_reg, val; \ rtx base_reg, val; \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment