gcc: xtensa: make register elimination data static
authorMax Filippov <jcmvbkbc@gmail.com>
Mon, 15 Jun 2020 05:09:36 +0000 (22:09 -0700)
committerMax Filippov <jcmvbkbc@gmail.com>
Mon, 15 Jun 2020 10:24:23 +0000 (03:24 -0700)
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.

gcc/config/xtensa/xtensa.c
gcc/config/xtensa/xtensa.h

index 550c9cdfd89275cc5196ba4b71b1490f12916773..e3afb70cdf04aea6f9e138d3837d99cb8de51d01 100644 (file)
@@ -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
index 8e1bcf823e46bdf5447639b9d331ee15a5b0bded..fb5aee870dd5f199c87e7f1f6ef6cf1954f8664d 100644 (file)
@@ -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)                   \