Skip to content

Commit 0b4f83f

Browse files
Mike Palldstogov
Mike Pall
authored andcommitted
DynASM/ARM64: Add VREG support.
Contributed by Hao Sun and Nick Gasson.
1 parent b428c51 commit 0b4f83f

File tree

2 files changed

+41
-18
lines changed

2 files changed

+41
-18
lines changed

ext/opcache/jit/dynasm/dasm_arm64.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ enum {
2323
/* The following actions also have an argument. */
2424
DASM_REL_PC, DASM_LABEL_PC,
2525
DASM_IMM, DASM_IMM6, DASM_IMM12, DASM_IMM13W, DASM_IMM13X, DASM_IMML,
26+
DASM_VREG,
2627
DASM__MAX
2728
};
2829

@@ -39,6 +40,7 @@ enum {
3940
#define DASM_S_RANGE_LG 0x13000000
4041
#define DASM_S_RANGE_PC 0x14000000
4142
#define DASM_S_RANGE_REL 0x15000000
43+
#define DASM_S_RANGE_VREG 0x16000000
4244
#define DASM_S_UNDEF_LG 0x21000000
4345
#define DASM_S_UNDEF_PC 0x22000000
4446

@@ -312,13 +314,17 @@ void dasm_put(Dst_DECL, int start, ...)
312314
}
313315
case DASM_IMML: {
314316
#ifdef DASM_CHECKS
315-
int scale = (p[-2] >> 30);
317+
int scale = (ins & 3);
316318
CK((!(n & ((1<<scale)-1)) && (unsigned int)(n>>scale) < 4096) ||
317319
(unsigned int)(n+256) < 512, RANGE_I);
318320
#endif
319321
b[pos++] = n;
320322
break;
321323
}
324+
case DASM_VREG:
325+
CK(n < 32, RANGE_VREG);
326+
b[pos++] = n;
327+
break;
322328
}
323329
}
324330
}
@@ -375,7 +381,7 @@ int dasm_link(Dst_DECL, size_t *szp)
375381
case DASM_REL_LG: case DASM_REL_PC: pos++; break;
376382
case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;
377383
case DASM_IMM: case DASM_IMM6: case DASM_IMM12: case DASM_IMM13W:
378-
case DASM_IMML: pos++; break;
384+
case DASM_IMML: case DASM_VREG: pos++; break;
379385
case DASM_IMM13X: pos += 2; break;
380386
}
381387
}
@@ -468,11 +474,14 @@ int dasm_encode(Dst_DECL, void *buffer)
468474
cp[-1] |= (dasm_imm13(n, *b++) << 10);
469475
break;
470476
case DASM_IMML: {
471-
int scale = (p[-2] >> 30);
477+
int scale = (ins & 3);
472478
cp[-1] |= (!(n & ((1<<scale)-1)) && (unsigned int)(n>>scale) < 4096) ?
473479
((n << (10-scale)) | 0x01000000) : ((n & 511) << 12);
474480
break;
475481
}
482+
case DASM_VREG:
483+
cp[-1] |= (n & 0x1f) << (ins & 0x1f);
484+
break;
476485
default: *cp++ = ins; break;
477486
}
478487
}

ext/opcache/jit/dynasm/dasm_arm64.lua

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ local action_names = {
4040
"STOP", "SECTION", "ESC", "REL_EXT",
4141
"ALIGN", "REL_LG", "LABEL_LG",
4242
"REL_PC", "LABEL_PC", "IMM", "IMM6", "IMM12", "IMM13W", "IMM13X", "IMML",
43+
"VREG",
4344
}
4445

