function.c (STACK_ALIGNMENT_NEEDED): New macro.

* function.c (STACK_ALIGNMENT_NEEDED): New macro.  Default to 1.
	(assign_stack_local_1): Perform overall stack alignment only when
	STACK_ALIGNMENT_NEEDED is non-zero.
	* doc/tm.texi (STACK_ALIGNMENT_NEEDED): Document.

	* pa.c (compute_frame_size): Rename fsize to size.  Account for
	alignment to a word boundary before general register save block.  Only
	account for double-word alignment before floating point register save
	block if one or more are saved.  Don't allocate space for %r3 when
	frame pointer is needed.
	(hppa_expand_prologue): Include alignment to word boundary in local
	frame size.
	* pa.h (STARTING_FRAME_OFFSET): Define to 8 on both 32 and 64-bit ports.
	(STACK_ALIGNMENT_NEEDED): Define.

From-SVN: r63771
This commit is contained in:
John David Anglin 2003-03-04 06:20:17 +00:00 committed by John David Anglin
parent 9b23f09dc1
commit 95f3f59efd
5 changed files with 105 additions and 40 deletions

View File

@ -1,3 +1,20 @@
2003-03-04 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* function.c (STACK_ALIGNMENT_NEEDED): New macro. Default to 1.
(assign_stack_local_1): Perform overall stack alignment only when
STACK_ALIGNMENT_NEEDED is non-zero.
* doc/tm.texi (STACK_ALIGNMENT_NEEDED): Document.
* pa.c (compute_frame_size): Rename fsize to size. Account for
alignment to a word boundary before general register save block. Only
account for double-word alignment before floating point register save
block if one or more are saved. Don't allocate space for %r3 when
frame pointer is needed.
(hppa_expand_prologue): Include alignment to word boundary in local
frame size.
* pa.h (STARTING_FRAME_OFFSET): Define to 8 on both 32 and 64-bit ports.
(STACK_ALIGNMENT_NEEDED): Define.
2003-03-04 Kevin Buettner <kevinb@redhat.com>
* dwarf2out.c (rtl_for_decl_location): Don't return NULL_RTX for

View File

