Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions ext/opcache/jit/dynasm/dasm_arm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ enum {
/* The following actions also have an argument. */
DASM_REL_PC, DASM_LABEL_PC,
DASM_IMM, DASM_IMM6, DASM_IMM12, DASM_IMM13W, DASM_IMM13X, DASM_IMML,
DASM_VREG,
DASM__MAX
};

Expand All @@ -39,6 +40,7 @@ enum {
#define DASM_S_RANGE_LG 0x13000000
#define DASM_S_RANGE_PC 0x14000000
#define DASM_S_RANGE_REL 0x15000000
#define DASM_S_RANGE_VREG 0x16000000
#define DASM_S_UNDEF_LG 0x21000000
#define DASM_S_UNDEF_PC 0x22000000

Expand Down Expand Up @@ -312,13 +314,17 @@ void dasm_put(Dst_DECL, int start, ...)
}
case DASM_IMML: {
#ifdef DASM_CHECKS
int scale = (p[-2] >> 30);
int scale = (ins & 0x3);
CK((!(n & ((1<<scale)-1)) && (unsigned int)(n>>scale) < 4096) ||
(unsigned int)(n+256) < 512, RANGE_I);
#endif
b[pos++] = n;
break;
}
case DASM_VREG:
CK(n < 32, RANGE_VREG);
b[pos++] = n;
break;
}
}
}
Expand Down Expand Up @@ -377,6 +383,7 @@ int dasm_link(Dst_DECL, size_t *szp)
case DASM_IMM: case DASM_IMM6: case DASM_IMM12: case DASM_IMM13W:
case DASM_IMML: pos++; break;
case DASM_IMM13X: pos += 2; break;
case DASM_VREG: pos++; break;
}
}
stop: (void)0;
Expand Down Expand Up @@ -467,11 +474,14 @@ int dasm_encode(Dst_DECL, void *buffer)
cp[-1] |= (dasm_imm13(n, *b++) << 10);
break;
case DASM_IMML: {
int scale = (p[-2] >> 30);
int scale = (ins & 0x3);
cp[-1] |= (!(n & ((1<<scale)-1)) && (unsigned int)(n>>scale) < 4096) ?
((n << (10-scale)) | 0x01000000) : ((n & 511) << 12);
break;
}
case DASM_VREG:
cp[-1] |= (n & 0x1f) << (ins & 0x1f);
break;
default: *cp++ = ins; break;
}
}
Expand Down
36 changes: 24 additions & 12 deletions ext/opcache/jit/dynasm/dasm_arm64.lua
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ local action_names = {
"STOP", "SECTION", "ESC", "REL_EXT",
"ALIGN", "REL_LG", "LABEL_LG",
"REL_PC", "LABEL_PC", "IMM", "IMM6", "IMM12", "IMM13W", "IMM13X", "IMML",
"VREG"
}

-- Maximum number of section buffer positions for dasm_put().
Expand Down Expand Up @@ -246,7 +247,7 @@ local map_cond = {

local parse_reg_type

local function parse_reg(expr)
local function parse_reg(expr, shift)
if not expr then werror("expected register name") end
local tname, ovreg = match(expr, "^([%w_]+):(@?%l%d+)$")
local tp = map_type[tname or expr]
Expand All @@ -266,18 +267,29 @@ local function parse_reg(expr)
elseif parse_reg_type ~= rt then
werror("register size mismatch")
end
return r, tp
return shl(r, shift or 0), tp
end
end
-- Allow Rx(...) for dynamic register names
local vrt, vreg = match(expr, "^R([xwqdshb])(%b())$")
if vreg then
if not parse_reg_type then
parse_reg_type = vrt
elseif parse_reg_type ~= vrt then
werror("register size mismatch")
end
if shift then waction("VREG", shift, vreg) end
return 0
end
werror("bad register name `"..expr.."'")
end

local function parse_reg_base(expr)
if expr == "sp" then return 0x3e0 end
local base, tp = parse_reg(expr)
local base, tp = parse_reg(expr, 5)
if parse_reg_type ~= "x" then werror("bad register type") end
parse_reg_type = false
return shl(base, 5), tp
return base, tp
end

local parse_ctx = {}
Expand Down Expand Up @@ -403,7 +415,7 @@ local function parse_imm_load(imm, scale)
end
werror("out of range immediate `"..imm.."'")
else
waction("IMML", 0, imm)
waction("IMML", scale, imm)
return 0
end
end
Expand Down Expand Up @@ -470,7 +482,7 @@ local function parse_load(params, nparams, n, op)
if reg and tailr ~= "" then
local base, tp = parse_reg_base(reg)
if tp then
waction("IMML", 0, format(tp.ctypefmt, tailr))
waction("IMML", shr(op, 30), format(tp.ctypefmt, tailr))
return op + base
end
end
Expand All @@ -494,7 +506,7 @@ local function parse_load(params, nparams, n, op)
op = op + parse_imm_load(imm, scale)
else
local p2b, p3b, p3s = match(p2a, "^,%s*([^,%s]*)%s*,?%s*(%S*)%s*(.*)$")
op = op + shl(parse_reg(p2b), 16) + 0x00200800
op = op + parse_reg(p2b, 16) + 0x00200800
if parse_reg_type ~= "x" and parse_reg_type ~= "w" then
werror("bad index register type")
end
Expand Down Expand Up @@ -891,15 +903,15 @@ local function parse_template(params, template, nparams, pos)
for p in gmatch(sub(template, 9), ".") do
local q = params[n]
if p == "D" then
op = op + parse_reg(q); n = n + 1
op = op + parse_reg(q, 0); n = n + 1
elseif p == "N" then
op = op + shl(parse_reg(q), 5); n = n + 1
op = op + parse_reg(q, 5); n = n + 1
elseif p == "M" then
op = op + shl(parse_reg(q), 16); n = n + 1
op = op + parse_reg(q, 16); n = n + 1
elseif p == "A" then
op = op + shl(parse_reg(q), 10); n = n + 1
op = op + parse_reg(q, 10); n = n + 1
elseif p == "m" then
op = op + shl(parse_reg(params[n-1]), 16)
op = op + parse_reg(params[n-1], 16)

elseif p == "p" then
if q == "sp" then params[n] = "@x31" end
Expand Down