aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Krebbel <Andreas.Krebbel@de.ibm.com>2013-10-09 07:23:53 +0000
committerAndreas Krebbel <krebbel@gcc.gnu.org>2013-10-09 07:23:53 +0000
commit74129172c65297ba6d2023670e31de1f422db9ee (patch)
tree8ae21d67f935b724942595930ce9381c2a4f8a9e
parent6455a49ed4fd8b6338cb21122722c0f7a26e83ce (diff)
downloadgcc-74129172c65297ba6d2023670e31de1f422db9ee.zip
gcc-74129172c65297ba6d2023670e31de1f422db9ee.tar.gz
gcc-74129172c65297ba6d2023670e31de1f422db9ee.tar.bz2
s390.c (s390_frame_info): Restructure function.
2013-10-09 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> * config/s390/s390.c (s390_frame_info): Restructure function. From-SVN: r203304
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/config/s390/s390.c110
2 files changed, 53 insertions, 61 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9d3cad9..5694033 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,9 @@
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
gpr_save_slots.
(cfun_save_arg_fprs_p, cfun_gpr_save_slot): New macros.
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index a833fd6..28a09ec 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -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