Commit 888d2cd6 by Daniel Jacobowitz Committed by Daniel Jacobowitz

* defaults.h (REGNO_MODE_OK_FOR_BASE_P, REG_MODE_OK_FOR_BASE_P)

	(MODE_BASE_REG_REG_CLASS, REGNO_MODE_OK_FOR_REG_BASE_P)
	(REG_MODE_OK_FOR_REG_BASE_P): Provide default definitions.
	* regclass.c (record_address_regs): Remove ifdef.  Use
	REG_MODE_OK_FOR_REG_BASE_P and MODE_BASE_REG_REG_CLASS.
	* regrename.c (REG_MODE_OK_FOR_BASE_P): Remove unnecessary
	definition.
	(scan_rtx_address, replace_oldest_value_addr): Use
	REG_MODE_OK_FOR_REG_BASE_P and MODE_BASE_REG_REG_CLASS.
	* reload.c (REGNO_MODE_OK_FOR_BASE_P, REG_MODE_OK_FOR_BASE_P): Remove
	unnecessary definitions.
	(find_reloads_address_1): Support REG_MODE_OK_FOR_REG_BASE_P
	and MODE_BASE_REG_REG_CLASS.
	* config/arm/arm.h (MODE_BASE_REG_CLASS): Don't check reload_completed.
	(MODE_BASE_REG_REG_CLASS): Define.
	(REGNO_MODE_OK_FOR_REG_BASE_P): Define.
	(REG_MODE_OK_FOR_REG_BASE_P): Define.
	* doc/tm.texi (Register Classes): Document MODE_BASE_REG_REG_CLASS,
	REG_MODE_OK_FOR_REG_BASE_P, and REGNO_MODE_OK_FOR_REG_BASE_P.

