mirror of git://gcc.gnu.org/git/gcc.git
[V850] Hookize GO_IF_LEGITIMATE_ADDRESS
From-SVN: r225690
This commit is contained in:
parent
5d85afe92a
commit
b3ba1c09a8
|
|
@ -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>
|
2015-07-10 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
PR target/66819
|
PR target/66819
|
||||||
|
|
|
||||||
|
|
@ -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)))));
|
&& !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
|
static int
|
||||||
v850_memory_move_cost (machine_mode mode,
|
v850_memory_move_cost (machine_mode mode,
|
||||||
reg_class_t reg_class ATTRIBUTE_UNUSED,
|
reg_class_t reg_class ATTRIBUTE_UNUSED,
|
||||||
|
|
@ -3280,6 +3340,9 @@ v850_gen_movdi (rtx * operands)
|
||||||
#undef TARGET_LEGITIMATE_CONSTANT_P
|
#undef TARGET_LEGITIMATE_CONSTANT_P
|
||||||
#define TARGET_LEGITIMATE_CONSTANT_P v850_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
|
#undef TARGET_CAN_USE_DOLOOP_P
|
||||||
#define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost
|
#define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -592,88 +592,6 @@ struct cum_arg { int nbytes; };
|
||||||
/* Maximum number of registers that can appear in a valid memory address. */
|
/* Maximum number of registers that can appear in a valid memory address. */
|
||||||
|
|
||||||
#define MAX_REGS_PER_ADDRESS 1
|
#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,
|
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
|
||||||
return the mode to be used for the comparison.
|
return the mode to be used for the comparison.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue