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:
Hao Sun 2021-06-09 12:57:33 +00:00 committed by haosun01
parent 3fbf51bb99
commit 12ee94ffad

View File

@ -441,6 +441,34 @@ local function parse_fpimm(imm)
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 s, s2 = match(expr, "^(%S+)%s*(.*)$")
s = map_shift[s]
@ -889,6 +917,7 @@ map_op = {
-- TODO: crc32*, aes*, sha*, pmull
-- TODO: SIMD instructions.
movi_2 = "2f00e400DOd",
}
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
elseif p == "F" then
op = op + parse_fpimm(q); n = n + 1
elseif p == "O" then
op = op + parse_imm64(q); n = n + 1
elseif p == "Z" then
if q ~= "#0" and q ~= "#0.0" then werror("expected zero immediate") end
n = n + 1