vax.c (legitimate_constant_address_p): New.

2005-04-27  Matt Thomas <matt@3am-software.com>

        * config/vax/vax.c (legitimate_constant_address_p): New.  Formerly
                CONSTANT_ADDRESS_P in config/vax/vax.h
        (legitimate_constant_p): Added.  Formerly CONSTANT_P in vax.h.
        (INDEX_REGISTER_P): New.
        (BASE_REGISTER_P): New.
        (indirectable_constant_address_p): New.  Adapted from
                INDIRECTABLE_CONSTANT_ADDRESS_P in vax.h.
                Use SYMBOL_REF_LOCAL_P.
        (indirectable_address_p): New.  Adapted from
                INDIRECTABLE_ADDRESS_P in vax.h.
        (nonindexed_address_p): New.  Adapted from
                GO_IF_NONINDEXED_ADDRESS in vax.h.
        (index_temp_p): New.  Adapted from
                INDEX_TERM_P in vax.h.
        (reg_plus_index_p): New.  Adapted from
                GO_IF_REG_PLUS_INDEX in vax.h.
        (legitimate_address_p): New.  Adapted from
                GO_IF_LEGITIMATE_ADDRESS in vax.h
        (vax_mode_dependent_address_p): New.  Adapted from
                GO_IF_MODE_DEPENDENT_ADDRESS in vax.h
        * config/vax/vax.h (CONSTANT_ADDRESS_P): Use
                legitimate_constant_address_p
        (CONSTANT_P): Use legitimate_constant_p.
        (INDIRECTABLE_CONSTANT_ADDRESS_P): Removed.
        (INDIRECTABLE_ADDRESS_P): Removed.
        (GO_IF_NONINDEXED_ADDRESS): Removed.
        (INDEX_TEMP_P): Removed.
        (GO_IF_REG_PLUS_INDEX): Removed.
        (GO_IF_LEGITIMATE_ADDRESS): Use legitimate_address_p.
                Two definitions, depending on whether REG_OK_STRICT is defined.
        (GO_IF_MODE_DEPENDENT_ADDRESS): Use vax_mode_dependent_address_p.
                Two definitions, depending on whether REG_OK_STRICT is defined.
        * config/vax/vax-protos.h (legitimate_constant_address_p): Prototype
                added.
        (legitimate_constant_p): Prototype added.
        (legitimate_address_p): Prototype added.
        (vax_mode_dependent_address_p): Prototype added.

From-SVN: r98814
This commit is contained in:
Matt Thomas 2005-04-27 02:18:43 +00:00 committed by Matt Thomas
parent 5dbc71f878
commit fbf5558065
4 changed files with 285 additions and 154 deletions

View file

@ -1,3 +1,43 @@
2005-04-27 Matt Thomas <matt@3am-software.com>
* config/vax/vax.c (legitimate_constant_address_p): New. Formerly
CONSTANT_ADDRESS_P in config/vax/vax.h
(legitimate_constant_p): Added. Formerly CONSTANT_P in vax.h.
(INDEX_REGISTER_P): New.
(BASE_REGISTER_P): New.
(indirectable_constant_address_p): New. Adapted from
INDIRECTABLE_CONSTANT_ADDRESS_P in vax.h.
Use SYMBOL_REF_LOCAL_P.
(indirectable_address_p): New. Adapted from
INDIRECTABLE_ADDRESS_P in vax.h.
(nonindexed_address_p): New. Adapted from
GO_IF_NONINDEXED_ADDRESS in vax.h.
(index_temp_p): New. Adapted from
INDEX_TERM_P in vax.h.
(reg_plus_index_p): New. Adapted from
GO_IF_REG_PLUS_INDEX in vax.h.
(legitimate_address_p): New. Adapted from
GO_IF_LEGITIMATE_ADDRESS in vax.h
(vax_mode_dependent_address_p): New. Adapted from
GO_IF_MODE_DEPENDENT_ADDRESS in vax.h
* config/vax/vax.h (CONSTANT_ADDRESS_P): Use
legitimate_constant_address_p
(CONSTANT_P): Use legitimate_constant_p.
(INDIRECTABLE_CONSTANT_ADDRESS_P): Removed.
(INDIRECTABLE_ADDRESS_P): Removed.
(GO_IF_NONINDEXED_ADDRESS): Removed.
(INDEX_TEMP_P): Removed.
(GO_IF_REG_PLUS_INDEX): Removed.
(GO_IF_LEGITIMATE_ADDRESS): Use legitimate_address_p.
Two definitions, depending on whether REG_OK_STRICT is defined.
(GO_IF_MODE_DEPENDENT_ADDRESS): Use vax_mode_dependent_address_p.
Two definitions, depending on whether REG_OK_STRICT is defined.
* config/vax/vax-protos.h (legitimate_constant_address_p): Prototype
added.
(legitimate_constant_p): Prototype added.
(legitimate_address_p): Prototype added.
(vax_mode_dependent_address_p): Prototype added.
2005-04-27 Kazu Hirata <kazu@cs.umass.edu>
* tree.h (phi_arg_d): Expand a comment in phi_arg_d.

