mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 15:14:08 +00:00
ARM64: Use movi to materialize FP constants.
Thanks to Peter Cawley. #1245
This commit is contained in:
parent
2d54213e7c
commit
6f834087d0
@ -658,6 +658,10 @@ local map_datafp = { -- Data processing, SIMD and FP.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{ -- 010
|
||||||
|
shift = 0, mask = 0x81f8fc00,
|
||||||
|
[0x100e400] = "moviDdG"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -832,6 +836,20 @@ local function parse_fpimm8(op)
|
|||||||
return sign * frac * 2^exp
|
return sign * frac * 2^exp
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function decode_fpmovi(op)
|
||||||
|
local lo = rshift(op, 5)
|
||||||
|
local hi = rshift(op, 9)
|
||||||
|
lo = bor(band(lo, 1) * 0xff, band(lo, 2) * 0x7f80, band(lo, 4) * 0x3fc000,
|
||||||
|
band(lo, 8) * 0x1fe00000)
|
||||||
|
hi = bor(band(hi, 1) * 0xff, band(hi, 0x80) * 0x1fe,
|
||||||
|
band(hi, 0x100) * 0xff00, band(hi, 0x200) * 0x7f8000)
|
||||||
|
if hi ~= 0 then
|
||||||
|
return fmt_hex32(hi)..tohex(lo)
|
||||||
|
else
|
||||||
|
return fmt_hex32(lo)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function prefer_bfx(sf, uns, imms, immr)
|
local function prefer_bfx(sf, uns, imms, immr)
|
||||||
if imms < immr or imms == 31 or imms == 63 then
|
if imms < immr or imms == 31 or imms == 63 then
|
||||||
return false
|
return false
|
||||||
@ -1131,6 +1149,8 @@ local function disass_ins(ctx)
|
|||||||
x = 0
|
x = 0
|
||||||
elseif p == "F" then
|
elseif p == "F" then
|
||||||
x = parse_fpimm8(op)
|
x = parse_fpimm8(op)
|
||||||
|
elseif p == "G" then
|
||||||
|
x = "#0x"..decode_fpmovi(op)
|
||||||
elseif p == "g" or p == "f" or p == "x" or p == "w" or
|
elseif p == "g" or p == "f" or p == "x" or p == "w" or
|
||||||
p == "d" or p == "s" then
|
p == "d" or p == "s" then
|
||||||
-- These are handled in D/N/M/A.
|
-- These are handled in D/N/M/A.
|
||||||
|
@ -66,6 +66,17 @@ static uint32_t emit_isfpk64(uint64_t n)
|
|||||||
return ~0u;
|
return ~0u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t emit_isfpmovi(uint64_t n)
|
||||||
|
{
|
||||||
|
/* Is every byte either 0x00 or 0xff? */
|
||||||
|
if ((n & U64x(01010101,01010101)) * 0xff != n) return 0;
|
||||||
|
/* Form 8-bit value by taking one bit from each byte. */
|
||||||
|
n &= U64x(80402010,08040201);
|
||||||
|
n = (n * U64x(01010101,01010101)) >> 56;
|
||||||
|
/* Split into the format expected by movi. */
|
||||||
|
return ((n & 0xe0) << 6) | 0x700 | (n & 0x1f);
|
||||||
|
}
|
||||||
|
|
||||||
/* -- Emit basic instructions --------------------------------------------- */
|
/* -- Emit basic instructions --------------------------------------------- */
|
||||||
|
|
||||||
static void emit_dnma(ASMState *as, A64Ins ai, Reg rd, Reg rn, Reg rm, Reg ra)
|
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)
|
|||||||
if (fpk != ~0u) {
|
if (fpk != ~0u) {
|
||||||
emit_d(as, A64I_FMOV_DI | A64F_FP8(fpk), (r & 31));
|
emit_d(as, A64I_FMOV_DI | A64F_FP8(fpk), (r & 31));
|
||||||
return;
|
return;
|
||||||
|
} else if ((fpk = emit_isfpmovi(*k))) {
|
||||||
|
emit_d(as, A64I_MOVI_DI | (fpk << 5), (r & 31));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ofs = glofs(as, k);
|
ofs = glofs(as, k);
|
||||||
|
@ -320,6 +320,7 @@ typedef enum A64Ins {
|
|||||||
A64I_FMOV_R_D = 0x9e660000,
|
A64I_FMOV_R_D = 0x9e660000,
|
||||||
A64I_FMOV_D_R = 0x9e670000,
|
A64I_FMOV_D_R = 0x9e670000,
|
||||||
A64I_FMOV_DI = 0x1e601000,
|
A64I_FMOV_DI = 0x1e601000,
|
||||||
|
A64I_MOVI_DI = 0x2f000400,
|
||||||
} A64Ins;
|
} A64Ins;
|
||||||
|
|
||||||
#define A64I_BR_AUTH (LJ_ABI_PAUTH ? A64I_BRAAZ : A64I_BR)
|
#define A64I_BR_AUTH (LJ_ABI_PAUTH ? A64I_BRAAZ : A64I_BR)
|
||||||
|
Loading…
Reference in New Issue
Block a user