aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorWilco Dijkstra <wdijkstr@arm.com>2016-10-21 17:04:21 +0000
committerWilco Dijkstra <wilco@gcc.gnu.org>2016-10-21 17:04:21 +0000
commit4b0685d91591a8493e7fd41f87c8690c675c40d9 (patch)
tree5db6300c2af15dbe11dae0ce8ae9d65e363b666c /gcc
parentd17f7088fbe9b7d159021d0442d174925df7b20d (diff)
downloadgcc-4b0685d91591a8493e7fd41f87c8690c675c40d9.zip
gcc-4b0685d91591a8493e7fd41f87c8690c675c40d9.tar.gz
gcc-4b0685d91591a8493e7fd41f87c8690c675c40d9.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/aarch64/aarch64.c19
2 files changed, 22 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6102719..0625c00 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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,
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 6b27309..584e1f5 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;