aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2020-06-14 22:09:36 -0700
committerMax Filippov <jcmvbkbc@gmail.com>2020-06-15 03:24:23 -0700
commitf50c32fa7ab4d3bb8b8091c6d38186799b81093b (patch)
tree2e08fa94114934bac2af06c0f41ae5a7535d75e0
parentce5a3d6bde7b3ca53c9988b057fa59ef411b1b76 (diff)
downloadgcc-f50c32fa7ab4d3bb8b8091c6d38186799b81093b.zip
gcc-f50c32fa7ab4d3bb8b8091c6d38186799b81093b.tar.gz
gcc-f50c32fa7ab4d3bb8b8091c6d38186799b81093b.tar.bz2
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 <jcmvbkbc@gmail.com> 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.
-rw-r--r--gcc/config/xtensa/xtensa.c16
-rw-r--r--gcc/config/xtensa/xtensa.h26
2 files changed, 34 insertions, 8 deletions
diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
index 550c9cd..e3afb70 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 8e1bcf8..fb5aee8 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) \