From e34eae8888cd66006f9de43305acd53bb3e41fd8 Mon Sep 17 00:00:00 2001 From: Hao Sun Date: Wed, 9 Jun 2021 12:50:53 +0000 Subject: [PATCH] DynASM/arm64: Support shifted immediate for add/sub/adds/subs/cmp/cmn For instructions add/adds/sub/subs/cmp/cmn, optionally-shifted immediate value can be used. Note that only left shift by 0 or 12 is accepted. Example: ``` | add x0, x0, #0x1, lsl #12 | add x0, sp, #0x2, lsl #0 | adds x0, x0, #0x3, lsl #0 | adds w0, w0, #0x4, lsl #12 | cmn sp, #0x5, lsl #12 | cmn w0, #0x6, lsl #0 | sub x0, x1, #0x7, lsl #0 | subs x0, x1, #0x8, lsl #12 | cmp x0, #0x9, lsl #0 | cmp x0, #0x9, lsl #12 ``` Disassembly: ``` 0xffffbc8c734c: add x0, x0, #0x1, lsl #12 0xffffbc8c7350: add x0, sp, #0x2 0xffffbc8c7354: adds x0, x0, #0x3 0xffffbc8c7358: adds w0, w0, #0x4, lsl #12 0xffffbc8c735c: cmn sp, #0x5, lsl #12 0xffffbc8c7360: cmn w0, #0x6 0xffffbc8c7364: sub x0, x1, #0x7 0xffffbc8c7368: subs x0, x1, #0x8, lsl #12 0xffffbc8c736c: cmp x0, #0x9 0xffffbc8c7370: cmp x0, #0x9, lsl #12 ``` Change-Id: I7afc76807d9e7821e92d974aae6ca03ee5f33eff --- dynasm/dasm_arm64.lua | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/dynasm/dasm_arm64.lua b/dynasm/dasm_arm64.lua index cb82dc4a..00fbda2c 100644 --- a/dynasm/dasm_arm64.lua +++ b/dynasm/dasm_arm64.lua @@ -458,6 +458,14 @@ local function parse_lslx16(expr) return shl(n, 17) end +local function parse_lsl12(expr) + local n = match(expr, "^lsl%s*#(%d+)$") + n = tonumber(n) + if not n then werror("expected shift operand") end + if n ~= 0 and n ~= 12 then werror("bad shift amount") end + return (n == 12 and shl(1, 22) or 0) +end + local function parse_extend(expr) local s, s2 = match(expr, "^(%S+)%s*(.*)$") if s == "lsl" then @@ -664,18 +672,18 @@ end) map_op = { -- Basic data processing instructions. add_3 = "0b000000DNMg|11000000pDpNIg|8b206000pDpNMx", - add_4 = "0b000000DNMSg|0b200000DNMXg|8b200000pDpNMXx|8b200000pDpNxMwX", + add_4 = "0b000000DNMSg|0b200000DNMXg|8b200000pDpNMXx|8b200000pDpNxMwX|11000000pDpNIrg", adds_3 = "2b000000DNMg|31000000DpNIg|ab206000DpNMx", - adds_4 = "2b000000DNMSg|2b200000DNMXg|ab200000DpNMXx|ab200000DpNxMwX", + adds_4 = "2b000000DNMSg|2b200000DNMXg|ab200000DpNMXx|ab200000DpNxMwX|31000000DpNIrg", cmn_2 = "2b00001fNMg|3100001fpNIg|ab20601fpNMx", - cmn_3 = "2b00001fNMSg|2b20001fNMXg|ab20001fpNMXx|ab20001fpNxMwX", + cmn_3 = "2b00001fNMSg|2b20001fNMXg|ab20001fpNMXx|ab20001fpNxMwX|3100001fpNIrg", sub_3 = "4b000000DNMg|51000000pDpNIg|cb206000pDpNMx", - sub_4 = "4b000000DNMSg|4b200000DNMXg|cb200000pDpNMXx|cb200000pDpNxMwX", + sub_4 = "4b000000DNMSg|4b200000DNMXg|cb200000pDpNMXx|cb200000pDpNxMwX|51000000pDpNIrg", subs_3 = "6b000000DNMg|71000000DpNIg|eb206000DpNMx", - subs_4 = "6b000000DNMSg|6b200000DNMXg|eb200000DpNMXx|eb200000DpNxMwX", + subs_4 = "6b000000DNMSg|6b200000DNMXg|eb200000DpNMXx|eb200000DpNxMwX||71000000DpNIrg", cmp_2 = "6b00001fNMg|7100001fpNIg|eb20601fpNMx", - cmp_3 = "6b00001fNMSg|6b20001fNMXg|eb20001fpNMXx|eb20001fpNxMwX", + cmp_3 = "6b00001fNMSg|6b20001fNMXg|eb20001fpNMXx|eb20001fpNxMwX|7100001fpNIrg", neg_2 = "4b0003e0DMg", neg_3 = "4b0003e0DMSg", @@ -985,6 +993,8 @@ local function parse_template(params, template, nparams, pos) op = op + parse_extend(q); n = n + 1 elseif p == "R" then op = op + parse_lslx16(q); n = n + 1 + elseif p == "r" then + op = op + parse_lsl12(q); n = n + 1 elseif p == "C" then op = op + parse_cond(q, 0); n = n + 1 elseif p == "c" then