xtensa: add support for SSP
authorMax Filippov <jcmvbkbc@gmail.com>
Mon, 8 May 2017 23:53:14 +0000 (23:53 +0000)
committerMax Filippov <jcmvbkbc@gcc.gnu.org>
Mon, 8 May 2017 23:53:14 +0000 (23:53 +0000)
gcc/
2017-05-08  Max Filippov  <jcmvbkbc@gmail.com>

* config/xtensa/xtensa-protos.h
        (xtensa_initial_elimination_offset): New declaration.
* config/xtensa/xtensa.c (xtensa_initial_elimination_offset):
New function. Move its body from the INITIAL_ELIMINATION_OFFSET
macro definition, add case for FRAME_POINTER_REGNUM when
FRAME_GROWS_DOWNWARD.
* config/xtensa/xtensa.h (FRAME_GROWS_DOWNWARD): New macro
definition.
(INITIAL_ELIMINATION_OFFSET): Replace body with call to
xtensa_initial_elimination_offset.

From-SVN: r247771

gcc/ChangeLog
gcc/config/xtensa/xtensa-protos.h
gcc/config/xtensa/xtensa.c
gcc/config/xtensa/xtensa.h

index 4ba97f7a8d198b1bfba27b88a50064fbc79cae42..2bfe7043ec71546ea2a17856519a86abf9093615 100644 (file)
@@ -1,3 +1,16 @@
+2017-05-08  Max Filippov  <jcmvbkbc@gmail.com>
+
+       * config/xtensa/xtensa-protos.h
+               (xtensa_initial_elimination_offset): New declaration.
+       * config/xtensa/xtensa.c (xtensa_initial_elimination_offset):
+       New function. Move its body from the INITIAL_ELIMINATION_OFFSET
+       macro definition, add case for FRAME_POINTER_REGNUM when
+       FRAME_GROWS_DOWNWARD.
+       * config/xtensa/xtensa.h (FRAME_GROWS_DOWNWARD): New macro
+       definition.
+       (INITIAL_ELIMINATION_OFFSET): Replace body with call to
+       xtensa_initial_elimination_offset.
+
 2017-05-08  Nathan Sidwell  <nathan@acm.org>
 
        * doc/invoke.texi: Alphabetize -fdump options.
index 38901b7530ae471235e3fa758207060eda37f886..dac5657948e5ae684cae4dc61eef9f1c91d4acfd 100644 (file)
@@ -73,5 +73,6 @@ extern void xtensa_expand_prologue (void);
 extern void xtensa_expand_epilogue (void);
 extern void order_regs_for_local_alloc (void);
 extern enum reg_class xtensa_regno_to_class (int regno);
+extern HOST_WIDE_INT xtensa_initial_elimination_offset (int from, int to);
 
 #endif /* !__XTENSA_PROTOS_H__ */
index 0181dde039bd770c2d6fee33d97932bfaa3a04bb..015dd1049fb23b0ebace45e4e0bdcdc21a6088d6 100644 (file)
@@ -2676,6 +2676,30 @@ xtensa_frame_pointer_required (void)
   return false;
 }
 
+HOST_WIDE_INT
+xtensa_initial_elimination_offset (int from, int to)
+{
+  long frame_size = compute_frame_size (get_frame_size ());
+  HOST_WIDE_INT offset;
+
+  switch (from)
+    {
+    case FRAME_POINTER_REGNUM:
+      if (FRAME_GROWS_DOWNWARD)
+       offset = frame_size - (WINDOW_SIZE * UNITS_PER_WORD)
+         - cfun->machine->callee_save_size;
+      else
+       offset = 0;
+      break;
+    case ARG_POINTER_REGNUM:
+      offset = frame_size;
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  return offset;
+}
 
 /* minimum frame = reg save area (4 words) plus static chain (1 word)
    and the total number of words must be a multiple of 128 bits.  */
index c32e8caf6dd4ea7fd94d416d1aad8849e5f39b35..08457a435a26f1cd7f6f211cf4717e4a46b43f0a 100644 (file)
@@ -460,9 +460,11 @@ enum reg_class
 
 #define STACK_GROWS_DOWNWARD 1
 
+#define FRAME_GROWS_DOWNWARD flag_stack_protect
+
 /* Offset within stack frame to start allocating local variables at.  */
 #define STARTING_FRAME_OFFSET                                          \
-  crtl->outgoing_args_size
+  (FRAME_GROWS_DOWNWARD ? 0 : crtl->outgoing_args_size)
 
 /* The ARG_POINTER and FRAME_POINTER are not real Xtensa registers, so
    they are eliminated to either the stack pointer or hard frame pointer.  */
@@ -474,20 +476,7 @@ enum reg_class
 
 /* Specify the initial difference between the specified pair of registers.  */
 #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)                   \
-  do {                                                                 \
-    long frame_size = compute_frame_size (get_frame_size ());          \
-    switch (FROM)                                                      \
-      {                                                                        \
-      case FRAME_POINTER_REGNUM:                                       \
-        (OFFSET) = 0;                                                  \
-       break;                                                          \
-      case ARG_POINTER_REGNUM:                                         \
-        (OFFSET) = frame_size;                                         \
-       break;                                                          \
-      default:                                                         \
-       gcc_unreachable ();                                             \
-      }                                                                        \
-  } while (0)
+  (OFFSET) = xtensa_initial_elimination_offset ((FROM), (TO))
 
 /* If defined, the maximum amount of space required for outgoing
    arguments will be computed and placed into the variable