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
This commit is contained in:
Hao Sun 2021-06-09 12:50:53 +00:00 committed by haosun01
parent 3fbf51bb99
commit e34eae8888

View File

@ -458,6 +458,14 @@ local function parse_lslx16(expr)
return shl(n, 17) return shl(n, 17)
end 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 function parse_extend(expr)
local s, s2 = match(expr, "^(%S+)%s*(.*)$") local s, s2 = match(expr, "^(%S+)%s*(.*)$")
if s == "lsl" then if s == "lsl" then
@ -664,18 +672,18 @@ end)
map_op = { map_op = {
-- Basic data processing instructions. -- Basic data processing instructions.
add_3 = "0b000000DNMg|11000000pDpNIg|8b206000pDpNMx", add_3 = "0b000000DNMg|11000000pDpNIg|8b206000pDpNMx",
add_4 = "0b000000DNMSg|0b200000DNMXg|8b200000pDpNMXx|8b200000pDpNxMwX", add_4 = "0b000000DNMSg|0b200000DNMXg|8b200000pDpNMXx|8b200000pDpNxMwX|11000000pDpNIrg",
adds_3 = "2b000000DNMg|31000000DpNIg|ab206000DpNMx", adds_3 = "2b000000DNMg|31000000DpNIg|ab206000DpNMx",
adds_4 = "2b000000DNMSg|2b200000DNMXg|ab200000DpNMXx|ab200000DpNxMwX", adds_4 = "2b000000DNMSg|2b200000DNMXg|ab200000DpNMXx|ab200000DpNxMwX|31000000DpNIrg",
cmn_2 = "2b00001fNMg|3100001fpNIg|ab20601fpNMx", cmn_2 = "2b00001fNMg|3100001fpNIg|ab20601fpNMx",
cmn_3 = "2b00001fNMSg|2b20001fNMXg|ab20001fpNMXx|ab20001fpNxMwX", cmn_3 = "2b00001fNMSg|2b20001fNMXg|ab20001fpNMXx|ab20001fpNxMwX|3100001fpNIrg",
sub_3 = "4b000000DNMg|51000000pDpNIg|cb206000pDpNMx", sub_3 = "4b000000DNMg|51000000pDpNIg|cb206000pDpNMx",
sub_4 = "4b000000DNMSg|4b200000DNMXg|cb200000pDpNMXx|cb200000pDpNxMwX", sub_4 = "4b000000DNMSg|4b200000DNMXg|cb200000pDpNMXx|cb200000pDpNxMwX|51000000pDpNIrg",
subs_3 = "6b000000DNMg|71000000DpNIg|eb206000DpNMx", subs_3 = "6b000000DNMg|71000000DpNIg|eb206000DpNMx",
subs_4 = "6b000000DNMSg|6b200000DNMXg|eb200000DpNMXx|eb200000DpNxMwX", subs_4 = "6b000000DNMSg|6b200000DNMXg|eb200000DpNMXx|eb200000DpNxMwX||71000000DpNIrg",
cmp_2 = "6b00001fNMg|7100001fpNIg|eb20601fpNMx", cmp_2 = "6b00001fNMg|7100001fpNIg|eb20601fpNMx",
cmp_3 = "6b00001fNMSg|6b20001fNMXg|eb20001fpNMXx|eb20001fpNxMwX", cmp_3 = "6b00001fNMSg|6b20001fNMXg|eb20001fpNMXx|eb20001fpNxMwX|7100001fpNIrg",
neg_2 = "4b0003e0DMg", neg_2 = "4b0003e0DMg",
neg_3 = "4b0003e0DMSg", neg_3 = "4b0003e0DMSg",
@ -985,6 +993,8 @@ local function parse_template(params, template, nparams, pos)
op = op + parse_extend(q); n = n + 1 op = op + parse_extend(q); n = n + 1
elseif p == "R" then elseif p == "R" then
op = op + parse_lslx16(q); n = n + 1 op = op + parse_lslx16(q); n = n + 1
elseif p == "r" then
op = op + parse_lsl12(q); n = n + 1
elseif p == "C" then elseif p == "C" then
op = op + parse_cond(q, 0); n = n + 1 op = op + parse_cond(q, 0); n = n + 1
elseif p == "c" then elseif p == "c" then