sh.c (regno_reg_class): Add GENERAL_REGS for soft frame pointer.

* config/sh/sh.c (regno_reg_class): Add GENERAL_REGS for
	soft frame pointer.
	(sh_expand_prologue): Use hard_frame_pointer_rtx instead
	of frame_pointer_rtx.
	(sh_expand_epilogue): Likewise.
	(sh_set_return_address): Likewise.
	(initial_elimination_offset): Use HARD_FRAME_POINTER_REGNUM
	instead of FRAME_POINTER_REGNUM if needed.  Add elimination
	offsets from FRAME_POINTER_REGNUM.
	* config/sh/sh.h (SH_REGISTER_NAMES_INITIALIZER): Add sfp.
	(sh_register_names): Add initializer for sfp.
	(GENERAL_OR_AP_REGISTER_P): Permit FRAME_POINTER_REGNUM.
	(VALID_REGISTER_P): Likewise.
	(FIRST_PSEUDO_REGISTER): Update.
	(DWARF_FRAME_REGISTERS): Define.
	(FIXED_REGISTERS, CALL_USED_REGISTERS): Add sfp.
	(HARD_FRAME_POINTER_REGNUM): Define.
	(FRAME_POINTER_REGNUM): Redefine.
	(ELIMINABLE_REGS): Never eliminate to FRAME_POINTER_REGNUM,
	but HARD_FRAME_POINTER_REGNUM instead.  Add eliminations
	from FRAME_POINTER_REGNUM.
	(CAN_ELIMINATE): Use HARD_FRAME_POINTER_REGNUM instead of
	FRAME_POINTER_REGNUM.
	(REG_CLASS_CONTENTS): Add sfp.
	(REG_ALLOC_ORDER): Likewise.
	(FRAME_GROWS_DOWNWARD): Set to 1.  Update comment.
	(GO_IF_LEGITIMATE_ADDRESS): Use hard_frame_pointer_rtx instead
	of frame_pointer_rtx.
	(LEGITIMIZE_RELOAD_ADDRESS): Likewise.

From-SVN: r102187
This commit is contained in:
Kaz Kojima 2005-07-20 05:03:25 +00:00
parent 1ade5842af
commit 96a2347e1d
3 changed files with 81 additions and 31 deletions

View File

@ -1,3 +1,35 @@
2005-07-20 Kaz Kojima <kkojima@gcc.gnu.org>
* config/sh/sh.c (regno_reg_class): Add GENERAL_REGS for
soft frame pointer.
(sh_expand_prologue): Use hard_frame_pointer_rtx instead
of frame_pointer_rtx.
(sh_expand_epilogue): Likewise.
(sh_set_return_address): Likewise.
(initial_elimination_offset): Use HARD_FRAME_POINTER_REGNUM
instead of FRAME_POINTER_REGNUM if needed. Add elimination
offsets from FRAME_POINTER_REGNUM.
* config/sh/sh.h (SH_REGISTER_NAMES_INITIALIZER): Add sfp.
(sh_register_names): Add initializer for sfp.
(GENERAL_OR_AP_REGISTER_P): Permit FRAME_POINTER_REGNUM.
(VALID_REGISTER_P): Likewise.
(FIRST_PSEUDO_REGISTER): Update.
(DWARF_FRAME_REGISTERS): Define.
(FIXED_REGISTERS, CALL_USED_REGISTERS): Add sfp.
(HARD_FRAME_POINTER_REGNUM): Define.
(FRAME_POINTER_REGNUM): Redefine.
(ELIMINABLE_REGS): Never eliminate to FRAME_POINTER_REGNUM,
but HARD_FRAME_POINTER_REGNUM instead. Add eliminations
from FRAME_POINTER_REGNUM.
(CAN_ELIMINATE): Use HARD_FRAME_POINTER_REGNUM instead of
FRAME_POINTER_REGNUM.
(REG_CLASS_CONTENTS): Add sfp.
(REG_ALLOC_ORDER): Likewise.
(FRAME_GROWS_DOWNWARD): Set to 1. Update comment.
(GO_IF_LEGITIMATE_ADDRESS): Use hard_frame_pointer_rtx instead
of frame_pointer_rtx.
(LEGITIMIZE_RELOAD_ADDRESS): Likewise.
2005-07-19 James A. Morrison <phython@gcc.gnu.org>
* fold-const.c (tree_expr_nonnegative_p): Only return true for

View File

