If the number of integer callee-saves is odd, any FP callee-saves use 8-byte aligned LDP/STP.

If the number of integer callee-saves is odd, any FP callee-saves use 8-byte
aligned LDP/STP.  Since 16-byte alignment may be faster on some CPUs, align
the FP callee-saves to 16 bytes and use the alignment gap for the last FP
callee-save when possible.

    gcc/
        * config/aarch64/aarch64.c (aarch64_layout_frame):
        Align FP callee-saves.

From-SVN: r241419
This commit is contained in:
Wilco Dijkstra 2016-10-21 17:04:21 +00:00 committed by Wilco Dijkstra
parent d17f7088fb
commit 4b0685d915
2 changed files with 22 additions and 2 deletions

View File

@ -1,3 +1,8 @@
2016-10-21 Wilco Dijkstra <wdijkstr@arm.com>
* config/aarch64/aarch64.c (aarch64_layout_frame):
Align FP callee-saves.
2016-10-21 Jakub Jelinek <jakub@redhat.com>
* config/i386/adxintrin.h (_subborrow_u32, _addcarry_u32,

View File

@ -2734,7 +2734,7 @@ static void
aarch64_layout_frame (void)
{
HOST_WIDE_INT offset = 0;
int regno;
int regno, last_fp_reg = INVALID_REGNUM;
if (reload_completed && cfun->machine->frame.laid_out)
return;
@ -2768,7 +2768,10 @@ aarch64_layout_frame (void)
for (regno = V0_REGNUM; regno <= V31_REGNUM; regno++)
if (df_regs_ever_live_p (regno)
&& !call_used_regs[regno])
cfun->machine->frame.reg_offset[regno] = SLOT_REQUIRED;
{
cfun->machine->frame.reg_offset[regno] = SLOT_REQUIRED;
last_fp_reg = regno;
}
if (frame_pointer_needed)
{
@ -2792,9 +2795,21 @@ aarch64_layout_frame (void)
offset += UNITS_PER_WORD;
}
HOST_WIDE_INT max_int_offset = offset;
offset = ROUND_UP (offset, STACK_BOUNDARY / BITS_PER_UNIT);
bool has_align_gap = offset != max_int_offset;
for (regno = V0_REGNUM; regno <= V31_REGNUM; regno++)
if (cfun->machine->frame.reg_offset[regno] == SLOT_REQUIRED)
{
/* If there is an alignment gap between integer and fp callee-saves,
allocate the last fp register to it if possible. */
if (regno == last_fp_reg && has_align_gap && (offset & 8) == 0)
{
cfun->machine->frame.reg_offset[regno] = max_int_offset;
break;
}
cfun->machine->frame.reg_offset[regno] = offset;
if (cfun->machine->frame.wb_candidate1 == INVALID_REGNUM)
cfun->machine->frame.wb_candidate1 = regno;