diff options
author | Dmitry Stogov <dmitry@zend.com> | 2020-07-14 15:14:21 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2020-07-14 15:14:21 +0300 |
commit | ddba2a705e924eb6a2e8dd6a718b48a5dd47e049 (patch) | |
tree | 82f57ac451925aab40d881b840f3b71f628beba8 /ext | |
parent | 06162194d67adfdcabf49f2dfae0c0a524368d89 (diff) | |
download | php-git-ddba2a705e924eb6a2e8dd6a718b48a5dd47e049.tar.gz |
Better support for 64-bit .aword constants
Diffstat (limited to 'ext')
-rw-r--r-- | ext/opcache/jit/dynasm/dasm_x86.h | 12 | ||||
-rw-r--r-- | ext/opcache/jit/dynasm/dasm_x86.lua | 52 |
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 |