re PR target/37633 (wrong register use on sh64)
PR target/37633 * config/sh/sh.c (sh_hard_regno_mode_ok): New function. * config/sh/sh.h (HARD_REGNO_MODE_OK): Use it. * config/sh/sh-protos.h (sh_hard_regno_mode_ok): Declare. From-SVN: r141282
This commit is contained in:
parent
e58d5f65d7
commit
347146a487
gcc
@ -1,3 +1,10 @@
|
||||
2008-10-22 Kaz Kojima <kkojima@gcc.gnu.org>
|
||||
|
||||
PR target/37633
|
||||
* config/sh/sh.c (sh_hard_regno_mode_ok): New function.
|
||||
* config/sh/sh.h (HARD_REGNO_MODE_OK): Use it.
|
||||
* config/sh/sh-protos.h (sh_hard_regno_mode_ok): Declare.
|
||||
|
||||
2008-10-22 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR target/37880
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Definitions of target machine for GNU compiler for Renesas / SuperH SH.
|
||||
Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2003,
|
||||
2004, 2005, 2006, 2007
|
||||
2004, 2005, 2006, 2007, 2008
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Steve Chamberlain (sac@cygnus.com).
|
||||
Improved by Jim Wilson (wilson@cygnus.com).
|
||||
@ -174,7 +174,7 @@ extern enum reg_class sh_secondary_reload (bool, rtx, enum reg_class,
|
||||
extern int sh2a_get_function_vector_number (rtx);
|
||||
extern int sh2a_is_function_vector_call (rtx);
|
||||
extern void sh_fix_range (const char *);
|
||||
|
||||
extern bool sh_hard_regno_mode_ok (unsigned int, enum machine_mode);
|
||||
#endif /* ! GCC_SH_PROTOS_H */
|
||||
|
||||
#ifdef SYMBIAN
|
||||
|
@ -10193,6 +10193,108 @@ sh_expand_binop_v2sf (enum rtx_code code, rtx op0, rtx op1, rtx op2)
|
||||
emit_insn (gen_binary_sf_op1 (op0, op1, op2, op));
|
||||
}
|
||||
|
||||
/* Return true if hard register REGNO can hold a value of machine-mode MODE.
|
||||
We can allow any mode in any general register. The special registers
|
||||
only allow SImode. Don't allow any mode in the PR.
|
||||
|
||||
We cannot hold DCmode values in the XD registers because alter_reg
|
||||
handles subregs of them incorrectly. We could work around this by
|
||||
spacing the XD registers like the DR registers, but this would require
|
||||
additional memory in every compilation to hold larger register vectors.
|
||||
We could hold SFmode / SCmode values in XD registers, but that
|
||||
would require a tertiary reload when reloading from / to memory,
|
||||
and a secondary reload to reload from / to general regs; that
|
||||
seems to be a loosing proposition.
|
||||
|
||||
We want to allow TImode FP regs so that when V4SFmode is loaded as TImode,
|
||||
it won't be ferried through GP registers first. */
|
||||
|
||||
bool
|
||||
sh_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
|
||||
{
|
||||
if (SPECIAL_REGISTER_P (regno))
|
||||
return mode == SImode;
|
||||
|
||||
if (regno == FPUL_REG)
|
||||
return (mode == SImode || mode == SFmode);
|
||||
|
||||
if (FP_REGISTER_P (regno) && mode == SFmode)
|
||||
return true;
|
||||
|
||||
if (mode == V2SFmode)
|
||||
{
|
||||
if (((FP_REGISTER_P (regno) && (regno - FIRST_FP_REG) % 2 == 0)
|
||||
|| GENERAL_REGISTER_P (regno)))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mode == V4SFmode)
|
||||
{
|
||||
if ((FP_REGISTER_P (regno) && (regno - FIRST_FP_REG) % 4 == 0)
|
||||
|| GENERAL_REGISTER_P (regno))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mode == V16SFmode)
|
||||
{
|
||||
if (TARGET_SHMEDIA)
|
||||
{
|
||||
if (FP_REGISTER_P (regno) && (regno - FIRST_FP_REG) % 16 == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return regno == FIRST_XD_REG;
|
||||
}
|
||||
|
||||
if (FP_REGISTER_P (regno))
|
||||
{
|
||||
if (mode == SFmode
|
||||
|| mode == SImode
|
||||
|| ((TARGET_SH2E || TARGET_SHMEDIA) && mode == SCmode)
|
||||
|| ((((TARGET_SH4 || TARGET_SH2A_DOUBLE) && mode == DFmode)
|
||||
|| mode == DCmode
|
||||
|| (TARGET_SHMEDIA
|
||||
&& (mode == DFmode || mode == DImode
|
||||
|| mode == V2SFmode || mode == TImode)))
|
||||
&& ((regno - FIRST_FP_REG) & 1) == 0)
|
||||
|| ((TARGET_SH4 || TARGET_SHMEDIA) && mode == TImode
|
||||
&& ((regno - FIRST_FP_REG) & 3) == 0))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if (XD_REGISTER_P (regno))
|
||||
return mode == DFmode;
|
||||
|
||||
if (TARGET_REGISTER_P (regno))
|
||||
return (mode == DImode || mode == SImode || mode == PDImode);
|
||||
|
||||
if (regno == PR_REG)
|
||||
return mode == SImode;
|
||||
|
||||
if (regno == FPSCR_REG)
|
||||
return mode == PSImode;
|
||||
|
||||
/* FIXME. This works around PR target/37633 for -O0. */
|
||||
if (!optimize && TARGET_SHMEDIA32 && GET_MODE_SIZE (mode) > 4)
|
||||
{
|
||||
unsigned int n = GET_MODE_SIZE (mode) / 8;
|
||||
|
||||
if (regno >= FIRST_GENERAL_REG + 10 - n + 1
|
||||
&& regno <= FIRST_GENERAL_REG + 14)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Return the class of registers for which a mode change from FROM to TO
|
||||
is invalid. */
|
||||
bool
|
||||
|
@ -1208,52 +1208,10 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
|
||||
? ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD/2 - 1) / (UNITS_PER_WORD/2)) \
|
||||
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
|
||||
|
||||
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
|
||||
We can allow any mode in any general register. The special registers
|
||||
only allow SImode. Don't allow any mode in the PR. */
|
||||
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. */
|
||||
|
||||
/* We cannot hold DCmode values in the XD registers because alter_reg
|
||||
handles subregs of them incorrectly. We could work around this by
|
||||
spacing the XD registers like the DR registers, but this would require
|
||||
additional memory in every compilation to hold larger register vectors.
|
||||
We could hold SFmode / SCmode values in XD registers, but that
|
||||
would require a tertiary reload when reloading from / to memory,
|
||||
and a secondary reload to reload from / to general regs; that
|
||||
seems to be a loosing proposition. */
|
||||
/* We want to allow TImode FP regs so that when V4SFmode is loaded as TImode,
|
||||
it won't be ferried through GP registers first. */
|
||||
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
|
||||
(SPECIAL_REGISTER_P (REGNO) ? (MODE) == SImode \
|
||||
: (REGNO) == FPUL_REG ? (MODE) == SImode || (MODE) == SFmode \
|
||||
: FP_REGISTER_P (REGNO) && (MODE) == SFmode \
|
||||
? 1 \
|
||||
: (MODE) == V2SFmode \
|
||||
? ((FP_REGISTER_P (REGNO) && ((REGNO) - FIRST_FP_REG) % 2 == 0) \
|
||||
|| GENERAL_REGISTER_P (REGNO)) \
|
||||
: (MODE) == V4SFmode \
|
||||
? ((FP_REGISTER_P (REGNO) && ((REGNO) - FIRST_FP_REG) % 4 == 0) \
|
||||
|| GENERAL_REGISTER_P (REGNO)) \
|
||||
: (MODE) == V16SFmode \
|
||||
? (TARGET_SHMEDIA \
|
||||
? (FP_REGISTER_P (REGNO) && ((REGNO) - FIRST_FP_REG) % 16 == 0) \
|
||||
: (REGNO) == FIRST_XD_REG) \
|
||||
: FP_REGISTER_P (REGNO) \
|
||||
? ((MODE) == SFmode || (MODE) == SImode \
|
||||
|| ((TARGET_SH2E || TARGET_SHMEDIA) && (MODE) == SCmode) \
|
||||
|| ((((TARGET_SH4 || TARGET_SH2A_DOUBLE) && (MODE) == DFmode) || (MODE) == DCmode \
|
||||
|| (TARGET_SHMEDIA && ((MODE) == DFmode || (MODE) == DImode \
|
||||
|| (MODE) == V2SFmode || (MODE) == TImode))) \
|
||||
&& (((REGNO) - FIRST_FP_REG) & 1) == 0) \
|
||||
|| ((TARGET_SH4 || TARGET_SHMEDIA) \
|
||||
&& (MODE) == TImode \
|
||||
&& (((REGNO) - FIRST_FP_REG) & 3) == 0)) \
|
||||
: XD_REGISTER_P (REGNO) \
|
||||
? (MODE) == DFmode \
|
||||
: TARGET_REGISTER_P (REGNO) \
|
||||
? ((MODE) == DImode || (MODE) == SImode || (MODE) == PDImode) \
|
||||
: (REGNO) == PR_REG ? (MODE) == SImode \
|
||||
: (REGNO) == FPSCR_REG ? (MODE) == PSImode \
|
||||
: 1)
|
||||
sh_hard_regno_mode_ok ((REGNO), (MODE))
|
||||
|
||||
/* Value is 1 if it is a good idea to tie two pseudo registers
|
||||
when one has mode MODE1 and one has mode MODE2.
|
||||
|
Loading…
Reference in New Issue
Block a user