[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:
parent
6ff11db28b
commit
d9600ae5a3
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user