From 86e8dcd5e291965c27761633174fd9e65a293136 Mon Sep 17 00:00:00 2001 From: Edmund Grimley Evans Date: Mon, 2 Mar 2015 20:39:28 +0000 Subject: [PATCH] arm64: Improve constant generation, with tests. --- arm64-gen.c | 30 ++++++++++++++++++++++-------- tests/tests2/73_arm64.c | 18 ++++++++++++++++++ tests/tests2/73_arm64.expect | 15 +++++++++++++++ 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/arm64-gen.c b/arm64-gen.c index 814fa165..d64be1ae 100644 --- a/arm64-gen.c +++ b/arm64-gen.c @@ -204,16 +204,30 @@ static void arm64_movimm(int r, uint64_t x) { uint32_t i; if ((i = arm64_movi(r, x))) - o(i); + o(i); // a single MOV else { - // This could be improved: - o(0x52800000 | r | (x & 0xffff) << 5); // movz w(r),#(x & 0xffff) - for (i = 1; i < 4; i++) - if (x >> 16 * i & 0xffff) { - o(0xf2800000 | r | (x >> 16 * i & 0xffff) << 5 | i << 21); - // movk w(r),#(*),lsl #(*) + // MOVZ/MOVN and 1-3 MOVKs + int z = 0, m = 0; + uint32_t mov1 = 0xd2800000; // movz + uint64_t x1 = x; + for (i = 0; i < 64; i += 16) { + 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) } } diff --git a/tests/tests2/73_arm64.c b/tests/tests2/73_arm64.c index 31abbd60..21a2462d 100644 --- a/tests/tests2/73_arm64.c +++ b/tests/tests2/73_arm64.c @@ -409,6 +409,24 @@ void movi(void) pll(0x007fffc0); pll(0x03fff80003fff800); 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) diff --git a/tests/tests2/73_arm64.expect b/tests/tests2/73_arm64.expect index c0846775..00e55296 100644 --- a/tests/tests2/73_arm64.expect +++ b/tests/tests2/73_arm64.expect @@ -121,3 +121,18 @@ f8f8f8f8 7fffc0 3fff80003fff800 7fffffffffe00 +abcd1234 +abcd00001234 +abcd000000001234 +abcd12340000 +abcd000012340000 +abcd123400000000 +ffffffffabcd1234 +ffffabcdffff1234 +abcdffffffff1234 +ffffabcd1234ffff +abcdffff1234ffff +abcd1234ffffffff +ffffef0123456789 +abcdef012345ffff +abcdef0123456789 -- 2.11.4.GIT