From 12ee94ffad513f38a973e733e09ca1a1ca558854 Mon Sep 17 00:00:00 2001 From: Hao Sun Date: Wed, 9 Jun 2021 12:57:33 +0000 Subject: [PATCH] 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 --- dynasm/dasm_arm64.lua | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/dynasm/dasm_arm64.lua b/dynasm/dasm_arm64.lua index cb82dc4a..002b2ef5 100644 --- a/dynasm/dasm_arm64.lua +++ b/dynasm/dasm_arm64.lua @@ -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