aboutsummaryrefslogtreecommitdiff
path: root/dynasm/dasm_x86.lua
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dynasm/dasm_x86.lua42
1 files changed, 35 insertions, 7 deletions
diff --git a/dynasm/dasm_x86.lua b/dynasm/dasm_x86.lua
index bc9a0001..0c803dcd 100644
--- a/dynasm/dasm_x86.lua
+++ b/dynasm/dasm_x86.lua
@@ -484,6 +484,22 @@ local function wputdarg(n)
484 end 484 end
485end 485end
486 486
487-- Put signed or unsigned qword or arg.
488local function wputqarg(n)
489 local tn = type(n)
490 if tn == "number" then -- This is only used for numbers from -2^31..2^32-1.
491 wputb(band(n, 255))
492 wputb(band(shr(n, 8), 255))
493 wputb(band(shr(n, 16), 255))
494 wputb(shr(n, 24))
495 local sign = n < 0 and 255 or 0
496 wputb(sign); wputb(sign); wputb(sign); wputb(sign)
497 else
498 waction("IMM_D", format("(unsigned int)(%s)", n))
499 waction("IMM_D", format("(unsigned int)((unsigned long long)(%s)>>32)", n))
500 end
501end
502
487-- Put operand-size dependent number or arg (defaults to dword). 503-- Put operand-size dependent number or arg (defaults to dword).
488local function wputszarg(sz, n) 504local function wputszarg(sz, n)
489 if not sz or sz == "d" or sz == "q" then wputdarg(n) 505 if not sz or sz == "d" or sz == "q" then wputdarg(n)
@@ -663,10 +679,16 @@ local function opmodestr(op, args)
663end 679end
664 680
665-- Convert number to valid integer or nil. 681-- Convert number to valid integer or nil.
666local function toint(expr) 682local function toint(expr, isqword)
667 local n = tonumber(expr) 683 local n = tonumber(expr)
668 if n then 684 if n then
669 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
670 werror("bad integer number `"..expr.."'") 692 werror("bad integer number `"..expr.."'")
671 end 693 end
672 return n 694 return n
@@ -749,7 +771,7 @@ local function rtexpr(expr)
749end 771end
750 772
751-- Parse operand and return { mode, opsize, reg, xreg, xsc, disp, imm }. 773-- Parse operand and return { mode, opsize, reg, xreg, xsc, disp, imm }.
752local function parseoperand(param) 774local function parseoperand(param, isqword)
753 local t = {} 775 local t = {}
754 776
755 local expr = param 777 local expr = param
@@ -837,7 +859,7 @@ local function parseoperand(param)
837 t.disp = dispexpr(tailx) 859 t.disp = dispexpr(tailx)
838 else 860 else
839 -- imm or opsize*imm 861 -- imm or opsize*imm
840 local imm = toint(expr) 862 local imm = toint(expr, isqword)
841 if not imm and sub(expr, 1, 1) == "*" and t.opsize then 863 if not imm and sub(expr, 1, 1) == "*" and t.opsize then
842 imm = toint(sub(expr, 2)) 864 imm = toint(sub(expr, 2))
843 if imm then 865 if imm then
@@ -1952,7 +1974,7 @@ local function dopattern(pat, args, sz, op, needrex)
1952 local a = args[narg] 1974 local a = args[narg]
1953 narg = narg + 1 1975 narg = narg + 1
1954 local mode, imm = a.mode, a.imm 1976 local mode, imm = a.mode, a.imm
1955 if mode == "iJ" and not match("iIJ", c) then 1977 if mode == "iJ" and not match(x64 and "J" or "iIJ", c) then
1956 werror("bad operand size for label") 1978 werror("bad operand size for label")
1957 end 1979 end
1958 if c == "S" then 1980 if c == "S" then
@@ -2144,14 +2166,16 @@ end
2144local function op_data(params) 2166local function op_data(params)
2145 if not params then return "imm..." end 2167 if not params then return "imm..." end
2146 local sz = sub(params.op, 2, 2) 2168 local sz = sub(params.op, 2, 2)
2147 if sz == "a" then sz = addrsize end 2169 if sz == "l" then sz = "d" elseif sz == "a" then sz = addrsize end
2148 for _,p in ipairs(params) do 2170 for _,p in ipairs(params) do
2149 local a = parseoperand(p) 2171 local a = parseoperand(p, sz == "q")
2150 if sub(a.mode, 1, 1) ~= "i" or (a.opsize and a.opsize ~= sz) then 2172 if sub(a.mode, 1, 1) ~= "i" or (a.opsize and a.opsize ~= sz) then
2151 werror("bad mode or size in `"..p.."'") 2173 werror("bad mode or size in `"..p.."'")
2152 end 2174 end
2153 if a.mode == "iJ" then 2175 if a.mode == "iJ" then
2154 wputlabel("IMM_", a.imm, 1) 2176 wputlabel("IMM_", a.imm, 1)
2177 elseif sz == "q" then
2178 wputqarg(a.imm)
2155 else 2179 else
2156 wputszarg(sz, a.imm) 2180 wputszarg(sz, a.imm)
2157 end 2181 end
@@ -2163,7 +2187,11 @@ map_op[".byte_*"] = op_data
2163map_op[".sbyte_*"] = op_data 2187map_op[".sbyte_*"] = op_data
2164map_op[".word_*"] = op_data 2188map_op[".word_*"] = op_data
2165map_op[".dword_*"] = op_data 2189map_op[".dword_*"] = op_data
2190map_op[".qword_*"] = op_data
2166map_op[".aword_*"] = op_data 2191map_op[".aword_*"] = op_data
2192map_op[".long_*"] = op_data
2193map_op[".quad_*"] = op_data
2194map_op[".addr_*"] = op_data
2167 2195
2168------------------------------------------------------------------------------ 2196------------------------------------------------------------------------------
2169 2197