diff options
author | Kaz Kojima <kkojima@gcc.gnu.org> | 2005-07-20 05:03:25 +0000 |
---|---|---|
committer | Kaz Kojima <kkojima@gcc.gnu.org> | 2005-07-20 05:03:25 +0000 |
commit | 96a2347e1d837369cf266b937faf59511f0307ce (patch) | |
tree | ff2c9b1760f5089fcbdcdae862139ea4b667cf53 /gcc/config/sh | |
parent | 1ade5842af034a0f4e9d606b17ee3ea64375d78a (diff) | |
download | gcc-96a2347e1d837369cf266b937faf59511f0307ce.zip gcc-96a2347e1d837369cf266b937faf59511f0307ce.tar.gz gcc-96a2347e1d837369cf266b937faf59511f0307ce.tar.bz2 |
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
Diffstat (limited to 'gcc/config/sh')
-rw-r--r-- | gcc/config/sh/sh.c | 24 | ||||
-rw-r--r-- | gcc/config/sh/sh.h | 56 |
2 files changed, 49 insertions, 31 deletions
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 4ff591a..c773f4e 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -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; diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h index 61005f0..835f669 100644 --- a/gcc/config/sh/sh.h +++ b/gcc/config/sh/sh.h @@ -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; \ |