Unified · Split
| @@ -204,16 +204,30 @@ static void arm64_movimm(int r, uint64_t x) · 203 unmodified lines | |||
| 204 | { | 204 | { |
| 205 | uint32_t i; | 205 | uint32_t i; |
| 206 | if ((i = arm64_movi(r, x))) | 206 | if ((i = arm64_movi(r, x))) |
| 207 | o(i); | 207 | o(i); // a single MOV |
| 208 | else { | 208 | else { |
| 209 | // This could be improved: | 209 | // MOVZ/MOVN and 1-3 MOVKs |
| 210 | o(0x52800000 | r | (x & 0xffff) << 5); // movz w(r),#(x & 0xffff) | 210 | int z = 0, m = 0; |
| 211 | for (i = 1; i < 4; i++) | 211 | uint32_t mov1 = 0xd2800000; // movz |
| 212 | if (x >> 16 * i & 0xffff) { | 212 | uint64_t x1 = x; |
| 213 | o(0xf2800000 | r | (x >> 16 * i & 0xffff) << 5 | i << 21); | 213 | for (i = 0; i < 64; i += 16) { |
| 214 | // movk w(r),#(*),lsl #(*) | 214 | z += !(x >> i & 0xffff); |
| 215 | m += !(~x >> i & 0xffff); | ||
| 216 | } | ||
| 217 | if (m > z) { | ||
| 218 | x1 = ~x; | ||
| 219 | mov1 = 0x92800000; // movn | ||
| 220 | } | ||
| 221 | for (i = 0; i < 64; i += 16) | ||
| 222 | if (x1 >> i & 0xffff) { | ||
| 223 | o(mov1 | r | (x1 >> i & 0xffff) << 5 | i << 17); | ||
| 224 | // movz/movn x(r),#(*),lsl #(i) | ||
| 225 | break; | ||
| 215 | } | 226 | } |
| 216 | 227 | for (i += 16; i < 64; i += 16) | |
| 228 | if (x1 >> i & 0xffff) | ||
| 229 | o(0xf2800000 | r | (x >> i & 0xffff) << 5 | i << 17); | ||
| 230 | // movk x(r),#(*),lsl #(i) | ||
| 217 | } | 231 | } |
| 218 | } | 232 | } |
| 219 | 233 | ||
| @@ -409,6 +409,24 @@ void movi(void) · 408 unmodified lines | |||
| 409 | pll(0x007fffc0); | 409 | pll(0x007fffc0); |
| 410 | pll(0x03fff80003fff800); | 410 | pll(0x03fff80003fff800); |
| 411 | pll(0x0007fffffffffe00); | 411 | pll(0x0007fffffffffe00); |
| 412 | |||
| 413 | pll(0xabcd1234); | ||
| 414 | pll(0xabcd00001234); | ||
| 415 | pll(0xabcd000000001234); | ||
| 416 | pll(0xabcd12340000); | ||
| 417 | pll(0xabcd000012340000); | ||
| 418 | pll(0xabcd123400000000); | ||
| 419 | pll(0xffffffffabcd1234); | ||
| 420 | pll(0xffffabcdffff1234); | ||
| 421 | pll(0xabcdffffffff1234); | ||
| 422 | pll(0xffffabcd1234ffff); | ||
| 423 | pll(0xabcdffff1234ffff); | ||
| 424 | pll(0xabcd1234ffffffff); | ||
| 425 | |||
| 426 | pll(0xffffef0123456789); | ||
| 427 | pll(0xabcdef012345ffff); | ||
| 428 | |||
| 429 | pll(0xabcdef0123456789); | ||
| 412 | } | 430 | } |
| 413 | 431 | ||
| 414 | void pcs(void) | 432 | void pcs(void) |
| @@ -121,3 +121,18 @@ f8f8f8f8 · 120 unmodified lines | |||
| 121 | 7fffc0 | 121 | 7fffc0 |
| 122 | 3fff80003fff800 | 122 | 3fff80003fff800 |
| 123 | 7fffffffffe00 | 123 | 7fffffffffe00 |
| 124 | abcd1234 | ||
| 125 | abcd00001234 | ||
| 126 | abcd000000001234 | ||
| 127 | abcd12340000 | ||
| 128 | abcd000012340000 | ||
| 129 | abcd123400000000 | ||
| 130 | ffffffffabcd1234 | ||
| 131 | ffffabcdffff1234 | ||
| 132 | abcdffffffff1234 | ||
| 133 | ffffabcd1234ffff | ||
| 134 | abcdffff1234ffff | ||
| 135 | abcd1234ffffffff | ||
| 136 | ffffef0123456789 | ||
| 137 | abcdef012345ffff | ||
| 138 | abcdef0123456789 | ||