From f50c32fa7ab4d3bb8b8091c6d38186799b81093b Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sun, 14 Jun 2020 22:09:36 -0700 Subject: [PATCH] gcc: xtensa: make register elimination data static Remove ABI reference from the ELIMINABLE_REGS to avoid static data initialization dependency on xtensa core configuration. 2020-06-15 Max Filippov gcc/ * config/xtensa/xtensa.c (xtensa_can_eliminate): New function. (TARGET_CAN_ELIMINATE): New macro. * config/xtensa/xtensa.h (XTENSA_WINDOWED_HARD_FRAME_POINTER_REGNUM) (XTENSA_CALL0_HARD_FRAME_POINTER_REGNUM): New macros. (HARD_FRAME_POINTER_REGNUM): Define using XTENSA_*_HARD_FRAME_POINTER_REGNUM. (ELIMINABLE_REGS): Replace lines with HARD_FRAME_POINTER_REGNUM by lines with XTENSA_WINDOWED_HARD_FRAME_POINTER_REGNUM and XTENSA_CALL0_HARD_FRAME_POINTER_REGNUM. --- gcc/config/xtensa/xtensa.c | 16 ++++++++++++++++ gcc/config/xtensa/xtensa.h | 26 ++++++++++++++++++-------- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c index 550c9cdfd89..e3afb70cdf0 100644 --- a/gcc/config/xtensa/xtensa.c +++ b/gcc/config/xtensa/xtensa.c @@ -183,6 +183,8 @@ static unsigned int xtensa_hard_regno_nregs (unsigned int, machine_mode); static bool xtensa_hard_regno_mode_ok (unsigned int, machine_mode); static bool xtensa_modes_tieable_p (machine_mode, machine_mode); static HOST_WIDE_INT xtensa_constant_alignment (const_tree, HOST_WIDE_INT); +static bool xtensa_can_eliminate (const int from ATTRIBUTE_UNUSED, + const int to); static HOST_WIDE_INT xtensa_starting_frame_offset (void); static unsigned HOST_WIDE_INT xtensa_asan_shadow_offset (void); @@ -326,6 +328,9 @@ static rtx xtensa_delegitimize_address (rtx); #undef TARGET_CONSTANT_ALIGNMENT #define TARGET_CONSTANT_ALIGNMENT xtensa_constant_alignment +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE xtensa_can_eliminate + #undef TARGET_STARTING_FRAME_OFFSET #define TARGET_STARTING_FRAME_OFFSET xtensa_starting_frame_offset @@ -4411,6 +4416,17 @@ xtensa_constant_alignment (const_tree exp, HOST_WIDE_INT align) return align; } +static bool +xtensa_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) +{ + gcc_assert (from == ARG_POINTER_REGNUM || from == FRAME_POINTER_REGNUM); + + /* If we need a frame pointer, ARG_POINTER_REGNUM and FRAME_POINTER_REGNUM + can only eliminate to HARD_FRAME_POINTER_REGNUM. */ + return to == HARD_FRAME_POINTER_REGNUM + || (!frame_pointer_needed && to == STACK_POINTER_REGNUM); +} + /* Implement TARGET_STARTING_FRAME_OFFSET. */ static HOST_WIDE_INT diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h index 8e1bcf823e4..fb5aee870dd 100644 --- a/gcc/config/xtensa/xtensa.h +++ b/gcc/config/xtensa/xtensa.h @@ -314,8 +314,13 @@ extern int leaf_function; #define STACK_POINTER_REGNUM (GP_REG_FIRST + 1) /* Base register for access to local variables of the function. */ -#define HARD_FRAME_POINTER_REGNUM (GP_REG_FIRST + \ - (TARGET_WINDOWED_ABI ? 7 : 15)) +#define HARD_FRAME_POINTER_REGNUM \ + (TARGET_WINDOWED_ABI \ + ? XTENSA_WINDOWED_HARD_FRAME_POINTER_REGNUM \ + : XTENSA_CALL0_HARD_FRAME_POINTER_REGNUM) + +#define XTENSA_WINDOWED_HARD_FRAME_POINTER_REGNUM (GP_REG_FIRST + 7) +#define XTENSA_CALL0_HARD_FRAME_POINTER_REGNUM (GP_REG_FIRST + 15) /* The register number of the frame pointer register, which is used to access automatic variables in the stack frame. For Xtensa, this @@ -434,12 +439,17 @@ enum reg_class || (flag_sanitize & SANITIZE_ADDRESS) != 0) /* The ARG_POINTER and FRAME_POINTER are not real Xtensa registers, so - they are eliminated to either the stack pointer or hard frame pointer. */ -#define ELIMINABLE_REGS \ -{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ - { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \ - { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ - { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}} + they are eliminated to either the stack pointer or hard frame pointer. + Since hard frame pointer is different register in windowed and call0 + ABIs list them both and only allow real HARD_FRAME_POINTER_REGNUM in + TARGET_CAN_ELIMINATE. */ +#define ELIMINABLE_REGS \ +{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ + { ARG_POINTER_REGNUM, XTENSA_WINDOWED_HARD_FRAME_POINTER_REGNUM}, \ + { ARG_POINTER_REGNUM, XTENSA_CALL0_HARD_FRAME_POINTER_REGNUM}, \ + { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ + { FRAME_POINTER_REGNUM, XTENSA_WINDOWED_HARD_FRAME_POINTER_REGNUM}, \ + { FRAME_POINTER_REGNUM, XTENSA_CALL0_HARD_FRAME_POINTER_REGNUM}} /* Specify the initial difference between the specified pair of registers. */ #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ -- 2.30.2