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:
Kaz Kojima 2010-04-11 22:59:36 +00:00
parent c11c09f9be
commit 6f50eb9c74
4 changed files with 99 additions and 77 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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

View File

@ -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. */