|
@@ -484,6 +484,22 @@ local function wputdarg(n)
|
|
|
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).
|
|
|
local function wputszarg(sz, n)
|
|
|
if not sz or sz == "d" or sz == "q" then wputdarg(n)
|
|
@@ -663,10 +679,16 @@ local function opmodestr(op, args)
|
|
|
end
|
|
|
|
|
|
-- Convert number to valid integer or nil.
|
|
|
-local function toint(expr)
|
|
|
+local function toint(expr, isqword)
|
|
|
local n = tonumber(expr)
|
|
|
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.."'")
|
|
|
end
|
|
|
return n
|
|
@@ -749,7 +771,7 @@ local function rtexpr(expr)
|
|
|
end
|
|
|
|
|
|
-- Parse operand and return { mode, opsize, reg, xreg, xsc, disp, imm }.
|
|
|
-local function parseoperand(param)
|
|
|
+local function parseoperand(param, isqword)
|
|
|
local t = {}
|
|
|
|
|
|
local expr = param
|
|
@@ -837,7 +859,7 @@ local function parseoperand(param)
|
|
|
t.disp = dispexpr(tailx)
|
|
|
else
|
|
|
-- 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
|
|
|
imm = toint(sub(expr, 2))
|
|
|
if imm then
|
|
@@ -1952,7 +1974,7 @@ local function dopattern(pat, args, sz, op, needrex)
|
|
|
local a = args[narg]
|
|
|
narg = narg + 1
|
|
|
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")
|
|
|
end
|
|
|
if c == "S" then
|
|
@@ -2144,14 +2166,16 @@ end
|
|
|
local function op_data(params)
|
|
|
if not params then return "imm..." end
|
|
|
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
|
|
|
- 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
|
|
|
werror("bad mode or size in `"..p.."'")
|
|
|
end
|
|
|
if a.mode == "iJ" then
|
|
|
wputlabel("IMM_", a.imm, 1)
|
|
|
+ elseif sz == "q" then
|
|
|
+ wputqarg(a.imm)
|
|
|
else
|
|
|
wputszarg(sz, a.imm)
|
|
|
end
|
|
@@ -2163,7 +2187,11 @@ map_op[".byte_*"] = op_data
|
|
|
map_op[".sbyte_*"] = op_data
|
|
|
map_op[".word_*"] = op_data
|
|
|
map_op[".dword_*"] = op_data
|
|
|
+map_op[".qword_*"] = op_data
|
|
|
map_op[".aword_*"] = op_data
|
|
|
+map_op[".long_*"] = op_data
|
|
|
+map_op[".quad_*"] = op_data
|
|
|
+map_op[".addr_*"] = op_data
|
|
|
|
|
|
------------------------------------------------------------------------------
|
|
|
|