Commit a39bdefc by Richard Henderson Committed by Richard Henderson

alpha.c (alpha_legitimate_address_p): New.

        * config/alpha/alpha.c (alpha_legitimate_address_p): New.
        * config/alpha/alpha-protos.h: Declare it.
        * config/alpha/alpha.h (GO_IF_LEGITIMATE_ADDRESS): Move to c file.
        (NONSTRICT_REG_OK_FOR_BASE_P): Rename from non-strict macro.
        (NONSTRICT_REG_OK_FP_BASE_P): Likewise.
        (STRICT_REG_OK_FOR_BASE_P): Rename from strict macro.
        (REG_OK_FOR_BASE_P): Select one of the above.

From-SVN: r45405
parent d4fbd953
2001-09-05 Richard Henderson <rth@redhat.com>
* config/alpha/alpha.c (alpha_legitimate_address_p): New.
* config/alpha/alpha-protos.h: Declare it.
* config/alpha/alpha.h (GO_IF_LEGITIMATE_ADDRESS): Move to c file.
(NONSTRICT_REG_OK_FOR_BASE_P): Rename from non-strict macro.
(NONSTRICT_REG_OK_FP_BASE_P): Likewise.
(STRICT_REG_OK_FOR_BASE_P): Rename from strict macro.
(REG_OK_FOR_BASE_P): Select one of the above.
2001-09-05 Richard Sandiford <rsandifo@redhat.com> 2001-09-05 Richard Sandiford <rsandifo@redhat.com>
* config/mips/t-elf (EXTRA_PARTS): Use EXTRA_MULTILIB_PARTS instead. * config/mips/t-elf (EXTRA_PARTS): Use EXTRA_MULTILIB_PARTS instead.
......
...@@ -73,6 +73,7 @@ extern int addition_operation PARAMS ((rtx, enum machine_mode)); ...@@ -73,6 +73,7 @@ extern int addition_operation PARAMS ((rtx, enum machine_mode));
extern rtx alpha_tablejump_addr_vec PARAMS ((rtx)); extern rtx alpha_tablejump_addr_vec PARAMS ((rtx));
extern rtx alpha_tablejump_best_label PARAMS ((rtx)); extern rtx alpha_tablejump_best_label PARAMS ((rtx));
extern bool alpha_legitimate_address_p PARAMS ((enum machine_mode, rtx, int));
extern rtx alpha_legitimize_address PARAMS ((rtx, rtx, enum machine_mode)); extern rtx alpha_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
extern rtx alpha_legitimize_reload_address PARAMS ((rtx, enum machine_mode, extern rtx alpha_legitimize_reload_address PARAMS ((rtx, enum machine_mode,
int, int, int)); int, int, int));
......
...@@ -1154,6 +1154,77 @@ alpha_tablejump_best_label (insn) ...@@ -1154,6 +1154,77 @@ alpha_tablejump_best_label (insn)
return best_label ? best_label : const0_rtx; return best_label ? best_label : const0_rtx;
} }
/* legitimate_address_p 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.
For Alpha, we have either a constant address or the sum of a
register and a constant address, or just a register. For DImode,
any of those forms can be surrounded with an AND that clear the
low-order three bits; this is an "unaligned" access. */
bool
alpha_legitimate_address_p (mode, x, strict)
enum machine_mode mode;
rtx x;
int strict;
{
/* If this is an ldq_u type address, discard the outer AND. */
if (mode == DImode
&& GET_CODE (x) == AND
&& GET_CODE (XEXP (x, 1)) == CONST_INT
&& INTVAL (XEXP (x, 1)) == -8)
x = XEXP (x, 0);
/* Discard non-paradoxical subregs. */
if (GET_CODE (x) == SUBREG
&& (GET_MODE_SIZE (GET_MODE (x))
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
x = SUBREG_REG (x);
/* Unadorned general registers are valid. */
if (REG_P (x)
&& (strict
? STRICT_REG_OK_FOR_BASE_P (x)
: NONSTRICT_REG_OK_FOR_BASE_P (x)))
return true;
/* Constant addresses (i.e. +/- 32k) are valid. */
if (CONSTANT_ADDRESS_P (x))
return true;
/* Register plus a small constant offset is valid. */
if (GET_CODE (x) == PLUS)
{
rtx ofs = XEXP (x, 1);
x = XEXP (x, 0);
/* Discard non-paradoxical subregs. */
if (GET_CODE (x) == SUBREG
&& (GET_MODE_SIZE (GET_MODE (x))
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
x = SUBREG_REG (x);
if (REG_P (x))
{
if (! strict
&& NONSTRICT_REG_OK_FP_BASE_P (x)
&& GET_CODE (ofs) == CONST_INT)
return true;
if ((strict
? STRICT_REG_OK_FOR_BASE_P (x)
: NONSTRICT_REG_OK_FOR_BASE_P (x))
&& CONSTANT_ADDRESS_P (ofs))
return true;
}
else if (GET_CODE (x) == ADDRESSOF
&& GET_CODE (ofs) == CONST_INT)
return true;
}
return false;
}
/* Try machine-dependent ways of modifying an illegitimate address /* Try machine-dependent ways of modifying an illegitimate address
to be legitimate. If we find one, return the new, valid address. */ to be legitimate. If we find one, return the new, valid address. */
......
...@@ -1359,15 +1359,13 @@ do { \ ...@@ -1359,15 +1359,13 @@ do { \
After reload, it makes no difference, since pseudo regs have After reload, it makes no difference, since pseudo regs have
been eliminated by then. */ been eliminated by then. */
#ifndef REG_OK_STRICT
/* Nonzero if X is a hard reg that can be used as an index /* Nonzero if X is a hard reg that can be used as an index
or if it is a pseudo reg. */ or if it is a pseudo reg. */
#define REG_OK_FOR_INDEX_P(X) 0 #define REG_OK_FOR_INDEX_P(X) 0
/* Nonzero if X is a hard reg that can be used as a base reg /* Nonzero if X is a hard reg that can be used as a base reg
or if it is a pseudo reg. */ or if it is a pseudo reg. */
#define REG_OK_FOR_BASE_P(X) \ #define NONSTRICT_REG_OK_FOR_BASE_P(X) \
(REGNO (X) < 32 || REGNO (X) == 63 || REGNO (X) >= FIRST_PSEUDO_REGISTER) (REGNO (X) < 32 || REGNO (X) == 63 || REGNO (X) >= FIRST_PSEUDO_REGISTER)
/* ??? Nonzero if X is the frame pointer, or some virtual register /* ??? Nonzero if X is the frame pointer, or some virtual register
...@@ -1375,92 +1373,40 @@ do { \ ...@@ -1375,92 +1373,40 @@ do { \
have offsets greater than 32K. This is done because register have offsets greater than 32K. This is done because register
elimination offsets will change the hi/lo split, and if we split elimination offsets will change the hi/lo split, and if we split
before reload, we will require additional instructions. */ before reload, we will require additional instructions. */
#define REG_OK_FP_BASE_P(X) \ #define NONSTRICT_REG_OK_FP_BASE_P(X) \
(REGNO (X) == 31 || REGNO (X) == 63 \ (REGNO (X) == 31 || REGNO (X) == 63 \
|| (REGNO (X) >= FIRST_PSEUDO_REGISTER \ || (REGNO (X) >= FIRST_PSEUDO_REGISTER \
&& REGNO (X) < LAST_VIRTUAL_REGISTER)) && REGNO (X) < LAST_VIRTUAL_REGISTER))
#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. */ /* 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)) #define STRICT_REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
#define REG_OK_FP_BASE_P(X) 0
#ifdef REG_OK_STRICT
#define REG_OK_FOR_BASE_P(X) STRICT_REG_OK_FOR_BASE_P (X)
#else
#define REG_OK_FOR_BASE_P(X) NONSTRICT_REG_OK_FOR_BASE_P (X)
#endif #endif
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression that is a
that is a valid memory address for an instruction. valid memory address for an instruction. */
The MODE argument is the machine mode for the MEM expression
that wants to use this address.
For Alpha, we have either a constant address or the sum of a register
and a constant address, or just a register. For DImode, any of those
forms can be surrounded with an AND that clear the low-order three bits;
this is an "unaligned" access.
First define the basic valid address. */
#define GO_IF_LEGITIMATE_SIMPLE_ADDRESS(MODE, X, ADDR) \
{ \
rtx tmp = (X); \
if (GET_CODE (tmp) == SUBREG \
&& (GET_MODE_SIZE (GET_MODE (tmp)) \
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (tmp))))) \
tmp = SUBREG_REG (tmp); \
if (REG_P (tmp) && REG_OK_FOR_BASE_P (tmp)) \
goto ADDR; \
if (CONSTANT_ADDRESS_P (X)) \
goto ADDR; \
if (GET_CODE (X) == PLUS) \
{ \
tmp = XEXP (X, 0); \
if (GET_CODE (tmp) == SUBREG \
&& (GET_MODE_SIZE (GET_MODE (tmp)) \
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (tmp))))) \
tmp = SUBREG_REG (tmp); \
if (REG_P (tmp)) \
{ \
if (REG_OK_FP_BASE_P (tmp) \
&& GET_CODE (XEXP (X, 1)) == CONST_INT) \
goto ADDR; \
if (REG_OK_FOR_BASE_P (tmp) \
&& CONSTANT_ADDRESS_P (XEXP (X, 1))) \
goto ADDR; \
} \
else if (GET_CODE (tmp) == ADDRESSOF \
&& CONSTANT_ADDRESS_P (XEXP (X, 1))) \
goto ADDR; \
} \
}
/* Now accept the simple address, or, for DImode only, an AND of a simple
address that turns off the low three bits. */
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ #ifdef REG_OK_STRICT
{ GO_IF_LEGITIMATE_SIMPLE_ADDRESS (MODE, X, ADDR); \ #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN) \
if ((MODE) == DImode \ do { \
&& GET_CODE (X) == AND \ if (alpha_legitimate_address_p (MODE, X, 1)) \
&& GET_CODE (XEXP (X, 1)) == CONST_INT \ goto WIN; \
&& INTVAL (XEXP (X, 1)) == -8) \ } while (0)
GO_IF_LEGITIMATE_SIMPLE_ADDRESS (MODE, XEXP (X, 0), ADDR); \ #else
} #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN) \
do { \
if (alpha_legitimate_address_p (MODE, X, 0)) \
goto WIN; \
} while (0)
#endif
/* Try machine-dependent ways of modifying an illegitimate address /* Try machine-dependent ways of modifying an illegitimate address
to be legitimate. If we find one, return the new, valid 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. This macro is used in only one place: `memory_address' in explow.c. */
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.
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. */
#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \ #define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
do { \ do { \
......
...@@ -663,7 +663,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" ...@@ -663,7 +663,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
[(set (match_operand:DI 0 "register_operand" "=r") [(set (match_operand:DI 0 "register_operand" "=r")
(plus:DI (match_operand:DI 1 "reg_no_subreg_operand" "r") (plus:DI (match_operand:DI 1 "reg_no_subreg_operand" "r")
(match_operand:DI 2 "const_int_operand" "n")))] (match_operand:DI 2 "const_int_operand" "n")))]
"REG_OK_FP_BASE_P (operands[1]) "NONSTRICT_REG_OK_FP_BASE_P (operands[1])
&& INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) >= 0
/* This is the largest constant an lda+ldah pair can add, minus /* This is the largest constant an lda+ldah pair can add, minus
an upper bound on the displacement between SP and AP during an upper bound on the displacement between SP and AP during
......
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