aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2024-08-15 00:22:47 +0200
committerMike Pall <mike>2024-08-15 00:22:47 +0200
commit6f834087d0553b68b61770c69109894bf3f375ef (patch)
treed5e9e28ab33d7308dba53827c17fd5cb9defebe8
parent2d54213e7ca9f276e080671dfcad2d26fbea2de4 (diff)
downloadluajit-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.lua20
-rw-r--r--src/lj_emit_arm64.h14
-rw-r--r--src/lj_target_arm64.h1
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
833end 837end
834 838
839local 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
851end
852
835local function prefer_bfx(sf, uns, imms, immr) 853local 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
69static 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
71static void emit_dnma(ASMState *as, A64Ins ai, Reg rd, Reg rn, Reg rm, Reg ra) 82static 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)