]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
s390.c (s390_frame_info): Restructure function.
authorAndreas Krebbel <Andreas.Krebbel@de.ibm.com>
Wed, 9 Oct 2013 07:23:53 +0000 (07:23 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Wed, 9 Oct 2013 07:23:53 +0000 (07:23 +0000)
2013-10-09  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

* config/s390/s390.c (s390_frame_info): Restructure function.

From-SVN: r203304

gcc/ChangeLog
gcc/config/s390/s390.c

index 9d3cad9784e5d3fecb7899f90fdd104f651e771c..56940339fba5a3fb85d567b58e18cebbbc042246 100644 (file)
@@ -1,3 +1,7 @@
+2013-10-09  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
+
+       * config/s390/s390.c (s390_frame_info): Restructure function.
+
 2013-10-09  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
 
        * config/s390/s390.c (struct s390_frame_layout): New field
index a833fd64ea0a948c12797b6f39bee0ff6a18cb2e..28a09ecf34970dd722f9885cd02e8325687f3e0e 100644 (file)
@@ -7781,7 +7781,7 @@ s390_optimize_register_info ()
 static void
 s390_frame_info (void)
 {
-  int i;
+  HOST_WIDE_INT lowest_offset;
 
   cfun_frame_layout.first_save_gpr_slot = cfun_frame_layout.first_save_gpr;
   cfun_frame_layout.last_save_gpr_slot = cfun_frame_layout.last_save_gpr;
@@ -7805,6 +7805,7 @@ s390_frame_info (void)
 
   if (!TARGET_PACKED_STACK)
     {
+      /* Fixed stack layout.  */
       cfun_frame_layout.backchain_offset = 0;
       cfun_frame_layout.f0_offset = 16 * UNITS_PER_LONG;
       cfun_frame_layout.f4_offset = cfun_frame_layout.f0_offset + 2 * 8;
@@ -7812,45 +7813,30 @@ s390_frame_info (void)
       cfun_frame_layout.gprs_offset = (cfun_frame_layout.first_save_gpr_slot
                                       * UNITS_PER_LONG);
     }
-  else if (TARGET_BACKCHAIN) /* kernel stack layout */
+  else if (TARGET_BACKCHAIN)
     {
+      /* Kernel stack layout - packed stack, backchain, no float  */
+      gcc_assert (TARGET_SOFT_FLOAT);
       cfun_frame_layout.backchain_offset = (STACK_POINTER_OFFSET
                                            - UNITS_PER_LONG);
-      cfun_frame_layout.gprs_offset
-       = (cfun_frame_layout.backchain_offset
-          - (STACK_POINTER_REGNUM - cfun_frame_layout.first_save_gpr_slot + 1)
-          * UNITS_PER_LONG);
 
-      if (TARGET_64BIT)
-       {
-         cfun_frame_layout.f4_offset
-           = (cfun_frame_layout.gprs_offset
-              - 8 * (cfun_fpr_save_p (FPR4_REGNUM)
-                     + cfun_fpr_save_p (FPR6_REGNUM)));
+      /* The distance between the backchain and the return address
+        save slot must not change.  So we always need a slot for the
+        stack pointer which resides in between.  */
+      cfun_frame_layout.last_save_gpr_slot = STACK_POINTER_REGNUM;
 
-         cfun_frame_layout.f0_offset
-           = (cfun_frame_layout.f4_offset
-              - 8 * (cfun_fpr_save_p (FPR0_REGNUM)
-                     + cfun_fpr_save_p (FPR2_REGNUM)));
-       }
-      else
-       {
-         /* On 31 bit we have to care about alignment of the
-            floating point regs to provide fastest access.  */
-         cfun_frame_layout.f0_offset
-           = ((cfun_frame_layout.gprs_offset
-               & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1))
-              - 8 * (cfun_fpr_save_p (FPR0_REGNUM)
-                     + cfun_fpr_save_p (FPR2_REGNUM)));
+      cfun_frame_layout.gprs_offset
+       = cfun_frame_layout.backchain_offset - cfun_gprs_save_area_size;
 
-         cfun_frame_layout.f4_offset
-           = (cfun_frame_layout.f0_offset
-              - 8 * (cfun_fpr_save_p (FPR4_REGNUM)
-                     + cfun_fpr_save_p (FPR6_REGNUM)));
-       }
+      /* FPRs will not be saved.  Nevertheless pick sane values to
+        keep area calculations valid.  */
+      cfun_frame_layout.f0_offset =
+       cfun_frame_layout.f4_offset =
+       cfun_frame_layout.f8_offset = cfun_frame_layout.gprs_offset;
     }
-  else /* no backchain */
+  else
     {
+      /* Packed stack layout without backchain.  */
       cfun_frame_layout.f4_offset
        = (STACK_POINTER_OFFSET
           - 8 * (cfun_fpr_save_p (FPR4_REGNUM)
@@ -7863,47 +7849,49 @@ s390_frame_info (void)
 
       cfun_frame_layout.gprs_offset
        = cfun_frame_layout.f0_offset - cfun_gprs_save_area_size;
+
+      cfun_frame_layout.f8_offset = (cfun_frame_layout.gprs_offset
+                                    - cfun_frame_layout.high_fprs * 8);
     }
 
+  if (cfun_save_high_fprs_p)
+    cfun_frame_layout.frame_size += cfun_frame_layout.high_fprs * 8;
+
+  if (!crtl->is_leaf)
+    cfun_frame_layout.frame_size += crtl->outgoing_args_size;
+
+  /* In the following cases we have to allocate a STACK_POINTER_OFFSET
+     sized area at the bottom of the stack.  This is required also for
+     leaf functions.  When GCC generates a local stack reference it
+     will always add STACK_POINTER_OFFSET to all these references.  */
   if (crtl->is_leaf
       && !TARGET_TPF_PROFILING
       && cfun_frame_layout.frame_size == 0
-      && !cfun_save_high_fprs_p
       && !cfun->calls_alloca)
     return;
 
-  if (!TARGET_PACKED_STACK)
-    cfun_frame_layout.frame_size += (STACK_POINTER_OFFSET
-                                    + crtl->outgoing_args_size
-                                    + cfun_frame_layout.high_fprs * 8);
-  else
-    {
-      if (TARGET_BACKCHAIN)
-       cfun_frame_layout.frame_size += UNITS_PER_LONG;
+  /* Calculate the number of bytes we have used in our own register
+     save area.  With the packed stack layout we can re-use the
+     remaining bytes for normal stack elements.  */
 
-      /* No alignment trouble here because f8-f15 are only saved under
-        64 bit.  */
-      cfun_frame_layout.f8_offset = (MIN (MIN (cfun_frame_layout.f0_offset,
-                                              cfun_frame_layout.f4_offset),
-                                         cfun_frame_layout.gprs_offset)
-                                    - cfun_frame_layout.high_fprs * 8);
-
-      cfun_frame_layout.frame_size += cfun_frame_layout.high_fprs * 8;
-
-      for (i = FPR0_REGNUM; i <= FPR7_REGNUM; i++)
-       if (cfun_fpr_save_p (i))
-         cfun_frame_layout.frame_size += 8;
+  if (TARGET_PACKED_STACK)
+    lowest_offset = MIN (MIN (cfun_frame_layout.f0_offset,
+                             cfun_frame_layout.f4_offset),
+                        cfun_frame_layout.gprs_offset);
+  else
+    lowest_offset = 0;
 
-      cfun_frame_layout.frame_size += cfun_gprs_save_area_size;
+  if (TARGET_BACKCHAIN)
+    lowest_offset = MIN (lowest_offset, cfun_frame_layout.backchain_offset);
 
-      /* If under 31 bit an odd number of gprs has to be saved we have to adjust
-        the frame size to sustain 8 byte alignment of stack frames.  */
-      cfun_frame_layout.frame_size = ((cfun_frame_layout.frame_size +
-                                      STACK_BOUNDARY / BITS_PER_UNIT - 1)
-                                     & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));
+  cfun_frame_layout.frame_size += STACK_POINTER_OFFSET - lowest_offset;
 
-      cfun_frame_layout.frame_size += crtl->outgoing_args_size;
-    }
+  /* If under 31 bit an odd number of gprs has to be saved we have to
+     adjust the frame size to sustain 8 byte alignment of stack
+     frames.  */
+  cfun_frame_layout.frame_size = ((cfun_frame_layout.frame_size +
+                                  STACK_BOUNDARY / BITS_PER_UNIT - 1)
+                                 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));
 }
 
 /* Generate frame layout.  Fills in register and frame data for the current