arm64: Improve constant generation, with tests.
This commit is contained in:
30
arm64-gen.c
30
arm64-gen.c
@ -204,16 +204,30 @@ static void arm64_movimm(int r, uint64_t x)
|
|||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
if ((i = arm64_movi(r, x)))
|
if ((i = arm64_movi(r, x)))
|
||||||
o(i);
|
o(i); // a single MOV
|
||||||
else {
|
else {
|
||||||
// This could be improved:
|
// MOVZ/MOVN and 1-3 MOVKs
|
||||||
o(0x52800000 | r | (x & 0xffff) << 5); // movz w(r),#(x & 0xffff)
|
int z = 0, m = 0;
|
||||||
for (i = 1; i < 4; i++)
|
uint32_t mov1 = 0xd2800000; // movz
|
||||||
if (x >> 16 * i & 0xffff) {
|
uint64_t x1 = x;
|
||||||
o(0xf2800000 | r | (x >> 16 * i & 0xffff) << 5 | i << 21);
|
for (i = 0; i < 64; i += 16) {
|
||||||
// movk w(r),#(*),lsl #(*)
|
z += !(x >> i & 0xffff);
|
||||||
|
m += !(~x >> i & 0xffff);
|
||||||
|
}
|
||||||
|
if (m > z) {
|
||||||
|
x1 = ~x;
|
||||||
|
mov1 = 0x92800000; // movn
|
||||||
|
}
|
||||||
|
for (i = 0; i < 64; i += 16)
|
||||||
|
if (x1 >> i & 0xffff) {
|
||||||
|
o(mov1 | r | (x1 >> i & 0xffff) << 5 | i << 17);
|
||||||
|
// movz/movn x(r),#(*),lsl #(i)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
for (i += 16; i < 64; i += 16)
|
||||||
|
if (x1 >> i & 0xffff)
|
||||||
|
o(0xf2800000 | r | (x >> i & 0xffff) << 5 | i << 17);
|
||||||
|
// movk x(r),#(*),lsl #(i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -409,6 +409,24 @@ void movi(void)
|
|||||||
pll(0x007fffc0);
|
pll(0x007fffc0);
|
||||||
pll(0x03fff80003fff800);
|
pll(0x03fff80003fff800);
|
||||||
pll(0x0007fffffffffe00);
|
pll(0x0007fffffffffe00);
|
||||||
|
|
||||||
|
pll(0xabcd1234);
|
||||||
|
pll(0xabcd00001234);
|
||||||
|
pll(0xabcd000000001234);
|
||||||
|
pll(0xabcd12340000);
|
||||||
|
pll(0xabcd000012340000);
|
||||||
|
pll(0xabcd123400000000);
|
||||||
|
pll(0xffffffffabcd1234);
|
||||||
|
pll(0xffffabcdffff1234);
|
||||||
|
pll(0xabcdffffffff1234);
|
||||||
|
pll(0xffffabcd1234ffff);
|
||||||
|
pll(0xabcdffff1234ffff);
|
||||||
|
pll(0xabcd1234ffffffff);
|
||||||
|
|
||||||
|
pll(0xffffef0123456789);
|
||||||
|
pll(0xabcdef012345ffff);
|
||||||
|
|
||||||
|
pll(0xabcdef0123456789);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcs(void)
|
void pcs(void)
|
||||||
|
|||||||
@ -121,3 +121,18 @@ f8f8f8f8
|
|||||||
7fffc0
|
7fffc0
|
||||||
3fff80003fff800
|
3fff80003fff800
|
||||||
7fffffffffe00
|
7fffffffffe00
|
||||||
|
abcd1234
|
||||||
|
abcd00001234
|
||||||
|
abcd000000001234
|
||||||
|
abcd12340000
|
||||||
|
abcd000012340000
|
||||||
|
abcd123400000000
|
||||||
|
ffffffffabcd1234
|
||||||
|
ffffabcdffff1234
|
||||||
|
abcdffffffff1234
|
||||||
|
ffffabcd1234ffff
|
||||||
|
abcdffff1234ffff
|
||||||
|
abcd1234ffffffff
|
||||||
|
ffffef0123456789
|
||||||
|
abcdef012345ffff
|
||||||
|
abcdef0123456789
|
||||||
|
|||||||
Reference in New Issue
Block a user