From-SVN: r88948
parent 3d4818fd
2004-10-12 Daniel Jacobowitz <dan@debian.org>
* defaults.h (REGNO_MODE_OK_FOR_BASE_P, REG_MODE_OK_FOR_BASE_P)
(MODE_BASE_REG_REG_CLASS, REGNO_MODE_OK_FOR_REG_BASE_P)
(REG_MODE_OK_FOR_REG_BASE_P): Provide default definitions.
* regclass.c (record_address_regs): Remove ifdef. Use
REG_MODE_OK_FOR_REG_BASE_P and MODE_BASE_REG_REG_CLASS.
* regrename.c (REG_MODE_OK_FOR_BASE_P): Remove unnecessary
definition.
(scan_rtx_address, replace_oldest_value_addr): Use
REG_MODE_OK_FOR_REG_BASE_P and MODE_BASE_REG_REG_CLASS.
* reload.c (REGNO_MODE_OK_FOR_BASE_P, REG_MODE_OK_FOR_BASE_P): Remove
unnecessary definitions.
(find_reloads_address_1): Support REG_MODE_OK_FOR_REG_BASE_P
and MODE_BASE_REG_REG_CLASS.
* config/arm/arm.h (MODE_BASE_REG_CLASS): Don't check reload_completed.
(MODE_BASE_REG_REG_CLASS): Define.
(REGNO_MODE_OK_FOR_REG_BASE_P): Define.
(REG_MODE_OK_FOR_REG_BASE_P): Define.
* doc/tm.texi (Register Classes): Document MODE_BASE_REG_REG_CLASS,
REG_MODE_OK_FOR_REG_BASE_P, and REGNO_MODE_OK_FOR_REG_BASE_P.
2004-10-12 Daniel Berlin <dberlin@dberlin.org> 2004-10-12 Daniel Berlin <dberlin@dberlin.org>
* tree-ssa-alias.c (verify_name_tags): New function. * tree-ssa-alias.c (verify_name_tags): New function.
......
...@@ -1218,12 +1218,14 @@ enum reg_class ...@@ -1218,12 +1218,14 @@ enum reg_class
/* For the Thumb the high registers cannot be used as base registers /* For the Thumb the high registers cannot be used as base registers
when addressing quantities in QI or HI mode; if we don't know the when addressing quantities in QI or HI mode; if we don't know the
mode, then we must be conservative. After reload we must also be mode, then we must be conservative. */
conservative, since we can't support SP+reg addressing, and we
can't fix up any bad substitutions. */
#define MODE_BASE_REG_CLASS(MODE) \ #define MODE_BASE_REG_CLASS(MODE) \
(TARGET_ARM ? GENERAL_REGS : \ (TARGET_ARM ? GENERAL_REGS : \
(((MODE) == SImode && !reload_completed) ? BASE_REGS : LO_REGS)) (((MODE) == SImode) ? BASE_REGS : LO_REGS))
/* For Thumb we can not support SP+reg addressing, so we return LO_REGS
instead of BASE_REGS. */
#define MODE_BASE_REG_REG_CLASS(MODE) BASE_REG_CLASS
/* When SMALL_REGISTER_CLASSES is nonzero, the compiler allows /* When SMALL_REGISTER_CLASSES is nonzero, the compiler allows
registers explicitly used in the rtl to be used as spill registers registers explicitly used in the rtl to be used as spill registers
...@@ -1980,6 +1982,11 @@ typedef struct ...@@ -1980,6 +1982,11 @@ typedef struct
? THUMB_REGNO_MODE_OK_FOR_BASE_P (REGNO, MODE) \ ? THUMB_REGNO_MODE_OK_FOR_BASE_P (REGNO, MODE) \
: ARM_REGNO_OK_FOR_BASE_P (REGNO)) : ARM_REGNO_OK_FOR_BASE_P (REGNO))
/* Nonzero if X can be the base register in a reg+reg addressing mode.
For Thumb, we can not use SP + reg, so reject SP. */
#define REGNO_MODE_OK_FOR_REG_BASE_P(X, MODE) \
REGNO_OK_FOR_INDEX_P (X)
/* For ARM code, we don't care about the mode, but for Thumb, the index /* For ARM code, we don't care about the mode, but for Thumb, the index
must be suitable for use in a QImode load. */ must be suitable for use in a QImode load. */
#define REGNO_OK_FOR_INDEX_P(REGNO) \ #define REGNO_OK_FOR_INDEX_P(REGNO) \
...@@ -2123,6 +2130,10 @@ typedef struct ...@@ -2123,6 +2130,10 @@ typedef struct
? THUMB_REG_OK_FOR_INDEX_P (X) \ ? THUMB_REG_OK_FOR_INDEX_P (X) \
: ARM_REG_OK_FOR_INDEX_P (X)) : ARM_REG_OK_FOR_INDEX_P (X))
/* Nonzero if X can be the base register in a reg+reg addressing mode.
For Thumb, we can not use SP + reg, so reject SP. */
#define REG_MODE_OK_FOR_REG_BASE_P(X, MODE) \
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.
......
...@@ -577,6 +577,19 @@ do { fputs (integer_asm_op (POINTER_SIZE / BITS_PER_UNIT, TRUE), FILE); \ ...@@ -577,6 +577,19 @@ do { fputs (integer_asm_op (POINTER_SIZE / BITS_PER_UNIT, TRUE), FILE); \
#define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT #define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
#endif #endif
/* Some macros can be defined by the backend in either a mode-dependent
or mode-independent form. The compiler proper should only use the
mode-dependent form, providing VOIDmode when the mode is unknown.
We can't poison the macros because the backend may reference them. */
#ifndef REGNO_MODE_OK_FOR_BASE_P
#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) REGNO_OK_FOR_BASE_P (REGNO)
#endif
#ifndef REG_MODE_OK_FOR_BASE_P
#define REG_MODE_OK_FOR_BASE_P(REG, MODE) REG_OK_FOR_BASE_P (REG)
#endif
/* Determine the register class for registers suitable to be the base /* Determine the register class for registers suitable to be the base
address register in a MEM. Allow the choice to be dependent upon address register in a MEM. Allow the choice to be dependent upon
the mode of the memory access. */ the mode of the memory access. */
...@@ -584,6 +597,20 @@ do { fputs (integer_asm_op (POINTER_SIZE / BITS_PER_UNIT, TRUE), FILE); \ ...@@ -584,6 +597,20 @@ do { fputs (integer_asm_op (POINTER_SIZE / BITS_PER_UNIT, TRUE), FILE); \
#define MODE_BASE_REG_CLASS(MODE) BASE_REG_CLASS #define MODE_BASE_REG_CLASS(MODE) BASE_REG_CLASS
#endif #endif
/* Some machines require a different base register class if the index
is a register. By default, assume that a base register is acceptable. */
#ifndef MODE_BASE_REG_REG_CLASS
#define MODE_BASE_REG_REG_CLASS(MODE) MODE_BASE_REG_CLASS(MODE)
#endif
#ifndef REGNO_MODE_OK_FOR_REG_BASE_P
#define REGNO_MODE_OK_FOR_REG_BASE_P(REGNO, MODE) REGNO_MODE_OK_FOR_BASE_P (REGNO, MODE)
#endif
#ifndef REG_MODE_OK_FOR_REG_BASE_P
#define REG_MODE_OK_FOR_REG_BASE_P(REGNO, MODE) REG_MODE_OK_FOR_BASE_P (REGNO, MODE)
#endif
#ifndef LARGEST_EXPONENT_IS_NORMAL #ifndef LARGEST_EXPONENT_IS_NORMAL
#define LARGEST_EXPONENT_IS_NORMAL(SIZE) 0 #define LARGEST_EXPONENT_IS_NORMAL(SIZE) 0
#endif #endif
......
...@@ -2402,6 +2402,13 @@ the selection of a base register in a mode dependent manner. If ...@@ -2402,6 +2402,13 @@ the selection of a base register in a mode dependent manner. If
@code{BASE_REG_CLASS}. @code{BASE_REG_CLASS}.
@end defmac @end defmac
@defmac MODE_BASE_REG_REG_CLASS (@var{mode})
A C expression whose value is the register class to which a valid
base register must belong in order to be used in a base plus index
register address. You should define this macro if base plus index
addresses have different requirements than other base register uses.
@end defmac
@defmac INDEX_REG_CLASS @defmac INDEX_REG_CLASS
A macro whose definition is the name of the class to which a valid A macro whose definition is the name of the class to which a valid
index register must belong. An index register is one used in an index register must belong. An index register is one used in an
...@@ -2455,6 +2462,15 @@ you define this macro, the compiler will use it instead of ...@@ -2455,6 +2462,15 @@ you define this macro, the compiler will use it instead of
@code{REGNO_OK_FOR_BASE_P}. @code{REGNO_OK_FOR_BASE_P}.
@end defmac @end defmac
@defmac REGNO_MODE_OK_FOR_REG_BASE_P (@var{num}, @var{mode})
A C expression which is nonzero if register number @var{num} is suitable for
use as a base register in base plus index operand addresses, accessing
memory in mode @var{mode}. It may be either a suitable hard register or a
pseudo register that has been allocated such a hard register. You should
define this macro if base plus index addresses have different requirements
than other base register uses.
@end defmac
@defmac REGNO_OK_FOR_INDEX_P (@var{num}) @defmac REGNO_OK_FOR_INDEX_P (@var{num})
A C expression which is nonzero if register number @var{num} is A C expression which is nonzero if register number @var{num} is
suitable for use as an index register in operand addresses. It may be suitable for use as an index register in operand addresses. It may be
...@@ -5003,6 +5019,15 @@ you define this macro, the compiler will use it instead of ...@@ -5003,6 +5019,15 @@ you define this macro, the compiler will use it instead of
@code{REG_OK_FOR_BASE_P}. @code{REG_OK_FOR_BASE_P}.
@end defmac @end defmac
@defmac REG_MODE_OK_FOR_REG_BASE_P (@var{x}, @var{mode})
A C expression which is nonzero if @var{x} (assumed to be a @code{reg} RTX)
is suitable for use as a base register in base plus index operand addresses,
accessing memory in mode @var{mode}. It may be either a suitable hard
register or a pseudo register that has been allocated such a hard register.
You should define this macro if base plus index addresses have different
requirements than other base register uses.
@end defmac
@defmac REG_OK_FOR_INDEX_P (@var{x}) @defmac REG_OK_FOR_INDEX_P (@var{x})
A C expression that is nonzero if @var{x} (assumed to be a @code{reg} A C expression that is nonzero if @var{x} (assumed to be a @code{reg}
RTX) is valid for use as an index register. RTX) is valid for use as an index register.
......
...@@ -2011,25 +2011,27 @@ record_address_regs (rtx x, enum reg_class class, int scale) ...@@ -2011,25 +2011,27 @@ record_address_regs (rtx x, enum reg_class class, int scale)
record_address_regs (arg0, INDEX_REG_CLASS, scale); record_address_regs (arg0, INDEX_REG_CLASS, scale);
/* If both operands are registers but one is already a hard register /* If both operands are registers but one is already a hard register
of index or base class, give the other the class that the hard of index or reg-base class, give the other the class that the
register is not. */ hard register is not. */
#ifdef REG_OK_FOR_BASE_P
else if (code0 == REG && code1 == REG else if (code0 == REG && code1 == REG
&& REGNO (arg0) < FIRST_PSEUDO_REGISTER && REGNO (arg0) < FIRST_PSEUDO_REGISTER
&& (REG_OK_FOR_BASE_P (arg0) || REG_OK_FOR_INDEX_P (arg0))) && (REG_MODE_OK_FOR_REG_BASE_P (arg0, VOIDmode)
|| REG_OK_FOR_INDEX_P (arg0)))
record_address_regs (arg1, record_address_regs (arg1,
REG_OK_FOR_BASE_P (arg0) REG_MODE_OK_FOR_REG_BASE_P (arg0, VOIDmode)
? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (VOIDmode), ? INDEX_REG_CLASS
: MODE_BASE_REG_REG_CLASS (VOIDmode),
scale); scale);
else if (code0 == REG && code1 == REG else if (code0 == REG && code1 == REG
&& REGNO (arg1) < FIRST_PSEUDO_REGISTER && REGNO (arg1) < FIRST_PSEUDO_REGISTER
&& (REG_OK_FOR_BASE_P (arg1) || REG_OK_FOR_INDEX_P (arg1))) && (REG_MODE_OK_FOR_REG_BASE_P (arg1, VOIDmode)
|| REG_OK_FOR_INDEX_P (arg1)))
record_address_regs (arg0, record_address_regs (arg0,
REG_OK_FOR_BASE_P (arg1) REG_MODE_OK_FOR_REG_BASE_P (arg1, VOIDmode)
? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (VOIDmode), ? INDEX_REG_CLASS
: MODE_BASE_REG_REG_CLASS (VOIDmode),
scale); scale);
#endif
/* If one operand is known to be a pointer, it must be the base /* If one operand is known to be a pointer, it must be the base
with the other operand the index. Likewise if the other operand with the other operand the index. Likewise if the other operand
...@@ -2038,14 +2040,16 @@ record_address_regs (rtx x, enum reg_class class, int scale) ...@@ -2038,14 +2040,16 @@ record_address_regs (rtx x, enum reg_class class, int scale)
else if ((code0 == REG && REG_POINTER (arg0)) else if ((code0 == REG && REG_POINTER (arg0))
|| code1 == MULT) || code1 == MULT)
{ {
record_address_regs (arg0, MODE_BASE_REG_CLASS (VOIDmode), scale); record_address_regs (arg0, MODE_BASE_REG_REG_CLASS (VOIDmode),
scale);
record_address_regs (arg1, INDEX_REG_CLASS, scale); record_address_regs (arg1, INDEX_REG_CLASS, scale);
} }
else if ((code1 == REG && REG_POINTER (arg1)) else if ((code1 == REG && REG_POINTER (arg1))
|| code0 == MULT) || code0 == MULT)
{ {
record_address_regs (arg0, INDEX_REG_CLASS, scale); record_address_regs (arg0, INDEX_REG_CLASS, scale);
record_address_regs (arg1, MODE_BASE_REG_CLASS (VOIDmode), scale); record_address_regs (arg1, MODE_BASE_REG_REG_CLASS (VOIDmode),
scale);
} }
/* Otherwise, count equal chances that each might be a base /* Otherwise, count equal chances that each might be a base
...@@ -2053,10 +2057,10 @@ record_address_regs (rtx x, enum reg_class class, int scale) ...@@ -2053,10 +2057,10 @@ record_address_regs (rtx x, enum reg_class class, int scale)
else else
{ {
record_address_regs (arg0, MODE_BASE_REG_CLASS (VOIDmode), record_address_regs (arg0, MODE_BASE_REG_REG_CLASS (VOIDmode),
scale / 2); scale / 2);
record_address_regs (arg0, INDEX_REG_CLASS, scale / 2); record_address_regs (arg0, INDEX_REG_CLASS, scale / 2);
record_address_regs (arg1, MODE_BASE_REG_CLASS (VOIDmode), record_address_regs (arg1, MODE_BASE_REG_REG_CLASS (VOIDmode),
scale / 2); scale / 2);
record_address_regs (arg1, INDEX_REG_CLASS, scale / 2); record_address_regs (arg1, INDEX_REG_CLASS, scale / 2);
} }
......
...@@ -36,10 +36,6 @@ ...@@ -36,10 +36,6 @@
#include "toplev.h" #include "toplev.h"
#include "obstack.h" #include "obstack.h"
#ifndef REG_MODE_OK_FOR_BASE_P
#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
#endif
static const char *const reg_class_names[] = REG_CLASS_NAMES; static const char *const reg_class_names[] = REG_CLASS_NAMES;
struct du_chain struct du_chain
...@@ -524,6 +520,7 @@ scan_rtx_address (rtx insn, rtx *loc, enum reg_class cl, ...@@ -524,6 +520,7 @@ scan_rtx_address (rtx insn, rtx *loc, enum reg_class cl,
rtx op1 = orig_op1; rtx op1 = orig_op1;
rtx *locI = NULL; rtx *locI = NULL;
rtx *locB = NULL; rtx *locB = NULL;
rtx *locB_reg = NULL;
if (GET_CODE (op0) == SUBREG) if (GET_CODE (op0) == SUBREG)
{ {
...@@ -560,14 +557,14 @@ scan_rtx_address (rtx insn, rtx *loc, enum reg_class cl, ...@@ -560,14 +557,14 @@ scan_rtx_address (rtx insn, rtx *loc, enum reg_class cl,
int index_op; int index_op;
if (REG_OK_FOR_INDEX_P (op0) if (REG_OK_FOR_INDEX_P (op0)
&& REG_MODE_OK_FOR_BASE_P (op1, mode)) && REG_MODE_OK_FOR_REG_BASE_P (op1, mode))
index_op = 0; index_op = 0;
else if (REG_OK_FOR_INDEX_P (op1) else if (REG_OK_FOR_INDEX_P (op1)
&& REG_MODE_OK_FOR_BASE_P (op0, mode)) && REG_MODE_OK_FOR_REG_BASE_P (op0, mode))
index_op = 1; index_op = 1;
else if (REG_MODE_OK_FOR_BASE_P (op1, mode)) else if (REG_MODE_OK_FOR_REG_BASE_P (op1, mode))
index_op = 0; index_op = 0;
else if (REG_MODE_OK_FOR_BASE_P (op0, mode)) else if (REG_MODE_OK_FOR_REG_BASE_P (op0, mode))
index_op = 1; index_op = 1;
else if (REG_OK_FOR_INDEX_P (op1)) else if (REG_OK_FOR_INDEX_P (op1))
index_op = 1; index_op = 1;
...@@ -575,7 +572,7 @@ scan_rtx_address (rtx insn, rtx *loc, enum reg_class cl, ...@@ -575,7 +572,7 @@ scan_rtx_address (rtx insn, rtx *loc, enum reg_class cl,
index_op = 0; index_op = 0;
locI = &XEXP (x, index_op); locI = &XEXP (x, index_op);
locB = &XEXP (x, !index_op); locB_reg = &XEXP (x, !index_op);
} }
else if (code0 == REG) else if (code0 == REG)
{ {
...@@ -592,6 +589,9 @@ scan_rtx_address (rtx insn, rtx *loc, enum reg_class cl, ...@@ -592,6 +589,9 @@ scan_rtx_address (rtx insn, rtx *loc, enum reg_class cl,
scan_rtx_address (insn, locI, INDEX_REG_CLASS, action, mode); scan_rtx_address (insn, locI, INDEX_REG_CLASS, action, mode);
if (locB) if (locB)
scan_rtx_address (insn, locB, MODE_BASE_REG_CLASS (mode), action, mode); scan_rtx_address (insn, locB, MODE_BASE_REG_CLASS (mode), action, mode);
if (locB_reg)
scan_rtx_address (insn, locB_reg, MODE_BASE_REG_REG_CLASS (mode),
action, mode);
return; return;
} }
...@@ -1415,6 +1415,7 @@ replace_oldest_value_addr (rtx *loc, enum reg_class cl, ...@@ -1415,6 +1415,7 @@ replace_oldest_value_addr (rtx *loc, enum reg_class cl,
rtx op1 = orig_op1; rtx op1 = orig_op1;
rtx *locI = NULL; rtx *locI = NULL;
rtx *locB = NULL; rtx *locB = NULL;
rtx *locB_reg = NULL;
if (GET_CODE (op0) == SUBREG) if (GET_CODE (op0) == SUBREG)
{ {
...@@ -1451,14 +1452,14 @@ replace_oldest_value_addr (rtx *loc, enum reg_class cl, ...@@ -1451,14 +1452,14 @@ replace_oldest_value_addr (rtx *loc, enum reg_class cl,
int index_op; int index_op;
if (REG_OK_FOR_INDEX_P (op0) if (REG_OK_FOR_INDEX_P (op0)
&& REG_MODE_OK_FOR_BASE_P (op1, mode)) && REG_MODE_OK_FOR_REG_BASE_P (op1, mode))
index_op = 0; index_op = 0;
else if (REG_OK_FOR_INDEX_P (op1) else if (REG_OK_FOR_INDEX_P (op1)
&& REG_MODE_OK_FOR_BASE_P (op0, mode)) && REG_MODE_OK_FOR_REG_BASE_P (op0, mode))
index_op = 1; index_op = 1;
else if (REG_MODE_OK_FOR_BASE_P (op1, mode)) else if (REG_MODE_OK_FOR_REG_BASE_P (op1, mode))
index_op = 0; index_op = 0;
else if (REG_MODE_OK_FOR_BASE_P (op0, mode)) else if (REG_MODE_OK_FOR_REG_BASE_P (op0, mode))
index_op = 1; index_op = 1;
else if (REG_OK_FOR_INDEX_P (op1)) else if (REG_OK_FOR_INDEX_P (op1))
index_op = 1; index_op = 1;
...@@ -1466,7 +1467,7 @@ replace_oldest_value_addr (rtx *loc, enum reg_class cl, ...@@ -1466,7 +1467,7 @@ replace_oldest_value_addr (rtx *loc, enum reg_class cl,
index_op = 0; index_op = 0;
locI = &XEXP (x, index_op); locI = &XEXP (x, index_op);
locB = &XEXP (x, !index_op); locB_reg = &XEXP (x, !index_op);
} }
else if (code0 == REG) else if (code0 == REG)
{ {
...@@ -1486,6 +1487,10 @@ replace_oldest_value_addr (rtx *loc, enum reg_class cl, ...@@ -1486,6 +1487,10 @@ replace_oldest_value_addr (rtx *loc, enum reg_class cl,
changed |= replace_oldest_value_addr (locB, changed |= replace_oldest_value_addr (locB,
MODE_BASE_REG_CLASS (mode), MODE_BASE_REG_CLASS (mode),
mode, insn, vd); mode, insn, vd);
if (locB_reg)
changed |= replace_oldest_value_addr (locB_reg,
MODE_BASE_REG_REG_CLASS (mode),
mode, insn, vd);
return changed; return changed;
} }
......
...@@ -108,14 +108,6 @@ a register with any other reload. */ ...@@ -108,14 +108,6 @@ a register with any other reload. */
#include "params.h" #include "params.h"
#include "target.h" #include "target.h"
#ifndef REGNO_MODE_OK_FOR_BASE_P
#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) REGNO_OK_FOR_BASE_P (REGNO)
#endif
#ifndef REG_MODE_OK_FOR_BASE_P
#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
#endif
/* True if X is a constant that can be forced into the constant pool. */ /* True if X is a constant that can be forced into the constant pool. */
#define CONST_POOL_OK_P(X) \ #define CONST_POOL_OK_P(X) \
(CONSTANT_P (X) \ (CONSTANT_P (X) \
...@@ -5227,7 +5219,8 @@ update_auto_inc_notes (rtx insn ATTRIBUTE_UNUSED, int regno ATTRIBUTE_UNUSED, ...@@ -5227,7 +5219,8 @@ update_auto_inc_notes (rtx insn ATTRIBUTE_UNUSED, int regno ATTRIBUTE_UNUSED,
is strictly valid.) is strictly valid.)
CONTEXT = 1 means we are considering regs as index regs, CONTEXT = 1 means we are considering regs as index regs,
= 0 means we are considering them as base regs. = 0 means we are considering them as base regs, = 2 means we
are considering them as base regs for REG + REG.
OPNUM and TYPE specify the purpose of any reloads made. OPNUM and TYPE specify the purpose of any reloads made.
...@@ -5250,8 +5243,23 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, ...@@ -5250,8 +5243,23 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
rtx *loc, int opnum, enum reload_type type, rtx *loc, int opnum, enum reload_type type,
int ind_levels, rtx insn) int ind_levels, rtx insn)
{ {
#define REG_OK_FOR_CONTEXT(CONTEXT, REGNO, MODE) \
((CONTEXT) == 2 \
? REGNO_MODE_OK_FOR_REG_BASE_P (REGNO, MODE) \
: (CONTEXT) == 1 \
? REGNO_OK_FOR_INDEX_P (REGNO) \
: REGNO_MODE_OK_FOR_BASE_P (REGNO, MODE))
enum reg_class context_reg_class;
RTX_CODE code = GET_CODE (x); RTX_CODE code = GET_CODE (x);
if (context == 2)
context_reg_class = MODE_BASE_REG_REG_CLASS (mode);
else if (context == 1)
context_reg_class = INDEX_REG_CLASS;
else
context_reg_class = MODE_BASE_REG_CLASS (mode);
switch (code) switch (code)
{ {
case PLUS: case PLUS:
...@@ -5294,12 +5302,12 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, ...@@ -5294,12 +5302,12 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
register remateralization for expression like &localvar*4. Reload it. register remateralization for expression like &localvar*4. Reload it.
It may be possible to combine the displacement on the outer level, It may be possible to combine the displacement on the outer level,
but it is probably not worthwhile to do so. */ but it is probably not worthwhile to do so. */
if (context) if (context == 1)
{ {
find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0), find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0),
opnum, ADDR_TYPE (type), ind_levels, insn); opnum, ADDR_TYPE (type), ind_levels, insn);
push_reload (*loc, NULL_RTX, loc, (rtx*) 0, push_reload (*loc, NULL_RTX, loc, (rtx*) 0,
(context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)), context_reg_class,
GET_MODE (x), VOIDmode, 0, 0, opnum, type); GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1; return 1;
} }
...@@ -5335,22 +5343,22 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, ...@@ -5335,22 +5343,22 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
else if (code0 == REG && code1 == REG) else if (code0 == REG && code1 == REG)
{ {
if (REG_OK_FOR_INDEX_P (op0) if (REG_OK_FOR_INDEX_P (op0)
&& REG_MODE_OK_FOR_BASE_P (op1, mode)) && REG_MODE_OK_FOR_REG_BASE_P (op1, mode))
return 0; return 0;
else if (REG_OK_FOR_INDEX_P (op1) else if (REG_OK_FOR_INDEX_P (op1)
&& REG_MODE_OK_FOR_BASE_P (op0, mode)) && REG_MODE_OK_FOR_REG_BASE_P (op0, mode))
return 0; return 0;
else if (REG_MODE_OK_FOR_BASE_P (op1, mode)) else if (REG_MODE_OK_FOR_REG_BASE_P (op1, mode))
find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum, find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
type, ind_levels, insn); type, ind_levels, insn);
else if (REG_MODE_OK_FOR_BASE_P (op0, mode)) else if (REG_MODE_OK_FOR_REG_BASE_P (op0, mode))
find_reloads_address_1 (mode, orig_op1, 1, &XEXP (x, 1), opnum, find_reloads_address_1 (mode, orig_op1, 1, &XEXP (x, 1), opnum,
type, ind_levels, insn); type, ind_levels, insn);
else if (REG_OK_FOR_INDEX_P (op1)) else if (REG_OK_FOR_INDEX_P (op1))
find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum, find_reloads_address_1 (mode, orig_op0, 2, &XEXP (x, 0), opnum,
type, ind_levels, insn); type, ind_levels, insn);
else if (REG_OK_FOR_INDEX_P (op0)) else if (REG_OK_FOR_INDEX_P (op0))
find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum, find_reloads_address_1 (mode, orig_op1, 2, &XEXP (x, 1), opnum,
type, ind_levels, insn); type, ind_levels, insn);
else else
{ {
...@@ -5514,9 +5522,8 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, ...@@ -5514,9 +5522,8 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
if (reg_renumber[regno] >= 0) if (reg_renumber[regno] >= 0)
regno = reg_renumber[regno]; regno = reg_renumber[regno];
if ((regno >= FIRST_PSEUDO_REGISTER if (regno >= FIRST_PSEUDO_REGISTER
|| !(context ? REGNO_OK_FOR_INDEX_P (regno) || !REG_OK_FOR_CONTEXT (context, regno, mode))
: REGNO_MODE_OK_FOR_BASE_P (regno, mode))))
{ {
int reloadnum; int reloadnum;
...@@ -5552,8 +5559,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, ...@@ -5552,8 +5559,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
x = XEXP (x, 0); x = XEXP (x, 0);
reloadnum reloadnum
= push_reload (x, x, loc, loc, = push_reload (x, x, loc, loc,
(context ? INDEX_REG_CLASS : context_reg_class,
MODE_BASE_REG_CLASS (mode)),
GET_MODE (x), GET_MODE (x), 0, 0, GET_MODE (x), GET_MODE (x), 0, 0,
opnum, RELOAD_OTHER); opnum, RELOAD_OTHER);
} }
...@@ -5561,8 +5567,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, ...@@ -5561,8 +5567,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
{ {
reloadnum reloadnum
= push_reload (x, NULL_RTX, loc, (rtx*) 0, = push_reload (x, NULL_RTX, loc, (rtx*) 0,
(context ? INDEX_REG_CLASS : context_reg_class,
MODE_BASE_REG_CLASS (mode)),
GET_MODE (x), GET_MODE (x), 0, 0, GET_MODE (x), GET_MODE (x), 0, 0,
opnum, type); opnum, type);
rld[reloadnum].inc rld[reloadnum].inc
...@@ -5602,8 +5607,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, ...@@ -5602,8 +5607,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
opnum, type, ind_levels, insn); opnum, type, ind_levels, insn);
reloadnum = push_reload (x, NULL_RTX, loc, (rtx*) 0, reloadnum = push_reload (x, NULL_RTX, loc, (rtx*) 0,
(context ? INDEX_REG_CLASS : context_reg_class,
MODE_BASE_REG_CLASS (mode)),
GET_MODE (x), VOIDmode, 0, 0, opnum, type); GET_MODE (x), VOIDmode, 0, 0, opnum, type);
rld[reloadnum].inc rld[reloadnum].inc
= find_inc_amount (PATTERN (this_insn), XEXP (x, 0)); = find_inc_amount (PATTERN (this_insn), XEXP (x, 0));
...@@ -5632,7 +5636,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, ...@@ -5632,7 +5636,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0), find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0),
opnum, ADDR_TYPE (type), ind_levels, insn); opnum, ADDR_TYPE (type), ind_levels, insn);
push_reload (*loc, NULL_RTX, loc, (rtx*) 0, push_reload (*loc, NULL_RTX, loc, (rtx*) 0,
(context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)), context_reg_class,
GET_MODE (x), VOIDmode, 0, 0, opnum, type); GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1; return 1;
...@@ -5643,8 +5647,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, ...@@ -5643,8 +5647,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
if (reg_equiv_constant[regno] != 0) if (reg_equiv_constant[regno] != 0)
{ {
find_reloads_address_part (reg_equiv_constant[regno], loc, find_reloads_address_part (reg_equiv_constant[regno], loc,
(context ? INDEX_REG_CLASS : context_reg_class,
MODE_BASE_REG_CLASS (mode)),
GET_MODE (x), opnum, type, ind_levels); GET_MODE (x), opnum, type, ind_levels);
return 1; return 1;
} }
...@@ -5654,8 +5657,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, ...@@ -5654,8 +5657,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
if (reg_equiv_mem[regno] != 0) if (reg_equiv_mem[regno] != 0)
{ {
push_reload (reg_equiv_mem[regno], NULL_RTX, loc, (rtx*) 0, push_reload (reg_equiv_mem[regno], NULL_RTX, loc, (rtx*) 0,
(context ? INDEX_REG_CLASS : context_reg_class,
MODE_BASE_REG_CLASS (mode)),
GET_MODE (x), VOIDmode, 0, 0, opnum, type); GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1; return 1;
} }
...@@ -5678,12 +5680,11 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, ...@@ -5678,12 +5680,11 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
if (reg_renumber[regno] >= 0) if (reg_renumber[regno] >= 0)
regno = reg_renumber[regno]; regno = reg_renumber[regno];
if ((regno >= FIRST_PSEUDO_REGISTER if (regno >= FIRST_PSEUDO_REGISTER
|| !(context ? REGNO_OK_FOR_INDEX_P (regno) || !REG_OK_FOR_CONTEXT (context, regno, mode))
: REGNO_MODE_OK_FOR_BASE_P (regno, mode))))
{ {
push_reload (x, NULL_RTX, loc, (rtx*) 0, push_reload (x, NULL_RTX, loc, (rtx*) 0,
(context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)), context_reg_class,
GET_MODE (x), VOIDmode, 0, 0, opnum, type); GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1; return 1;
} }
...@@ -5695,7 +5696,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, ...@@ -5695,7 +5696,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
if (regno_clobbered_p (regno, this_insn, GET_MODE (x), 0)) if (regno_clobbered_p (regno, this_insn, GET_MODE (x), 0))
{ {
push_reload (x, NULL_RTX, loc, (rtx*) 0, push_reload (x, NULL_RTX, loc, (rtx*) 0,
(context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)), context_reg_class,
GET_MODE (x), VOIDmode, 0, 0, opnum, type); GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1; return 1;
} }
...@@ -5712,12 +5713,10 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, ...@@ -5712,12 +5713,10 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
{ {
int regno ATTRIBUTE_UNUSED = subreg_regno (x); int regno ATTRIBUTE_UNUSED = subreg_regno (x);
if (! (context ? REGNO_OK_FOR_INDEX_P (regno) if (! REG_OK_FOR_CONTEXT (context, regno, mode))
: REGNO_MODE_OK_FOR_BASE_P (regno, mode)))
{ {
push_reload (x, NULL_RTX, loc, (rtx*) 0, push_reload (x, NULL_RTX, loc, (rtx*) 0,
(context ? INDEX_REG_CLASS : context_reg_class,
MODE_BASE_REG_CLASS (mode)),
GET_MODE (x), VOIDmode, 0, 0, opnum, type); GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1; return 1;
} }
...@@ -5726,8 +5725,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, ...@@ -5726,8 +5725,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
is larger than the class size, then reload the whole SUBREG. */ is larger than the class size, then reload the whole SUBREG. */
else else
{ {
enum reg_class class = (context ? INDEX_REG_CLASS enum reg_class class = context_reg_class;
: MODE_BASE_REG_CLASS (mode));
if ((unsigned) CLASS_MAX_NREGS (class, GET_MODE (SUBREG_REG (x))) if ((unsigned) CLASS_MAX_NREGS (class, GET_MODE (SUBREG_REG (x)))
> reg_class_size[class]) > reg_class_size[class])
{ {
...@@ -5757,6 +5755,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, ...@@ -5757,6 +5755,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
} }
} }
#undef REG_OK_FOR_CONTEXT
return 0; return 0;
} }
......
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