From 4b0685d91591a8493e7fd41f87c8690c675c40d9 Mon Sep 17 00:00:00 2001 From: Wilco Dijkstra Date: Fri, 21 Oct 2016 17:04:21 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 5 +++++ gcc/config/aarch64/aarch64.c | 19 +++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 610271900ef..0625c00044c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2016-10-21 Wilco Dijkstra + + * config/aarch64/aarch64.c (aarch64_layout_frame): + Align FP callee-saves. + 2016-10-21 Jakub Jelinek * config/i386/adxintrin.h (_subborrow_u32, _addcarry_u32, diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 6b27309337b..584e1f5a477 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -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; -- 2.30.2