[AArch64] Unify vector and core register save/restore code.
From-SVN: r212955
This commit is contained in:
parent
72df5c1f62
commit
0ec74a1ee3
@ -1,3 +1,9 @@
|
||||
2014-07-23 Jiong Wang <jiong.wang@arm.com>
|
||||
|
||||
* 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 <jiong.wang@arm.com>
|
||||
|
||||
* config/aarch64/aarch64.c (aarch64_gen_load_pair)
|
||||
|
@ -1950,92 +1950,31 @@ 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,
|
||||
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,
|
||||
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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user