rs6000.c (rs6000_legitimate_address): Allow any stack offsets if not REG_OK_STRICT.
2000-05-01 Franz Sirl <Franz.Sirl-kernel@lauterbach.com> * config/rs6000/rs6000.c (rs6000_legitimate_address): Allow any stack offsets if not REG_OK_STRICT. * config/rs6000/rs6000.h (REG_OK_STRICT_FLAG): New macro. (INT_REG_OK_FOR_INDEX_P): Likewise. (INT_REG_OK_FOR_BASE_P): Likewise. (REG_OK_FOR_INDEX_P): Use INT_REG_OK_FOR_INDEX_P. (REG_OK_FOR_BASE_P): Use INT_REG_OK_FOR_BASE_P. (LEGITIMATE_OFFSET_ADDRESS_P): Use INT_REG_OK_FOR_INDEX_P and INT_REG_OK_FOR_BASE_P instead of REG_OK_FOR_INDEX_P and REG_OK_FOR_BASE_P. Take an additional parameter. (LEGITIMATE_INDEXED_ADDRESS_P): Likeewise. (LEGITIMATE_INDIRECT_ADDRESS_P): Likewise. (LEGITIMATE_LO_SUM_ADDRESS_P): Likewise. (GO_IF_LEGITIMATE_ADDRESS): Move code into new function rs6000_legitimate_address() and use it. * config/rs6000/rs6000.c: Update all callers. (rs6000_legitimate_address): New function. From-SVN: r41772
This commit is contained in:
parent
d34c5b8062
commit
258bfae2f7
@ -1,3 +1,24 @@
|
||||
2000-05-01 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
|
||||
|
||||
* config/rs6000/rs6000.c (rs6000_legitimate_address): Allow any stack
|
||||
offsets if not REG_OK_STRICT.
|
||||
|
||||
* config/rs6000/rs6000.h (REG_OK_STRICT_FLAG): New macro.
|
||||
(INT_REG_OK_FOR_INDEX_P): Likewise.
|
||||
(INT_REG_OK_FOR_BASE_P): Likewise.
|
||||
(REG_OK_FOR_INDEX_P): Use INT_REG_OK_FOR_INDEX_P.
|
||||
(REG_OK_FOR_BASE_P): Use INT_REG_OK_FOR_BASE_P.
|
||||
(LEGITIMATE_OFFSET_ADDRESS_P): Use INT_REG_OK_FOR_INDEX_P and
|
||||
INT_REG_OK_FOR_BASE_P instead of REG_OK_FOR_INDEX_P and
|
||||
REG_OK_FOR_BASE_P. Take an additional parameter.
|
||||
(LEGITIMATE_INDEXED_ADDRESS_P): Likeewise.
|
||||
(LEGITIMATE_INDIRECT_ADDRESS_P): Likewise.
|
||||
(LEGITIMATE_LO_SUM_ADDRESS_P): Likewise.
|
||||
(GO_IF_LEGITIMATE_ADDRESS): Move code into new function
|
||||
rs6000_legitimate_address() and use it.
|
||||
* config/rs6000/rs6000.c: Update all callers.
|
||||
(rs6000_legitimate_address): New function.
|
||||
|
||||
2001-05-02 David Edelsohn <edelsohn@gnu.org>
|
||||
|
||||
* config/rs6000/rs6000.c (rs6000_emit_move): Merge
|
||||
|
@ -107,6 +107,7 @@ extern struct rtx_def *create_TOC_reference PARAMS ((rtx));
|
||||
extern void rs6000_emit_eh_toc_restore PARAMS ((rtx));
|
||||
extern void rs6000_emit_move PARAMS ((rtx, rtx, enum machine_mode));
|
||||
extern rtx rs6000_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
|
||||
extern int rs6000_legitimate_address PARAMS ((enum machine_mode, rtx, int));
|
||||
extern void rs6000_select_rtx_section PARAMS ((enum machine_mode, rtx));
|
||||
|
||||
extern rtx rs6000_return_addr PARAMS ((int, rtx));
|
||||
|
@ -1550,6 +1550,58 @@ rs6000_legitimize_address (x, oldx, mode)
|
||||
else
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
||||
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
|
||||
that is a valid memory address for an instruction.
|
||||
The MODE argument is the machine mode for the MEM expression
|
||||
that wants to use this address.
|
||||
|
||||
On the RS/6000, there are four valid address: a SYMBOL_REF that
|
||||
refers to a constant pool entry of an address (or the sum of it
|
||||
plus a constant), a short (16-bit signed) constant plus a register,
|
||||
the sum of two registers, or a register indirect, possibly with an
|
||||
auto-increment. For DFmode and DImode with an constant plus register,
|
||||
we must ensure that both words are addressable or PowerPC64 with offset
|
||||
word aligned.
|
||||
|
||||
For modes spanning multiple registers (DFmode in 32-bit GPRs,
|
||||
32-bit DImode, TImode), indexed addressing cannot be used because
|
||||
adjacent memory cells are accessed by adding word-sized offsets
|
||||
during assembly output. */
|
||||
int
|
||||
rs6000_legitimate_address (mode, x, reg_ok_strict)
|
||||
enum machine_mode mode;
|
||||
rtx x;
|
||||
int reg_ok_strict;
|
||||
{
|
||||
if (LEGITIMATE_INDIRECT_ADDRESS_P (x, reg_ok_strict))
|
||||
return 1;
|
||||
if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
|
||||
&& TARGET_UPDATE
|
||||
&& LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (x, 0), reg_ok_strict))
|
||||
return 1;
|
||||
if (LEGITIMATE_SMALL_DATA_P (mode, x))
|
||||
return 1;
|
||||
if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
|
||||
return 1;
|
||||
/* If not REG_OK_STRICT (before reload) let pass any stack offset. */
|
||||
if (! reg_ok_strict
|
||||
&& GET_CODE (x) == PLUS
|
||||
&& GET_CODE (XEXP (x, 0)) == REG
|
||||
&& XEXP (x, 0) == virtual_stack_vars_rtx
|
||||
&& GET_CODE (XEXP (x, 1)) == CONST_INT)
|
||||
return 1;
|
||||
if (LEGITIMATE_OFFSET_ADDRESS_P (mode, x, reg_ok_strict))
|
||||
return 1;
|
||||
if (mode != TImode
|
||||
&& (TARGET_HARD_FLOAT || TARGET_POWERPC64 || mode != DFmode)
|
||||
&& (TARGET_POWERPC64 || mode != DImode)
|
||||
&& LEGITIMATE_INDEXED_ADDRESS_P (x, reg_ok_strict))
|
||||
return 1;
|
||||
if (LEGITIMATE_LO_SUM_ADDRESS_P (mode, x, reg_ok_strict))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Emit a move from SOURCE to DEST in mode MODE. */
|
||||
void
|
||||
@ -3098,14 +3150,14 @@ lmw_operation (op, mode)
|
||||
|| count != 32 - (int) dest_regno)
|
||||
return 0;
|
||||
|
||||
if (LEGITIMATE_INDIRECT_ADDRESS_P (src_addr))
|
||||
if (LEGITIMATE_INDIRECT_ADDRESS_P (src_addr, 0))
|
||||
{
|
||||
offset = 0;
|
||||
base_regno = REGNO (src_addr);
|
||||
if (base_regno == 0)
|
||||
return 0;
|
||||
}
|
||||
else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, src_addr))
|
||||
else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, src_addr, 0))
|
||||
{
|
||||
offset = INTVAL (XEXP (src_addr, 1));
|
||||
base_regno = REGNO (XEXP (src_addr, 0));
|
||||
@ -3128,12 +3180,12 @@ lmw_operation (op, mode)
|
||||
|| GET_MODE (SET_SRC (elt)) != SImode)
|
||||
return 0;
|
||||
newaddr = XEXP (SET_SRC (elt), 0);
|
||||
if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr))
|
||||
if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
|
||||
{
|
||||
newoffset = 0;
|
||||
addr_reg = newaddr;
|
||||
}
|
||||
else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr))
|
||||
else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
|
||||
{
|
||||
addr_reg = XEXP (newaddr, 0);
|
||||
newoffset = INTVAL (XEXP (newaddr, 1));
|
||||
@ -3176,14 +3228,14 @@ stmw_operation (op, mode)
|
||||
|| count != 32 - (int) src_regno)
|
||||
return 0;
|
||||
|
||||
if (LEGITIMATE_INDIRECT_ADDRESS_P (dest_addr))
|
||||
if (LEGITIMATE_INDIRECT_ADDRESS_P (dest_addr, 0))
|
||||
{
|
||||
offset = 0;
|
||||
base_regno = REGNO (dest_addr);
|
||||
if (base_regno == 0)
|
||||
return 0;
|
||||
}
|
||||
else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, dest_addr))
|
||||
else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, dest_addr, 0))
|
||||
{
|
||||
offset = INTVAL (XEXP (dest_addr, 1));
|
||||
base_regno = REGNO (XEXP (dest_addr, 0));
|
||||
@ -3206,12 +3258,12 @@ stmw_operation (op, mode)
|
||||
|| GET_MODE (SET_DEST (elt)) != SImode)
|
||||
return 0;
|
||||
newaddr = XEXP (SET_DEST (elt), 0);
|
||||
if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr))
|
||||
if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
|
||||
{
|
||||
newoffset = 0;
|
||||
addr_reg = newaddr;
|
||||
}
|
||||
else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr))
|
||||
else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
|
||||
{
|
||||
addr_reg = XEXP (newaddr, 0);
|
||||
newoffset = INTVAL (XEXP (newaddr, 1));
|
||||
@ -4270,7 +4322,7 @@ print_operand (file, x, code)
|
||||
|
||||
case 'X':
|
||||
if (GET_CODE (x) == MEM
|
||||
&& LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0)))
|
||||
&& LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0), 0))
|
||||
putc ('x', file);
|
||||
return;
|
||||
|
||||
|
@ -1789,26 +1789,28 @@ typedef struct rs6000_args
|
||||
After reload, it makes no difference, since pseudo regs have
|
||||
been eliminated by then. */
|
||||
|
||||
#ifndef REG_OK_STRICT
|
||||
#ifdef REG_OK_STRICT
|
||||
# define REG_OK_STRICT_FLAG 1
|
||||
#else
|
||||
# define REG_OK_STRICT_FLAG 0
|
||||
#endif
|
||||
|
||||
/* Nonzero if X is a hard reg that can be used as an index
|
||||
or if it is a pseudo reg. */
|
||||
#define REG_OK_FOR_INDEX_P(X) \
|
||||
(REGNO (X) <= 31 || REGNO (X) == 67 || REGNO (X) >= FIRST_PSEUDO_REGISTER)
|
||||
or if it is a pseudo reg in the non-strict case. */
|
||||
#define INT_REG_OK_FOR_INDEX_P(X, STRICT) \
|
||||
((! (STRICT) \
|
||||
&& (REGNO (X) <= 31 \
|
||||
|| REGNO (X) == ARG_POINTER_REGNUM \
|
||||
|| REGNO (X) >= FIRST_PSEUDO_REGISTER)) \
|
||||
|| ((STRICT) && REGNO_OK_FOR_INDEX_P (REGNO (X))))
|
||||
|
||||
/* 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) \
|
||||
(REGNO (X) > 0 && REG_OK_FOR_INDEX_P (X))
|
||||
or if it is a pseudo reg in the non-strict case. */
|
||||
#define INT_REG_OK_FOR_BASE_P(X, STRICT) \
|
||||
(REGNO (X) > 0 && INT_REG_OK_FOR_INDEX_P (X, (STRICT)))
|
||||
|
||||
#else
|
||||
|
||||
/* 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))
|
||||
/* 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))
|
||||
|
||||
#endif
|
||||
#define REG_OK_FOR_INDEX_P(X) INT_REG_OK_FOR_INDEX_P (X, REG_OK_STRICT_FLAG)
|
||||
#define REG_OK_FOR_BASE_P(X) INT_REG_OK_FOR_BASE_P (X, REG_OK_STRICT_FLAG)
|
||||
|
||||
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
|
||||
that is a valid memory address for an instruction.
|
||||
@ -1845,68 +1847,51 @@ typedef struct rs6000_args
|
||||
&& (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST) \
|
||||
&& small_data_operand (X, MODE))
|
||||
|
||||
#define LEGITIMATE_ADDRESS_INTEGER_P(X,OFFSET) \
|
||||
#define LEGITIMATE_ADDRESS_INTEGER_P(X, OFFSET) \
|
||||
(GET_CODE (X) == CONST_INT \
|
||||
&& (unsigned HOST_WIDE_INT) (INTVAL (X) + (OFFSET) + 0x8000) < 0x10000)
|
||||
|
||||
#define LEGITIMATE_OFFSET_ADDRESS_P(MODE,X) \
|
||||
(GET_CODE (X) == PLUS \
|
||||
&& GET_CODE (XEXP (X, 0)) == REG \
|
||||
&& REG_OK_FOR_BASE_P (XEXP (X, 0)) \
|
||||
&& LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0) \
|
||||
&& (((MODE) != DFmode && (MODE) != DImode) \
|
||||
|| (TARGET_32BIT \
|
||||
? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) \
|
||||
: ! (INTVAL (XEXP (X, 1)) & 3))) \
|
||||
&& ((MODE) != TImode \
|
||||
|| (TARGET_32BIT \
|
||||
? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 12) \
|
||||
: (LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 8) \
|
||||
#define LEGITIMATE_OFFSET_ADDRESS_P(MODE, X, STRICT) \
|
||||
(GET_CODE (X) == PLUS \
|
||||
&& GET_CODE (XEXP (X, 0)) == REG \
|
||||
&& INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT)) \
|
||||
&& LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0) \
|
||||
&& (((MODE) != DFmode && (MODE) != DImode) \
|
||||
|| (TARGET_32BIT \
|
||||
? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) \
|
||||
: ! (INTVAL (XEXP (X, 1)) & 3))) \
|
||||
&& ((MODE) != TImode \
|
||||
|| (TARGET_32BIT \
|
||||
? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 12) \
|
||||
: (LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 8) \
|
||||
&& ! (INTVAL (XEXP (X, 1)) & 3)))))
|
||||
|
||||
#define LEGITIMATE_INDEXED_ADDRESS_P(X) \
|
||||
(GET_CODE (X) == PLUS \
|
||||
&& GET_CODE (XEXP (X, 0)) == REG \
|
||||
&& GET_CODE (XEXP (X, 1)) == REG \
|
||||
&& ((REG_OK_FOR_BASE_P (XEXP (X, 0)) \
|
||||
&& REG_OK_FOR_INDEX_P (XEXP (X, 1))) \
|
||||
|| (REG_OK_FOR_BASE_P (XEXP (X, 1)) \
|
||||
&& REG_OK_FOR_INDEX_P (XEXP (X, 0)))))
|
||||
#define LEGITIMATE_INDEXED_ADDRESS_P(X, STRICT) \
|
||||
(GET_CODE (X) == PLUS \
|
||||
&& GET_CODE (XEXP (X, 0)) == REG \
|
||||
&& GET_CODE (XEXP (X, 1)) == REG \
|
||||
&& ((INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT)) \
|
||||
&& INT_REG_OK_FOR_INDEX_P (XEXP (X, 1), (STRICT))) \
|
||||
|| (INT_REG_OK_FOR_BASE_P (XEXP (X, 1), (STRICT)) \
|
||||
&& INT_REG_OK_FOR_INDEX_P (XEXP (X, 0), (STRICT)))))
|
||||
|
||||
#define LEGITIMATE_INDIRECT_ADDRESS_P(X) \
|
||||
(GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X))
|
||||
#define LEGITIMATE_INDIRECT_ADDRESS_P(X, STRICT) \
|
||||
(GET_CODE (X) == REG && INT_REG_OK_FOR_BASE_P (X, (STRICT)))
|
||||
|
||||
#define LEGITIMATE_LO_SUM_ADDRESS_P(MODE, X) \
|
||||
(TARGET_ELF \
|
||||
&& ! flag_pic && ! TARGET_TOC \
|
||||
&& (MODE) != DImode \
|
||||
&& (MODE) != TImode \
|
||||
&& (TARGET_HARD_FLOAT || (MODE) != DFmode) \
|
||||
&& GET_CODE (X) == LO_SUM \
|
||||
&& GET_CODE (XEXP (X, 0)) == REG \
|
||||
&& REG_OK_FOR_BASE_P (XEXP (X, 0)) \
|
||||
#define LEGITIMATE_LO_SUM_ADDRESS_P(MODE, X, STRICT) \
|
||||
(TARGET_ELF \
|
||||
&& ! flag_pic && ! TARGET_TOC \
|
||||
&& (MODE) != DImode \
|
||||
&& (MODE) != TImode \
|
||||
&& (TARGET_HARD_FLOAT || (MODE) != DFmode) \
|
||||
&& GET_CODE (X) == LO_SUM \
|
||||
&& GET_CODE (XEXP (X, 0)) == REG \
|
||||
&& INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT)) \
|
||||
&& CONSTANT_P (XEXP (X, 1)))
|
||||
|
||||
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
|
||||
{ if (LEGITIMATE_INDIRECT_ADDRESS_P (X)) \
|
||||
goto ADDR; \
|
||||
if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == PRE_DEC) \
|
||||
&& TARGET_UPDATE \
|
||||
&& LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (X, 0))) \
|
||||
goto ADDR; \
|
||||
if (LEGITIMATE_SMALL_DATA_P (MODE, X)) \
|
||||
goto ADDR; \
|
||||
if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (X)) \
|
||||
goto ADDR; \
|
||||
if (LEGITIMATE_OFFSET_ADDRESS_P (MODE, X)) \
|
||||
goto ADDR; \
|
||||
if ((MODE) != TImode \
|
||||
&& (TARGET_HARD_FLOAT || TARGET_POWERPC64 || (MODE) != DFmode) \
|
||||
&& (TARGET_POWERPC64 || (MODE) != DImode) \
|
||||
&& LEGITIMATE_INDEXED_ADDRESS_P (X)) \
|
||||
goto ADDR; \
|
||||
if (LEGITIMATE_LO_SUM_ADDRESS_P (MODE, X)) \
|
||||
goto ADDR; \
|
||||
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
|
||||
{ if (rs6000_legitimate_address (MODE, X, REG_OK_STRICT_FLAG)) \
|
||||
goto ADDR; \
|
||||
}
|
||||
|
||||
/* Try machine-dependent ways of modifying an illegitimate address
|
||||
|
Loading…
Reference in New Issue
Block a user