aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/v850/v850.c63
-rw-r--r--gcc/config/v850/v850.h82
3 files changed, 72 insertions, 82 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index efaf9d3..e45616e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2015-07-10 Anatoly Sokolov <aesok@post.ru>
+
+ * config/v850/v850.h (REG_OK_FOR_BASE_P, REG_OK_FOR_INDEX_P,
+ REG_OK_FOR_BASE_P_STRICT, REG_OK_FOR_INDEX_P_STRICT, STRICT,
+ RTX_OK_FOR_BASE_P, GO_IF_LEGITIMATE_ADDRESS): Remove macros.
+ * config/v850/v850.c (v850_reg_ok_for_base_, v850_rtx_ok_for_base_p,
+ v850_legitimate_address_p): New functions.
+ (TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P): Define.
+
2015-07-10 H.J. Lu <hongjiu.lu@intel.com>
PR target/66819
diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c
index 95c20cc..2474e75 100644
--- a/gcc/config/v850/v850.c
+++ b/gcc/config/v850/v850.c
@@ -3078,6 +3078,66 @@ v850_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
&& !CONST_OK_FOR_K (INTVAL (XEXP (XEXP (x, 0), 1)))));
}
+/* Helper function for `v850_legitimate_address_p'. */
+
+static bool
+v850_reg_ok_for_base_p (const_rtx reg, bool strict_p)
+{
+ if (strict_p)
+ {
+ return REGNO_OK_FOR_BASE_P (REGNO (reg));
+ } else {
+ return true;
+ }
+}
+
+/* Accept either REG or SUBREG where a register is valid. */
+
+static bool
+v850_rtx_ok_for_base_p (const_rtx x, bool strict_p)
+{
+ return ((REG_P (x) && v850_reg_ok_for_base_p (x, strict_p))
+ || (SUBREG_P (x) && REG_P (SUBREG_REG (x))
+ && v850_reg_ok_for_base_p (SUBREG_REG (x), strict_p)));
+}
+
+/* Implement TARGET_LEGITIMATE_ADDRESS_P. */
+
+static bool
+v850_legitimate_address_p (machine_mode mode, rtx x, bool strict_p,
+ addr_space_t as ATTRIBUTE_UNUSED)
+{
+ gcc_assert (ADDR_SPACE_GENERIC_P (as));
+
+ if (v850_rtx_ok_for_base_p (x, strict_p))
+ return true;
+ if (CONSTANT_ADDRESS_P (x)
+ && (mode == QImode || INTVAL (x) % 2 == 0)
+ && (GET_MODE_SIZE (mode) <= 4 || INTVAL (x) % 4 == 0))
+ return true;
+ if (GET_CODE (x) == LO_SUM
+ && REG_P (XEXP (x, 0))
+ && v850_reg_ok_for_base_p (XEXP (x, 0), strict_p)
+ && CONSTANT_P (XEXP (x, 1))
+ && (!CONST_INT_P (XEXP (x, 1))
+ || ((mode == QImode || INTVAL (XEXP (x, 1)) % 2 == 0)
+ && constraint_satisfied_p (XEXP (x, 1), CONSTRAINT_K)))
+ && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (word_mode))
+ return true;
+ if (special_symbolref_operand (x, mode)
+ && (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (word_mode)))
+ return true;
+ if (GET_CODE (x) == PLUS
+ && v850_rtx_ok_for_base_p (XEXP (x, 0), strict_p)
+ && constraint_satisfied_p (XEXP (x,1), CONSTRAINT_K)
+ && ((mode == QImode || INTVAL (XEXP (x, 1)) % 2 == 0)
+ && CONST_OK_FOR_K (INTVAL (XEXP (x, 1))
+ + (GET_MODE_NUNITS (mode) * UNITS_PER_WORD))))
+ return true;
+
+ return false;
+}
+
static int
v850_memory_move_cost (machine_mode mode,
reg_class_t reg_class ATTRIBUTE_UNUSED,
@@ -3280,6 +3340,9 @@ v850_gen_movdi (rtx * operands)
#undef TARGET_LEGITIMATE_CONSTANT_P
#define TARGET_LEGITIMATE_CONSTANT_P v850_legitimate_constant_p
+#undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
+#define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P v850_legitimate_address_p
+
#undef TARGET_CAN_USE_DOLOOP_P
#define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost
diff --git a/gcc/config/v850/v850.h b/gcc/config/v850/v850.h
index 45ff1d5..dcc169b 100644
--- a/gcc/config/v850/v850.h
+++ b/gcc/config/v850/v850.h
@@ -592,88 +592,6 @@ struct cum_arg { int nbytes; };
/* Maximum number of registers that can appear in a valid memory address. */
#define MAX_REGS_PER_ADDRESS 1
-
-/* 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. */
-
-#ifndef REG_OK_STRICT
-
-/* 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) 0
-/* 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
-#define REG_OK_FOR_INDEX_P_STRICT(X) 0
-#define REG_OK_FOR_BASE_P_STRICT(X) REGNO_OK_FOR_BASE_P (REGNO (X))
-#define STRICT 0
-
-#else
-
-/* Nonzero if X is a hard reg that can be used as an index. */
-#define REG_OK_FOR_INDEX_P(X) 0
-/* 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 1
-
-#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. */
-
-/* Accept either REG or SUBREG where a register is valid. */
-
-#define RTX_OK_FOR_BASE_P(X) \
- ((REG_P (X) && REG_OK_FOR_BASE_P (X)) \
- || (GET_CODE (X) == SUBREG && REG_P (SUBREG_REG (X)) \
- && REG_OK_FOR_BASE_P (SUBREG_REG (X))))
-
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-do { \
- if (RTX_OK_FOR_BASE_P (X)) \
- goto ADDR; \
- if (CONSTANT_ADDRESS_P (X) \
- && (MODE == QImode || INTVAL (X) % 2 == 0) \
- && (GET_MODE_SIZE (MODE) <= 4 || INTVAL (X) % 4 == 0)) \
- goto ADDR; \
- if (GET_CODE (X) == LO_SUM \
- && REG_P (XEXP (X, 0)) \
- && REG_OK_FOR_BASE_P (XEXP (X, 0)) \
- && CONSTANT_P (XEXP (X, 1)) \
- && (GET_CODE (XEXP (X, 1)) != CONST_INT \
- || ((MODE == QImode || INTVAL (XEXP (X, 1)) % 2 == 0) \
- && CONST_OK_FOR_K (INTVAL (XEXP (X, 1))))) \
- && GET_MODE_SIZE (MODE) <= GET_MODE_SIZE (word_mode)) \
- goto ADDR; \
- if (special_symbolref_operand (X, MODE) \
- && (GET_MODE_SIZE (MODE) <= GET_MODE_SIZE (word_mode))) \
- goto ADDR; \
- if (GET_CODE (X) == PLUS \
- && RTX_OK_FOR_BASE_P (XEXP (X, 0)) \
- && constraint_satisfied_p (XEXP (X,1), CONSTRAINT_K) \
- && ((MODE == QImode || INTVAL (XEXP (X, 1)) % 2 == 0) \
- && CONST_OK_FOR_K (INTVAL (XEXP (X, 1)) \
- + (GET_MODE_NUNITS (MODE) * UNITS_PER_WORD)))) \
- goto ADDR; \
-} while (0)
-
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
return the mode to be used for the comparison.