@ -169,7 +169,7 @@ enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER] =
DF_REGS, DF_REGS, DF_REGS, DF_REGS,
NO_REGS, GENERAL_REGS, PR_REGS, T_REGS,
MAC_REGS, MAC_REGS, FPUL_REGS, FPSCR_REGS,
GENERAL_REGS,
GENERAL_REGS, GENERAL_REGS,
};
char sh_register_names[FIRST_PSEUDO_REGISTER] \
@ -6004,7 +6004,7 @@ sh_expand_prologue (void)
stack_pointer_rtx, 0, NULL);
if (frame_pointer_needed)
frame_insn (GEN_MOV (frame_pointer_rtx, stack_pointer_rtx));
frame_insn (GEN_MOV (hard_frame_pointer_rtx, stack_pointer_rtx));
if (TARGET_SHCOMPACT
&& (current_function_args_info.call_cookie & ~ CALL_COOKIE_RET_TRAMP(1)))
@ -6066,14 +6066,15 @@ sh_expand_epilogue (bool sibcall_p)
when exception handling is enabled. See PR/18032. */
if (flag_exceptions)
emit_insn (gen_blockage ());
output_stack_adjust (frame_size, frame_pointer_rtx, e, &live_regs_mask);
output_stack_adjust (frame_size, hard_frame_pointer_rtx, e,
&live_regs_mask);
/* We must avoid moving the stack pointer adjustment past code
which reads from the local frame, else an interrupt could
occur after the SP adjustment and clobber data in the local
frame. */
emit_insn (gen_blockage ());
emit_insn (GEN_MOV (stack_pointer_rtx, frame_pointer_rtx));
emit_insn (GEN_MOV (stack_pointer_rtx, hard_frame_pointer_rtx));
}
else if (frame_size)
{
@ -6350,7 +6351,7 @@ sh_set_return_address (rtx ra, rtx tmp)
pr_offset = rounded_frame_size (d);
emit_insn (GEN_MOV (tmp, GEN_INT (pr_offset)));
emit_insn (GEN_ADD3 (tmp, tmp, frame_pointer_rtx));
emit_insn (GEN_ADD3 (tmp, tmp, hard_frame_pointer_rtx));
tmp = gen_rtx_MEM (Pmode, tmp);
emit_insn (GEN_MOV (tmp, ra));
@ -7269,7 +7270,7 @@ initial_elimination_offset (int from, int to)
total_saved_regs_space = regs_saved + regs_saved_rounding;
if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
return total_saved_regs_space + total_auto_space
+ current_function_args_info.byref_regs * 8;
@ -7278,11 +7279,18 @@ initial_elimination_offset (int from, int to)
+ current_function_args_info.byref_regs * 8;
/* Initial gap between fp and sp is 0. */
if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
return 0;
if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
return rounded_frame_size (0);
if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
return rounded_frame_size (0);
gcc_assert (from == RETURN_ADDRESS_POINTER_REGNUM
&& (to == FRAME_POINTER_REGNUM || to == STACK_POINTER_REGNUM));
&& (to == HARD_FRAME_POINTER_REGNUM
|| to == STACK_POINTER_REGNUM));
if (TARGET_SH5)
{
int n = total_saved_regs_space;

View File

@ -882,7 +882,7 @@ extern char sh_register_names[][MAX_REGISTER_NAME_LENGTH + 1];
"tr0", "tr1", "tr2", "tr3", "tr4", "tr5", "tr6", "tr7", \
"xd0", "xd2", "xd4", "xd6", "xd8", "xd10", "xd12", "xd14", \
"gbr", "ap", "pr", "t", "mach", "macl", "fpul", "fpscr", \
"rap" \
"rap", "sfp" \
}
#define REGNAMES_ARR_INDEX_1(index) \
@ -907,7 +907,7 @@ extern char sh_register_names[][MAX_REGISTER_NAME_LENGTH + 1];
REGNAMES_ARR_INDEX_8 (128), \
REGNAMES_ARR_INDEX_8 (136), \
REGNAMES_ARR_INDEX_8 (144), \
REGNAMES_ARR_INDEX_1 (152) \
REGNAMES_ARR_INDEX_2 (152) \
}
#define ADDREGNAMES_SIZE 32
@ -969,7 +969,8 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
(unsigned HOST_WIDE_INT) LAST_GENERAL_REG)
#define GENERAL_OR_AP_REGISTER_P(REGNO) \
(GENERAL_REGISTER_P (REGNO) || ((REGNO) == AP_REG))
(GENERAL_REGISTER_P (REGNO) || ((REGNO) == AP_REG) \
|| ((REGNO) == FRAME_POINTER_REGNUM))
#define FP_REGISTER_P(REGNO) \
((int) (REGNO) >= FIRST_FP_REG && (int) (REGNO) <= LAST_FP_REG)
@ -999,6 +1000,7 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
#define VALID_REGISTER_P(REGNO) \
(SHMEDIA_REGISTER_P (REGNO) || XD_REGISTER_P (REGNO) \
|| (REGNO) == AP_REG || (REGNO) == RAP_REG \
|| (REGNO) == FRAME_POINTER_REGNUM \
|| (TARGET_SH1 && (SPECIAL_REGISTER_P (REGNO) || (REGNO) == PR_REG)) \
|| (TARGET_SH2E && (REGNO) == FPUL_REG))
@ -1011,7 +1013,10 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
? DImode \
: SImode)
#define FIRST_PSEUDO_REGISTER 153
#define FIRST_PSEUDO_REGISTER 154
/* Don't count soft frame pointer. */
#define DWARF_FRAME_REGISTERS (FIRST_PSEUDO_REGISTER - 1)
/* 1 for registers that have pervasive standard uses
and are not available for the register allocator.
@ -1048,8 +1053,8 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
0, 0, 0, 0, 0, 0, 0, 0, \
/*"gbr", "ap", "pr", "t", "mach", "macl", "fpul", "fpscr", */ \
1, 1, 1, 1, 1, 1, 0, 1, \
/*"rap" */ \
1, \
/*"rap", "sfp" */ \
1, 1, \
}
/* 1 for registers not available across function calls.
@ -1088,8 +1093,8 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
1, 1, 1, 1, 1, 1, 0, 0, \
/*"gbr", "ap", "pr", "t", "mach", "macl", "fpul", "fpscr", */ \
1, 1, 1, 1, 1, 1, 1, 1, \
/*"rap" */ \
1, \
/*"rap", "sfp" */ \
1, 1, \
}
/* CONDITIONAL_REGISTER_USAGE might want to make a register call-used, yet
@ -1204,7 +1209,10 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
#define STACK_POINTER_REGNUM SP_REG
/* Base register for access to local variables of the function. */
#define FRAME_POINTER_REGNUM FP_REG
#define HARD_FRAME_POINTER_REGNUM FP_REG
/* Base register for access to local variables of the function. */
#define FRAME_POINTER_REGNUM 153
/* Fake register that holds the address on the stack of the
current function's return address. */
@ -1246,16 +1254,18 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
of elimination fail. */
#define ELIMINABLE_REGS \
{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{{ HARD_FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
{ RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ RETURN_ADDRESS_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
{ RETURN_ADDRESS_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM},}
{ ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM},}
/* Given FROM and TO register numbers, say whether this elimination
is allowed. */
#define CAN_ELIMINATE(FROM, TO) \
(!((FROM) == FRAME_POINTER_REGNUM && FRAME_POINTER_REQUIRED))
(!((FROM) == HARD_FRAME_POINTER_REGNUM && FRAME_POINTER_REQUIRED))
/* Define the offset between two registers, one to be eliminated, and the other
its replacement, at the start of a routine. */
@ -1380,7 +1390,7 @@ enum reg_class
/* SIBCALL_REGS: Initialized in CONDITIONAL_REGISTER_USAGE. */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, \
/* GENERAL_REGS: */ \
{ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x01020000 }, \
{ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x03020000 }, \
/* FP0_REGS: */ \
{ 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000 }, \
/* FP_REGS: */ \
@ -1396,7 +1406,7 @@ enum reg_class
/* TARGET_REGS: */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000000ff }, \
/* ALL_REGS: */ \
{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01ffffff }, \
{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03ffffff }, \
}
/* The same information, inverted:
@ -1446,7 +1456,7 @@ extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
128,129,130,131,132,133,134,135, \
/* Fixed registers */ \
15, 16, 24, 25, 26, 27, 63,144, \
145,146,147,148,149,152 }
145,146,147,148,149,152,153 }
/* The class value for index registers, and the one for base regs. */
#define INDEX_REG_CLASS \
@ -1695,10 +1705,8 @@ extern enum reg_class reg_class_from_letter[];
#define STACK_GROWS_DOWNWARD
/* Define this macro to non-zero if the addresses of local variable slots
are at negative offsets from the frame pointer.
The SH only has positive indexes, so grow the frame up. */
#define FRAME_GROWS_DOWNWARD 0
are at negative offsets from the frame pointer. */
#define FRAME_GROWS_DOWNWARD 1
/* Offset from the frame pointer to the first local variable slot to
be allocated. */
@ -2528,9 +2536,11 @@ struct sh_args {
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 == frame_pointer_rtx) \
|| ((xop0 == stack_pointer_rtx \
|| xop0 == hard_frame_pointer_rtx) \
&& REG_P (xop1) && REGNO (xop1) == R0_REG) \
|| ((xop1 == stack_pointer_rtx || xop1 == frame_pointer_rtx) \
|| ((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) \
@ -2625,7 +2635,7 @@ struct sh_args {
&& ! ((MODE) == PSImode && (TYPE) == RELOAD_FOR_INPUT_ADDRESS) \
&& (ALLOW_INDEXED_ADDRESS \
|| XEXP ((X), 0) == stack_pointer_rtx \
|| XEXP ((X), 0) == frame_pointer_rtx)) \
|| XEXP ((X), 0) == hard_frame_pointer_rtx)) \
{ \
rtx index_rtx = XEXP (X, 1); \
HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base; \