the common reg save/restore function should skip those write-back candidate reg if 'skip_wb' be true.
*no functional change* ok to install? thanks. gcc/ * config/aarch64/aarch64.c (aarch64_save_callee_save_common): New parameter "skip_wb". (aarch64_restore_callee_save_common): Likewise. (aarch64_expand_prologue): Update call site. (aarch64_expand_epilogue): Likewise.
>From a85dde9bd3a0dab1d1c2ddf82b134137fb1cab80 Mon Sep 17 00:00:00 2001 From: Jiong Wang <jiong.w...@arm.com> Date: Tue, 17 Jun 2014 22:23:12 +0100 Subject: [PATCH 16/19] [AArch64/GCC][17/20] New parameter 'skip_wb' for 'aarch64_save/restore_callee_save_common' the common reg save/restore function should skip those write-back candidate reg if 'skip_wb' be true. *no functional change* 2014-06-16 Jiong Wang <jiong.w...@arm.com> Marcus Shawcroft <marcus.shawcr...@arm.com> gcc/ * config/aarch64/aarch64.c (aarch64_save_callee_save_common): New parameter "skip_wb". (aarch64_restore_callee_save_common): Likewise. (aarch64_expand_prologue): Update call site. (aarch64_expand_epilogue): Likewise. --- gcc/config/aarch64/aarch64.c | 47 ++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index a6b253a..26d5fba 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -2039,7 +2039,7 @@ aarch64_gen_load_pair (enum machine_mode mode, rtx reg1, rtx mem1, rtx reg2, static void aarch64_save_callee_saves (enum machine_mode mode, HOST_WIDE_INT start_offset, - unsigned start, unsigned limit) + unsigned start, unsigned limit, bool skip_wb) { rtx insn; rtx (*gen_mem_ref) (enum machine_mode, rtx) = (frame_pointer_needed @@ -2051,11 +2051,16 @@ aarch64_save_callee_saves (enum machine_mode mode, HOST_WIDE_INT start_offset, regno <= limit; regno = aarch64_next_callee_save (regno + 1, limit)) { - rtx reg = gen_rtx_REG (mode, regno); - rtx mem; + rtx reg, mem; + HOST_WIDE_INT offset; - HOST_WIDE_INT offset = start_offset - + cfun->machine->frame.reg_offset[regno]; + if (skip_wb + && (regno == cfun->machine->frame.wb_candidate1 + || regno == cfun->machine->frame.wb_candidate2)) + continue; + + reg = gen_rtx_REG (mode, regno); + offset = start_offset + cfun->machine->frame.reg_offset[regno]; mem = gen_mem_ref (mode, plus_constant (Pmode, stack_pointer_rtx, offset)); @@ -2092,7 +2097,7 @@ aarch64_save_callee_saves (enum machine_mode mode, HOST_WIDE_INT start_offset, static void aarch64_restore_callee_saves (enum machine_mode mode, HOST_WIDE_INT start_offset, unsigned start, - unsigned limit) + unsigned limit, bool skip_wb) { rtx insn; rtx base_rtx = stack_pointer_rtx; @@ -2106,9 +2111,14 @@ aarch64_restore_callee_saves (enum machine_mode mode, regno <= limit; regno = aarch64_next_callee_save (regno + 1, limit)) { - rtx reg = gen_rtx_REG (mode, regno); - rtx mem; + rtx reg, mem; + if (skip_wb + && (regno == cfun->machine->frame.wb_candidate1 + || regno == cfun->machine->frame.wb_candidate2)) + continue; + + reg = gen_rtx_REG (mode, regno); offset = start_offset + cfun->machine->frame.reg_offset[regno]; mem = gen_mem_ref (mode, plus_constant (Pmode, base_rtx, offset)); @@ -2264,6 +2274,8 @@ aarch64_expand_prologue (void) if (offset > 0) { + bool skip_wb = false; + /* Save the frame pointer and lr if the frame pointer is needed first. Make the frame pointer point to the location of the old frame pointer on the stack. */ @@ -2281,7 +2293,7 @@ aarch64_expand_prologue (void) GEN_INT (offset)))); aarch64_save_callee_saves (DImode, fp_offset, R29_REGNUM, - R30_REGNUM); + R30_REGNUM, skip_wb); } else aarch64_pushwb_pair_reg (DImode, R29_REGNUM, R30_REGNUM, offset); @@ -2300,7 +2312,8 @@ aarch64_expand_prologue (void) insn = emit_insn (gen_stack_tie (stack_pointer_rtx, hard_frame_pointer_rtx)); - aarch64_save_callee_saves (DImode, fp_offset, R0_REGNUM, R28_REGNUM); + aarch64_save_callee_saves (DImode, fp_offset, R0_REGNUM, R28_REGNUM, + skip_wb); } else { @@ -2308,10 +2321,12 @@ aarch64_expand_prologue (void) GEN_INT (-offset))); RTX_FRAME_RELATED_P (insn) = 1; - aarch64_save_callee_saves (DImode, fp_offset, R0_REGNUM, R30_REGNUM); + aarch64_save_callee_saves (DImode, fp_offset, R0_REGNUM, R30_REGNUM, + skip_wb); } - aarch64_save_callee_saves (DFmode, fp_offset, V0_REGNUM, V31_REGNUM); + aarch64_save_callee_saves (DFmode, fp_offset, V0_REGNUM, V31_REGNUM, + skip_wb); } /* when offset >= 512, @@ -2336,6 +2351,7 @@ aarch64_expand_epilogue (bool for_sibcall) HOST_WIDE_INT fp_offset; rtx insn; rtx cfa_reg; + bool skip_wb = false; aarch64_layout_frame (); @@ -2384,20 +2400,21 @@ aarch64_expand_epilogue (bool for_sibcall) } aarch64_restore_callee_saves (DFmode, frame_pointer_needed ? 0 : fp_offset, - V0_REGNUM, V31_REGNUM); + V0_REGNUM, V31_REGNUM, skip_wb); if (offset > 0) { if (frame_pointer_needed) { - aarch64_restore_callee_saves (DImode, 0, R0_REGNUM, R28_REGNUM); + aarch64_restore_callee_saves (DImode, 0, R0_REGNUM, R28_REGNUM, + skip_wb); aarch64_popwb_pair_reg (DImode, R29_REGNUM, R30_REGNUM, offset, cfa_reg); } else { aarch64_restore_callee_saves (DImode, fp_offset, R0_REGNUM, - R30_REGNUM); + R30_REGNUM, skip_wb); insn = emit_insn (gen_add2_insn (stack_pointer_rtx, GEN_INT (offset))); RTX_FRAME_RELATED_P (insn) = 1; -- 1.7.9.5