Commit c747993a by Ian Bolton Committed by Kyrylo Tkachov

[AArch64] Use MOVN to generate 64-bit negative immediates where sensible

	* config/aarch64/aarch64.c (aarch64_expand_mov_immediate):
	Use MOVN when one of the half-words is 0xffff.

Co-Authored-By: Kyrylo Tkachov <kyrylo.tkachov@arm.com>

From-SVN: r213711
parent 4da2eb98
2014-08-07 Ian Bolton <ian.bolton@arm.com>
Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/aarch64/aarch64.c (aarch64_expand_mov_immediate):
Use MOVN when one of the half-words is 0xffff.
2014-08-07 Marat Zakirov <m.zakirov@samsung.com> 2014-08-07 Marat Zakirov <m.zakirov@samsung.com>
* config/arm/thumb1.md (*thumb1_movqi_insn): Copy of thumb1_movhi_insn. * config/arm/thumb1.md (*thumb1_movqi_insn): Copy of thumb1_movhi_insn.
......
...@@ -1006,7 +1006,7 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm) ...@@ -1006,7 +1006,7 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
unsigned HOST_WIDE_INT val; unsigned HOST_WIDE_INT val;
bool subtargets; bool subtargets;
rtx subtarget; rtx subtarget;
int one_match, zero_match; int one_match, zero_match, first_not_ffff_match;
gcc_assert (mode == SImode || mode == DImode); gcc_assert (mode == SImode || mode == DImode);
...@@ -1107,29 +1107,48 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm) ...@@ -1107,29 +1107,48 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
one_match = 0; one_match = 0;
zero_match = 0; zero_match = 0;
mask = 0xffff; mask = 0xffff;
first_not_ffff_match = -1;
for (i = 0; i < 64; i += 16, mask <<= 16) for (i = 0; i < 64; i += 16, mask <<= 16)
{ {
if ((val & mask) == mask)
one_match++;
else
{
if (first_not_ffff_match < 0)
first_not_ffff_match = i;
if ((val & mask) == 0) if ((val & mask) == 0)
zero_match++; zero_match++;
else if ((val & mask) == mask) }
one_match++;
} }
if (one_match == 2) if (one_match == 2)
{ {
mask = 0xffff; /* Set one of the quarters and then insert back into result. */
for (i = 0; i < 64; i += 16, mask <<= 16) mask = 0xffffll << first_not_ffff_match;
emit_insn (gen_rtx_SET (VOIDmode, dest, GEN_INT (val | mask)));
emit_insn (gen_insv_immdi (dest, GEN_INT (first_not_ffff_match),
GEN_INT ((val >> first_not_ffff_match)
& 0xffff)));
return;
}
if (one_match > zero_match)
{ {
if ((val & mask) != mask) /* Set either first three quarters or all but the third. */
mask = 0xffffll << (16 - first_not_ffff_match);
emit_insn (gen_rtx_SET (VOIDmode, dest,
GEN_INT (val | mask | 0xffffffff00000000ull)));
/* Now insert other two quarters. */
for (i = first_not_ffff_match + 16, mask <<= (first_not_ffff_match << 1);
i < 64; i += 16, mask <<= 16)
{ {
emit_insn (gen_rtx_SET (VOIDmode, dest, GEN_INT (val | mask))); if ((val & mask) != mask)
emit_insn (gen_insv_immdi (dest, GEN_INT (i), emit_insn (gen_insv_immdi (dest, GEN_INT (i),
GEN_INT ((val >> i) & 0xffff))); GEN_INT ((val >> i) & 0xffff)));
return;
}
} }
gcc_unreachable (); return;
} }
if (zero_match == 2) if (zero_match == 2)
......
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