diff options
author | Matt Thomas <matt@3am-software.com> | 2005-04-27 02:18:43 +0000 |
---|---|---|
committer | Matt Thomas <matt@gcc.gnu.org> | 2005-04-27 02:18:43 +0000 |
commit | fbf5558065bc2bd017d5d44864bacdaa68686081 (patch) | |
tree | f72e817f6196b693963cba7817da875ccc9d1ad6 /gcc/config/vax | |
parent | 5dbc71f87890e49c10594e4b38309ffc0ca508d9 (diff) | |
download | gcc-fbf5558065bc2bd017d5d44864bacdaa68686081.zip gcc-fbf5558065bc2bd017d5d44864bacdaa68686081.tar.gz gcc-fbf5558065bc2bd017d5d44864bacdaa68686081.tar.bz2 |
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
Diffstat (limited to 'gcc/config/vax')
-rw-r--r-- | gcc/config/vax/vax-protos.h | 6 | ||||
-rw-r--r-- | gcc/config/vax/vax.c | 224 | ||||
-rw-r--r-- | gcc/config/vax/vax.h | 173 |
3 files changed, 247 insertions, 156 deletions
diff --git a/gcc/config/vax/vax-protos.h b/gcc/config/vax/vax-protos.h index 3b07ae4..7c1efcc 100644 --- a/gcc/config/vax/vax-protos.h +++ b/gcc/config/vax/vax-protos.h @@ -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 */ - diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c index f39bcbf..c2396f6 100644 --- a/gcc/config/vax/vax.c +++ b/gcc/config/vax/vax.c @@ -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; +} diff --git a/gcc/config/vax/vax.h b/gcc/config/vax/vax.h index af3eab5..de8f0d6 100644 --- a/gcc/config/vax/vax.h +++ b/gcc/config/vax/vax.h @@ -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. - - The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS, - except for CONSTANT_ADDRESS_P which is actually machine-independent. */ - -#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); } } } - + 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; } + +#endif + /* 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. */ |