@ -3195,15 +3195,24 @@ compute_frame_size (size, fregs_live)
int size;
int *fregs_live;
{
int i, fsize;
int freg_saved = 0;
int i, j;
/* Space for frame pointer + filler. If any frame is allocated
we need to add this in because of STARTING_FRAME_OFFSET.
/* The code in hppa_expand_prologue and hppa_expand_epilogue must
be consistent with the rounding and size calculation done here.
Change them at the same time. */
Similar code also appears in hppa_expand_prologue. Change both
of them at the same time. */
fsize = size + (size || frame_pointer_needed ? STARTING_FRAME_OFFSET : 0);
/* We do our own stack alignment. First, round the size of the
stack locals up to a word boundary. */
size = (size + UNITS_PER_WORD - 1) & ~(UNITS_PER_WORD - 1);
/* Space for previous frame pointer + filler. If any frame is
allocated, we need to add in the STARTING_FRAME_OFFSET. We
waste some space here for the sake of HP compatibility. The
first slot is only used when the frame pointer is needed. */
if (size || frame_pointer_needed)
size += STARTING_FRAME_OFFSET;
/* If the current function calls __builtin_eh_return, then we need
to allocate stack space for registers that will hold data for
the exception handler. */
@ -3213,41 +3222,49 @@ compute_frame_size (size, fregs_live)
for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
continue;
fsize += i * UNITS_PER_WORD;
size += i * UNITS_PER_WORD;
}
/* Account for space used by the callee general register saves. */
for (i = 18; i >= 3; i--)
for (i = 18, j = frame_pointer_needed ? 4 : 3; i >= j; i--)
if (regs_ever_live[i])
fsize += UNITS_PER_WORD;
/* Round the stack. */
fsize = (fsize + 7) & ~7;
size += UNITS_PER_WORD;
/* Account for space used by the callee floating point register saves. */
for (i = FP_SAVED_REG_LAST; i >= FP_SAVED_REG_FIRST; i -= FP_REG_STEP)
if (regs_ever_live[i]
|| (! TARGET_64BIT && regs_ever_live[i + 1]))
|| (!TARGET_64BIT && regs_ever_live[i + 1]))
{
if (fregs_live)
*fregs_live = 1;
freg_saved = 1;
/* We always save both halves of the FP register, so always
increment the frame size by 8 bytes. */
fsize += 8;
size += 8;
}
/* If any of the floating registers are saved, account for the
alignment needed for the floating point register save block. */
if (freg_saved)
{
size = (size + 7) & ~7;
if (fregs_live)
*fregs_live = 1;
}
/* The various ABIs include space for the outgoing parameters in the
size of the current function's stack frame. */
fsize += current_function_outgoing_args_size;
size of the current function's stack frame. We don't need to align
for the outgoing arguments as their alignment is set by the final
rounding for the frame as a whole. */
size += current_function_outgoing_args_size;
/* Allocate space for the fixed frame marker. This space must be
allocated for any function that makes calls or otherwise allocates
stack space. */
if (!current_function_is_leaf || fsize)
fsize += TARGET_64BIT ? 16 : 32;
if (!current_function_is_leaf || size)
size += TARGET_64BIT ? 16 : 32;
return ((fsize + PREFERRED_STACK_BOUNDARY / 8 - 1)
/* Finally, round to the preferred stack boundary. */
return ((size + PREFERRED_STACK_BOUNDARY / 8 - 1)
& ~(PREFERRED_STACK_BOUNDARY / 8 - 1));
}
@ -3313,8 +3330,8 @@ pa_output_function_prologue (file, size)
void
hppa_expand_prologue ()
{
int size = get_frame_size ();
int merge_sp_adjust_with_store = 0;
int size = get_frame_size ();
int i, offset;
rtx insn, tmpreg;
@ -3322,13 +3339,12 @@ hppa_expand_prologue ()
fr_saved = 0;
save_fregs = 0;
/* Allocate space for frame pointer + filler. If any frame is allocated
we need to add this in because of STARTING_FRAME_OFFSET.
Similar code also appears in compute_frame_size. Change both
of them at the same time. */
local_fsize = size + (size || frame_pointer_needed
? STARTING_FRAME_OFFSET : 0);
/* Compute total size for frame pointer, filler, locals and rounding to
the next word boundary. Similar code appears in compute_frame_size
and must be changed in tandem with this code. */
local_fsize = (size + UNITS_PER_WORD - 1) & ~(UNITS_PER_WORD - 1);
if (local_fsize || frame_pointer_needed)
local_fsize += STARTING_FRAME_OFFSET;
actual_fsize = compute_frame_size (size, &save_fregs);

View File

@ -676,10 +676,17 @@ extern struct rtx_def *hppa_pic_save_rtx PARAMS ((void));
/* 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. The start of the locals must lie on
a STACK_BOUNDARY or else the frame size of leaf functions will not
be zero. */
#define STARTING_FRAME_OFFSET (TARGET_64BIT ? 16 : 8)
of the first local allocated.
On the 32-bit ports, we reserve one slot for the previous frame
pointer and one fill slot. The fill slot is for compatibility
with HP compiled programs. On the 64-bit ports, we reserve one
slot for the previous frame pointer. */
#define STARTING_FRAME_OFFSET 8
/* Define STACK_ALIGNMENT_NEEDED to zero to disable final alignment
of the stack. The default is to align it to STACK_BOUNDARY. */
#define STACK_ALIGNMENT_NEEDED 0
/* If we generate an insn to push BYTES bytes,
this says how many the stack pointer really advances by.

View File

@ -2816,6 +2816,16 @@ value @code{STARTING_FRAME_OFFSET}.
@c i'm not sure if the above is still correct.. had to change it to get
@c rid of an overfull. --mew 2feb93
@findex STACK_ALIGNMENT_NEEDED
@item STACK_ALIGNMENT_NEEDED
Define to zero to disable final alignment of the stack during reload.
The non-zero default for this macro is suitable for most ports.
On ports where @code{STARTING_FRAME_OFFSET} is non-zero or where there
is a register save block following the local block that doesn't require
alignment to @code{STACK_BOUNDARY}, it may be beneficial to disable
stack alignment and do it in the backend.
@findex STACK_POINTER_OFFSET
@item STACK_POINTER_OFFSET
Offset from the stack pointer register to the first location at which

View File

@ -70,6 +70,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT
#endif
#ifndef STACK_ALIGNMENT_NEEDED
#define STACK_ALIGNMENT_NEEDED 1
#endif
/* Some systems use __main in a way incompatible with its use in gcc, in these
cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
give the same symbol without quotes for an alternative entry point. You
@ -566,16 +570,27 @@ assign_stack_local_1 (mode, size, align, function)
frame_off = STARTING_FRAME_OFFSET % frame_alignment;
frame_phase = frame_off ? frame_alignment - frame_off : 0;
/* Round frame offset to that alignment.
We must be careful here, since FRAME_OFFSET might be negative and
division with a negative dividend isn't as well defined as we might
like. So we instead assume that ALIGNMENT is a power of two and
use logical operations which are unambiguous. */
/* Round the frame offset to the specified alignment. The default is
to always honor requests to align the stack but a port may choose to
do its own stack alignment by defining STACK_ALIGNMENT_NEEDED. */
if (STACK_ALIGNMENT_NEEDED
|| mode != BLKmode
|| size != 0)
{
/* We must be careful here, since FRAME_OFFSET might be negative and
division with a negative dividend isn't as well defined as we might
like. So we instead assume that ALIGNMENT is a power of two and
use logical operations which are unambiguous. */
#ifdef FRAME_GROWS_DOWNWARD
function->x_frame_offset = FLOOR_ROUND (function->x_frame_offset - frame_phase, alignment) + frame_phase;
function->x_frame_offset
= (FLOOR_ROUND (function->x_frame_offset - frame_phase, alignment)
+ frame_phase);
#else
function->x_frame_offset = CEIL_ROUND (function->x_frame_offset - frame_phase, alignment) + frame_phase;
function->x_frame_offset
= (CEIL_ROUND (function->x_frame_offset - frame_phase, alignment)
+ frame_phase);
#endif
}
/* On a big-endian machine, if we are allocating more space than we will use,
use the least significant bytes of those that are allocated. */