sh-protos.h (sh_legitimize_reload_address): Declare.
* config/sh/sh-protos.h (sh_legitimize_reload_address): Declare. * config/sh/sh.c: Include reload.h. (sh_legitimize_reload_address): New. * config/sh/sh.h (LEGITIMIZE_RELOAD_ADDRESS): Use sh_legitimize_reload_address. From-SVN: r158208
This commit is contained in:
parent
c11c09f9be
commit
6f50eb9c74
|
@ -1,3 +1,11 @@
|
|||
2010-04-11 Kaz Kojima <kkojima@gcc.gnu.org>
|
||||
|
||||
* config/sh/sh-protos.h (sh_legitimize_reload_address): Declare.
|
||||
* config/sh/sh.c: Include reload.h.
|
||||
(sh_legitimize_reload_address): New.
|
||||
* config/sh/sh.h (LEGITIMIZE_RELOAD_ADDRESS): Use
|
||||
sh_legitimize_reload_address.
|
||||
|
||||
2010-04-11 Kaushik Phatak <kaushik.phatak@kpitcummins.com>
|
||||
|
||||
* config/sh/sh.md (*movqi_pop): New insn pattern.
|
||||
|
|
|
@ -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, 2008, 2009
|
||||
2004, 2005, 2006, 2007, 2008, 2009, 2010
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Steve Chamberlain (sac@cygnus.com).
|
||||
Improved by Jim Wilson (wilson@cygnus.com).
|
||||
|
@ -59,6 +59,7 @@ extern int fp_one_operand (rtx);
|
|||
extern int fp_int_operand (rtx);
|
||||
extern rtx get_fpscr_rtx (void);
|
||||
extern bool sh_legitimate_index_p (enum machine_mode, rtx);
|
||||
extern bool sh_legitimize_reload_address (rtx *, enum machine_mode, int, int);
|
||||
extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
|
||||
extern int nonpic_symbol_mentioned_p (rtx);
|
||||
extern void emit_sf_insn (rtx);
|
||||
|
|
|
@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "flags.h"
|
||||
#include "expr.h"
|
||||
#include "optabs.h"
|
||||
#include "reload.h"
|
||||
#include "function.h"
|
||||
#include "regs.h"
|
||||
#include "hard-reg-set.h"
|
||||
|
@ -9625,6 +9626,88 @@ sh_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
|
|||
return x;
|
||||
}
|
||||
|
||||
/* Attempt to replace *P, which is an address that needs reloading, with
|
||||
a valid memory address for an operand of mode MODE.
|
||||
Like for sh_legitimize_address, for the SH we try to get a normal form
|
||||
of the address. That will allow inheritance of the address reloads. */
|
||||
|
||||
bool
|
||||
sh_legitimize_reload_address (rtx *p, enum machine_mode mode, int opnum,
|
||||
int itype)
|
||||
{
|
||||
enum reload_type type = (enum reload_type) itype;
|
||||
|
||||
if (GET_CODE (*p) == PLUS
|
||||
&& (GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8)
|
||||
&& CONST_INT_P (XEXP (*p, 1))
|
||||
&& BASE_REGISTER_RTX_P (XEXP (*p, 0))
|
||||
&& ! TARGET_SHMEDIA
|
||||
&& ! (TARGET_SH4 && mode == DFmode)
|
||||
&& ! (mode == PSImode && type == RELOAD_FOR_INPUT_ADDRESS)
|
||||
&& (ALLOW_INDEXED_ADDRESS
|
||||
|| XEXP (*p, 0) == stack_pointer_rtx
|
||||
|| XEXP (*p, 0) == hard_frame_pointer_rtx))
|
||||
{
|
||||
rtx index_rtx = XEXP (*p, 1);
|
||||
HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base;
|
||||
rtx sum;
|
||||
|
||||
if (TARGET_SH2A && mode == DFmode && (offset & 0x7))
|
||||
{
|
||||
push_reload (*p, NULL_RTX, p, NULL,
|
||||
BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, type);
|
||||
goto win;
|
||||
}
|
||||
if (TARGET_SH2E && mode == SFmode)
|
||||
{
|
||||
*p = copy_rtx (*p);
|
||||
push_reload (*p, NULL_RTX, p, NULL,
|
||||
BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, type);
|
||||
goto win;
|
||||
}
|
||||
/* Instead of offset_base 128..131 use 124..127, so that
|
||||
simple add suffices. */
|
||||
if (offset > 127)
|
||||
offset_base = ((offset + 4) & ~60) - 4;
|
||||
else
|
||||
offset_base = offset & ~60;
|
||||
/* Sometimes the normal form does not suit DImode. We could avoid
|
||||
that by using smaller ranges, but that would give less optimized
|
||||
code when SImode is prevalent. */
|
||||
if (offset_base != 0
|
||||
&& GET_MODE_SIZE (mode) + offset - offset_base <= 64)
|
||||
{
|
||||
sum = gen_rtx_PLUS (Pmode, XEXP (*p, 0), GEN_INT (offset_base));
|
||||
*p = gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - offset_base));
|
||||
push_reload (sum, NULL_RTX, &XEXP (*p, 0), NULL,
|
||||
BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, type);
|
||||
goto win;
|
||||
}
|
||||
}
|
||||
/* We must re-recognize what we created before. */
|
||||
else if (GET_CODE (*p) == PLUS
|
||||
&& (GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8)
|
||||
&& GET_CODE (XEXP (*p, 0)) == PLUS
|
||||
&& CONST_INT_P (XEXP (XEXP (*p, 0), 1))
|
||||
&& BASE_REGISTER_RTX_P (XEXP (XEXP (*p, 0), 0))
|
||||
&& CONST_INT_P (XEXP (*p, 1))
|
||||
&& ! TARGET_SHMEDIA
|
||||
&& ! (TARGET_SH2E && mode == SFmode))
|
||||
{
|
||||
/* Because this address is so complex, we know it must have
|
||||
been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
|
||||
it is already unshared, and needs no further unsharing. */
|
||||
push_reload (XEXP (*p, 0), NULL_RTX, &XEXP (*p, 0), NULL,
|
||||
BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, type);
|
||||
goto win;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
win:
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Mark the use of a constant in the literal table. If the constant
|
||||
has multiple labels, make it unique. */
|
||||
static rtx
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* Definitions of target machine for GNU compiler for Renesas / SuperH SH.
|
||||
Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||
2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Steve Chamberlain (sac@cygnus.com).
|
||||
Improved by Jim Wilson (wilson@cygnus.com).
|
||||
|
||||
|
@ -2010,84 +2011,13 @@ struct sh_args {
|
|||
|
||||
/* A C compound statement that attempts to replace X, which is an address
|
||||
that needs reloading, with a valid memory address for an operand of
|
||||
mode MODE. WIN is a C statement label elsewhere in the code.
|
||||
|
||||
Like for LEGITIMIZE_ADDRESS, for the SH we try to get a normal form
|
||||
of the address. That will allow inheritance of the address reloads. */
|
||||
mode MODE. WIN is a C statement label elsewhere in the code. */
|
||||
|
||||
#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \
|
||||
{ \
|
||||
if (GET_CODE (X) == PLUS \
|
||||
&& (GET_MODE_SIZE (MODE) == 4 || GET_MODE_SIZE (MODE) == 8) \
|
||||
&& CONST_INT_P (XEXP (X, 1)) \
|
||||
&& BASE_REGISTER_RTX_P (XEXP (X, 0)) \
|
||||
&& ! TARGET_SHMEDIA \
|
||||
&& ! (TARGET_SH4 && (MODE) == DFmode) \
|
||||
&& ! ((MODE) == PSImode && (TYPE) == RELOAD_FOR_INPUT_ADDRESS) \
|
||||
&& (ALLOW_INDEXED_ADDRESS \
|
||||
|| XEXP ((X), 0) == stack_pointer_rtx \
|
||||
|| XEXP ((X), 0) == hard_frame_pointer_rtx)) \
|
||||
{ \
|
||||
rtx index_rtx = XEXP (X, 1); \
|
||||
HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base; \
|
||||
rtx sum; \
|
||||
\
|
||||
if (TARGET_SH2A && (MODE) == DFmode && (offset & 0x7)) \
|
||||
{ \
|
||||
push_reload (X, NULL_RTX, &X, NULL, \
|
||||
BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, (OPNUM), \
|
||||
(TYPE)); \
|
||||
goto WIN; \
|
||||
} \
|
||||
if (TARGET_SH2E && MODE == SFmode) \
|
||||
{ \
|
||||
X = copy_rtx (X); \
|
||||
push_reload (X, NULL_RTX, &X, NULL, \
|
||||
BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, (OPNUM), \
|
||||
(TYPE)); \
|
||||
goto WIN; \
|
||||
} \
|
||||
/* Instead of offset_base 128..131 use 124..127, so that \
|
||||
simple add suffices. */ \
|
||||
if (offset > 127) \
|
||||
{ \
|
||||
offset_base = ((offset + 4) & ~60) - 4; \
|
||||
} \
|
||||
else \
|
||||
offset_base = offset & ~60; \
|
||||
/* Sometimes the normal form does not suit DImode. We \
|
||||
could avoid that by using smaller ranges, but that \
|
||||
would give less optimized code when SImode is \
|
||||
prevalent. */ \
|
||||
if (GET_MODE_SIZE (MODE) + offset - offset_base <= 64) \
|
||||
{ \
|
||||
sum = gen_rtx_PLUS (Pmode, XEXP (X, 0), \
|
||||
GEN_INT (offset_base)); \
|
||||
X = gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - offset_base));\
|
||||
push_reload (sum, NULL_RTX, &XEXP (X, 0), NULL, \
|
||||
BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, (OPNUM), \
|
||||
(TYPE)); \
|
||||
goto WIN; \
|
||||
} \
|
||||
} \
|
||||
/* We must re-recognize what we created before. */ \
|
||||
else if (GET_CODE (X) == PLUS \
|
||||
&& (GET_MODE_SIZE (MODE) == 4 || GET_MODE_SIZE (MODE) == 8) \
|
||||
&& GET_CODE (XEXP (X, 0)) == PLUS \
|
||||
&& CONST_INT_P (XEXP (XEXP (X, 0), 1)) \
|
||||
&& BASE_REGISTER_RTX_P (XEXP (XEXP (X, 0), 0)) \
|
||||
&& CONST_INT_P (XEXP (X, 1)) \
|
||||
&& ! TARGET_SHMEDIA \
|
||||
&& ! (TARGET_SH2E && MODE == SFmode)) \
|
||||
{ \
|
||||
/* Because this address is so complex, we know it must have \
|
||||
been created by LEGITIMIZE_RELOAD_ADDRESS before; thus, \
|
||||
it is already unshared, and needs no further unsharing. */ \
|
||||
push_reload (XEXP ((X), 0), NULL_RTX, &XEXP ((X), 0), NULL, \
|
||||
BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, (OPNUM), (TYPE));\
|
||||
do { \
|
||||
if (sh_legitimize_reload_address (&(X), (MODE), (OPNUM), (TYPE))) \
|
||||
goto WIN; \
|
||||
} \
|
||||
}
|
||||
} while (0)
|
||||
|
||||
/* Specify the machine mode that this machine uses
|
||||
for the index in the tablejump instruction. */
|
||||
|
|
Loading…
Reference in New Issue