[Linux-Xtensa] [PATCH 1/2] gcc: xtensa: make register elimination data static

Max Filippov jcmvbkbc at gmail.com
Mon Jun 15 10:44:06 UTC 2020


Remove ABI reference from the ELIMINABLE_REGS to avoid static data
initialization dependency on xtensa core configuration.

2020-06-15  Max Filippov  <jcmvbkbc at 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.
---
 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 550c9cdfd892..e3afb70cdf04 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 8e1bcf823e46..fb5aee870dd5 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.20.1



More information about the linux-xtensa mailing list