mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
DynASM/x86: Fix x64 .aword refs. Add .qword, .quad, .addr and .long.
Suggested by Dmitry Stogov.
This commit is contained in:
parent
521b367567
commit
1449663ecf
@ -239,8 +239,11 @@ void dasm_put(Dst_DECL, int start, ...)
|
|||||||
}
|
}
|
||||||
pos++;
|
pos++;
|
||||||
ofs += 4; /* Maximum offset needed. */
|
ofs += 4; /* Maximum offset needed. */
|
||||||
if (action == DASM_REL_LG || action == DASM_REL_PC)
|
if (action == DASM_REL_LG || action == DASM_REL_PC) {
|
||||||
b[pos++] = ofs; /* Store pass1 offset estimate. */
|
b[pos++] = ofs; /* Store pass1 offset estimate. */
|
||||||
|
} else if (sizeof(ptrdiff_t) == 8) {
|
||||||
|
ofs += 4;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case DASM_LABEL_LG: pl = D->lglabels + *p++; CKPL(lg, LG); goto putlabel;
|
case DASM_LABEL_LG: pl = D->lglabels + *p++; CKPL(lg, LG); goto putlabel;
|
||||||
case DASM_LABEL_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC);
|
case DASM_LABEL_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC);
|
||||||
@ -365,10 +368,22 @@ int dasm_link(Dst_DECL, size_t *szp)
|
|||||||
do { *((unsigned short *)cp) = (unsigned short)(x); cp+=2; } while (0)
|
do { *((unsigned short *)cp) = (unsigned short)(x); cp+=2; } while (0)
|
||||||
#define dasmd(x) \
|
#define dasmd(x) \
|
||||||
do { *((unsigned int *)cp) = (unsigned int)(x); cp+=4; } while (0)
|
do { *((unsigned int *)cp) = (unsigned int)(x); cp+=4; } while (0)
|
||||||
|
#define dasmq(x) \
|
||||||
|
do { *((unsigned long long *)cp) = (unsigned long long)(x); cp+=8; } while (0)
|
||||||
#else
|
#else
|
||||||
#define dasmw(x) do { dasmb(x); dasmb((x)>>8); } while (0)
|
#define dasmw(x) do { dasmb(x); dasmb((x)>>8); } while (0)
|
||||||
#define dasmd(x) do { dasmw(x); dasmw((x)>>16); } while (0)
|
#define dasmd(x) do { dasmw(x); dasmw((x)>>16); } while (0)
|
||||||
|
#define dasmq(x) do { dasmd(x); dasmd((x)>>32); } while (0)
|
||||||
#endif
|
#endif
|
||||||
|
static unsigned char *dasma_(unsigned char *cp, ptrdiff_t x)
|
||||||
|
{
|
||||||
|
if (sizeof(ptrdiff_t) == 8)
|
||||||
|
dasmq((unsigned long long)x);
|
||||||
|
else
|
||||||
|
dasmd((unsigned int)x);
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
#define dasma(x) (cp = dasma_(cp, (x)))
|
||||||
|
|
||||||
/* Pass 3: Encode sections. */
|
/* Pass 3: Encode sections. */
|
||||||
int dasm_encode(Dst_DECL, void *buffer)
|
int dasm_encode(Dst_DECL, void *buffer)
|
||||||
@ -443,12 +458,13 @@ int dasm_encode(Dst_DECL, void *buffer)
|
|||||||
goto wb;
|
goto wb;
|
||||||
}
|
}
|
||||||
case DASM_IMM_LG:
|
case DASM_IMM_LG:
|
||||||
p++; if (n < 0) { n = (int)(ptrdiff_t)D->globals[-n]; goto wd; }
|
p++;
|
||||||
|
if (n < 0) { dasma((ptrdiff_t)D->globals[-n]); break; }
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case DASM_IMM_PC: {
|
case DASM_IMM_PC: {
|
||||||
int *pb = DASM_POS2PTR(D, n);
|
int *pb = DASM_POS2PTR(D, n);
|
||||||
n = *pb < 0 ? pb[1] : (*pb + (int)(ptrdiff_t)base);
|
dasma(*pb < 0 ? (ptrdiff_t)pb[1] : (*pb + (ptrdiff_t)base));
|
||||||
goto wd;
|
break;
|
||||||
}
|
}
|
||||||
case DASM_LABEL_LG: {
|
case DASM_LABEL_LG: {
|
||||||
int idx = *p++;
|
int idx = *p++;
|
||||||
|
@ -484,6 +484,22 @@ local function wputdarg(n)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Put signed or unsigned qword or arg.
|
||||||
|
local function wputqarg(n)
|
||||||
|
local tn = type(n)
|
||||||
|
if tn == "number" then -- This is only used for numbers from -2^31..2^32-1.
|
||||||
|
wputb(band(n, 255))
|
||||||
|
wputb(band(shr(n, 8), 255))
|
||||||
|
wputb(band(shr(n, 16), 255))
|
||||||
|
wputb(shr(n, 24))
|
||||||
|
local sign = n < 0 and 255 or 0
|
||||||
|
wputb(sign); wputb(sign); wputb(sign); wputb(sign)
|
||||||
|
else
|
||||||
|
waction("IMM_D", format("(unsigned int)(%s)", n))
|
||||||
|
waction("IMM_D", format("(unsigned int)((unsigned long long)(%s)>>32)", n))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Put operand-size dependent number or arg (defaults to dword).
|
-- Put operand-size dependent number or arg (defaults to dword).
|
||||||
local function wputszarg(sz, n)
|
local function wputszarg(sz, n)
|
||||||
if not sz or sz == "d" or sz == "q" then wputdarg(n)
|
if not sz or sz == "d" or sz == "q" then wputdarg(n)
|
||||||
@ -663,10 +679,16 @@ local function opmodestr(op, args)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Convert number to valid integer or nil.
|
-- Convert number to valid integer or nil.
|
||||||
local function toint(expr)
|
local function toint(expr, isqword)
|
||||||
local n = tonumber(expr)
|
local n = tonumber(expr)
|
||||||
if n then
|
if n then
|
||||||
if n % 1 ~= 0 or n < -2147483648 or n > 4294967295 then
|
if n % 1 ~= 0 then
|
||||||
|
werror("not an integer number `"..expr.."'")
|
||||||
|
elseif isqword then
|
||||||
|
if n < -2147483648 or n > 2147483647 then
|
||||||
|
n = nil -- Handle it as an expression to avoid precision loss.
|
||||||
|
end
|
||||||
|
elseif n < -2147483648 or n > 4294967295 then
|
||||||
werror("bad integer number `"..expr.."'")
|
werror("bad integer number `"..expr.."'")
|
||||||
end
|
end
|
||||||
return n
|
return n
|
||||||
@ -749,7 +771,7 @@ local function rtexpr(expr)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Parse operand and return { mode, opsize, reg, xreg, xsc, disp, imm }.
|
-- Parse operand and return { mode, opsize, reg, xreg, xsc, disp, imm }.
|
||||||
local function parseoperand(param)
|
local function parseoperand(param, isqword)
|
||||||
local t = {}
|
local t = {}
|
||||||
|
|
||||||
local expr = param
|
local expr = param
|
||||||
@ -837,7 +859,7 @@ local function parseoperand(param)
|
|||||||
t.disp = dispexpr(tailx)
|
t.disp = dispexpr(tailx)
|
||||||
else
|
else
|
||||||
-- imm or opsize*imm
|
-- imm or opsize*imm
|
||||||
local imm = toint(expr)
|
local imm = toint(expr, isqword)
|
||||||
if not imm and sub(expr, 1, 1) == "*" and t.opsize then
|
if not imm and sub(expr, 1, 1) == "*" and t.opsize then
|
||||||
imm = toint(sub(expr, 2))
|
imm = toint(sub(expr, 2))
|
||||||
if imm then
|
if imm then
|
||||||
@ -1952,7 +1974,7 @@ local function dopattern(pat, args, sz, op, needrex)
|
|||||||
local a = args[narg]
|
local a = args[narg]
|
||||||
narg = narg + 1
|
narg = narg + 1
|
||||||
local mode, imm = a.mode, a.imm
|
local mode, imm = a.mode, a.imm
|
||||||
if mode == "iJ" and not match("iIJ", c) then
|
if mode == "iJ" and not match(x64 and "J" or "iIJ", c) then
|
||||||
werror("bad operand size for label")
|
werror("bad operand size for label")
|
||||||
end
|
end
|
||||||
if c == "S" then
|
if c == "S" then
|
||||||
@ -2144,14 +2166,16 @@ end
|
|||||||
local function op_data(params)
|
local function op_data(params)
|
||||||
if not params then return "imm..." end
|
if not params then return "imm..." end
|
||||||
local sz = sub(params.op, 2, 2)
|
local sz = sub(params.op, 2, 2)
|
||||||
if sz == "a" then sz = addrsize end
|
if sz == "l" then sz = "d" elseif sz == "a" then sz = addrsize end
|
||||||
for _,p in ipairs(params) do
|
for _,p in ipairs(params) do
|
||||||
local a = parseoperand(p)
|
local a = parseoperand(p, sz == "q")
|
||||||
if sub(a.mode, 1, 1) ~= "i" or (a.opsize and a.opsize ~= sz) then
|
if sub(a.mode, 1, 1) ~= "i" or (a.opsize and a.opsize ~= sz) then
|
||||||
werror("bad mode or size in `"..p.."'")
|
werror("bad mode or size in `"..p.."'")
|
||||||
end
|
end
|
||||||
if a.mode == "iJ" then
|
if a.mode == "iJ" then
|
||||||
wputlabel("IMM_", a.imm, 1)
|
wputlabel("IMM_", a.imm, 1)
|
||||||
|
elseif sz == "q" then
|
||||||
|
wputqarg(a.imm)
|
||||||
else
|
else
|
||||||
wputszarg(sz, a.imm)
|
wputszarg(sz, a.imm)
|
||||||
end
|
end
|
||||||
@ -2163,7 +2187,11 @@ map_op[".byte_*"] = op_data
|
|||||||
map_op[".sbyte_*"] = op_data
|
map_op[".sbyte_*"] = op_data
|
||||||
map_op[".word_*"] = op_data
|
map_op[".word_*"] = op_data
|
||||||
map_op[".dword_*"] = op_data
|
map_op[".dword_*"] = op_data
|
||||||
|
map_op[".qword_*"] = op_data
|
||||||
map_op[".aword_*"] = op_data
|
map_op[".aword_*"] = op_data
|
||||||
|
map_op[".long_*"] = op_data
|
||||||
|
map_op[".quad_*"] = op_data
|
||||||
|
map_op[".addr_*"] = op_data
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user