===================================================================
@@ -66,6 +66,7 @@
static void init_reg_tables (void);
static void block_move_call (rtx, rtx, rtx);
static int m32r_is_insn (rtx);
+static bool m32r_legitimate_address_p (enum machine_mode, rtx, bool);
static rtx m32r_legitimize_address (rtx, rtx, enum machine_mode);
static bool m32r_mode_dependent_address_p (const_rtx);
static tree m32r_handle_model_attribute (tree *, tree, tree, int, bool *);
@@ -124,6 +125,8 @@
#undef TARGET_ATTRIBUTE_TABLE
#define TARGET_ATTRIBUTE_TABLE m32r_attribute_table
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P m32r_legitimate_address_p
#undef TARGET_LEGITIMIZE_ADDRESS
#define TARGET_LEGITIMIZE_ADDRESS m32r_legitimize_address
#undef TARGET_MODE_DEPENDENT_ADDRESS_P
@@ -2844,6 +2847,107 @@
GEN_INT (3), SImode);
}
+/* True if X is a reg that can be used as a base reg. */
+
+static bool
+m32r_rtx_ok_for_base_p (const_rtx x, bool strict)
+{
+ if (! REG_P (x))
+ return false;
+
+ if (strict)
+ {
+ if (GPR_P (REGNO (x)))
+ return true;
+ }
+ else
+ {
+ if (GPR_P (REGNO (x))
+ || REGNO (x) == ARG_POINTER_REGNUM
+ || ! HARD_REGISTER_P (x))
+ return true;
+ }
+
+ return false;
+}
+
+static inline bool
+m32r_rtx_ok_for_offset_p (const_rtx x)
+{
+ return (CONST_INT_P (x) && INT16_P (INTVAL (x)));
+}
+
+static inline bool
+m32r_legitimate_offset_addres_p (enum machine_mode mode ATTRIBUTE_UNUSED,
+ const_rtx x, bool strict)
+{
+ if (GET_CODE (x) == PLUS
+ && m32r_rtx_ok_for_base_p (XEXP (x, 0), strict)
+ && m32r_rtx_ok_for_offset_p (XEXP (x, 1)))
+ return true;
+
+ return false;
+}
+
+/* For LO_SUM addresses, do not allow them if the MODE is > 1 word,
+ since more than one instruction will be required. */
+
+static inline bool
+m32r_legitimate_lo_sum_addres_p (enum machine_mode mode, const_rtx x,
+ bool strict)
+{
+ if (GET_CODE (x) == LO_SUM
+ && (mode != BLKmode && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
+ && m32r_rtx_ok_for_base_p (XEXP (x, 0), strict)
+ && CONSTANT_P (XEXP (x, 1)))
+ return true;
+
+ return false;
+}
+
+/* Is this a load and increment operation. */
+
+static inline bool
+m32r_load_postinc_p (enum machine_mode mode, const_rtx x, bool strict)
+{
+ if ((mode == SImode || mode == SFmode)
+ && GET_CODE (x) == POST_INC
+ && REG_P (XEXP (x, 0))
+ && m32r_rtx_ok_for_base_p (XEXP (x, 0), strict))
+ return true;
+
+ return false;
+}
+
+/* Is this an increment/decrement and store operation. */
+
+static inline bool
+m32r_store_preinc_predec_p (enum machine_mode mode, const_rtx x, bool strict)
+{
+ if ((mode == SImode || mode == SFmode)
+ && (GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
+ && REG_P (XEXP (x, 0)) \
+ && m32r_rtx_ok_for_base_p (XEXP (x, 0), strict))
+ return true;
+
+ return false;
+}
+
+/* Implement TARGET_LEGITIMATE_ADDRESS_P. */
+
+static bool
+m32r_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
+{
+ if (m32r_rtx_ok_for_base_p (x, strict)
+ || m32r_legitimate_offset_addres_p (mode, x, strict)
+ || m32r_legitimate_lo_sum_addres_p (mode, x, strict)
+ || m32r_load_postinc_p (mode, x, strict)
+ || m32r_store_preinc_predec_p (mode, x, strict))
+ return true;
+
+ return false;
+}
+
static void
m32r_conditional_register_usage (void)
{
===================================================================
@@ -118,7 +118,12 @@
(define_constraint "S"
"A store with pre {inc,dec}rement."
(and (match_code "mem")
- (match_test "STORE_PREINC_PREDEC_P (GET_MODE (op), XEXP (op, 0))")))
+ (match_test "mode == SImode || mode == SFmode")
+ (match_code "pre_inc,pre_dec" "0")
+ (match_code "reg" "00")
+ (match_test "GPR_P (REGNO (XEXP (XEXP (op, 0), 0)))
+ || REGNO (XEXP (XEXP (op, 0), 0)) == ARG_POINTER_REGNUM
+ || ! HARD_REGISTER_P (XEXP (XEXP (op, 0), 0))")))
(define_constraint "T"
"An indirect of a pointer."
@@ -128,7 +133,12 @@
(define_constraint "U"
"A load with post increment."
(and (match_code "mem")
- (match_test "LOAD_POSTINC_P (GET_MODE (op), XEXP (op, 0))")))
+ (match_test "mode == SImode || mode == SFmode")
+ (match_code "post_inc" "0")
+ (match_code "reg" "00")
+ (match_test "GPR_P (REGNO (XEXP (XEXP (op, 0), 0)))
+ || REGNO (XEXP (XEXP (op, 0), 0)) == ARG_POINTER_REGNUM
+ || ! HARD_REGISTER_P (XEXP (XEXP (op, 0), 0))")))
(define_constraint "W"
"zero immediate."
===================================================================
@@ -858,99 +858,6 @@
&& (GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF || GET_CODE (XEXP (XEXP (X, 0), 0)) == LABEL_REF) \
&& CONST_INT_P (XEXP (XEXP (X, 0), 1)) \
&& (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (X, 0), 1)) > 32767))
-
-/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
- and check its validity for a certain class.
- We have two alternate definitions for each of them.
- The usual definition accepts all pseudo regs; the other rejects
- them unless they have been allocated suitable hard regs.
- The symbol REG_OK_STRICT causes the latter definition to be used.
-
- Most source files want to accept pseudo regs in the hope that
- they will get allocated to the class that the insn wants them to be in.
- Source files for reload pass need to be strict.
- After reload, it makes no difference, since pseudo regs have
- been eliminated by then. */
-
-#ifdef REG_OK_STRICT
-
-/* Nonzero if X is a hard reg that can be used as a base reg. */
-#define REG_OK_FOR_BASE_P(X) GPR_P (REGNO (X))
-/* Nonzero if X is a hard reg that can be used as an index. */
-#define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_BASE_P (X)
-
-#else
-
-/* 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) \
- (GPR_P (REGNO (X)) \
- || (REGNO (X)) == ARG_POINTER_REGNUM \
- || REGNO (X) >= FIRST_PSEUDO_REGISTER)
-/* 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) REG_OK_FOR_BASE_P (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. */
-
-/* Local to this file. */
-#define RTX_OK_FOR_BASE_P(X) (REG_P (X) && REG_OK_FOR_BASE_P (X))
-
-/* Local to this file. */
-#define RTX_OK_FOR_OFFSET_P(X) \
- (CONST_INT_P (X) && INT16_P (INTVAL (X)))
-
-/* Local to this file. */
-#define LEGITIMATE_OFFSET_ADDRESS_P(MODE, X) \
- (GET_CODE (X) == PLUS \
- && RTX_OK_FOR_BASE_P (XEXP (X, 0)) \
- && RTX_OK_FOR_OFFSET_P (XEXP (X, 1)))
-
-/* Local to this file. */
-/* For LO_SUM addresses, do not allow them if the MODE is > 1 word,
- since more than one instruction will be required. */
-#define LEGITIMATE_LO_SUM_ADDRESS_P(MODE, X) \
- (GET_CODE (X) == LO_SUM \
- && (MODE != BLKmode && GET_MODE_SIZE (MODE) <= UNITS_PER_WORD)\
- && RTX_OK_FOR_BASE_P (XEXP (X, 0)) \
- && CONSTANT_P (XEXP (X, 1)))
-
-/* Local to this file. */
-/* Is this a load and increment operation. */
-#define LOAD_POSTINC_P(MODE, X) \
- (((MODE) == SImode || (MODE) == SFmode) \
- && GET_CODE (X) == POST_INC \
- && REG_P (XEXP (X, 0)) \
- && RTX_OK_FOR_BASE_P (XEXP (X, 0)))
-
-/* Local to this file. */
-/* Is this an increment/decrement and store operation. */
-#define STORE_PREINC_PREDEC_P(MODE, X) \
- (((MODE) == SImode || (MODE) == SFmode) \
- && (GET_CODE (X) == PRE_INC || GET_CODE (X) == PRE_DEC) \
- && REG_P (XEXP (X, 0)) \
- && RTX_OK_FOR_BASE_P (XEXP (X, 0)))
-
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
- do \
- { \
- if (RTX_OK_FOR_BASE_P (X)) \
- goto ADDR; \
- if (LEGITIMATE_OFFSET_ADDRESS_P ((MODE), (X))) \
- goto ADDR; \
- if (LEGITIMATE_LO_SUM_ADDRESS_P ((MODE), (X))) \
- goto ADDR; \
- if (LOAD_POSTINC_P ((MODE), (X))) \
- goto ADDR; \
- if (STORE_PREINC_PREDEC_P ((MODE), (X))) \
- goto ADDR; \
- } \
- while (0)
/* Condition code usage. */