aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arm64-gen.c30
-rw-r--r--tests/tests2/73_arm64.c18
-rw-r--r--tests/tests2/73_arm64.expect15
3 files changed, 55 insertions, 8 deletions
diff --git a/arm64-gen.c b/arm64-gen.c
index 814fa16..d64be1a 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 31abbd6..21a2462 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 c084677..00e5529 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