From 9a5fab4d2bc61b1b37c2c0d2b4246347331beb94 Mon Sep 17 00:00:00 2001 From: mshawcroft Date: Wed, 23 Jul 2014 16:20:38 +0000 Subject: [PATCH] [AArch64] Unify vector and core register save/restore code. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@212955 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 +++ gcc/config/aarch64/aarch64.c | 100 +++++++++++-------------------------------- 2 files changed, 30 insertions(+), 76 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2900bc6ef1b..940a327a1f7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2014-07-23 Jiong Wang + * config/aarch64/aarch64.c (aarch64_save_or_restore_fprs): Deleted. + (aarch64_save_callee_saves): New function to handle reg save + for both core and vectore regs. + +2014-07-23 Jiong Wang + * config/aarch64/aarch64.c (aarch64_gen_load_pair) (aarch64_gen_store_pair): New helper function. (aarch64_save_or_restore_callee_save_registers) diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 21745a0ad0b..e3a0c570b76 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -1950,93 +1950,32 @@ aarch64_gen_load_pair (enum machine_mode mode, rtx reg1, rtx mem1, rtx reg2, } } -static void -aarch64_save_or_restore_fprs (HOST_WIDE_INT start_offset, bool restore) -{ - unsigned regno; - unsigned regno2; - rtx insn; - rtx (*gen_mem_ref) (enum machine_mode, rtx) - = frame_pointer_needed ? gen_frame_mem : gen_rtx_MEM; - - - for (regno = aarch64_next_callee_save (V0_REGNUM, V31_REGNUM); - regno <= V31_REGNUM; - regno = aarch64_next_callee_save (regno + 1, V31_REGNUM)) - { - rtx reg = gen_rtx_REG (DFmode, regno); - rtx mem; - - HOST_WIDE_INT offset = start_offset - + cfun->machine->frame.reg_offset[regno]; - mem = gen_mem_ref (DFmode, plus_constant (Pmode, stack_pointer_rtx, - offset)); - - regno2 = aarch64_next_callee_save (regno + 1, V31_REGNUM); - - if (regno2 <= V31_REGNUM) - { - rtx reg2 = gen_rtx_REG (DFmode, regno2); - rtx mem2; - - offset = start_offset + cfun->machine->frame.reg_offset[regno2]; - mem2 = gen_mem_ref (DFmode, - plus_constant (Pmode, stack_pointer_rtx, offset)); - if (restore == false) - insn = emit_insn (aarch64_gen_store_pair (DFmode, mem, reg, mem2, reg2)); - else - { - insn = emit_insn (aarch64_gen_load_pair (DFmode, 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 - { - 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_FRAME_RELATED_P (insn) = 1; - } -} - /* offset from the stack pointer of where the saves and restore's have to happen. */ static void -aarch64_save_or_restore_callee_save_registers (HOST_WIDE_INT start_offset, - bool restore) +aarch64_save_or_restore_callee_saves (enum machine_mode mode, + HOST_WIDE_INT start_offset, + unsigned start, unsigned limit, + bool restore) { rtx insn; rtx (*gen_mem_ref) (enum machine_mode, rtx) = (frame_pointer_needed ? gen_frame_mem : gen_rtx_MEM); - unsigned limit = frame_pointer_needed ? R28_REGNUM : R30_REGNUM; unsigned regno; unsigned regno2; - for (regno = aarch64_next_callee_save (R0_REGNUM, limit); + for (regno = aarch64_next_callee_save (start, limit); regno <= limit; regno = aarch64_next_callee_save (regno + 1, limit)) { - rtx reg = gen_rtx_REG (DImode, regno); + rtx reg = gen_rtx_REG (mode, regno); rtx mem; HOST_WIDE_INT offset = start_offset + cfun->machine->frame.reg_offset[regno]; - mem = gen_mem_ref (Pmode, plus_constant (Pmode, stack_pointer_rtx, - offset)); + mem = gen_mem_ref (mode, plus_constant (Pmode, stack_pointer_rtx, + offset)); regno2 = aarch64_next_callee_save (regno + 1, limit); @@ -2045,17 +1984,19 @@ aarch64_save_or_restore_callee_save_registers (HOST_WIDE_INT start_offset, == cfun->machine->frame.reg_offset[regno2])) { - rtx reg2 = gen_rtx_REG (DImode, regno2); + rtx reg2 = gen_rtx_REG (mode, regno2); rtx mem2; offset = start_offset + cfun->machine->frame.reg_offset[regno2]; - mem2 = gen_mem_ref (Pmode, + mem2 = gen_mem_ref (mode, plus_constant (Pmode, stack_pointer_rtx, offset)); if (restore == false) - insn = emit_insn (aarch64_gen_store_pair (DImode, mem, reg, mem2, reg2)); + insn = emit_insn (aarch64_gen_store_pair (mode, mem, reg, mem2, + reg2)); else { - insn = emit_insn (aarch64_gen_load_pair (DImode, reg, mem, reg2, mem2)); + 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); } @@ -2079,7 +2020,6 @@ aarch64_save_or_restore_callee_save_registers (HOST_WIDE_INT start_offset, } RTX_FRAME_RELATED_P (insn) = 1; } - aarch64_save_or_restore_fprs (start_offset, restore); } /* AArch64 stack frames generated by this compiler look like: @@ -2272,7 +2212,11 @@ aarch64_expand_prologue (void) RTX_FRAME_RELATED_P (insn) = 1; } - aarch64_save_or_restore_callee_save_registers (fp_offset, 0); + 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); } /* when offset >= 512, @@ -2343,7 +2287,11 @@ aarch64_expand_epilogue (bool for_sibcall) cfa_reg = stack_pointer_rtx; } - aarch64_save_or_restore_callee_save_registers (fp_offset, 1); + 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); /* Restore the frame pointer and lr if the frame pointer is needed. */ if (offset > 0) -- 2.11.4.GIT