+2016-11-18 Dominik Vogt <vogt@linux.vnet.ibm.com>
+
+ PR bootstrap/77359
+ * config/rs6000/rs6000.c (rs6000_stack_info): Properly align local
+ variables in functions calling alloca. Also update the ASCII
+ drawings.
+ * config/rs6000/rs6000.h (STARTING_FRAME_OFFSET)
+ (STACK_DYNAMIC_OFFSET): Likewise.
+ * config/rs6000/aix.h (STARTING_FRAME_OFFSET)
+ (STACK_DYNAMIC_OFFSET): Copy AIX specific versions of the rs6000.h
+ macros to aix.h.
+
2016-11-18 Richard Sandiford <richard.sandiford@arm.com>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
#undef STACK_BOUNDARY
#define STACK_BOUNDARY 128
+/* Offset within stack frame to start allocating local variables at.
+ If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
+ first local allocated. Otherwise, it is the offset to the BEGINNING
+ of the first local allocated.
+
+ On the RS/6000, the frame pointer is the same as the stack pointer,
+ except for dynamic allocations. So we start after the fixed area and
+ outgoing parameter area.
+
+ If the function uses dynamic stack space (CALLS_ALLOCA is set), that
+ space needs to be aligned to STACK_BOUNDARY, i.e. the sum of the
+ sizes of the fixed area and the parameter area must be a multiple of
+ STACK_BOUNDARY. */
+
+#undef STARTING_FRAME_OFFSET
+#define STARTING_FRAME_OFFSET \
+ (FRAME_GROWS_DOWNWARD \
+ ? 0 \
+ : (cfun->calls_alloca \
+ ? RS6000_ALIGN (crtl->outgoing_args_size + RS6000_SAVE_AREA, 16) \
+ : (RS6000_ALIGN (crtl->outgoing_args_size, 16) + RS6000_SAVE_AREA)))
+
+/* Offset from the stack pointer register to an item dynamically
+ allocated on the stack, e.g., by `alloca'.
+
+ The default value for this macro is `STACK_POINTER_OFFSET' plus the
+ length of the outgoing arguments. The default is correct for most
+ machines. See `function.c' for details.
+
+ This value must be a multiple of STACK_BOUNDARY (hard coded in
+ `emit-rtl.c'). */
+#undef STACK_DYNAMIC_OFFSET
+#define STACK_DYNAMIC_OFFSET(FUNDECL) \
+ RS6000_ALIGN (crtl->outgoing_args_size + STACK_POINTER_OFFSET, 16)
+
#undef TARGET_IEEEQUAD
#define TARGET_IEEEQUAD 0
+---------------------------------------+
| saved TOC pointer | 20 40
+---------------------------------------+
- | Parameter save area (P) | 24 48
+ | Parameter save area (+padding*) (P) | 24 48
+---------------------------------------+
| Alloca space (A) | 24+P etc.
+---------------------------------------+
old SP->| back chain to caller's caller |
+---------------------------------------+
+ * If the alloca area is present, the parameter save area is
+ padded so that the former starts 16-byte aligned.
+
The required alignment for AIX configurations is two words (i.e., 8
or 16 bytes).
+---------------------------------------+
| Saved TOC pointer | 24
+---------------------------------------+
- | Parameter save area (P) | 32
+ | Parameter save area (+padding*) (P) | 32
+---------------------------------------+
| Alloca space (A) | 32+P
+---------------------------------------+
old SP->| back chain to caller's caller | 32+P+A+L+W+Y+G+F
+---------------------------------------+
+ * If the alloca area is present, the parameter save area is
+ padded so that the former starts 16-byte aligned.
V.4 stack frames look like:
+---------------------------------------+
| caller's saved LR | 4
+---------------------------------------+
- | Parameter save area (P) | 8
+ | Parameter save area (+padding*) (P) | 8
+---------------------------------------+
| Alloca space (A) | 8+P
+---------------------------------------+
old SP->| back chain to caller's caller |
+---------------------------------------+
+ * If the alloca area is present and the required alignment is
+ 16 bytes, the parameter save area is padded so that the
+ alloca area starts 16-byte aligned.
+
The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
given. (But note below and in sysv4.h that we require only 8 and
may round up the size of our stack frame anyways. The historical
info->reg_size = reg_size;
info->fixed_size = RS6000_SAVE_AREA;
info->vars_size = RS6000_ALIGN (get_frame_size (), 8);
- info->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
- TARGET_ALTIVEC ? 16 : 8);
+ if (cfun->calls_alloca)
+ info->parm_size =
+ RS6000_ALIGN (crtl->outgoing_args_size + info->fixed_size,
+ STACK_BOUNDARY / BITS_PER_UNIT) - info->fixed_size;
+ else
+ info->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
+ TARGET_ALTIVEC ? 16 : 8);
if (FRAME_GROWS_DOWNWARD)
info->vars_size
+= RS6000_ALIGN (info->fixed_size + info->vars_size + info->parm_size,
On the RS/6000, the frame pointer is the same as the stack pointer,
except for dynamic allocations. So we start after the fixed area and
- outgoing parameter area. */
+ outgoing parameter area.
+
+ If the function uses dynamic stack space (CALLS_ALLOCA is set), that
+ space needs to be aligned to STACK_BOUNDARY, i.e. the sum of the
+ sizes of the fixed area and the parameter area must be a multiple of
+ STACK_BOUNDARY. */
#define STARTING_FRAME_OFFSET \
(FRAME_GROWS_DOWNWARD \
? 0 \
- : (RS6000_ALIGN (crtl->outgoing_args_size, \
- (TARGET_ALTIVEC || TARGET_VSX) ? 16 : 8) \
- + RS6000_SAVE_AREA))
+ : (cfun->calls_alloca \
+ ? (RS6000_ALIGN (crtl->outgoing_args_size + RS6000_SAVE_AREA, \
+ (TARGET_ALTIVEC || TARGET_VSX) ? 16 : 8 )) \
+ : (RS6000_ALIGN (crtl->outgoing_args_size, \
+ (TARGET_ALTIVEC || TARGET_VSX) ? 16 : 8) \
+ + RS6000_SAVE_AREA)))
/* Offset from the stack pointer register to an item dynamically
allocated on the stack, e.g., by `alloca'.
The default value for this macro is `STACK_POINTER_OFFSET' plus the
length of the outgoing arguments. The default is correct for most
- machines. See `function.c' for details. */
+ machines. See `function.c' for details.
+
+ This value must be a multiple of STACK_BOUNDARY (hard coded in
+ `emit-rtl.c'). */
#define STACK_DYNAMIC_OFFSET(FUNDECL) \
- (RS6000_ALIGN (crtl->outgoing_args_size, \
- (TARGET_ALTIVEC || TARGET_VSX) ? 16 : 8) \
- + (STACK_POINTER_OFFSET))
+ RS6000_ALIGN (crtl->outgoing_args_size + STACK_POINTER_OFFSET, \
+ (TARGET_ALTIVEC || TARGET_VSX) ? 16 : 8)
/* If we generate an insn to push BYTES bytes,
this says how many the stack pointer really advances by.