Skip to content

Commit 4a50741

Browse files
committed
DynASM/x86: Fix x64 .aword refs. Add .qword, .quad, .addr and .long.
(Switch to .aword implementation by Make Pall)
1 parent e25fce6 commit 4a50741

File tree

2 files changed

+59
-69
lines changed

2 files changed

+59
-69
lines changed

ext/opcache/jit/dynasm/dasm_x86.h

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717

1818
/* Action definitions. DASM_STOP must be 255. */
1919
enum {
20-
DASM_DISP = 231,
20+
DASM_DISP = 233,
2121
DASM_IMM_S, DASM_IMM_B, DASM_IMM_W, DASM_IMM_D, DASM_IMM_WB, DASM_IMM_DB,
2222
DASM_VREG, DASM_SPACE, DASM_SETLABEL, DASM_REL_A, DASM_REL_LG, DASM_REL_PC,
23-
DASM_IMM_LG, DASM_IMM_LG64, DASM_IMM_PC, DASM_IMM_PC64, DASM_LABEL_LG, DASM_LABEL_PC,
24-
DASM_ALIGN, DASM_EXTERN, DASM_ESC, DASM_MARK, DASM_SECTION, DASM_STOP
23+
DASM_IMM_LG, DASM_IMM_PC, DASM_LABEL_LG, DASM_LABEL_PC, DASM_ALIGN,
24+
DASM_EXTERN, DASM_ESC, DASM_MARK, DASM_SECTION, DASM_STOP
2525
};
2626

2727
/* Maximum number of section buffer positions for a single dasm_put() call. */
@@ -221,7 +221,6 @@ void dasm_put(Dst_DECL, int start, ...)
221221
} else {
222222
int *pl, n;
223223
switch (action) {
224-
case DASM_IMM_LG64: ofs += 4;
225224
case DASM_REL_LG:
226225
case DASM_IMM_LG:
227226
n = *p++; pl = D->lglabels + n;
@@ -230,7 +229,6 @@ void dasm_put(Dst_DECL, int start, ...)
230229
pl -= 246; n = *pl;
231230
if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */
232231
goto linkrel;
233-
case DASM_IMM_PC64: ofs += 4;
234232
case DASM_REL_PC:
235233
case DASM_IMM_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC);
236234
putrel:
@@ -244,8 +242,11 @@ void dasm_put(Dst_DECL, int start, ...)
244242
}
245243
pos++;
246244
ofs += 4; /* Maximum offset needed. */
247-
if (action == DASM_REL_LG || action == DASM_REL_PC)
245+
if (action == DASM_REL_LG || action == DASM_REL_PC) {
248246
b[pos++] = ofs; /* Store pass1 offset estimate. */
247+
} else if (sizeof(ptrdiff_t) == 8) {
248+
ofs += 4;
249+
}
249250
break;
250251
case DASM_LABEL_LG: pl = D->lglabels + *p++; CKPL(lg, LG); goto putlabel;
251252
case DASM_LABEL_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC);
@@ -338,12 +339,10 @@ int dasm_link(Dst_DECL, size_t *szp)
338339
break;
339340
}
340341
/* fallthrough */
341-
case DASM_SPACE: case DASM_IMM_LG: case DASM_IMM_LG64: case DASM_VREG: p++;
342-
/* fallthrough */
342+
case DASM_SPACE: case DASM_IMM_LG: case DASM_VREG: p++;
343343
case DASM_DISP: case DASM_IMM_S: case DASM_IMM_B: case DASM_IMM_W:
344344
case DASM_IMM_D: case DASM_IMM_WB: case DASM_IMM_DB:
345-
case DASM_SETLABEL: case DASM_REL_A: case DASM_IMM_PC: case DASM_IMM_PC64:
346-
pos++; break;
345+
case DASM_SETLABEL: case DASM_REL_A: case DASM_IMM_PC: pos++; break;
347346
case DASM_LABEL_LG: p++;
348347
/* fallthrough */
349348
case DASM_LABEL_PC: b[pos++] += ofs; break; /* Fix label offset. */
@@ -369,17 +368,27 @@ int dasm_link(Dst_DECL, size_t *szp)
369368
#ifndef DASM_ALIGNED_WRITES
370369
typedef ZEND_SET_ALIGNED(1, unsigned short unaligned_short);
371370
typedef ZEND_SET_ALIGNED(1, unsigned int unaligned_int);
372-
typedef ZEND_SET_ALIGNED(1, uint64_t unaligned_uint64_t);
371+
typedef ZEND_SET_ALIGNED(1, unsigned long long unaligned_long_long);
373372
#define dasmw(x) \
374373
do { *((unaligned_short *)cp) = (unsigned short)(x); cp+=2; } while (0)
375374
#define dasmd(x) \
376375
do { *((unaligned_int *)cp) = (unsigned int)(x); cp+=4; } while (0)
377376
#define dasmq(x) \
378-
do { *((unaligned_uint64_t *)cp) = (uint64_t)(x); cp+=8; } while (0)
377+
do { *((unaligned_long_long *)cp) = (unsigned long long)(x); cp+=8; } while (0)
379378
#else
380379
#define dasmw(x) do { dasmb(x); dasmb((x)>>8); } while (0)
381380
#define dasmd(x) do { dasmw(x); dasmw((x)>>16); } while (0)
381+
#define dasmq(x) do { dasmd(x); dasmd((x)>>32); } while (0)
382382
#endif
383+
static unsigned char *dasma_(unsigned char *cp, ptrdiff_t x)
384+
{
385+
if (sizeof(ptrdiff_t) == 8)
386+
dasmq((unsigned long long)x);
387+
else
388+
dasmd((unsigned int)x);
389+
return cp;
390+
}
391+
#define dasma(x) (cp = dasma_(cp, (x)))
383392

