sh-protos.h (sh_legitimate_index_p): Declare.
* config/sh/sh-protos.h (sh_legitimate_index_p): Declare. (sh_legitimate_address_p): Likewise. * config/sh/sh.c (sh_legitimate_index_p): New. (sh_legitimate_address_p): Likewise. * config/sh/sh.h (REG_OK_FOR_BASE_P): Add STRICT parameter. (REG_OK_FOR_INDEX_P, SUBREG_OK_FOR_INDEX_P): Likewise. (MODE_DISP_OK_4, MODE_DISP_OK_8): Remove. (MAYBE_BASE_REGISTER_RTX_P): New macro. (MAYBE_INDEX_REGISTER_RTX_P): Likewise. (BASE_REGISTER_RTX_P): Use MAYBE_BASE_REGISTER_RTX_P. (INDEX_REGISTER_RTX_P): Use MAYBE_INDEX_REGISTER_RTX_P. (GO_IF_LEGITIMATE_INDEX): Use sh_legitimate_index_p. (GO_IF_LEGITIMATE_ADDRESS): Use sh_legitimate_address_p. From-SVN: r147450
This commit is contained in:
parent
1195342643
commit
cdeed45ae6
@ -1,3 +1,19 @@
|
||||
2009-05-12 Kaz Kojima <kkojima@gcc.gnu.org>
|
||||
|
||||
* config/sh/sh-protos.h (sh_legitimate_index_p): Declare.
|
||||
(sh_legitimate_address_p): Likewise.
|
||||
* config/sh/sh.c (sh_legitimate_index_p): New.
|
||||
(sh_legitimate_address_p): Likewise.
|
||||
* config/sh/sh.h (REG_OK_FOR_BASE_P): Add STRICT parameter.
|
||||
(REG_OK_FOR_INDEX_P, SUBREG_OK_FOR_INDEX_P): Likewise.
|
||||
(MODE_DISP_OK_4, MODE_DISP_OK_8): Remove.
|
||||
(MAYBE_BASE_REGISTER_RTX_P): New macro.
|
||||
(MAYBE_INDEX_REGISTER_RTX_P): Likewise.
|
||||
(BASE_REGISTER_RTX_P): Use MAYBE_BASE_REGISTER_RTX_P.
|
||||
(INDEX_REGISTER_RTX_P): Use MAYBE_INDEX_REGISTER_RTX_P.
|
||||
(GO_IF_LEGITIMATE_INDEX): Use sh_legitimate_index_p.
|
||||
(GO_IF_LEGITIMATE_ADDRESS): Use sh_legitimate_address_p.
|
||||
|
||||
2009-05-12 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* tree-inline.c (estimate_operator_cost): Add operands;
|
||||
|
@ -58,6 +58,8 @@ extern int fp_zero_operand (rtx);
|
||||
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_legitimate_address_p (enum machine_mode, rtx, bool);
|
||||
extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
|
||||
extern int nonpic_symbol_mentioned_p (rtx);
|
||||
extern void emit_sf_insn (rtx);
|
||||
|
@ -8950,6 +8950,124 @@ sh_insn_length_adjustment (rtx insn)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return TRUE for a valid displacement for the REG+disp addressing
|
||||
with MODE. */
|
||||
|
||||
/* ??? The SH2e does not have the REG+disp addressing mode when loading values
|
||||
into the FRx registers. We implement this by setting the maximum offset
|
||||
to zero when the value is SFmode. This also restricts loading of SFmode
|
||||
values into the integer registers, but that can't be helped. */
|
||||
|
||||
/* The SH allows a displacement in a QI or HI amode, but only when the
|
||||
other operand is R0. GCC doesn't handle this very well, so we forgot
|
||||
all of that.
|
||||
|
||||
A legitimate index for a QI or HI is 0, SI can be any number 0..63,
|
||||
DI can be any number 0..60. */
|
||||
|
||||
bool
|
||||
sh_legitimate_index_p (enum machine_mode mode, rtx op)
|
||||
{
|
||||
if (GET_CODE (op) == CONST_INT)
|
||||
{
|
||||
if (TARGET_SHMEDIA)
|
||||
{
|
||||
int size;
|
||||
|
||||
/* Check if this the address of an unaligned load / store. */
|
||||
if (mode == VOIDmode)
|
||||
return CONST_OK_FOR_I06 (INTVAL (op));
|
||||
|
||||
size = GET_MODE_SIZE (mode);
|
||||
return (!(INTVAL (op) & (size - 1))
|
||||
&& INTVAL (op) >= -512 * size
|
||||
&& INTVAL (op) < 512 * size);
|
||||
}
|
||||
|
||||
if (TARGET_SH2A)
|
||||
{
|
||||
if (GET_MODE_SIZE (mode) == 1
|
||||
&& (unsigned) INTVAL (op) < 4096)
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((GET_MODE_SIZE (mode) == 4
|
||||
&& (unsigned) INTVAL (op) < 64
|
||||
&& !(INTVAL (op) & 3)
|
||||
&& !(TARGET_SH2E && mode == SFmode))
|
||||
|| (GET_MODE_SIZE (mode) == 4
|
||||
&& (unsigned) INTVAL (op) < 16383
|
||||
&& !(INTVAL (op) & 3) && TARGET_SH2A))
|
||||
return true;
|
||||
|
||||
if ((GET_MODE_SIZE (mode) == 8
|
||||
&& (unsigned) INTVAL (op) < 60
|
||||
&& !(INTVAL (op) & 3)
|
||||
&& !((TARGET_SH4 || TARGET_SH2A) && mode == DFmode))
|
||||
|| ((GET_MODE_SIZE (mode)==8)
|
||||
&& (unsigned) INTVAL (op) < 8192
|
||||
&& !(INTVAL (op) & (TARGET_SH2A_DOUBLE ? 7 : 3))
|
||||
&& (TARGET_SH2A && mode == DFmode)))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Recognize an RTL expression that is a valid memory address for
|
||||
an instruction.
|
||||
The MODE argument is the machine mode for the MEM expression
|
||||
that wants to use this address.
|
||||
Allow REG
|
||||
REG+disp
|
||||
REG+r0
|
||||
REG++
|
||||
--REG */
|
||||
|
||||
bool
|
||||
sh_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
|
||||
{
|
||||
if (MAYBE_BASE_REGISTER_RTX_P (x, strict))
|
||||
return true;
|
||||
else if ((GET_CODE (x) == POST_INC || GET_CODE (x) == PRE_DEC)
|
||||
&& ! TARGET_SHMEDIA
|
||||
&& MAYBE_BASE_REGISTER_RTX_P (XEXP (x, 0), strict))
|
||||
return true;
|
||||
else if (GET_CODE (x) == PLUS
|
||||
&& (mode != PSImode || reload_completed))
|
||||
{
|
||||
rtx xop0 = XEXP (x, 0);
|
||||
rtx xop1 = XEXP (x, 1);
|
||||
|
||||
if (GET_MODE_SIZE (mode) <= 8
|
||||
&& MAYBE_BASE_REGISTER_RTX_P (xop0, strict)
|
||||
&& sh_legitimate_index_p (mode, xop1))
|
||||
return true;
|
||||
|
||||
if ((ALLOW_INDEXED_ADDRESS || GET_MODE (x) == DImode
|
||||
|| ((xop0 == stack_pointer_rtx
|
||||
|| xop0 == hard_frame_pointer_rtx)
|
||||
&& REG_P (xop1) && REGNO (xop1) == R0_REG)
|
||||
|| ((xop1 == stack_pointer_rtx
|
||||
|| xop1 == hard_frame_pointer_rtx)
|
||||
&& REG_P (xop0) && REGNO (xop0) == R0_REG))
|
||||
&& ((!TARGET_SHMEDIA && GET_MODE_SIZE (mode) <= 4)
|
||||
|| (TARGET_SHMEDIA && GET_MODE_SIZE (mode) <= 8)
|
||||
|| ((TARGET_SH4 || TARGET_SH2A_DOUBLE)
|
||||
&& TARGET_FMOVD && mode == DFmode)))
|
||||
{
|
||||
if (MAYBE_BASE_REGISTER_RTX_P (xop1, strict)
|
||||
&& MAYBE_INDEX_REGISTER_RTX_P (xop0, strict))
|
||||
return true;
|
||||
if (MAYBE_INDEX_REGISTER_RTX_P (xop1, strict)
|
||||
&& MAYBE_BASE_REGISTER_RTX_P (xop0, strict))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Return TRUE if X references a SYMBOL_REF or LABEL_REF whose symbol
|
||||
isn't protected by a PIC unspec. */
|
||||
int
|
||||
|
@ -2191,45 +2191,25 @@ struct sh_args {
|
||||
|
||||
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
|
||||
and check its validity for a certain class.
|
||||
We have two alternate definitions for each of them.
|
||||
The usual definition accepts all pseudo regs; the other rejects
|
||||
them unless they have been allocated suitable hard regs.
|
||||
The symbol REG_OK_STRICT causes the latter definition to be used. */
|
||||
The suitable hard regs are always accepted and all pseudo regs
|
||||
are also accepted if STRICT is not set. */
|
||||
|
||||
#ifndef REG_OK_STRICT
|
||||
/* Nonzero if X is a reg that can be used as a base reg. */
|
||||
#define REG_OK_FOR_BASE_P(X, STRICT) \
|
||||
(GENERAL_OR_AP_REGISTER_P (REGNO (X)) \
|
||||
|| (!STRICT && REGNO (X) >= FIRST_PSEUDO_REGISTER))
|
||||
|
||||
/* Nonzero if X is a hard reg that can be used as a base reg
|
||||
or if it is a pseudo reg. */
|
||||
#define REG_OK_FOR_BASE_P(X) \
|
||||
(GENERAL_OR_AP_REGISTER_P (REGNO (X)) || REGNO (X) >= FIRST_PSEUDO_REGISTER)
|
||||
/* Nonzero if X is a reg that can be used as an index. */
|
||||
#define REG_OK_FOR_INDEX_P(X, STRICT) \
|
||||
((TARGET_SHMEDIA ? GENERAL_REGISTER_P (REGNO (X)) \
|
||||
: REGNO (X) == R0_REG) \
|
||||
|| (!STRICT && REGNO (X) >= FIRST_PSEUDO_REGISTER))
|
||||
|
||||
/* Nonzero if X is a hard reg that can be used as an index
|
||||
or if it is a pseudo reg. */
|
||||
#define REG_OK_FOR_INDEX_P(X) \
|
||||
((TARGET_SHMEDIA ? GENERAL_REGISTER_P (REGNO (X)) \
|
||||
: REGNO (X) == R0_REG) || REGNO (X) >= FIRST_PSEUDO_REGISTER)
|
||||
|
||||
/* Nonzero if X/OFFSET is a hard reg that can be used as an index
|
||||
or if X is a pseudo reg. */
|
||||
#define SUBREG_OK_FOR_INDEX_P(X, OFFSET) \
|
||||
((TARGET_SHMEDIA ? GENERAL_REGISTER_P (REGNO (X)) \
|
||||
: REGNO (X) == R0_REG && OFFSET == 0) || REGNO (X) >= FIRST_PSEUDO_REGISTER)
|
||||
|
||||
#else
|
||||
|
||||
/* Nonzero if X is a hard reg that can be used as a base reg. */
|
||||
#define REG_OK_FOR_BASE_P(X) \
|
||||
REGNO_OK_FOR_BASE_P (REGNO (X))
|
||||
|
||||
/* Nonzero if X is a hard reg that can be used as an index. */
|
||||
#define REG_OK_FOR_INDEX_P(X) \
|
||||
REGNO_OK_FOR_INDEX_P (REGNO (X))
|
||||
|
||||
/* Nonzero if X/OFFSET is a hard reg that can be used as an index. */
|
||||
#define SUBREG_OK_FOR_INDEX_P(X, OFFSET) \
|
||||
(REGNO_OK_FOR_INDEX_P (REGNO (X)) && (OFFSET) == 0)
|
||||
|
||||
#endif
|
||||
/* Nonzero if X/OFFSET is a reg that can be used as an index. */
|
||||
#define SUBREG_OK_FOR_INDEX_P(X, OFFSET, STRICT) \
|
||||
((TARGET_SHMEDIA ? GENERAL_REGISTER_P (REGNO (X)) \
|
||||
: REGNO (X) == R0_REG && OFFSET == 0) \
|
||||
|| (!STRICT && REGNO (X) >= FIRST_PSEUDO_REGISTER))
|
||||
|
||||
/* Macros for extra constraints. */
|
||||
|
||||
@ -2305,144 +2285,55 @@ struct sh_args {
|
||||
|| PCREL_SYMOFF_P (OP)) \
|
||||
: NON_PIC_REFERENCE_P (OP))
|
||||
|
||||
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
|
||||
that is a valid memory address for an instruction.
|
||||
The MODE argument is the machine mode for the MEM expression
|
||||
that wants to use this address. */
|
||||
|
||||
#define MODE_DISP_OK_4(X,MODE) \
|
||||
(GET_MODE_SIZE (MODE) == 4 && (unsigned) INTVAL (X) < 64 \
|
||||
&& ! (INTVAL (X) & 3) && ! (TARGET_SH2E && (MODE) == SFmode))
|
||||
|
||||
#define MODE_DISP_OK_8(X,MODE) \
|
||||
((GET_MODE_SIZE(MODE)==8) && ((unsigned)INTVAL(X)<60) \
|
||||
&& ! (INTVAL(X) & 3) && ! (TARGET_SH4 && (MODE) == DFmode))
|
||||
|
||||
#undef MODE_DISP_OK_4
|
||||
#define MODE_DISP_OK_4(X,MODE) \
|
||||
((GET_MODE_SIZE (MODE) == 4 && (unsigned) INTVAL (X) < 64 \
|
||||
&& ! (INTVAL (X) & 3) && ! (TARGET_SH2E && (MODE) == SFmode)) \
|
||||
|| ((GET_MODE_SIZE(MODE)==4) && ((unsigned)INTVAL(X)<16383) \
|
||||
&& ! (INTVAL(X) & 3) && TARGET_SH2A))
|
||||
|
||||
#undef MODE_DISP_OK_8
|
||||
#define MODE_DISP_OK_8(X,MODE) \
|
||||
(((GET_MODE_SIZE(MODE)==8) && ((unsigned)INTVAL(X)<60) \
|
||||
&& ! (INTVAL(X) & 3) && ! ((TARGET_SH4 || TARGET_SH2A) && (MODE) == DFmode)) \
|
||||
|| ((GET_MODE_SIZE(MODE)==8) && ((unsigned)INTVAL(X)<8192) \
|
||||
&& ! (INTVAL(X) & (TARGET_SH2A_DOUBLE ? 7 : 3)) && (TARGET_SH2A && (MODE) == DFmode)))
|
||||
|
||||
#define BASE_REGISTER_RTX_P(X) \
|
||||
((GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) \
|
||||
|| (GET_CODE (X) == SUBREG \
|
||||
&& TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE ((X))), \
|
||||
#define MAYBE_BASE_REGISTER_RTX_P(X, STRICT) \
|
||||
((GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X, STRICT)) \
|
||||
|| (GET_CODE (X) == SUBREG \
|
||||
&& TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE ((X))), \
|
||||
GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (X)))) \
|
||||
&& GET_CODE (SUBREG_REG (X)) == REG \
|
||||
&& REG_OK_FOR_BASE_P (SUBREG_REG (X))))
|
||||
&& GET_CODE (SUBREG_REG (X)) == REG \
|
||||
&& REG_OK_FOR_BASE_P (SUBREG_REG (X), STRICT)))
|
||||
|
||||
/* Since this must be r0, which is a single register class, we must check
|
||||
SUBREGs more carefully, to be sure that we don't accept one that extends
|
||||
outside the class. */
|
||||
#define INDEX_REGISTER_RTX_P(X) \
|
||||
((GET_CODE (X) == REG && REG_OK_FOR_INDEX_P (X)) \
|
||||
|| (GET_CODE (X) == SUBREG \
|
||||
#define MAYBE_INDEX_REGISTER_RTX_P(X, STRICT) \
|
||||
((GET_CODE (X) == REG && REG_OK_FOR_INDEX_P (X, STRICT)) \
|
||||
|| (GET_CODE (X) == SUBREG \
|
||||
&& TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE ((X))), \
|
||||
GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (X)))) \
|
||||
&& GET_CODE (SUBREG_REG (X)) == REG \
|
||||
&& SUBREG_OK_FOR_INDEX_P (SUBREG_REG (X), SUBREG_BYTE (X))))
|
||||
&& SUBREG_OK_FOR_INDEX_P (SUBREG_REG (X), SUBREG_BYTE (X), STRICT)))
|
||||
|
||||
/* Jump to LABEL if X is a valid address RTX. This must also take
|
||||
REG_OK_STRICT into account when deciding about valid registers, but it uses
|
||||
the above macros so we are in luck.
|
||||
|
||||
Allow REG
|
||||
REG+disp
|
||||
REG+r0
|
||||
REG++
|
||||
--REG */
|
||||
|
||||
/* ??? The SH2e does not have the REG+disp addressing mode when loading values
|
||||
into the FRx registers. We implement this by setting the maximum offset
|
||||
to zero when the value is SFmode. This also restricts loading of SFmode
|
||||
values into the integer registers, but that can't be helped. */
|
||||
|
||||
/* The SH allows a displacement in a QI or HI amode, but only when the
|
||||
other operand is R0. GCC doesn't handle this very well, so we forgo
|
||||
all of that.
|
||||
|
||||
A legitimate index for a QI or HI is 0, SI can be any number 0..63,
|
||||
DI can be any number 0..60. */
|
||||
|
||||
#define GO_IF_LEGITIMATE_INDEX(MODE, OP, LABEL) \
|
||||
do { \
|
||||
if (GET_CODE (OP) == CONST_INT) \
|
||||
{ \
|
||||
if (TARGET_SHMEDIA) \
|
||||
{ \
|
||||
int MODE_SIZE; \
|
||||
/* Check if this the address of an unaligned load / store. */\
|
||||
if ((MODE) == VOIDmode) \
|
||||
{ \
|
||||
if (CONST_OK_FOR_I06 (INTVAL (OP))) \
|
||||
goto LABEL; \
|
||||
break; \
|
||||
} \
|
||||
MODE_SIZE = GET_MODE_SIZE (MODE); \
|
||||
if (! (INTVAL (OP) & (MODE_SIZE - 1)) \
|
||||
&& INTVAL (OP) >= -512 * MODE_SIZE \
|
||||
&& INTVAL (OP) < 512 * MODE_SIZE) \
|
||||
goto LABEL; \
|
||||
else \
|
||||
break; \
|
||||
} \
|
||||
if (TARGET_SH2A) \
|
||||
{ \
|
||||
if (GET_MODE_SIZE (MODE) == 1 \
|
||||
&& (unsigned) INTVAL (OP) < 4096) \
|
||||
goto LABEL; \
|
||||
} \
|
||||
if (MODE_DISP_OK_4 ((OP), (MODE))) goto LABEL; \
|
||||
if (MODE_DISP_OK_8 ((OP), (MODE))) goto LABEL; \
|
||||
} \
|
||||
} while(0)
|
||||
#ifdef REG_OK_STRICT
|
||||
#define BASE_REGISTER_RTX_P(X) MAYBE_BASE_REGISTER_RTX_P(X, true)
|
||||
#define INDEX_REGISTER_RTX_P(X) MAYBE_INDEX_REGISTER_RTX_P(X, true)
|
||||
#else
|
||||
#define BASE_REGISTER_RTX_P(X) MAYBE_BASE_REGISTER_RTX_P(X, false)
|
||||
#define INDEX_REGISTER_RTX_P(X) MAYBE_INDEX_REGISTER_RTX_P(X, false)
|
||||
#endif
|
||||
|
||||
#define ALLOW_INDEXED_ADDRESS \
|
||||
((!TARGET_SHMEDIA32 && !TARGET_SHCOMPACT) || TARGET_ALLOW_INDEXED_ADDRESS)
|
||||
|
||||
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
|
||||
{ \
|
||||
if (BASE_REGISTER_RTX_P (X)) \
|
||||
goto LABEL; \
|
||||
else if ((GET_CODE (X) == POST_INC || GET_CODE (X) == PRE_DEC) \
|
||||
&& ! TARGET_SHMEDIA \
|
||||
&& BASE_REGISTER_RTX_P (XEXP ((X), 0))) \
|
||||
goto LABEL; \
|
||||
else if (GET_CODE (X) == PLUS \
|
||||
&& ((MODE) != PSImode || reload_completed)) \
|
||||
{ \
|
||||
rtx xop0 = XEXP ((X), 0); \
|
||||
rtx xop1 = XEXP ((X), 1); \
|
||||
if (GET_MODE_SIZE (MODE) <= 8 && BASE_REGISTER_RTX_P (xop0)) \
|
||||
GO_IF_LEGITIMATE_INDEX ((MODE), xop1, LABEL); \
|
||||
if ((ALLOW_INDEXED_ADDRESS || GET_MODE (X) == DImode \
|
||||
|| ((xop0 == stack_pointer_rtx \
|
||||
|| xop0 == hard_frame_pointer_rtx) \
|
||||
&& REG_P (xop1) && REGNO (xop1) == R0_REG) \
|
||||
|| ((xop1 == stack_pointer_rtx \
|
||||
|| xop1 == hard_frame_pointer_rtx) \
|
||||
&& REG_P (xop0) && REGNO (xop0) == R0_REG)) \
|
||||
&& ((!TARGET_SHMEDIA && GET_MODE_SIZE (MODE) <= 4) \
|
||||
|| (TARGET_SHMEDIA && GET_MODE_SIZE (MODE) <= 8) \
|
||||
|| ((TARGET_SH4 || TARGET_SH2A_DOUBLE) \
|
||||
&& TARGET_FMOVD && MODE == DFmode))) \
|
||||
{ \
|
||||
if (BASE_REGISTER_RTX_P (xop1) && INDEX_REGISTER_RTX_P (xop0))\
|
||||
goto LABEL; \
|
||||
if (INDEX_REGISTER_RTX_P (xop1) && BASE_REGISTER_RTX_P (xop0))\
|
||||
goto LABEL; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
#define GO_IF_LEGITIMATE_INDEX(MODE, OP, WIN) \
|
||||
do { \
|
||||
if (sh_legitimate_index_p ((MODE), (OP))) \
|
||||
goto WIN; \
|
||||
} while (0)
|
||||
|
||||
#ifdef REG_OK_STRICT
|
||||
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
|
||||
do { \
|
||||
if (sh_legitimate_address_p ((MODE), (X), true)) \
|
||||
goto LABEL; \
|
||||
} while (0)
|
||||
#else
|
||||
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
|
||||
do { \
|
||||
if (sh_legitimate_address_p ((MODE), (X), false)) \
|
||||
goto LABEL; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
|
Loading…
Reference in New Issue
Block a user