[AARCH64] Refactor constant generation.

2012-12-03  Sofiane Naci  <sofiane.naci@arm.com>

	* config/aarch64/aarch64.c (aarch64_build_constant): Update prototype.
	Call emit_move_insn	instead of printing movi/movn/movz instructions.
	Call gen_insv_immdi instead of printing movk instruction.
	(aarch64_add_constant): Update prototype.
	Generate RTL instead of printing add/sub instructions.
	(aarch64_output_mi_thunk): Update calls to aarch64_build_constant
	and aarch64_add_constant.

From-SVN: r194080
This commit is contained in:
Sofiane Naci 2012-12-03 11:13:41 +00:00 committed by Sofiane Naci
parent 6ff11db28b
commit d9600ae5a3
2 changed files with 41 additions and 23 deletions

View File

@ -1,3 +1,13 @@
2012-12-03 Sofiane Naci <sofiane.naci@arm.com>
* config/aarch64/aarch64.c (aarch64_build_constant): Update prototype.
Call emit_move_insn instead of printing movi/movn/movz instructions.
Call gen_insv_immdi instead of printing movk instruction.
(aarch64_add_constant): Update prototype.
Generate RTL instead of printing add/sub instructions.
(aarch64_output_mi_thunk): Update calls to aarch64_build_constant
and aarch64_add_constant.
2012-12-03 Kai Tietz <ktietz@redhat.com>
PR target/53912

View File

@ -2236,12 +2236,10 @@ aarch64_final_eh_return_addr (void)
/* Output code to build up a constant in a register. */
static void
aarch64_build_constant (FILE *file,
int regnum,
HOST_WIDE_INT val)
aarch64_build_constant (int regnum, HOST_WIDE_INT val)
{
if (aarch64_bitmask_imm (val, DImode))
asm_fprintf (file, "\tmovi\t%r, %wd\n", regnum, val);
emit_move_insn (gen_rtx_REG (Pmode, regnum), GEN_INT (val));
else
{
int i;
@ -2272,12 +2270,14 @@ aarch64_build_constant (FILE *file,
the same. */
if (ncount < zcount)
{
asm_fprintf (file, "\tmovn\t%r, %wd\n", regnum, (~val) & 0xffff);
emit_move_insn (gen_rtx_REG (Pmode, regnum),
GEN_INT ((~val) & 0xffff));
tval = 0xffff;
}
else
{
asm_fprintf (file, "\tmovz\t%r, %wd\n", regnum, val & 0xffff);
emit_move_insn (gen_rtx_REG (Pmode, regnum),
GEN_INT (val & 0xffff));
tval = 0;
}
@ -2286,39 +2286,47 @@ aarch64_build_constant (FILE *file,
for (i = 16; i < 64; i += 16)
{
if ((val & 0xffff) != tval)
asm_fprintf (file, "\tmovk\t%r, %wd, lsl %d\n",
regnum, val & 0xffff, i);
emit_insn (gen_insv_immdi (gen_rtx_REG (Pmode, regnum),
GEN_INT (i), GEN_INT (val & 0xffff)));
val >>= 16;
}
}
}
static void
aarch64_add_constant (FILE *file, int regnum, int scratchreg,
HOST_WIDE_INT delta)
aarch64_add_constant (int regnum, int scratchreg, HOST_WIDE_INT delta)
{
HOST_WIDE_INT mdelta = delta;
rtx this_rtx = gen_rtx_REG (Pmode, regnum);
rtx scratch_rtx = gen_rtx_REG (Pmode, scratchreg);
if (mdelta < 0)
mdelta = -mdelta;
if (mdelta >= 4096 * 4096)
{
aarch64_build_constant (file, scratchreg, delta);
asm_fprintf (file, "\tadd\t%r, %r, %r\n", regnum, regnum,
scratchreg);
aarch64_build_constant (scratchreg, delta);
emit_insn (gen_add3_insn (this_rtx, this_rtx, scratch_rtx));
}
else if (mdelta > 0)
{
const char *const mi_op = delta < 0 ? "sub" : "add";
if (mdelta >= 4096)
asm_fprintf (file, "\t%s\t%r, %r, %wd, lsl 12\n", mi_op, regnum, regnum,
mdelta / 4096);
{
emit_insn (gen_rtx_SET (Pmode, scratch_rtx, GEN_INT (mdelta / 4096)));
rtx shift = gen_rtx_ASHIFT (Pmode, scratch_rtx, GEN_INT (12));
if (delta < 0)
emit_insn (gen_rtx_SET (Pmode, this_rtx,
gen_rtx_MINUS (Pmode, this_rtx, shift)));
else
emit_insn (gen_rtx_SET (Pmode, this_rtx,
gen_rtx_PLUS (Pmode, this_rtx, shift)));
}
if (mdelta % 4096 != 0)
asm_fprintf (file, "\t%s\t%r, %r, %wd\n", mi_op, regnum, regnum,
mdelta % 4096);
{
scratch_rtx = GEN_INT ((delta < 0 ? -1 : 1) * (mdelta % 4096));
emit_insn (gen_rtx_SET (Pmode, this_rtx,
gen_rtx_PLUS (Pmode, this_rtx, scratch_rtx)));
}
}
}
@ -2341,7 +2349,7 @@ aarch64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
emit_note (NOTE_INSN_PROLOGUE_END);
if (vcall_offset == 0)
aarch64_add_constant (file, this_regno, IP1_REGNUM, delta);
aarch64_add_constant (this_regno, IP1_REGNUM, delta);
else
{
gcc_assert ((vcall_offset & 0x7) == 0);
@ -2357,7 +2365,7 @@ aarch64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
addr = gen_rtx_PRE_MODIFY (Pmode, this_rtx,
plus_constant (Pmode, this_rtx, delta));
else
aarch64_add_constant (file, this_regno, IP1_REGNUM, delta);
aarch64_add_constant (this_regno, IP1_REGNUM, delta);
}
aarch64_emit_move (temp0, gen_rtx_MEM (Pmode, addr));
@ -2366,7 +2374,7 @@ aarch64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
addr = plus_constant (Pmode, temp0, vcall_offset);
else
{
aarch64_build_constant (file, IP1_REGNUM, vcall_offset);
aarch64_build_constant (IP1_REGNUM, vcall_offset);
addr = gen_rtx_PLUS (Pmode, temp0, temp1);
}