[AArch64] Infrastructure to allow optional use of write back.
From-SVN: r212997
This commit is contained in:
parent
363ffa50f1
commit
ae13fce333
@ -1,3 +1,9 @@
|
|||||||
|
2014-07-24 Jiong Wang <jiong.wang@arm.com>
|
||||||
|
|
||||||
|
* config/aarch64/aarch64.c (aarch64_restore_callee_saves)
|
||||||
|
(aarch64_save_callee_saves): New parameter "skip_wb".
|
||||||
|
(aarch64_expand_prologue, aarch64_expand_epilogue): Update call site.
|
||||||
|
|
||||||
2014-07-24 Jiong Wang <jiong.wang@arm.com>
|
2014-07-24 Jiong Wang <jiong.wang@arm.com>
|
||||||
|
|
||||||
* config/aarch64/aarch64.h (frame): New fields "wb_candidate1" and
|
* config/aarch64/aarch64.h (frame): New fields "wb_candidate1" and
|
||||||
|
@ -2042,7 +2042,7 @@ aarch64_gen_load_pair (enum machine_mode mode, rtx reg1, rtx mem1, rtx reg2,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
aarch64_save_callee_saves (enum machine_mode mode, HOST_WIDE_INT start_offset,
|
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 insn;
|
||||||
rtx (*gen_mem_ref) (enum machine_mode, rtx) = (frame_pointer_needed
|
rtx (*gen_mem_ref) (enum machine_mode, rtx) = (frame_pointer_needed
|
||||||
@ -2054,11 +2054,16 @@ aarch64_save_callee_saves (enum machine_mode mode, HOST_WIDE_INT start_offset,
|
|||||||
regno <= limit;
|
regno <= limit;
|
||||||
regno = aarch64_next_callee_save (regno + 1, limit))
|
regno = aarch64_next_callee_save (regno + 1, limit))
|
||||||
{
|
{
|
||||||
rtx reg = gen_rtx_REG (mode, regno);
|
rtx reg, mem;
|
||||||
rtx mem;
|
HOST_WIDE_INT offset;
|
||||||
|
|
||||||
HOST_WIDE_INT offset = start_offset
|
if (skip_wb
|
||||||
+ cfun->machine->frame.reg_offset[regno];
|
&& (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,
|
mem = gen_mem_ref (mode, plus_constant (Pmode, stack_pointer_rtx,
|
||||||
offset));
|
offset));
|
||||||
|
|
||||||
@ -2095,7 +2100,7 @@ aarch64_save_callee_saves (enum machine_mode mode, HOST_WIDE_INT start_offset,
|
|||||||
static void
|
static void
|
||||||
aarch64_restore_callee_saves (enum machine_mode mode,
|
aarch64_restore_callee_saves (enum machine_mode mode,
|
||||||
HOST_WIDE_INT start_offset, unsigned start,
|
HOST_WIDE_INT start_offset, unsigned start,
|
||||||
unsigned limit)
|
unsigned limit, bool skip_wb)
|
||||||
{
|
{
|
||||||
rtx insn;
|
rtx insn;
|
||||||
rtx base_rtx = stack_pointer_rtx;
|
rtx base_rtx = stack_pointer_rtx;
|
||||||
@ -2109,9 +2114,14 @@ aarch64_restore_callee_saves (enum machine_mode mode,
|
|||||||
regno <= limit;
|
regno <= limit;
|
||||||
regno = aarch64_next_callee_save (regno + 1, limit))
|
regno = aarch64_next_callee_save (regno + 1, limit))
|
||||||
{
|
{
|
||||||
rtx reg = gen_rtx_REG (mode, regno);
|
rtx reg, mem;
|
||||||
rtx 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];
|
offset = start_offset + cfun->machine->frame.reg_offset[regno];
|
||||||
mem = gen_mem_ref (mode, plus_constant (Pmode, base_rtx, offset));
|
mem = gen_mem_ref (mode, plus_constant (Pmode, base_rtx, offset));
|
||||||
|
|
||||||
@ -2267,6 +2277,8 @@ aarch64_expand_prologue (void)
|
|||||||
|
|
||||||
if (offset > 0)
|
if (offset > 0)
|
||||||
{
|
{
|
||||||
|
bool skip_wb = false;
|
||||||
|
|
||||||
/* Save the frame pointer and lr if the frame pointer is needed
|
/* Save the frame pointer and lr if the frame pointer is needed
|
||||||
first. Make the frame pointer point to the location of the
|
first. Make the frame pointer point to the location of the
|
||||||
old frame pointer on the stack. */
|
old frame pointer on the stack. */
|
||||||
@ -2284,7 +2296,7 @@ aarch64_expand_prologue (void)
|
|||||||
GEN_INT (offset))));
|
GEN_INT (offset))));
|
||||||
|
|
||||||
aarch64_save_callee_saves (DImode, fp_offset, R29_REGNUM,
|
aarch64_save_callee_saves (DImode, fp_offset, R29_REGNUM,
|
||||||
R30_REGNUM);
|
R30_REGNUM, skip_wb);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
aarch64_pushwb_pair_reg (DImode, R29_REGNUM, R30_REGNUM, offset);
|
aarch64_pushwb_pair_reg (DImode, R29_REGNUM, R30_REGNUM, offset);
|
||||||
@ -2303,7 +2315,8 @@ aarch64_expand_prologue (void)
|
|||||||
insn = emit_insn (gen_stack_tie (stack_pointer_rtx,
|
insn = emit_insn (gen_stack_tie (stack_pointer_rtx,
|
||||||
hard_frame_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
|
else
|
||||||
{
|
{
|
||||||
@ -2311,10 +2324,12 @@ aarch64_expand_prologue (void)
|
|||||||
GEN_INT (-offset)));
|
GEN_INT (-offset)));
|
||||||
RTX_FRAME_RELATED_P (insn) = 1;
|
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,
|
/* when offset >= 512,
|
||||||
@ -2339,6 +2354,7 @@ aarch64_expand_epilogue (bool for_sibcall)
|
|||||||
HOST_WIDE_INT fp_offset;
|
HOST_WIDE_INT fp_offset;
|
||||||
rtx insn;
|
rtx insn;
|
||||||
rtx cfa_reg;
|
rtx cfa_reg;
|
||||||
|
bool skip_wb = false;
|
||||||
|
|
||||||
aarch64_layout_frame ();
|
aarch64_layout_frame ();
|
||||||
|
|
||||||
@ -2387,20 +2403,21 @@ aarch64_expand_epilogue (bool for_sibcall)
|
|||||||
}
|
}
|
||||||
|
|
||||||
aarch64_restore_callee_saves (DFmode, frame_pointer_needed ? 0 : fp_offset,
|
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 (offset > 0)
|
||||||
{
|
{
|
||||||
if (frame_pointer_needed)
|
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,
|
aarch64_popwb_pair_reg (DImode, R29_REGNUM, R30_REGNUM, offset,
|
||||||
cfa_reg);
|
cfa_reg);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
aarch64_restore_callee_saves (DImode, fp_offset, R0_REGNUM,
|
aarch64_restore_callee_saves (DImode, fp_offset, R0_REGNUM,
|
||||||
R30_REGNUM);
|
R30_REGNUM, skip_wb);
|
||||||
insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
|
insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
|
||||||
GEN_INT (offset)));
|
GEN_INT (offset)));
|
||||||
RTX_FRAME_RELATED_P (insn) = 1;
|
RTX_FRAME_RELATED_P (insn) = 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user