aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/vax
diff options
context:
space:
mode:
authorMatt Thomas <matt@3am-software.com>2005-04-27 02:18:43 +0000
committerMatt Thomas <matt@gcc.gnu.org>2005-04-27 02:18:43 +0000
commitfbf5558065bc2bd017d5d44864bacdaa68686081 (patch)
treef72e817f6196b693963cba7817da875ccc9d1ad6 /gcc/config/vax
parent5dbc71f87890e49c10594e4b38309ffc0ca508d9 (diff)
downloadgcc-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.h6
-rw-r--r--gcc/config/vax/vax.c224
-rw-r--r--gcc/config/vax/vax.h173
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. */