View file

@ -20,6 +20,11 @@ Boston, MA 02111-1307, USA. */
extern void override_options (void);
extern int legitimate_constant_address_p (rtx);
extern int legitimate_constant_p (rtx);
extern int legitimate_address_p (enum machine_mode, rtx, int);
extern int vax_mode_dependent_address_p (rtx);
#ifdef RTX_CODE
extern const char *rev_cond_name (rtx);
extern void split_quadword_operands (rtx *, rtx *, int);
@ -34,4 +39,3 @@ extern const char * vax_output_conditional_branch (enum rtx_code);
#ifdef REAL_VALUE_TYPE
extern int check_float_value (enum machine_mode, REAL_VALUE_TYPE *, int);
#endif /* REAL_VALUE_TYPE */

View file

@ -1100,3 +1100,227 @@ vax_output_conditional_branch (enum rtx_code code)
}
}
/* 1 if X is an rtx for a constant that is a valid address. */
int
legitimate_constant_address_p (rtx x)
{
return (GET_CODE (x) == LABEL_REF || GET_CODE (x) == SYMBOL_REF
|| GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST
|| GET_CODE (x) == HIGH);
}
/* Nonzero if the constant value X is a legitimate general operand.
It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
int
legitimate_constant_p (rtx x ATTRIBUTE_UNUSED)
{
return 1;
}
/* The other macros defined here are used only in legitimate_address_p (). */
/* Nonzero if X is a hard reg that can be used as an index
or, if not strict, if it is a pseudo reg. */
#define INDEX_REGISTER_P(X, STRICT)
(GET_CODE (X) == REG && (!(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 not strict, if it is a pseudo reg. */
#define BASE_REGISTER_P(X, STRICT)
(GET_CODE (X) == REG && (!(STRICT) || REGNO_OK_FOR_BASE_P (REGNO (X))))
#ifdef NO_EXTERNAL_INDIRECT_ADDRESS
/* Re-definition of CONSTANT_ADDRESS_P, which is true only when there
are no SYMBOL_REFs for external symbols present. */
static int
indirectable_constant_address_p (rtx x)
{
if (!CONSTANT_ADDRESS_P (x))
return 0;
if (GET_CODE (x) == CONST && GET_CODE (XEXP ((x), 0)) == PLUS)
x = XEXP (XEXP (x, 0), 0);
if (GET_CODE (x) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (x))
return 0;
return 1;
}
#else /* not NO_EXTERNAL_INDIRECT_ADDRESS */
static int
indirectable_constant_address_p (rtx x)
{
return CONSTANT_ADDRESS_P (x);
}
#endif /* not NO_EXTERNAL_INDIRECT_ADDRESS */
/* Nonzero if X is an address which can be indirected. External symbols
could be in a sharable image library, so we disallow those. */
static int
indirectable_address_p(rtx x, int strict)
{
if (indirectable_constant_address_p (x))
return 1;
if (BASE_REGISTER_P (x, strict))
return 1;
if (GET_CODE (x) == PLUS
&& BASE_REGISTER_P (XEXP (x, 0), strict)
&& indirectable_constant_address_p (XEXP (x, 1)))
return 1;
return 0;
}
/* Return 1 if x is a valid address not using indexing.
(This much is the easy part.) */
static int
nonindexed_address_p (rtx x, int strict)
{
rtx xfoo0;
if (GET_CODE (x) == REG)
{
extern rtx *reg_equiv_mem;
if (! reload_in_progress
|| reg_equiv_mem[REGNO (x)] == 0
|| indirectable_address_p (reg_equiv_mem[REGNO (x)], strict))
return 1;
}
if (indirectable_constant_address_p (x))
return 1;
if (indirectable_address_p (x, strict))
return 1;
xfoo0 = XEXP (x, 0);
if (GET_CODE (x) == MEM && indirectable_address_p (xfoo0, strict))
return 1;
if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
&& BASE_REGISTER_P (xfoo0, strict))
return 1;
return 0;
}
/* 1 if PROD is either a reg times size of mode MODE and MODE is less
than or equal 8 bytes, or just a reg if MODE is one byte. */
static int
index_term_p (rtx prod, enum machine_mode mode, int strict)
{
rtx xfoo0, xfoo1;
if (GET_MODE_SIZE (mode) == 1)
return BASE_REGISTER_P (prod, strict);
if (GET_CODE (prod) != MULT || GET_MODE_SIZE (mode) > 8)
return 0;
xfoo0 = XEXP (prod, 0);
xfoo1 = XEXP (prod, 1);
if (GET_CODE (xfoo0) == CONST_INT
&& INTVAL (xfoo0) == (int)GET_MODE_SIZE (mode)
&& INDEX_REGISTER_P (xfoo1, strict))
return 1;
if (GET_CODE (xfoo1) == CONST_INT
&& INTVAL (xfoo1) == (int)GET_MODE_SIZE (mode)
&& INDEX_REGISTER_P (xfoo0, strict))
return 1;
return 0;
}
/* Return 1 if X is the sum of a register
and a valid index term for mode MODE. */
static int
reg_plus_index_p (rtx x, enum machine_mode mode, int strict)
{
rtx xfoo0, xfoo1;
if (GET_CODE (x) != PLUS)
return 0;
xfoo0 = XEXP (x, 0);
xfoo1 = XEXP (x, 1);
if (BASE_REGISTER_P (xfoo0, strict) && index_term_p (xfoo1, mode, strict))
return 1;
if (BASE_REGISTER_P (xfoo1, strict) && index_term_p (xfoo0, mode, strict))
return 1;
return 0;
}
/* legitimate_address_p returns 1 if it recognizes an RTL expression "x"
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. */
int
legitimate_address_p (enum machine_mode mode, rtx x, int strict)
{
rtx xfoo0, xfoo1;
if (nonindexed_address_p (x, strict))
return 1;
if (GET_CODE (x) != PLUS)
return 0;
/* Handle <address>[index] represented with index-sum outermost */
xfoo0 = XEXP (x, 0);
xfoo1 = XEXP (x, 1);
if (index_term_p (xfoo0, mode, strict)
&& nonindexed_address_p (xfoo1, strict))
return 1;
if (index_term_p (xfoo1, mode, strict)
&& nonindexed_address_p (xfoo0, strict))
return 1;
/* Handle offset(reg)[index] with offset added outermost */ \
if (indirectable_constant_address_p (xfoo0)
&& (BASE_REGISTER_P (xfoo1, strict)
|| reg_plus_index_p (xfoo1, mode, strict)))
return 1;
if (indirectable_constant_address_p (xfoo1)
&& (BASE_REGISTER_P (xfoo0, strict)
|| reg_plus_index_p (xfoo0, mode, strict)))
return 1;
return 0;
}
/* Return 1 if x (a legitimate address expression) has an effect that
depends on the machine mode it is used for. On the VAX, the predecrement
and postincrement address depend thus (the amount of decrement or
increment being the length of the operand) and all indexed address depend
thus (because the index scale factor is the length of the operand). */
int
vax_mode_dependent_address_p (rtx x)
{
rtx xfoo0, xfoo1;
if (GET_CODE (x) == POST_INC || GET_CODE (x) == PRE_DEC)
return 1;
if (GET_CODE (x) != PLUS)
return 0;
xfoo0 = XEXP (x, 0);
xfoo1 = XEXP (x, 1);
if (CONSTANT_ADDRESS_P (xfoo0) && GET_CODE (xfoo1) == REG)
return 0;
if (CONSTANT_ADDRESS_P (xfoo1) && GET_CODE (xfoo0) == REG)
return 0;
return 1;
}

View file

@ -541,15 +541,12 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
/* 1 if X is an rtx for a constant that is a valid address. */
#define CONSTANT_ADDRESS_P(X) \
(GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
|| GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \
|| GET_CODE (X) == HIGH)
#define CONSTANT_ADDRESS_P(X) legitimate_constant_address_p (X)
/* Nonzero if the constant value X is a legitimate general operand.
It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
#define LEGITIMATE_CONSTANT_P(X) 1
#define LEGITIMATE_CONSTANT_P(X) legitimate_constant_p (X)
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
@ -569,169 +566,35 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
/* 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) 1
/* 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) 1
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
that is a valid memory address for an instruction. */
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
{ if (legitimate_address_p ((MODE), (X), 0)) goto ADDR; }
#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
/* 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.
that is a valid memory address for an instruction. */
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
{ if (legitimate_address_p ((MODE), (X), 1)) goto ADDR; }
The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS,
except for CONSTANT_ADDRESS_P which is actually machine-independent. */
#endif
#ifdef NO_EXTERNAL_INDIRECT_ADDRESS
/* Zero if this contains a (CONST (PLUS (SYMBOL_REF) (...))) and the
symbol in the SYMBOL_REF is an external symbol. */
#define INDIRECTABLE_CONSTANT_P(X) \
(! (GET_CODE ((X)) == CONST \
&& GET_CODE (XEXP ((X), 0)) == PLUS \
&& GET_CODE (XEXP (XEXP ((X), 0), 0)) == SYMBOL_REF \
&& SYMBOL_REF_FLAG (XEXP (XEXP ((X), 0), 0))))
/* Re-definition of CONSTANT_ADDRESS_P, which is true only when there
are no SYMBOL_REFs for external symbols present. */
#define INDIRECTABLE_CONSTANT_ADDRESS_P(X) \
(GET_CODE (X) == LABEL_REF \
|| (GET_CODE (X) == SYMBOL_REF && !SYMBOL_REF_FLAG (X)) \
|| (GET_CODE (X) == CONST && INDIRECTABLE_CONSTANT_P(X)) \
|| GET_CODE (X) == CONST_INT)
/* Nonzero if X is an address which can be indirected. External symbols
could be in a sharable image library, so we disallow those. */
#define INDIRECTABLE_ADDRESS_P(X) \
(INDIRECTABLE_CONSTANT_ADDRESS_P (X) \
|| (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) \
|| (GET_CODE (X) == PLUS \
&& GET_CODE (XEXP (X, 0)) == REG \
&& REG_OK_FOR_BASE_P (XEXP (X, 0)) \
&& INDIRECTABLE_CONSTANT_ADDRESS_P (XEXP (X, 1))))
#else /* not NO_EXTERNAL_INDIRECT_ADDRESS */
#define INDIRECTABLE_CONSTANT_ADDRESS_P(X) CONSTANT_ADDRESS_P(X)
/* Nonzero if X is an address which can be indirected. */
#define INDIRECTABLE_ADDRESS_P(X) \
(CONSTANT_ADDRESS_P (X) \
|| (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) \
|| (GET_CODE (X) == PLUS \
&& GET_CODE (XEXP (X, 0)) == REG \
&& REG_OK_FOR_BASE_P (XEXP (X, 0)) \
&& CONSTANT_ADDRESS_P (XEXP (X, 1))))
#endif /* not NO_EXTERNAL_INDIRECT_ADDRESS */
/* Go to ADDR if X is a valid address not using indexing.
(This much is the easy part.) */
#define GO_IF_NONINDEXED_ADDRESS(X, ADDR) \
{ register rtx xfoob = (X); \
if (GET_CODE (xfoob) == REG) \
{ \
extern rtx *reg_equiv_mem; \
if (! reload_in_progress \
|| reg_equiv_mem[REGNO (xfoob)] == 0 \
|| INDIRECTABLE_ADDRESS_P (reg_equiv_mem[REGNO (xfoob)])) \
goto ADDR; \
} \
if (CONSTANT_ADDRESS_P (xfoob)) goto ADDR; \
if (INDIRECTABLE_ADDRESS_P (xfoob)) goto ADDR; \
xfoob = XEXP (X, 0); \
if (GET_CODE (X) == MEM && INDIRECTABLE_ADDRESS_P (xfoob)) \
goto ADDR; \
if ((GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_INC) \
&& GET_CODE (xfoob) == REG && REG_OK_FOR_BASE_P (xfoob)) \
goto ADDR; }
/* 1 if PROD is either a reg times size of mode MODE and MODE is less
than or equal 8 bytes, or just a reg if MODE is one byte.
This macro's expansion uses the temporary variables xfoo0 and xfoo1
that must be declared in the surrounding context. */
#define INDEX_TERM_P(PROD, MODE) \
(GET_MODE_SIZE (MODE) == 1 \
? (GET_CODE (PROD) == REG && REG_OK_FOR_BASE_P (PROD)) \
: (GET_CODE (PROD) == MULT && GET_MODE_SIZE (MODE) <= 8 \
&& \
(xfoo0 = XEXP (PROD, 0), xfoo1 = XEXP (PROD, 1), \
((((GET_CODE (xfoo0) == CONST_INT \
&& GET_CODE (xfoo1) == REG) \
&& INTVAL (xfoo0) == (int)GET_MODE_SIZE (MODE)) \
&& REG_OK_FOR_INDEX_P (xfoo1)) \
|| \
(((GET_CODE (xfoo1) == CONST_INT \
&& GET_CODE (xfoo0) == REG) \
&& INTVAL (xfoo1) == (int)GET_MODE_SIZE (MODE)) \
&& REG_OK_FOR_INDEX_P (xfoo0))))))
/* Go to ADDR if X is the sum of a register
and a valid index term for mode MODE. */
#define GO_IF_REG_PLUS_INDEX(X, MODE, ADDR) \
{ register rtx xfooa; \
if (GET_CODE (X) == PLUS) \
{ if (GET_CODE (XEXP (X, 0)) == REG \
&& REG_OK_FOR_BASE_P (XEXP (X, 0)) \
&& (xfooa = XEXP (X, 1), \
INDEX_TERM_P (xfooa, MODE))) \
goto ADDR; \
if (GET_CODE (XEXP (X, 1)) == REG \
&& REG_OK_FOR_BASE_P (XEXP (X, 1)) \
&& (xfooa = XEXP (X, 0), \
INDEX_TERM_P (xfooa, MODE))) \
goto ADDR; } }
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
{ register rtx xfoo, xfoo0, xfoo1; \
GO_IF_NONINDEXED_ADDRESS (X, ADDR); \
if (GET_CODE (X) == PLUS) \
{ /* Handle <address>[index] represented with index-sum outermost */\
xfoo = XEXP (X, 0); \
if (INDEX_TERM_P (xfoo, MODE)) \
{ GO_IF_NONINDEXED_ADDRESS (XEXP (X, 1), ADDR); } \
xfoo = XEXP (X, 1); \
if (INDEX_TERM_P (xfoo, MODE)) \
{ GO_IF_NONINDEXED_ADDRESS (XEXP (X, 0), ADDR); } \
/* Handle offset(reg)[index] with offset added outermost */ \
if (INDIRECTABLE_CONSTANT_ADDRESS_P (XEXP (X, 0))) \
{ if (GET_CODE (XEXP (X, 1)) == REG \
&& REG_OK_FOR_BASE_P (XEXP (X, 1))) \
goto ADDR; \
GO_IF_REG_PLUS_INDEX (XEXP (X, 1), MODE, ADDR); } \
if (INDIRECTABLE_CONSTANT_ADDRESS_P (XEXP (X, 1))) \
{ if (GET_CODE (XEXP (X, 0)) == REG \
&& REG_OK_FOR_BASE_P (XEXP (X, 0))) \
goto ADDR; \
GO_IF_REG_PLUS_INDEX (XEXP (X, 0), MODE, ADDR); } } }
/* Go to LABEL if ADDR (a legitimate address expression)
has an effect that depends on the machine mode it is used for.
On the VAX, the predecrement and postincrement address depend thus
(the amount of decrement or increment being the length of the operand)
and all indexed address depend thus (because the index scale factor
is the length of the operand). */
#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \
{ if (GET_CODE (ADDR) == POST_INC || GET_CODE (ADDR) == PRE_DEC) \
goto LABEL; \
if (GET_CODE (ADDR) == PLUS) \
{ if (CONSTANT_ADDRESS_P (XEXP (ADDR, 0)) \
&& GET_CODE (XEXP (ADDR, 1)) == REG); \
else if (CONSTANT_ADDRESS_P (XEXP (ADDR, 1)) \
&& GET_CODE (XEXP (ADDR, 0)) == REG); \
else goto LABEL; }}
has an effect that depends on the machine mode it is used for. */
#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \
{ if (vax_mode_dependent_address_p (ADDR)) goto LABEL; }
/* Specify the machine mode that this machine uses
for the index in the tablejump instruction. */