split save and restore code. the logic will be easier to understand.
ok for upstream? thanks. gcc/ * config/aarch64/aarch64.md: (aarch64_save_or_restore_callee_saves): Rename to aarch64_save_callee_saves, remove restore code. (aarch64_restore_callee_saves): New function.
>From b063ab3e22cd1bdd2eb6f2cf5790741e68c7c6e5 Mon Sep 17 00:00:00 2001 From: Jiong Wang <jiong.w...@arm.com> Date: Tue, 17 Jun 2014 22:14:43 +0100 Subject: [PATCH 11/19] [AArch64/GCC][11/20] Split save and restore code split save and restore code. the logic will be easier to understand. 2014-06-16 Jiong Wang <jiong.w...@arm.com> Marcus Shawcroft <marcus.shawcr...@arm.com> gcc/ * config/aarch64/aarch64.md: (aarch64_save_or_restore_callee_save_common): Rename to aarch64_save_callee_save_common, remove restore code. (aarch64_restore_callee_save_common): New function. --- gcc/config/aarch64/aarch64.c | 104 ++++++++++++++++++++++++++++-------------- 1 file changed, 69 insertions(+), 35 deletions(-) diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 4e35ebc..9772dc4 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -1948,13 +1948,9 @@ aarch64_gen_load_pair (enum machine_mode mode, rtx reg1, rtx mem1, rtx reg2, } -/* offset from the stack pointer of where the saves and - restore's have to happen. */ static void -aarch64_save_or_restore_callee_saves (enum machine_mode mode, - HOST_WIDE_INT start_offset, - unsigned start, unsigned limit, - bool restore) +aarch64_save_callee_saves (enum machine_mode mode, HOST_WIDE_INT start_offset, + unsigned start, unsigned limit) { rtx insn; rtx (*gen_mem_ref) (enum machine_mode, rtx) = (frame_pointer_needed @@ -1985,18 +1981,10 @@ aarch64_save_or_restore_callee_saves (enum machine_mode mode, rtx mem2; offset = start_offset + cfun->machine->frame.reg_offset[regno2]; - mem2 = gen_mem_ref (mode, - plus_constant (Pmode, stack_pointer_rtx, offset)); - if (restore == false) - insn = emit_insn (aarch64_gen_store_pair (mode, mem, reg, mem2, - reg2)); - else - { - insn = emit_insn (aarch64_gen_load_pair (mode, reg, mem, reg2, - mem2)); - add_reg_note (insn, REG_CFA_RESTORE, reg); - add_reg_note (insn, REG_CFA_RESTORE, reg2); - } + mem2 = gen_mem_ref (mode, plus_constant (Pmode, stack_pointer_rtx, + offset)); + insn = emit_insn (aarch64_gen_store_pair (mode, mem, reg, mem2, + reg2)); /* The first part of a frame-related parallel insn is always assumed to be relevant to the frame @@ -2006,15 +1994,64 @@ aarch64_save_or_restore_callee_saves (enum machine_mode mode, regno = regno2; } else + insn = emit_move_insn (mem, reg); + + RTX_FRAME_RELATED_P (insn) = 1; + } +} + +static void +aarch64_restore_callee_saves (enum machine_mode mode, + HOST_WIDE_INT start_offset, unsigned start, + unsigned limit) +{ + rtx insn; + rtx base_rtx = stack_pointer_rtx; + rtx (*gen_mem_ref) (enum machine_mode, rtx) = (frame_pointer_needed + ? gen_frame_mem : gen_rtx_MEM); + unsigned regno; + unsigned regno2; + HOST_WIDE_INT offset; + + for (regno = aarch64_next_callee_save (start, limit); + regno <= limit; + regno = aarch64_next_callee_save (regno + 1, limit)) + { + rtx reg = gen_rtx_REG (mode, regno); + rtx mem; + + offset = start_offset + cfun->machine->frame.reg_offset[regno]; + mem = gen_mem_ref (mode, plus_constant (Pmode, base_rtx, offset)); + + regno2 = aarch64_next_callee_save (regno + 1, limit); + + if (regno2 <= limit + && ((cfun->machine->frame.reg_offset[regno] + UNITS_PER_WORD) + == cfun->machine->frame.reg_offset[regno2])) { - if (restore == false) - insn = emit_move_insn (mem, reg); - else - { - insn = emit_move_insn (reg, mem); - add_reg_note (insn, REG_CFA_RESTORE, reg); - } + rtx reg2 = gen_rtx_REG (mode, regno2); + rtx mem2; + + offset = start_offset + cfun->machine->frame.reg_offset[regno2]; + mem2 = gen_mem_ref (mode, plus_constant (Pmode, base_rtx, offset)); + insn = emit_insn (aarch64_gen_load_pair (mode, reg, mem, reg2, + mem2)); + add_reg_note (insn, REG_CFA_RESTORE, reg); + add_reg_note (insn, REG_CFA_RESTORE, reg2); + + /* The first part of a frame-related parallel insn is + always assumed to be relevant to the frame + calculations; subsequent parts, are only + frame-related if explicitly marked. */ + RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, 1)) = 1; + regno = regno2; } + else + { + insn = emit_move_insn (reg, mem); + add_reg_note (insn, REG_CFA_RESTORE, reg); + } + RTX_FRAME_RELATED_P (insn) = 1; } } @@ -2209,11 +2246,10 @@ aarch64_expand_prologue (void) RTX_FRAME_RELATED_P (insn) = 1; } - aarch64_save_or_restore_callee_saves (DImode, fp_offset, R0_REGNUM, - frame_pointer_needed - ? R28_REGNUM : R30_REGNUM, false); - aarch64_save_or_restore_callee_saves (DFmode, fp_offset, V0_REGNUM, - V31_REGNUM, false); + aarch64_save_callee_saves (DImode, fp_offset, R0_REGNUM, + frame_pointer_needed + ? R28_REGNUM : R30_REGNUM); + aarch64_save_callee_saves (DFmode, fp_offset, V0_REGNUM, V31_REGNUM); } /* when offset >= 512, @@ -2284,11 +2320,9 @@ aarch64_expand_epilogue (bool for_sibcall) cfa_reg = stack_pointer_rtx; } - aarch64_save_or_restore_callee_saves (DImode, fp_offset, R0_REGNUM, - frame_pointer_needed - ? R28_REGNUM : R30_REGNUM, true); - aarch64_save_or_restore_callee_saves (DFmode, fp_offset, V0_REGNUM, - V31_REGNUM, true); + aarch64_restore_callee_saves (DImode, fp_offset, R0_REGNUM, + frame_pointer_needed ? R28_REGNUM : R30_REGNUM); + aarch64_restore_callee_saves (DFmode, fp_offset, V0_REGNUM, V31_REGNUM); /* Restore the frame pointer and lr if the frame pointer is needed. */ if (offset > 0) -- 1.7.9.5