4546
-- Maximum number of section buffer positions for dasm_put().
@@ -246,9 +247,12 @@ local map_cond = {
246247

247248
local parse_reg_type
248249

249-
local function parse_reg(expr)
250+
local function parse_reg(expr, shift)
250251
if not expr then werror("expected register name") end
251252
local tname, ovreg = match(expr, "^([%w_]+):(@?%l%d+)$")
253+
if not tname then
254+
tname, ovreg = match(expr, "^([%w_]+):(R[xwqdshb]%b())$")
255+
end
252256
local tp = map_type[tname or expr]
253257
if tp then
254258
local reg = ovreg or tp.reg
@@ -266,18 +270,28 @@ local function parse_reg(expr)
266270
elseif parse_reg_type ~= rt then
267271
werror("register size mismatch")
268272
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")
270282
end
283+
if shift then waction("VREG", shift, vreg) end
284+
return 0
271285
end
272286
werror("bad register name `"..expr.."'")
273287
end
274288

275289
local function parse_reg_base(expr)
276290
if expr == "sp" then return 0x3e0 end
277-
local base, tp = parse_reg(expr)
291+
local base, tp = parse_reg(expr, 5)
278292
if parse_reg_type ~= "x" then werror("bad register type") end
279293
parse_reg_type = false
280-
return shl(base, 5), tp
294+
return base, tp
281295
end
282296

283297
local parse_ctx = {}
@@ -403,7 +417,7 @@ local function parse_imm_load(imm, scale)
403417
end
404418
werror("out of range immediate `"..imm.."'")
405419
else
406-
waction("IMML", 0, imm)
420+
waction("IMML", scale, imm)
407421
return 0
408422
end
409423
end
@@ -462,6 +476,7 @@ end
462476

463477
local function parse_load(params, nparams, n, op)
464478
if params[n+2] then werror("too many operands") end
479+
local scale = shr(op, 30)
465480
local pn, p2 = params[n], params[n+1]
466481
local p1, wb = match(pn, "^%[%s*(.-)%s*%](!?)$")
467482
if not p1 then
@@ -470,14 +485,13 @@ local function parse_load(params, nparams, n, op)
470485
if reg and tailr ~= "" then
471486
local base, tp = parse_reg_base(reg)
472487
if tp then
473-
waction("IMML", 0, format(tp.ctypefmt, tailr))
488+
waction("IMML", scale, format(tp.ctypefmt, tailr))
474489
return op + base
475490
end
476491
end
477492
end
478493
werror("expected address operand")
479494
end
480-
local scale = shr(op, 30)
481495
if p2 then
482496
if wb == "!" then werror("bad use of '!'") end
483497
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)
494508
op = op + parse_imm_load(imm, scale)
495509
else
496510
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
498512
if parse_reg_type ~= "x" and parse_reg_type ~= "w" then
499513
werror("bad index register type")
500514
end
@@ -620,7 +634,7 @@ local function alias_bfx(p)
620634
end
621635

622636
local function alias_bfiz(p)
623-
parse_reg(p[1])
637+
parse_reg(p[1], 0)
624638
if parse_reg_type == "w" then
625639
p[3] = "#-("..p[3]:sub(2)..")%32"
626640
p[4] = "#("..p[4]:sub(2)..")-1"
@@ -631,7 +645,7 @@ local function alias_bfiz(p)
631645
end
632646

633647
local alias_lslimm = op_alias("ubfm_4", function(p)
634-
parse_reg(p[1])
648+
parse_reg(p[1], 0)
635649
local sh = p[3]:sub(2)
636650
if parse_reg_type == "w" then
637651
p[3] = "#-("..sh..")%32"
@@ -891,15 +905,15 @@ local function parse_template(params, template, nparams, pos)
891905
for p in gmatch(sub(template, 9), ".") do
892906
local q = params[n]
893907
if p == "D" then
894-
op = op + parse_reg(q); n = n + 1
908+
op = op + parse_reg(q, 0); n = n + 1
895909
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
897911
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
899913
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
901915
elseif p == "m" then
902-
op = op + shl(parse_reg(params[n-1]), 16)
916+
op = op + parse_reg(params[n-1], 16)
903917

904918
elseif p == "p" then
905919
if q == "sp" then params[n] = "@x31" end

0 commit comments

Comments
 (0)