mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-04-22 06:43:27 +00:00
DynASM/arm64: Partially support 'movi' instruction
In the development of PHP JIT/AArch64, `movi d0, #0` is needed to zero FP registers. In this patch, we partially support the 64-bit scalar variant of 'movi' instruction [1]. In this variant, 64-bit immediate value is acceptable with the condition that each byte is either all zeros or all ones. Note that the action to handle variables for this 64-bit immediate is not implemented yet. Example: ``` | movi d0, #0xffff00ffff | movi Rd(reg-ZREG_V0), #0 ``` Disassembly: ``` movi d0, #0xffff00ffff movi d0, #0x0 ``` [1] https://developer.arm.com/documentation/ddi0602/2020-12/SIMD-FP-Instructions/MOVI--Move-Immediate--vector--?lang=en Change-Id: I61701fc25b778393b4d1ae1798cd9541f115a351
This commit is contained in:
parent
3fbf51bb99
commit
12ee94ffad
@ -441,6 +441,34 @@ local function parse_fpimm(imm)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function parse_imm_movi(n)
|
||||||
|
local lo = tonumber(n % 0x100000000)
|
||||||
|
local hi = tonumber((n-lo) / 0x100000000)
|
||||||
|
local m = 0
|
||||||
|
for j=0,1 do
|
||||||
|
local h = j == 0 and hi or lo
|
||||||
|
for i=3,0,-1 do
|
||||||
|
local b = band(shr(h, i*8), 0xff)
|
||||||
|
if b ~= 0xff and b ~= 0 then return false, _ end
|
||||||
|
m = m*2 + band(b, 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true, m
|
||||||
|
end
|
||||||
|
|
||||||
|
local function parse_imm64(imm)
|
||||||
|
imm = match(imm, "^#(.*)$")
|
||||||
|
if not imm then werror("expected immediate operand") end
|
||||||
|
local n = parse_number(imm)
|
||||||
|
if n then
|
||||||
|
local ok, m = parse_imm_movi(n)
|
||||||
|
if ok then return shl(band(m, 0x1f), 5) + shl(band(m, 0xe0), 11) end
|
||||||
|
werror("invalid immediate `"..imm.."'")
|
||||||
|
else
|
||||||
|
werror("NYI movi imm action")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function parse_shift(expr)
|
local function parse_shift(expr)
|
||||||
local s, s2 = match(expr, "^(%S+)%s*(.*)$")
|
local s, s2 = match(expr, "^(%S+)%s*(.*)$")
|
||||||
s = map_shift[s]
|
s = map_shift[s]
|
||||||
@ -889,6 +917,7 @@ map_op = {
|
|||||||
|
|
||||||
-- TODO: crc32*, aes*, sha*, pmull
|
-- TODO: crc32*, aes*, sha*, pmull
|
||||||
-- TODO: SIMD instructions.
|
-- TODO: SIMD instructions.
|
||||||
|
movi_2 = "2f00e400DOd",
|
||||||
}
|
}
|
||||||
|
|
||||||
for cond,c in pairs(map_cond) do
|
for cond,c in pairs(map_cond) do
|
||||||
@ -975,6 +1004,8 @@ local function parse_template(params, template, nparams, pos)
|
|||||||
op = op + parse_imm(q, 4, 0, 0, false); n = n + 1
|
op = op + parse_imm(q, 4, 0, 0, false); n = n + 1
|
||||||
elseif p == "F" then
|
elseif p == "F" then
|
||||||
op = op + parse_fpimm(q); n = n + 1
|
op = op + parse_fpimm(q); n = n + 1
|
||||||
|
elseif p == "O" then
|
||||||
|
op = op + parse_imm64(q); n = n + 1
|
||||||
elseif p == "Z" then
|
elseif p == "Z" then
|
||||||
if q ~= "#0" and q ~= "#0.0" then werror("expected zero immediate") end
|
if q ~= "#0" and q ~= "#0.0" then werror("expected zero immediate") end
|
||||||
n = n + 1
|
n = n + 1
|
||||||
|
Loading…
Reference in New Issue
Block a user