384393
/* Pass 3: Encode sections. */
385394
int dasm_encode(Dst_DECL, void *buffer)
@@ -454,21 +463,12 @@ int dasm_encode(Dst_DECL, void *buffer)
454463
goto wb;
455464
}
456465
case DASM_IMM_LG:
457-
p++; if (n < 0) { n = (int)(ptrdiff_t)D->globals[-n]; goto wd; }
466+
p++;
467+
if (n < 0) { dasma((ptrdiff_t)D->globals[-n]); break; }
458468
/* fallthrough */
459469
case DASM_IMM_PC: {
460470
int *pb = DASM_POS2PTR(D, n);
461-
n = *pb < 0 ? pb[1] : (*pb + (int)(ptrdiff_t)base);
462-
goto wd;
463-
}
464-
case DASM_IMM_LG64: {
465-
p++;
466-
if (n < 0)
467-
dasmq((ptrdiff_t)D->globals[-n]);
468-
}
469-
case DASM_IMM_PC64: {
470-
int *pb = DASM_POS2PTR(D, n);
471-
dasmq(*pb < 0 ? pb[1] : (*pb + (ptrdiff_t)base));
471+
dasma(*pb < 0 ? (ptrdiff_t)pb[1] : (*pb + (ptrdiff_t)base));
472472
break;
473473
}
474474
case DASM_LABEL_LG: {

ext/opcache/jit/dynasm/dasm_x86.lua

Lines changed: 35 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ local action_names = {
4646
"SETLABEL", "REL_A",
4747
-- action arg (1 byte) or int arg, 2 buffer pos (link, offset):
4848
"REL_LG", "REL_PC",
49-
-- action arg (1 byte) or ptrdiff_t arg, 1 buffer pos (link):
50-
"IMM_LG", "IMM_LG64", "IMM_PC", "IMM_PC64",
49+
-- action arg (1 byte) or int arg, 1 buffer pos (link):
50+
"IMM_LG", "IMM_PC",
5151
-- action arg (1 byte) or int arg, 1 buffer pos (offset):
5252
"LABEL_LG", "LABEL_PC",
5353
-- action arg (1 byte), 1 buffer pos (offset):
@@ -438,16 +438,6 @@ local function wputlabel(aprefix, imm, num)
438438
end
439439
end
440440

441-
-- Put action for label arg (IMM_LG64, IMM_PC64, REL_LG, REL_PC).
442-
local function wputlabel64(aprefix, imm, num)
443-
if type(imm) == "number" then
444-
waction("IMM_LG64", nil, num);
445-
wputxb(imm)
446-
else
447-
waction("IMM_PC64", imm, num)
448-
end
449-
end
450-
451441
-- Put signed byte or arg.
452442
local function wputsbarg(n)
453443
if type(n) == "number" then
@@ -479,38 +469,34 @@ local function wputwarg(n)
479469
else waction("IMM_W", n) end
480470
end
481471

482-
-- Put signed or unsigned qword or arg.
483-
local function wputqarg(n)
472+
-- Put signed or unsigned dword or arg.
473+
local function wputdarg(n)
484474
local tn = type(n)
485475
if tn == "number" then
486476
wputb(band(n, 255))
487477
wputb(band(shr(n, 8), 255))
488478
wputb(band(shr(n, 16), 255))
489-
wputb(band(shr(n, 24), 255))
490-
wputb(band(shr(n, 32), 255))
491-
wputb(band(shr(n, 40), 255))
492-
wputb(band(shr(n, 48), 255))
493-
wputb(shr(n, 56))
479+
wputb(shr(n, 24))
494480
elseif tn == "table" then
495-
wputlabel64("IMM_", n[1], 1)
481+
wputlabel("IMM_", n[1], 1)
496482
else
497-
waction("IMM_D", format("(unsigned int)(%s)", n))
498-
waction("IMM_D", format("(unsigned int)((%s)>>32)", n))
483+
waction("IMM_D", n)
499484
end
500485
end
501486

502-
-- Put signed or unsigned dword or arg.
503-
local function wputdarg(n)
487+
-- Put signed or unsigned qword or arg.
488+
local function wputqarg(n)
504489
local tn = type(n)
505-
if tn == "number" then
490+
if tn == "number" then -- This is only used for numbers from -2^31..2^32-1.
506491
wputb(band(n, 255))
507492
wputb(band(shr(n, 8), 255))
508493
wputb(band(shr(n, 16), 255))
509494
wputb(shr(n, 24))
510-
elseif tn == "table" then
511-
wputlabel("IMM_", n[1], 1)
495+
local sign = n < 0 and 255 or 0
496+
wputb(sign); wputb(sign); wputb(sign); wputb(sign)
512497
else
513-
waction("IMM_D", n)
498+
waction("IMM_D", format("(unsigned int)(%s)", n))
499+
waction("IMM_D", format("(unsigned int)((unsigned long long)(%s)>>32)", n))
514500
end
515501
end
516502

@@ -693,10 +679,16 @@ local function opmodestr(op, args)
693679
end
694680

695681
-- Convert number to valid integer or nil.
696-
local function toint(expr)
682+
local function toint(expr, isqword)
697683
local n = tonumber(expr)
698684
if n then
699-
if n % 1 ~= 0 or n < -2147483648 or n > 4294967295 then
685+
if n % 1 ~= 0 then
686+
werror("not an integer number `"..expr.."'")
687+
elseif isqword then
688+
if n < -2147483648 or n > 2147483647 then
689+
n = nil -- Handle it as an expression to avoid precision loss.
690+
end
691+
elseif n < -2147483648 or n > 4294967295 then
700692
werror("bad integer number `"..expr.."'")
701693
end
702694
return n
@@ -779,7 +771,7 @@ local function rtexpr(expr)
779771
end
780772

781773
-- Parse operand and return { mode, opsize, reg, xreg, xsc, disp, imm }.
782-
local function parseoperand(param)
774+
local function parseoperand(param, isqword)
783775
local t = {}
784776

785777
local expr = param
@@ -867,7 +859,7 @@ local function parseoperand(param)
867859
t.disp = dispexpr(tailx)
868860
else
869861
-- imm or opsize*imm
870-
local imm = toint(expr)
862+
local imm = toint(expr, isqword)
871863
if not imm and sub(expr, 1, 1) == "*" and t.opsize then
872864
imm = toint(sub(expr, 2))
873865
if imm then
@@ -1982,7 +1974,7 @@ local function dopattern(pat, args, sz, op, needrex)
19821974
local a = args[narg]
19831975
narg = narg + 1
19841976
local mode, imm = a.mode, a.imm
1985-
if mode == "iJ" and not match("iIJ", c) then
1977+
if mode == "iJ" and not match(x64 and "J" or "iIJ", c) then
19861978
werror("bad operand size for label")
19871979
end
19881980
if c == "S" then
@@ -2174,24 +2166,18 @@ end
21742166
local function op_data(params)
21752167
if not params then return "imm..." end
21762168
local sz = sub(params.op, 2, 2)
2177-
if sz == "a" then sz = addrsize end
2169+
if sz == "l" then sz = "d" elseif sz == "a" then sz = addrsize end
21782170
for _,p in ipairs(params) do
2179-
local a = parseoperand(p)
2171+
local a = parseoperand(p, sz == "q")
21802172
if sub(a.mode, 1, 1) ~= "i" or (a.opsize and a.opsize ~= sz) then
21812173
werror("bad mode or size in `"..p.."'")
21822174
end
21832175
if a.mode == "iJ" then
2184-
if sz == 'q' then
2185-
wputlabel64("IMM_", a.imm, 1)
2186-
else
2187-
wputlabel("IMM_", a.imm, 1)
2188-
end
2176+
wputlabel("IMM_", a.imm, 1)
2177+
elseif sz == "q" then
2178+
wputqarg(a.imm)
21892179
else
2190-
if sz == 'q' then
2191-
wputqarg(a.imm)
2192-
else
2193-
wputszarg(sz, a.imm)
2194-
end
2180+
wputszarg(sz, a.imm)
21952181
end
21962182
if secpos+2 > maxsecpos then wflush() end
21972183
end
@@ -2201,7 +2187,11 @@ map_op[".byte_*"] = op_data
22012187
map_op[".sbyte_*"] = op_data
22022188
map_op[".word_*"] = op_data
22032189
map_op[".dword_*"] = op_data
2190+
map_op[".qword_*"] = op_data
22042191
map_op[".aword_*"] = op_data
2192+
map_op[".long_*"] = op_data
2193+
map_op[".quad_*"] = op_data
2194+
map_op[".addr_*"] = op_data
22052195

22062196
------------------------------------------------------------------------------
22072197

0 commit comments

Comments
 (0)