[V850] Hookize GO_IF_LEGITIMATE_ADDRESS

From-SVN: r225690
This commit is contained in:
Anatoly Sokolov 2015-07-11 00:31:19 +03:00 committed by Anatoly Sokolov
parent 5d85afe92a
commit b3ba1c09a8
3 changed files with 72 additions and 82 deletions

View File

@ -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

View File

@ -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

View File

@ -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.