summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2020-07-14 15:14:21 +0300
committerDmitry Stogov <dmitry@zend.com>2020-07-14 15:14:21 +0300
commitddba2a705e924eb6a2e8dd6a718b48a5dd47e049 (patch)
tree82f57ac451925aab40d881b840f3b71f628beba8 /ext
parent06162194d67adfdcabf49f2dfae0c0a524368d89 (diff)
downloadphp-git-ddba2a705e924eb6a2e8dd6a718b48a5dd47e049.tar.gz
Better support for 64-bit .aword constants
Diffstat (limited to 'ext')
-rw-r--r--ext/opcache/jit/dynasm/dasm_x86.h12
-rw-r--r--ext/opcache/jit/dynasm/dasm_x86.lua52
2 files changed, 52 insertions, 12 deletions
diff --git a/ext/opcache/jit/dynasm/dasm_x86.h b/ext/opcache/jit/dynasm/dasm_x86.h
index 39449c15af..89e99fec51 100644
--- a/ext/opcache/jit/dynasm/dasm_x86.h
+++ b/ext/opcache/jit/dynasm/dasm_x86.h
@@ -17,10 +17,10 @@
/* Action definitions. DASM_STOP must be 255. */
enum {
- DASM_DISP = 232,
+ DASM_DISP = 231,
DASM_IMM_S, DASM_IMM_B, DASM_IMM_W, DASM_IMM_D, DASM_IMM_WB, DASM_IMM_DB,
DASM_VREG, DASM_SPACE, DASM_SETLABEL, DASM_REL_A, DASM_REL_LG, DASM_REL_PC,
- DASM_IMM_LG, DASM_IMM_PC, DASM_IMM_PC64, DASM_LABEL_LG, DASM_LABEL_PC,
+ DASM_IMM_LG, DASM_IMM_LG64, DASM_IMM_PC, DASM_IMM_PC64, DASM_LABEL_LG, DASM_LABEL_PC,
DASM_ALIGN, DASM_EXTERN, DASM_ESC, DASM_MARK, DASM_SECTION, DASM_STOP
};
@@ -220,6 +220,7 @@ void dasm_put(Dst_DECL, int start, ...)
} else {
int *pl, n;
switch (action) {
+ case DASM_IMM_LG64: ofs += 4;
case DASM_REL_LG:
case DASM_IMM_LG:
n = *p++; pl = D->lglabels + n;
@@ -333,7 +334,7 @@ int dasm_link(Dst_DECL, size_t *szp)
pos += 2;
break;
}
- case DASM_SPACE: case DASM_IMM_LG: case DASM_VREG: p++;
+ case DASM_SPACE: case DASM_IMM_LG: case DASM_IMM_LG64: case DASM_VREG: p++;
case DASM_DISP: case DASM_IMM_S: case DASM_IMM_B: case DASM_IMM_W:
case DASM_IMM_D: case DASM_IMM_WB: case DASM_IMM_DB:
case DASM_SETLABEL: case DASM_REL_A: case DASM_IMM_PC: case DASM_IMM_PC64:
@@ -447,6 +448,11 @@ int dasm_encode(Dst_DECL, void *buffer)
n = *pb < 0 ? pb[1] : (*pb + (int)(ptrdiff_t)base);
goto wd;
}
+ case DASM_IMM_LG64: {
+ p++;
+ if (n < 0)
+ dasmq((ptrdiff_t)D->globals[-n]);
+ }
case DASM_IMM_PC64: {
int *pb = DASM_POS2PTR(D, n);
dasmq(*pb < 0 ? pb[1] : (*pb + (ptrdiff_t)base));
diff --git a/ext/opcache/jit/dynasm/dasm_x86.lua b/ext/opcache/jit/dynasm/dasm_x86.lua
index f7d81d838f..0c94a7b5f7 100644
--- a/ext/opcache/jit/dynasm/dasm_x86.lua
+++ b/ext/opcache/jit/dynasm/dasm_x86.lua
@@ -46,8 +46,8 @@ local action_names = {
"SETLABEL", "REL_A",
-- action arg (1 byte) or int arg, 2 buffer pos (link, offset):
"REL_LG", "REL_PC",
- -- action arg (1 byte) or int arg, 1 buffer pos (link):
- "IMM_LG", "IMM_PC", "IMM_PC64",
+ -- action arg (1 byte) or ptrdiff_t arg, 1 buffer pos (link):
+ "IMM_LG", "IMM_LG64", "IMM_PC", "IMM_PC64",
-- action arg (1 byte) or int arg, 1 buffer pos (offset):
"LABEL_LG", "LABEL_PC",
-- action arg (1 byte), 1 buffer pos (offset):
@@ -434,11 +434,17 @@ local function wputlabel(aprefix, imm, num)
end
wputxb(imm)
else
- if aprefix == "IMM_" and x64 then
- waction("IMM_PC64", imm, num)
- else
- waction(aprefix.."PC", imm, num)
- end
+ waction(aprefix.."PC", imm, num)
+ end
+end
+
+-- Put action for label arg (IMM_LG64, IMM_PC64, REL_LG, REL_PC).
+local function wputlabel64(aprefix, imm, num)
+ if type(imm) == "number" then
+ waction("IMM_LG64", nil, num);
+ wputxb(imm)
+ else
+ waction("IMM_PC64", imm, num)
end
end
@@ -473,6 +479,26 @@ local function wputwarg(n)
else waction("IMM_W", n) end
end
+-- Put signed or unsigned qword or arg.
+local function wputqarg(n)
+ local tn = type(n)
+ if tn == "number" then
+ wputb(band(n, 255))
+ wputb(band(shr(n, 8), 255))
+ wputb(band(shr(n, 16), 255))
+ wputb(band(shr(n, 24), 255))
+ wputb(band(shr(n, 32), 255))
+ wputb(band(shr(n, 40), 255))
+ wputb(band(shr(n, 48), 255))
+ wputb(shr(n, 56))
+ elseif tn == "table" then
+ wputlabel64("IMM_", n[1], 1)
+ else
+ waction("IMM_D", format("(unsigned int)(%s)", n))
+ waction("IMM_D", format("(unsigned int)((%s)>>32)", n))
+ end
+end
+
-- Put signed or unsigned dword or arg.
local function wputdarg(n)
local tn = type(n)
@@ -2069,9 +2095,17 @@ local function op_data(params)
werror("bad mode or size in `"..p.."'")
end
if a.mode == "iJ" then
- wputlabel("IMM_", a.imm, 1)
+ if sz == 'q' then
+ wputlabel64("IMM_", a.imm, 1)
+ else
+ wputlabel("IMM_", a.imm, 1)
+ end
else
- wputszarg(sz, a.imm)
+ if sz == 'q' then
+ wputqarg(a.imm)
+ else
+ wputszarg(sz, a.imm)
+ end
end
if secpos+2 > maxsecpos then wflush() end
end