diff options
Diffstat (limited to '')
-rw-r--r-- | src/lj_emit_arm64.h | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/src/lj_emit_arm64.h b/src/lj_emit_arm64.h index 51d0c351..0967f6e4 100644 --- a/src/lj_emit_arm64.h +++ b/src/lj_emit_arm64.h | |||
@@ -66,6 +66,17 @@ static uint32_t emit_isfpk64(uint64_t n) | |||
66 | return ~0u; | 66 | return ~0u; |
67 | } | 67 | } |
68 | 68 | ||
69 | static uint32_t emit_isfpmovi(uint64_t n) | ||
70 | { | ||
71 | /* Is every byte either 0x00 or 0xff? */ | ||
72 | if ((n & U64x(01010101,01010101)) * 0xff != n) return 0; | ||
73 | /* Form 8-bit value by taking one bit from each byte. */ | ||
74 | n &= U64x(80402010,08040201); | ||
75 | n = (n * U64x(01010101,01010101)) >> 56; | ||
76 | /* Split into the format expected by movi. */ | ||
77 | return ((n & 0xe0) << 6) | 0x700 | (n & 0x1f); | ||
78 | } | ||
79 | |||
69 | /* -- Emit basic instructions --------------------------------------------- */ | 80 | /* -- Emit basic instructions --------------------------------------------- */ |
70 | 81 | ||
71 | static void emit_dnma(ASMState *as, A64Ins ai, Reg rd, Reg rn, Reg rm, Reg ra) | 82 | static void emit_dnma(ASMState *as, A64Ins ai, Reg rd, Reg rn, Reg rm, Reg ra) |
@@ -300,6 +311,9 @@ static void emit_loadk64(ASMState *as, Reg r, IRIns *ir) | |||
300 | if (fpk != ~0u) { | 311 | if (fpk != ~0u) { |
301 | emit_d(as, A64I_FMOV_DI | A64F_FP8(fpk), (r & 31)); | 312 | emit_d(as, A64I_FMOV_DI | A64F_FP8(fpk), (r & 31)); |
302 | return; | 313 | return; |
314 | } else if ((fpk = emit_isfpmovi(*k))) { | ||
315 | emit_d(as, A64I_MOVI_DI | (fpk << 5), (r & 31)); | ||
316 | return; | ||
303 | } | 317 | } |
304 | } | 318 | } |
305 | ofs = glofs(as, k); | 319 | ofs = glofs(as, k); |