diff options
author | Mike Pall <mike> | 2024-08-15 00:22:47 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2024-08-15 00:22:47 +0200 |
commit | 6f834087d0553b68b61770c69109894bf3f375ef (patch) | |
tree | d5e9e28ab33d7308dba53827c17fd5cb9defebe8 | |
parent | 2d54213e7ca9f276e080671dfcad2d26fbea2de4 (diff) | |
download | luajit-6f834087d0553b68b61770c69109894bf3f375ef.tar.gz luajit-6f834087d0553b68b61770c69109894bf3f375ef.tar.bz2 luajit-6f834087d0553b68b61770c69109894bf3f375ef.zip |
ARM64: Use movi to materialize FP constants.
Thanks to Peter Cawley. #1245
-rw-r--r-- | src/jit/dis_arm64.lua | 20 | ||||
-rw-r--r-- | src/lj_emit_arm64.h | 14 | ||||
-rw-r--r-- | src/lj_target_arm64.h | 1 |
3 files changed, 35 insertions, 0 deletions
diff --git a/src/jit/dis_arm64.lua b/src/jit/dis_arm64.lua index 84677666..2741cd2e 100644 --- a/src/jit/dis_arm64.lua +++ b/src/jit/dis_arm64.lua | |||
@@ -658,6 +658,10 @@ local map_datafp = { -- Data processing, SIMD and FP. | |||
658 | } | 658 | } |
659 | } | 659 | } |
660 | } | 660 | } |
661 | }, | ||
662 | { -- 010 | ||
663 | shift = 0, mask = 0x81f8fc00, | ||
664 | [0x100e400] = "moviDdG" | ||
661 | } | 665 | } |
662 | } | 666 | } |
663 | 667 | ||
@@ -832,6 +836,20 @@ local function parse_fpimm8(op) | |||
832 | return sign * frac * 2^exp | 836 | return sign * frac * 2^exp |
833 | end | 837 | end |
834 | 838 | ||
839 | local function decode_fpmovi(op) | ||
840 | local lo = rshift(op, 5) | ||
841 | local hi = rshift(op, 9) | ||
842 | lo = bor(band(lo, 1) * 0xff, band(lo, 2) * 0x7f80, band(lo, 4) * 0x3fc000, | ||
843 | band(lo, 8) * 0x1fe00000) | ||
844 | hi = bor(band(hi, 1) * 0xff, band(hi, 0x80) * 0x1fe, | ||
845 | band(hi, 0x100) * 0xff00, band(hi, 0x200) * 0x7f8000) | ||
846 | if hi ~= 0 then | ||
847 | return fmt_hex32(hi)..tohex(lo) | ||
848 | else | ||
849 | return fmt_hex32(lo) | ||
850 | end | ||
851 | end | ||
852 | |||
835 | local function prefer_bfx(sf, uns, imms, immr) | 853 | local function prefer_bfx(sf, uns, imms, immr) |
836 | if imms < immr or imms == 31 or imms == 63 then | 854 | if imms < immr or imms == 31 or imms == 63 then |
837 | return false | 855 | return false |
@@ -1131,6 +1149,8 @@ local function disass_ins(ctx) | |||
1131 | x = 0 | 1149 | x = 0 |
1132 | elseif p == "F" then | 1150 | elseif p == "F" then |
1133 | x = parse_fpimm8(op) | 1151 | x = parse_fpimm8(op) |
1152 | elseif p == "G" then | ||
1153 | x = "#0x"..decode_fpmovi(op) | ||
1134 | elseif p == "g" or p == "f" or p == "x" or p == "w" or | 1154 | elseif p == "g" or p == "f" or p == "x" or p == "w" or |
1135 | p == "d" or p == "s" then | 1155 | p == "d" or p == "s" then |
1136 | -- These are handled in D/N/M/A. | 1156 | -- These are handled in D/N/M/A. |
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); |
diff --git a/src/lj_target_arm64.h b/src/lj_target_arm64.h index c34f1e59..8ed8851c 100644 --- a/src/lj_target_arm64.h +++ b/src/lj_target_arm64.h | |||
@@ -320,6 +320,7 @@ typedef enum A64Ins { | |||
320 | A64I_FMOV_R_D = 0x9e660000, | 320 | A64I_FMOV_R_D = 0x9e660000, |
321 | A64I_FMOV_D_R = 0x9e670000, | 321 | A64I_FMOV_D_R = 0x9e670000, |
322 | A64I_FMOV_DI = 0x1e601000, | 322 | A64I_FMOV_DI = 0x1e601000, |
323 | A64I_MOVI_DI = 0x2f000400, | ||
323 | } A64Ins; | 324 | } A64Ins; |
324 | 325 | ||
325 | #define A64I_BR_AUTH (LJ_ABI_PAUTH ? A64I_BRAAZ : A64I_BR) | 326 | #define A64I_BR_AUTH (LJ_ABI_PAUTH ? A64I_BRAAZ : A64I_BR) |