mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-18 22:11:41 +08:00
* [SH] Miscellaneous changes for LRA.
From-SVN: r218889
This commit is contained in:
parent
106a52b7bf
commit
fc1fcfa0b6
@ -1,3 +1,17 @@
|
||||
2014-12-19 Kaz Kojima <kkojima@gcc.gnu.org>
|
||||
|
||||
* config/sh/predicates.md (general_movsrc_operand): Allow only
|
||||
valid plus address expressions.
|
||||
(general_movdst_operand): Likewise.
|
||||
(t_reg_operand): Allow (zero_extend (reg t)).
|
||||
* config/sh/sh-protos.h (sh_hard_regno_caller_save_mode): Declare.
|
||||
* config/sh/sh.c (sh_hard_regno_caller_save_mode): New function.
|
||||
(sh_secondary_reload): Return NO_REGS instead of FPUL_REGS in one
|
||||
case.
|
||||
* config/sh/sh.h (HARD_REGNO_CALLER_SAVE_MODE): Define.
|
||||
* config/sh/sh.md (untyped_call): Clobber function value
|
||||
registers before call.
|
||||
|
||||
2014-12-19 Kaz Kojima <kkojima@gcc.gnu.org>
|
||||
|
||||
* config/sh/sh.c (sh_lra_p): New function.
|
||||
|
@ -510,7 +510,25 @@
|
||||
&& GET_CODE (x) == PLUS && REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1)))
|
||||
return false;
|
||||
|
||||
if ((mode == QImode || mode == HImode)
|
||||
if (GET_CODE (x) == PLUS)
|
||||
{
|
||||
rtx y = XEXP (x, 0);
|
||||
|
||||
if (! REG_P (y)
|
||||
&& ! (GET_CODE (y) == SUBREG && REG_P (SUBREG_REG (y))))
|
||||
return false;
|
||||
y = XEXP (x, 1);
|
||||
if (! REG_P (y)
|
||||
&& ! (GET_CODE (y) == SUBREG && REG_P (SUBREG_REG (y)))
|
||||
&& ! CONST_INT_P (y))
|
||||
return false;
|
||||
}
|
||||
|
||||
/* LRA will try to satisfy the constraints for the memory displacements
|
||||
and thus we must not reject invalid displacements in the predicate,
|
||||
or else LRA will bail out.
|
||||
FIXME: maybe remove this check completely? */
|
||||
if (!lra_in_progress && (mode == QImode || mode == HImode)
|
||||
&& GET_CODE (x) == PLUS
|
||||
&& REG_P (XEXP (x, 0))
|
||||
&& CONST_INT_P (XEXP (x, 1)))
|
||||
@ -595,7 +613,25 @@
|
||||
&& GET_CODE (x) == PLUS && REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1)))
|
||||
return false;
|
||||
|
||||
if ((mode == QImode || mode == HImode)
|
||||
if (GET_CODE (x) == PLUS)
|
||||
{
|
||||
rtx y = XEXP (x, 0);
|
||||
|
||||
if (! REG_P (y)
|
||||
&& ! (GET_CODE (y) == SUBREG && REG_P (SUBREG_REG (y))))
|
||||
return false;
|
||||
y = XEXP (x, 1);
|
||||
if (! REG_P (y)
|
||||
&& ! (GET_CODE (y) == SUBREG && REG_P (SUBREG_REG (y)))
|
||||
&& ! CONST_INT_P (y))
|
||||
return false;
|
||||
}
|
||||
|
||||
/* LRA will try to satisfy the constraints for the memory displacements
|
||||
and thus we must not reject invalid displacements in the predicate,
|
||||
or else LRA will bail out.
|
||||
FIXME: maybe remove this check completely? */
|
||||
if (!lra_in_progress && (mode == QImode || mode == HImode)
|
||||
&& GET_CODE (x) == PLUS
|
||||
&& REG_P (XEXP (x, 0))
|
||||
&& CONST_INT_P (XEXP (x, 1)))
|
||||
@ -1117,6 +1153,8 @@
|
||||
|
||||
case ZERO_EXTEND:
|
||||
case SIGN_EXTEND:
|
||||
if (REG_P (XEXP (op, 0)) && REGNO (XEXP (op, 0)) == T_REG)
|
||||
return true;
|
||||
return GET_CODE (XEXP (op, 0)) == SUBREG
|
||||
&& REG_P (SUBREG_REG (XEXP (op, 0)))
|
||||
&& REGNO (SUBREG_REG (XEXP (op, 0))) == T_REG;
|
||||
|
@ -262,5 +262,7 @@ extern int sh2a_get_function_vector_number (rtx);
|
||||
extern bool sh2a_is_function_vector_call (rtx);
|
||||
extern void sh_fix_range (const char *);
|
||||
extern bool sh_hard_regno_mode_ok (unsigned int, machine_mode);
|
||||
extern machine_mode sh_hard_regno_caller_save_mode (unsigned int, unsigned int,
|
||||
machine_mode);
|
||||
extern bool sh_can_use_simple_return_p (void);
|
||||
#endif /* ! GCC_SH_PROTOS_H */
|
||||
|
@ -12186,6 +12186,26 @@ sh_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Specify the modes required to caller save a given hard regno.
|
||||
choose_hard_reg_mode chooses mode based on HARD_REGNO_MODE_OK
|
||||
and returns ?Imode for float regs when sh_hard_regno_mode_ok
|
||||
permits integer modes on them. That makes LRA's split process
|
||||
unhappy. See PR55212.
|
||||
*/
|
||||
machine_mode
|
||||
sh_hard_regno_caller_save_mode (unsigned int regno, unsigned int nregs,
|
||||
machine_mode mode)
|
||||
{
|
||||
if (FP_REGISTER_P (regno)
|
||||
&& (mode == SFmode
|
||||
|| mode == SCmode
|
||||
|| ((mode == DFmode || mode == DCmode)
|
||||
&& ((regno - FIRST_FP_REG) & 1) == 0)))
|
||||
return mode;
|
||||
|
||||
return choose_hard_reg_mode (regno, nregs, false);
|
||||
}
|
||||
|
||||
/* Return the class of registers for which a mode change from FROM to TO
|
||||
is invalid. */
|
||||
bool
|
||||
@ -13183,7 +13203,7 @@ sh_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i,
|
||||
{
|
||||
if (rclass == FPUL_REGS)
|
||||
return GENERAL_REGS;
|
||||
return FPUL_REGS;
|
||||
return NO_REGS; // LRA wants NO_REGS here, it used to be FPUL_REGS;
|
||||
}
|
||||
if ((rclass == TARGET_REGS
|
||||
|| (TARGET_SHMEDIA && rclass == SIBCALL_REGS))
|
||||
|
@ -905,6 +905,10 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
|
||||
&& (GET_MODE_SIZE (MODE2) <= 4)) \
|
||||
: ((MODE1) != SFmode && (MODE2) != SFmode))))
|
||||
|
||||
/* Specify the modes required to caller save a given hard regno. */
|
||||
#define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \
|
||||
sh_hard_regno_caller_save_mode ((REGNO), (NREGS), (MODE))
|
||||
|
||||
/* A C expression that is nonzero if hard register NEW_REG can be
|
||||
considered for use as a rename register for OLD_REG register */
|
||||
#define HARD_REGNO_RENAME_OK(OLD_REG, NEW_REG) \
|
||||
|
@ -10055,6 +10055,18 @@ label:
|
||||
(match_operand 2 "" "")])]
|
||||
"(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
|
||||
{
|
||||
if (! TARGET_SHMEDIA)
|
||||
{
|
||||
/* RA does not know that the call sets the function value registers.
|
||||
We avoid problems by claiming that those registers are clobbered
|
||||
at this point. */
|
||||
for (int i = 0; i < XVECLEN (operands[2], 0); i++)
|
||||
{
|
||||
rtx set = XVECEXP (operands[2], 0, i);
|
||||
emit_clobber (SET_SRC (set));
|
||||
}
|
||||
}
|
||||
|
||||
emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
|
||||
|
||||
for (int i = 0; i < XVECLEN (operands[2], 0); i++)
|
||||
|
Loading…
x
Reference in New Issue
Block a user