diff options
author | Mike Pall <mike> | 2021-03-31 18:11:32 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2021-03-31 18:11:32 +0200 |
commit | d1132afb25e2ba66d5d4c287b886a3c0a61bd9db (patch) | |
tree | ffdc630b5ed78067458ee65e542e352b224704d6 /dynasm/dasm_arm64.lua | |
parent | 66563bdab0c7acf3cd61dc6cfcca36275951d084 (diff) | |
download | luajit-d1132afb25e2ba66d5d4c287b886a3c0a61bd9db.tar.gz luajit-d1132afb25e2ba66d5d4c287b886a3c0a61bd9db.tar.bz2 luajit-d1132afb25e2ba66d5d4c287b886a3c0a61bd9db.zip |
DynASM/ARM64: Add VREG support.
Contributed by Hao Sun and Nick Gasson.
Diffstat (limited to '')
-rw-r--r-- | dynasm/dasm_arm64.lua | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/dynasm/dasm_arm64.lua b/dynasm/dasm_arm64.lua index 861ff2b2..82412a05 100644 --- a/dynasm/dasm_arm64.lua +++ b/dynasm/dasm_arm64.lua | |||
@@ -40,6 +40,7 @@ local action_names = { | |||
40 | "STOP", "SECTION", "ESC", "REL_EXT", | 40 | "STOP", "SECTION", "ESC", "REL_EXT", |
41 | "ALIGN", "REL_LG", "LABEL_LG", | 41 | "ALIGN", "REL_LG", "LABEL_LG", |
42 | "REL_PC", "LABEL_PC", "IMM", "IMM6", "IMM12", "IMM13W", "IMM13X", "IMML", | 42 | "REL_PC", "LABEL_PC", "IMM", "IMM6", "IMM12", "IMM13W", "IMM13X", "IMML", |
43 | "VREG", | ||
43 | } | 44 | } |
44 | 45 | ||
45 | -- Maximum number of section buffer positions for dasm_put(). | 46 | -- Maximum number of section buffer positions for dasm_put(). |
@@ -246,9 +247,12 @@ local map_cond = { | |||
246 | 247 | ||
247 | local parse_reg_type | 248 | local parse_reg_type |
248 | 249 | ||
249 | local function parse_reg(expr) | 250 | local function parse_reg(expr, shift) |
250 | if not expr then werror("expected register name") end | 251 | if not expr then werror("expected register name") end |
251 | local tname, ovreg = match(expr, "^([%w_]+):(@?%l%d+)$") | 252 | local tname, ovreg = match(expr, "^([%w_]+):(@?%l%d+)$") |
253 | if not tname then | ||
254 | tname, ovreg = match(expr, "^([%w_]+):(R[xwqdshb]%b())$") | ||
255 | end | ||
252 | local tp = map_type[tname or expr] | 256 | local tp = map_type[tname or expr] |
253 | if tp then | 257 | if tp then |
254 | local reg = ovreg or tp.reg | 258 | local reg = ovreg or tp.reg |
@@ -266,18 +270,28 @@ local function parse_reg(expr) | |||
266 | elseif parse_reg_type ~= rt then | 270 | elseif parse_reg_type ~= rt then |
267 | werror("register size mismatch") | 271 | werror("register size mismatch") |
268 | end | 272 | end |
269 | return r, tp | 273 | return shl(r, shift), tp |
274 | end | ||
275 | end | ||
276 | local vrt, vreg = match(expr, "^R([xwqdshb])(%b())$") | ||
277 | if vreg then | ||
278 | if not parse_reg_type then | ||
279 | parse_reg_type = vrt | ||
280 | elseif parse_reg_type ~= vrt then | ||
281 | werror("register size mismatch") | ||
270 | end | 282 | end |
283 | if shift then waction("VREG", shift, vreg) end | ||
284 | return 0 | ||
271 | end | 285 | end |
272 | werror("bad register name `"..expr.."'") | 286 | werror("bad register name `"..expr.."'") |
273 | end | 287 | end |
274 | 288 | ||
275 | local function parse_reg_base(expr) | 289 | local function parse_reg_base(expr) |
276 | if expr == "sp" then return 0x3e0 end | 290 | if expr == "sp" then return 0x3e0 end |
277 | local base, tp = parse_reg(expr) | 291 | local base, tp = parse_reg(expr, 5) |
278 | if parse_reg_type ~= "x" then werror("bad register type") end | 292 | if parse_reg_type ~= "x" then werror("bad register type") end |
279 | parse_reg_type = false | 293 | parse_reg_type = false |
280 | return shl(base, 5), tp | 294 | return base, tp |
281 | end | 295 | end |
282 | 296 | ||
283 | local parse_ctx = {} | 297 | local parse_ctx = {} |
@@ -403,7 +417,7 @@ local function parse_imm_load(imm, scale) | |||
403 | end | 417 | end |
404 | werror("out of range immediate `"..imm.."'") | 418 | werror("out of range immediate `"..imm.."'") |
405 | else | 419 | else |
406 | waction("IMML", 0, imm) | 420 | waction("IMML", scale, imm) |
407 | return 0 | 421 | return 0 |
408 | end | 422 | end |
409 | end | 423 | end |
@@ -462,6 +476,7 @@ end | |||
462 | 476 | ||
463 | local function parse_load(params, nparams, n, op) | 477 | local function parse_load(params, nparams, n, op) |
464 | if params[n+2] then werror("too many operands") end | 478 | if params[n+2] then werror("too many operands") end |
479 | local scale = shr(op, 30) | ||
465 | local pn, p2 = params[n], params[n+1] | 480 | local pn, p2 = params[n], params[n+1] |
466 | local p1, wb = match(pn, "^%[%s*(.-)%s*%](!?)$") | 481 | local p1, wb = match(pn, "^%[%s*(.-)%s*%](!?)$") |
467 | if not p1 then | 482 | if not p1 then |
@@ -470,14 +485,13 @@ local function parse_load(params, nparams, n, op) | |||
470 | if reg and tailr ~= "" then | 485 | if reg and tailr ~= "" then |
471 | local base, tp = parse_reg_base(reg) | 486 | local base, tp = parse_reg_base(reg) |
472 | if tp then | 487 | if tp then |
473 | waction("IMML", 0, format(tp.ctypefmt, tailr)) | 488 | waction("IMML", scale, format(tp.ctypefmt, tailr)) |
474 | return op + base | 489 | return op + base |
475 | end | 490 | end |
476 | end | 491 | end |
477 | end | 492 | end |
478 | werror("expected address operand") | 493 | werror("expected address operand") |
479 | end | 494 | end |
480 | local scale = shr(op, 30) | ||
481 | if p2 then | 495 | if p2 then |
482 | if wb == "!" then werror("bad use of '!'") end | 496 | if wb == "!" then werror("bad use of '!'") end |
483 | op = op + parse_reg_base(p1) + parse_imm(p2, 9, 12, 0, true) + 0x400 | 497 | op = op + parse_reg_base(p1) + parse_imm(p2, 9, 12, 0, true) + 0x400 |
@@ -494,7 +508,7 @@ local function parse_load(params, nparams, n, op) | |||
494 | op = op + parse_imm_load(imm, scale) | 508 | op = op + parse_imm_load(imm, scale) |
495 | else | 509 | else |
496 | local p2b, p3b, p3s = match(p2a, "^,%s*([^,%s]*)%s*,?%s*(%S*)%s*(.*)$") | 510 | local p2b, p3b, p3s = match(p2a, "^,%s*([^,%s]*)%s*,?%s*(%S*)%s*(.*)$") |
497 | op = op + shl(parse_reg(p2b), 16) + 0x00200800 | 511 | op = op + parse_reg(p2b, 16) + 0x00200800 |
498 | if parse_reg_type ~= "x" and parse_reg_type ~= "w" then | 512 | if parse_reg_type ~= "x" and parse_reg_type ~= "w" then |
499 | werror("bad index register type") | 513 | werror("bad index register type") |
500 | end | 514 | end |
@@ -620,7 +634,7 @@ local function alias_bfx(p) | |||
620 | end | 634 | end |
621 | 635 | ||
622 | local function alias_bfiz(p) | 636 | local function alias_bfiz(p) |
623 | parse_reg(p[1]) | 637 | parse_reg(p[1], 0) |
624 | if parse_reg_type == "w" then | 638 | if parse_reg_type == "w" then |
625 | p[3] = "#-("..p[3]:sub(2)..")%32" | 639 | p[3] = "#-("..p[3]:sub(2)..")%32" |
626 | p[4] = "#("..p[4]:sub(2)..")-1" | 640 | p[4] = "#("..p[4]:sub(2)..")-1" |
@@ -631,7 +645,7 @@ local function alias_bfiz(p) | |||
631 | end | 645 | end |
632 | 646 | ||
633 | local alias_lslimm = op_alias("ubfm_4", function(p) | 647 | local alias_lslimm = op_alias("ubfm_4", function(p) |
634 | parse_reg(p[1]) | 648 | parse_reg(p[1], 0) |
635 | local sh = p[3]:sub(2) | 649 | local sh = p[3]:sub(2) |
636 | if parse_reg_type == "w" then | 650 | if parse_reg_type == "w" then |
637 | p[3] = "#-("..sh..")%32" | 651 | p[3] = "#-("..sh..")%32" |
@@ -891,15 +905,15 @@ local function parse_template(params, template, nparams, pos) | |||
891 | for p in gmatch(sub(template, 9), ".") do | 905 | for p in gmatch(sub(template, 9), ".") do |
892 | local q = params[n] | 906 | local q = params[n] |
893 | if p == "D" then | 907 | if p == "D" then |
894 | op = op + parse_reg(q); n = n + 1 | 908 | op = op + parse_reg(q, 0); n = n + 1 |
895 | elseif p == "N" then | 909 | elseif p == "N" then |
896 | op = op + shl(parse_reg(q), 5); n = n + 1 | 910 | op = op + parse_reg(q, 5); n = n + 1 |
897 | elseif p == "M" then | 911 | elseif p == "M" then |
898 | op = op + shl(parse_reg(q), 16); n = n + 1 | 912 | op = op + parse_reg(q, 16); n = n + 1 |
899 | elseif p == "A" then | 913 | elseif p == "A" then |
900 | op = op + shl(parse_reg(q), 10); n = n + 1 | 914 | op = op + parse_reg(q, 10); n = n + 1 |
901 | elseif p == "m" then | 915 | elseif p == "m" then |
902 | op = op + shl(parse_reg(params[n-1]), 16) | 916 | op = op + parse_reg(params[n-1], 16) |
903 | 917 | ||
904 | elseif p == "p" then | 918 | elseif p == "p" then |
905 | if q == "sp" then params[n] = "@x31" end | 919 | if q == "sp" then params[n] = "@x31" end |