Commit 37d6a4b7 by Jiong Wang Committed by Jiong Wang

[AArch64][3/3] Migrate aarch64_expand_prologue/epilogue to aarch64_add_constant

gcc/
	* config/aarch64/aarch64.c (aarch64_add_constant): New parameter
	"frame_related_p".  Generate CFA annotation when it's necessary.
	(aarch64_expand_prologue): Use aarch64_add_constant.
	(aarch64_expand_epilogue): Likewise.
	(aarch64_output_mi_thunk): Pass "false" when calling
	aarch64_add_constant.

From-SVN: r238714
parent c4ddc43a
2016-07-25 Jiong Wang <jiong.wang@arm.com> 2016-07-25 Jiong Wang <jiong.wang@arm.com>
* config/aarch64/aarch64.c (aarch64_add_constant): New parameter
"frame_related_p". Generate CFA annotation when it's necessary.
(aarch64_expand_prologue): Use aarch64_add_constant.
(aarch64_expand_epilogue): Likewise.
(aarch64_output_mi_thunk): Pass "false" when calling
aarch64_add_constant.
2016-07-25 Jiong Wang <jiong.wang@arm.com>
* config/aarch64/aarch64.c (aarch64_add_constant): Optimize instruction * config/aarch64/aarch64.c (aarch64_add_constant): Optimize instruction
sequences. sequences.
......
...@@ -1941,14 +1941,19 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm) ...@@ -1941,14 +1941,19 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
} }
/* Add DELTA to REGNUM in mode MODE. SCRATCHREG can be used to held /* Add DELTA to REGNUM in mode MODE. SCRATCHREG can be used to held
intermediate value if necessary. */ intermediate value if necessary.
This function is sometimes used to adjust the stack pointer, so we must
ensure that it can never cause transient stack deallocation by writing an
invalid value into REGNUM. */
static void static void
aarch64_add_constant (machine_mode mode, int regnum, int scratchreg, aarch64_add_constant (machine_mode mode, int regnum, int scratchreg,
HOST_WIDE_INT delta) HOST_WIDE_INT delta, bool frame_related_p)
{ {
HOST_WIDE_INT mdelta = abs_hwi (delta); HOST_WIDE_INT mdelta = abs_hwi (delta);
rtx this_rtx = gen_rtx_REG (mode, regnum); rtx this_rtx = gen_rtx_REG (mode, regnum);
rtx_insn *insn;
/* Do nothing if mdelta is zero. */ /* Do nothing if mdelta is zero. */
if (!mdelta) if (!mdelta)
...@@ -1957,7 +1962,8 @@ aarch64_add_constant (machine_mode mode, int regnum, int scratchreg, ...@@ -1957,7 +1962,8 @@ aarch64_add_constant (machine_mode mode, int regnum, int scratchreg,
/* We only need single instruction if the offset fit into add/sub. */ /* We only need single instruction if the offset fit into add/sub. */
if (aarch64_uimm12_shift (mdelta)) if (aarch64_uimm12_shift (mdelta))
{ {
emit_insn (gen_add2_insn (this_rtx, GEN_INT (delta))); insn = emit_insn (gen_add2_insn (this_rtx, GEN_INT (delta)));
RTX_FRAME_RELATED_P (insn) = frame_related_p;
return; return;
} }
...@@ -1970,15 +1976,23 @@ aarch64_add_constant (machine_mode mode, int regnum, int scratchreg, ...@@ -1970,15 +1976,23 @@ aarch64_add_constant (machine_mode mode, int regnum, int scratchreg,
HOST_WIDE_INT low_off = mdelta & 0xfff; HOST_WIDE_INT low_off = mdelta & 0xfff;
low_off = delta < 0 ? -low_off : low_off; low_off = delta < 0 ? -low_off : low_off;
emit_insn (gen_add2_insn (this_rtx, GEN_INT (low_off))); insn = emit_insn (gen_add2_insn (this_rtx, GEN_INT (low_off)));
emit_insn (gen_add2_insn (this_rtx, GEN_INT (delta - low_off))); RTX_FRAME_RELATED_P (insn) = frame_related_p;
insn = emit_insn (gen_add2_insn (this_rtx, GEN_INT (delta - low_off)));
RTX_FRAME_RELATED_P (insn) = frame_related_p;
return; return;
} }
/* Otherwise use generic function to handle all other situations. */ /* Otherwise use generic function to handle all other situations. */
rtx scratch_rtx = gen_rtx_REG (mode, scratchreg); rtx scratch_rtx = gen_rtx_REG (mode, scratchreg);
aarch64_internal_mov_immediate (scratch_rtx, GEN_INT (delta), true, mode); aarch64_internal_mov_immediate (scratch_rtx, GEN_INT (delta), true, mode);
emit_insn (gen_add2_insn (this_rtx, scratch_rtx)); insn = emit_insn (gen_add2_insn (this_rtx, scratch_rtx));
if (frame_related_p)
{
RTX_FRAME_RELATED_P (insn) = frame_related_p;
rtx adj = plus_constant (mode, this_rtx, delta);
add_reg_note (insn , REG_CFA_ADJUST_CFA, gen_rtx_SET (this_rtx, adj));
}
} }
static bool static bool
...@@ -3113,36 +3127,7 @@ aarch64_expand_prologue (void) ...@@ -3113,36 +3127,7 @@ aarch64_expand_prologue (void)
frame_size -= (offset + crtl->outgoing_args_size); frame_size -= (offset + crtl->outgoing_args_size);
fp_offset = 0; fp_offset = 0;
if (frame_size >= 0x1000000) aarch64_add_constant (Pmode, SP_REGNUM, IP0_REGNUM, -frame_size, true);
{
rtx op0 = gen_rtx_REG (Pmode, IP0_REGNUM);
emit_move_insn (op0, GEN_INT (-frame_size));
insn = emit_insn (gen_add2_insn (stack_pointer_rtx, op0));
add_reg_note (insn, REG_CFA_ADJUST_CFA,
gen_rtx_SET (stack_pointer_rtx,
plus_constant (Pmode, stack_pointer_rtx,
-frame_size)));
RTX_FRAME_RELATED_P (insn) = 1;
}
else if (frame_size > 0)
{
int hi_ofs = frame_size & 0xfff000;
int lo_ofs = frame_size & 0x000fff;
if (hi_ofs)
{
insn = emit_insn (gen_add2_insn
(stack_pointer_rtx, GEN_INT (-hi_ofs)));
RTX_FRAME_RELATED_P (insn) = 1;
}
if (lo_ofs)
{
insn = emit_insn (gen_add2_insn
(stack_pointer_rtx, GEN_INT (-lo_ofs)));
RTX_FRAME_RELATED_P (insn) = 1;
}
}
} }
else else
frame_size = -1; frame_size = -1;
...@@ -3362,31 +3347,7 @@ aarch64_expand_epilogue (bool for_sibcall) ...@@ -3362,31 +3347,7 @@ aarch64_expand_epilogue (bool for_sibcall)
if (need_barrier_p) if (need_barrier_p)
emit_insn (gen_stack_tie (stack_pointer_rtx, stack_pointer_rtx)); emit_insn (gen_stack_tie (stack_pointer_rtx, stack_pointer_rtx));
if (frame_size >= 0x1000000) aarch64_add_constant (Pmode, SP_REGNUM, IP0_REGNUM, frame_size, true);
{
rtx op0 = gen_rtx_REG (Pmode, IP0_REGNUM);
emit_move_insn (op0, GEN_INT (frame_size));
insn = emit_insn (gen_add2_insn (stack_pointer_rtx, op0));
}
else
{
int hi_ofs = frame_size & 0xfff000;
int lo_ofs = frame_size & 0x000fff;
if (hi_ofs && lo_ofs)
{
insn = emit_insn (gen_add2_insn
(stack_pointer_rtx, GEN_INT (hi_ofs)));
RTX_FRAME_RELATED_P (insn) = 1;
frame_size = lo_ofs;
}
insn = emit_insn (gen_add2_insn
(stack_pointer_rtx, GEN_INT (frame_size)));
}
/* Reset the CFA to be SP + 0. */
add_reg_note (insn, REG_CFA_DEF_CFA, stack_pointer_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
} }
/* Stack adjustment for exception handler. */ /* Stack adjustment for exception handler. */
...@@ -3473,7 +3434,7 @@ aarch64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, ...@@ -3473,7 +3434,7 @@ aarch64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
emit_note (NOTE_INSN_PROLOGUE_END); emit_note (NOTE_INSN_PROLOGUE_END);
if (vcall_offset == 0) if (vcall_offset == 0)
aarch64_add_constant (Pmode, this_regno, IP1_REGNUM, delta); aarch64_add_constant (Pmode, this_regno, IP1_REGNUM, delta, false);
else else
{ {
gcc_assert ((vcall_offset & (POINTER_BYTES - 1)) == 0); gcc_assert ((vcall_offset & (POINTER_BYTES - 1)) == 0);
...@@ -3489,7 +3450,7 @@ aarch64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, ...@@ -3489,7 +3450,7 @@ aarch64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
addr = gen_rtx_PRE_MODIFY (Pmode, this_rtx, addr = gen_rtx_PRE_MODIFY (Pmode, this_rtx,
plus_constant (Pmode, this_rtx, delta)); plus_constant (Pmode, this_rtx, delta));
else else
aarch64_add_constant (Pmode, this_regno, IP1_REGNUM, delta); aarch64_add_constant (Pmode, this_regno, IP1_REGNUM, delta, false);
} }
if (Pmode == ptr_mode) if (Pmode == ptr_mode)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment