mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-23 19:03:59 +08:00
rtl.h (simplify_subreg_regno): Declare.
gcc/ * rtl.h (simplify_subreg_regno): Declare. * rtlanal.c (simplify_subreg_regno): New function, split out from... * simplify-rtx.c (simplify_subreg): ...here. * reload.c (find_reloads): Use simplify_subreg_regno instead of subreg_offset_representable_p. From-SVN: r139736
This commit is contained in:
parent
9b3f31f2ed
commit
eef302d277
@ -1,3 +1,11 @@
|
||||
2008-08-28 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* rtl.h (simplify_subreg_regno): Declare.
|
||||
* rtlanal.c (simplify_subreg_regno): New function, split out from...
|
||||
* simplify-rtx.c (simplify_subreg): ...here.
|
||||
* reload.c (find_reloads): Use simplify_subreg_regno instead of
|
||||
subreg_offset_representable_p.
|
||||
|
||||
2008-08-28 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
|
||||
|
||||
PR c/30949
|
||||
|
11
gcc/reload.c
11
gcc/reload.c
@ -2999,12 +2999,11 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
|
||||
if (REG_P (SUBREG_REG (operand))
|
||||
&& REGNO (SUBREG_REG (operand)) < FIRST_PSEUDO_REGISTER)
|
||||
{
|
||||
if (!subreg_offset_representable_p
|
||||
(REGNO (SUBREG_REG (operand)),
|
||||
GET_MODE (SUBREG_REG (operand)),
|
||||
SUBREG_BYTE (operand),
|
||||
GET_MODE (operand)))
|
||||
force_reload = 1;
|
||||
if (simplify_subreg_regno (REGNO (SUBREG_REG (operand)),
|
||||
GET_MODE (SUBREG_REG (operand)),
|
||||
SUBREG_BYTE (operand),
|
||||
GET_MODE (operand)) < 0)
|
||||
force_reload = 1;
|
||||
offset += subreg_regno_offset (REGNO (SUBREG_REG (operand)),
|
||||
GET_MODE (SUBREG_REG (operand)),
|
||||
SUBREG_BYTE (operand),
|
||||
|
@ -1084,6 +1084,8 @@ extern unsigned int subreg_regno_offset (unsigned int, enum machine_mode,
|
||||
extern bool subreg_offset_representable_p (unsigned int, enum machine_mode,
|
||||
unsigned int, enum machine_mode);
|
||||
extern unsigned int subreg_regno (const_rtx);
|
||||
extern int simplify_subreg_regno (unsigned int, enum machine_mode,
|
||||
unsigned int, enum machine_mode);
|
||||
extern unsigned int subreg_nregs (const_rtx);
|
||||
extern unsigned int subreg_nregs_with_regno (unsigned int, const_rtx);
|
||||
extern unsigned HOST_WIDE_INT nonzero_bits (const_rtx, enum machine_mode);
|
||||
|
@ -3244,6 +3244,64 @@ subreg_offset_representable_p (unsigned int xregno, enum machine_mode xmode,
|
||||
return info.representable_p;
|
||||
}
|
||||
|
||||
/* Return the number of a YMODE register to which
|
||||
|
||||
(subreg:YMODE (reg:XMODE XREGNO) OFFSET)
|
||||
|
||||
can be simplified. Return -1 if the subreg can't be simplified.
|
||||
|
||||
XREGNO is a hard register number. */
|
||||
|
||||
int
|
||||
simplify_subreg_regno (unsigned int xregno, enum machine_mode xmode,
|
||||
unsigned int offset, enum machine_mode ymode)
|
||||
{
|
||||
struct subreg_info info;
|
||||
unsigned int yregno;
|
||||
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
/* Give the backend a chance to disallow the mode change. */
|
||||
if (GET_MODE_CLASS (xmode) != MODE_COMPLEX_INT
|
||||
&& GET_MODE_CLASS (xmode) != MODE_COMPLEX_FLOAT
|
||||
&& REG_CANNOT_CHANGE_MODE_P (xregno, xmode, ymode))
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
/* We shouldn't simplify stack-related registers. */
|
||||
if ((!reload_completed || frame_pointer_needed)
|
||||
&& (xregno == FRAME_POINTER_REGNUM
|
||||
|| xregno == HARD_FRAME_POINTER_REGNUM))
|
||||
return -1;
|
||||
|
||||
if (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
|
||||
&& xregno == ARG_POINTER_REGNUM)
|
||||
return -1;
|
||||
|
||||
if (xregno == STACK_POINTER_REGNUM)
|
||||
return -1;
|
||||
|
||||
/* Try to get the register offset. */
|
||||
subreg_get_info (xregno, xmode, offset, ymode, &info);
|
||||
if (!info.representable_p)
|
||||
return -1;
|
||||
|
||||
/* Make sure that the offsetted register value is in range. */
|
||||
yregno = xregno + info.offset;
|
||||
if (!HARD_REGISTER_NUM_P (yregno))
|
||||
return -1;
|
||||
|
||||
/* See whether (reg:YMODE YREGNO) is valid.
|
||||
|
||||
??? We allow invalid registers if (reg:XMODE XREGNO) is also invalid.
|
||||
This is a kludge to work around how float/complex arguments are passed
|
||||
on 32-bit SPARC and should be fixed. */
|
||||
if (!HARD_REGNO_MODE_OK (yregno, ymode)
|
||||
&& HARD_REGNO_MODE_OK (xregno, xmode))
|
||||
return -1;
|
||||
|
||||
return (int) yregno;
|
||||
}
|
||||
|
||||
/* Return the final regno that a subreg expression refers to. */
|
||||
unsigned int
|
||||
subreg_regno (const_rtx x)
|
||||
|
@ -5069,35 +5069,13 @@ simplify_subreg (enum machine_mode outermode, rtx op,
|
||||
suppress this simplification. If the hard register is the stack,
|
||||
frame, or argument pointer, leave this as a SUBREG. */
|
||||
|
||||
if (REG_P (op)
|
||||
&& REGNO (op) < FIRST_PSEUDO_REGISTER
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
&& ! (REG_CANNOT_CHANGE_MODE_P (REGNO (op), innermode, outermode)
|
||||
&& GET_MODE_CLASS (innermode) != MODE_COMPLEX_INT
|
||||
&& GET_MODE_CLASS (innermode) != MODE_COMPLEX_FLOAT)
|
||||
#endif
|
||||
&& ((reload_completed && !frame_pointer_needed)
|
||||
|| (REGNO (op) != FRAME_POINTER_REGNUM
|
||||
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
|
||||
&& REGNO (op) != HARD_FRAME_POINTER_REGNUM
|
||||
#endif
|
||||
))
|
||||
#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
|
||||
&& REGNO (op) != ARG_POINTER_REGNUM
|
||||
#endif
|
||||
&& REGNO (op) != STACK_POINTER_REGNUM
|
||||
&& subreg_offset_representable_p (REGNO (op), innermode,
|
||||
byte, outermode))
|
||||
if (REG_P (op) && HARD_REGISTER_P (op))
|
||||
{
|
||||
unsigned int regno = REGNO (op);
|
||||
unsigned int final_regno
|
||||
= regno + subreg_regno_offset (regno, innermode, byte, outermode);
|
||||
unsigned int regno, final_regno;
|
||||
|
||||
/* ??? We do allow it if the current REG is not valid for
|
||||
its mode. This is a kludge to work around how float/complex
|
||||
arguments are passed on 32-bit SPARC and should be fixed. */
|
||||
if (HARD_REGNO_MODE_OK (final_regno, outermode)
|
||||
|| ! HARD_REGNO_MODE_OK (regno, innermode))
|
||||
regno = REGNO (op);
|
||||
final_regno = simplify_subreg_regno (regno, innermode, byte, outermode);
|
||||
if (HARD_REGISTER_NUM_P (final_regno))
|
||||
{
|
||||
rtx x;
|
||||
int final_offset = byte;
|
||||
|
Loading…
Reference in New Issue
Block a user