arm64: Improve constant generation, with tests.

This commit is contained in:
Edmund Grimley Evans
2015-03-02 20:39:28 +00:00
parent 883fd365c7
commit 86e8dcd5e2
3 changed files with 55 additions and 8 deletions

View File

@ -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)
} }
} }

View File

@ -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)

View File

@ -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