summaryrefslogtreecommitdiff
path: root/dynasm
diff options
context:
space:
mode:
authorMike Pall <mike>2012-07-08 16:25:38 +0200
committerMike Pall <mike>2012-07-08 16:27:18 +0200
commitc00ffcb870cd51849ee2a0f1bf1862ac965026b7 (patch)
treee9af978c9883e709b1b5e5a845ce8ef5b6d0c490 /dynasm
parente3dec0438d50dbdf0184078d4e0233e399725787 (diff)
downloadluajit2-c00ffcb870cd51849ee2a0f1bf1862ac965026b7.tar.gz
Change DynASM bit operations to use Lua BitOp.
Diffstat (limited to 'dynasm')
-rw-r--r--dynasm/dasm_arm.lua73
-rw-r--r--dynasm/dasm_mips.lua44
-rw-r--r--dynasm/dasm_ppc.lua66
-rw-r--r--dynasm/dasm_x86.lua52
4 files changed, 105 insertions, 130 deletions
diff --git a/dynasm/dasm_arm.lua b/dynasm/dasm_arm.lua
index cc4fa177..4735f323 100644
--- a/dynasm/dasm_arm.lua
+++ b/dynasm/dasm_arm.lua
@@ -26,6 +26,9 @@ local _s = string
local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
local match, gmatch, gsub = _s.match, _s.gmatch, _s.gsub
local concat, sort, insert = table.concat, table.sort, table.insert
+local bit = bit or require("bit")
+local band, shl, shr, sar = bit.band, bit.lshift, bit.rshift, bit.arshift
+local ror, tohex = bit.ror, bit.tohex
-- Inherited tables and callbacks.
local g_opt, g_arch
@@ -60,11 +63,6 @@ local secpos = 1
------------------------------------------------------------------------------
--- Return 8 digit hex number.
-local function tohex(x)
- return sub(format("%08x", x), -8) -- Avoid 64 bit portability problem in Lua.
-end
-
-- Dump action names and numbers.
local function dumpactions(out)
out:write("DynASM encoding engine action codes:\n")
@@ -483,8 +481,8 @@ local function parse_reglist(reglist)
if not reglist then werror("register list expected") end
local rr = 0
for p in gmatch(reglist..",", "%s*([^,]*),") do
- local rbit = 2^parse_gpr(gsub(p, "%s+$", ""))
- if ((rr - (rr % rbit)) / rbit) % 2 ~= 0 then
+ local rbit = shl(1, parse_gpr(gsub(p, "%s+$", "")))
+ if band(rr, rbit) ~= 0 then
werror("duplicate register `"..p.."'")
end
rr = rr + rbit
@@ -497,16 +495,14 @@ local function parse_imm(imm, bits, shift, scale, signed)
if not imm then werror("expected immediate operand") end
local n = tonumber(imm)
if n then
- if n % 2^scale == 0 then
- n = n / 2^scale
+ local m = sar(n, scale)
+ if shl(m, scale) == n then
if signed then
- if n >= 0 then
- if n < 2^(bits-1) then return n*2^shift end
- else
- if n >= -(2^(bits-1))-1 then return (n+2^bits)*2^shift end
- end
+ local s = sar(m, bits-1)
+ if s == 0 then return shl(m, shift)
+ elseif s == -1 then return shl(m + shl(1, bits), shift) end
else
- if n >= 0 and n <= 2^bits-1 then return n*2^shift end
+ if sar(m, bits) == 0 then return shl(m, shift) end
end
end
werror("out of range immediate `"..imm.."'")
@@ -519,11 +515,10 @@ end
local function parse_imm12(imm)
local n = tonumber(imm)
if n then
- local m = n
+ local m = band(n)
for i=0,-15,-1 do
- if m >= 0 and m <= 255 and n % 1 == 0 then return m + (i%16) * 256 end
- local t = m % 4
- m = (m - t) / 4 + t * 2^30
+ if shr(m, 8) == 0 then return m + shl(band(i, 15), 8) end
+ m = ror(m, 2)
end
werror("out of range immediate `"..imm.."'")
else
@@ -537,10 +532,7 @@ local function parse_imm16(imm)
if not imm then werror("expected immediate operand") end
local n = tonumber(imm)
if n then
- if n >= 0 and n <= 65535 and n % 1 == 0 then
- local t = n % 4096
- return (n - t) * 16 + t
- end
+ if shr(n, 16) == 0 then return band(n, 0x0fff) + shl(band(n, 0xf000), 4) end
werror("out of range immediate `"..imm.."'")
else
waction("IMM16", 32*16, imm)
@@ -555,7 +547,7 @@ local function parse_imm_load(imm, ext)
if n >= -255 and n <= 255 then
local up = 0x00800000
if n < 0 then n = -n; up = 0 end
- return (n-(n%16))*16+(n%16) + up
+ return shl(band(n, 0xf0), 4) + band(n, 0x0f) + up
end
else
if n >= -4095 and n <= 4095 then
@@ -565,7 +557,7 @@ local function parse_imm_load(imm, ext)
end
werror("out of range immediate `"..imm.."'")
else
- waction(ext and "IMML8" or "IMML12", 32768 + 32*(ext and 8 or 12), imm)
+ waction(ext and "IMML8" or "IMML12", 32768 + shl(ext and 8 or 12, 5), imm)
return 0
end
end
@@ -578,10 +570,10 @@ local function parse_shift(shift, gprok)
s = map_shift[s]
if not s then werror("expected shift operand") end
if sub(s2, 1, 1) == "#" then
- return parse_imm(s2, 5, 7, 0, false) + s * 32
+ return parse_imm(s2, 5, 7, 0, false) + shl(s, 5)
else
if not gprok then werror("expected immediate shift operand") end
- return parse_gpr(s2) * 256 + s * 32 + 16
+ return shl(parse_gpr(s2), 8) + shl(s, 5) + 16
end
end
end
@@ -617,12 +609,12 @@ local function parse_label(label, def)
end
local function parse_load(params, nparams, n, op)
- local oplo = op % 256
+ local oplo = band(op, 255)
local ext, ldrd = (oplo ~= 0), (oplo == 208)
local d
if (ldrd or oplo == 240) then
- d = ((op - (op % 4096)) / 4096) % 16
- if d % 2 ~= 0 then werror("odd destination register") end
+ d = band(shr(op, 12), 15)
+ if band(d, 1) ~= 0 then werror("odd destination register") end
end
local pn = params[n]
local p1, wb = match(pn, "^%[%s*(.-)%s*%](!?)$")
@@ -640,7 +632,7 @@ local function parse_load(params, nparams, n, op)
if tp then
waction(ext and "IMML8" or "IMML12", 32768 + 32*(ext and 8 or 12),
format(tp.ctypefmt, tailr))
- return op + d * 65536 + 0x01000000 + (ext and 0x00400000 or 0)
+ return op + shl(d, 16) + 0x01000000 + (ext and 0x00400000 or 0)
end
end
end
@@ -650,7 +642,7 @@ local function parse_load(params, nparams, n, op)
if p2 then
if wb == "!" then werror("bad use of '!'") end
local p3 = params[n+2]
- op = op + parse_gpr(p1) * 65536
+ op = op + shl(parse_gpr(p1), 16)
local imm = match(p2, "^#(.*)$")
if imm then
local m = parse_imm_load(imm, ext)
@@ -664,7 +656,7 @@ local function parse_load(params, nparams, n, op)
end
else
local p1a, p2 = match(p1, "^([^,%s]*)%s*(.*)$")
- op = op + parse_gpr(p1a) * 65536 + 0x01000000
+ op = op + shl(parse_gpr(p1a), 16) + 0x01000000
if p2 ~= "" then
local imm = match(p2, "^,%s*#(.*)$")
if imm then
@@ -704,11 +696,11 @@ map_op[".template__"] = function(params, template, nparams)
-- Process each character.
for p in gmatch(sub(template, 9), ".") do
if p == "D" then
- op = op + parse_gpr(params[n]) * 4096; n = n + 1
+ op = op + shl(parse_gpr(params[n]), 12); n = n + 1
elseif p == "N" then
- op = op + parse_gpr(params[n]) * 65536; n = n + 1
+ op = op + shl(parse_gpr(params[n]), 16); n = n + 1
elseif p == "S" then
- op = op + parse_gpr(params[n]) * 256; n = n + 1
+ op = op + shl(parse_gpr(params[n]), 8); n = n + 1
elseif p == "M" then
op = op + parse_gpr(params[n]); n = n + 1
elseif p == "P" then
@@ -738,7 +730,7 @@ map_op[".template__"] = function(params, template, nparams)
end
elseif p == "n" then
local r, wb = match(params[n], "^([^!]*)(!?)$")
- op = op + parse_gpr(r) * 65536 + (wb == "!" and 0x00200000 or 0)
+ op = op + shl(parse_gpr(r), 16) + (wb == "!" and 0x00200000 or 0)
n = n + 1
elseif p == "R" then
op = op + parse_reglist(params[n]); n = n + 1
@@ -751,17 +743,16 @@ map_op[".template__"] = function(params, template, nparams)
if imm then
op = op + parse_imm(params[n], 5, 7, 0, false); n = n + 1
else
- op = op + parse_gpr(params[n]) * 256 + 16
+ op = op + shl(parse_gpr(params[n]), 8) + 16
end
elseif p == "X" then
op = op + parse_imm(params[n], 5, 16, 0, false); n = n + 1
elseif p == "K" then
local imm = tonumber(match(params[n], "^#(.*)$")); n = n + 1
- if not imm or imm % 1 ~= 0 or imm < 0 or imm > 0xffff then
+ if not imm or shr(imm, 16) ~= 0 then
werror("bad immediate operand")
end
- local t = imm % 16
- op = op + (imm - t) * 16 + t
+ op = op + shl(band(imm, 0xfff0), 4) + band(imm, 0x000f)
elseif p == "T" then
op = op + parse_imm(params[n], 24, 0, 0, false); n = n + 1
elseif p == "s" then
diff --git a/dynasm/dasm_mips.lua b/dynasm/dasm_mips.lua
index aa33f0cc..c387d292 100644
--- a/dynasm/dasm_mips.lua
+++ b/dynasm/dasm_mips.lua
@@ -26,6 +26,8 @@ local _s = string
local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
local match, gmatch = _s.match, _s.gmatch
local concat, sort = table.concat, table.sort
+local bit = bit or require("bit")
+local band, shl, sar, tohex = bit.band, bit.lshift, bit.arshift, bit.tohex
-- Inherited tables and callbacks.
local g_opt, g_arch
@@ -60,11 +62,6 @@ local secpos = 1
------------------------------------------------------------------------------
--- Return 8 digit hex number.
-local function tohex(x)
- return sub(format("%08x", x), -8) -- Avoid 64 bit portability problem in Lua.
-end
-
-- Dump action names and numbers.
local function dumpactions(out)
out:write("DynASM encoding engine action codes:\n")
@@ -639,16 +636,14 @@ end
local function parse_imm(imm, bits, shift, scale, signed)
local n = tonumber(imm)
if n then
- if n % 2^scale == 0 then
- n = n / 2^scale
+ local m = sar(n, scale)
+ if shl(m, scale) == n then
if signed then
- if n >= 0 then
- if n < 2^(bits-1) then return n*2^shift end
- else
- if n >= -(2^(bits-1))-1 then return (n+2^bits)*2^shift end
- end
+ local s = sar(m, bits-1)
+ if s == 0 then return shl(m, shift)
+ elseif s == -1 then return shl(m + shl(1, bits), shift) end
else
- if n >= 0 and n <= 2^bits-1 then return n*2^shift end
+ if sar(m, bits) == 0 then return shl(m, shift) end
end
end
werror("out of range immediate `"..imm.."'")
@@ -664,7 +659,7 @@ end
local function parse_disp(disp)
local imm, reg = match(disp, "^(.*)%(([%w_:]+)%)$")
if imm then
- local r = parse_gpr(reg)*2^21
+ local r = shl(parse_gpr(reg), 21)
local extname = match(imm, "^extern%s+(%S+)$")
if extname then
waction("REL_EXT", map_extern[extname], nil, 1)
@@ -678,7 +673,7 @@ local function parse_disp(disp)
local r, tp = parse_gpr(reg)
if tp then
waction("IMM", 32768+16*32, format(tp.ctypefmt, tailr))
- return r*2^21
+ return shl(r, 21)
end
end
werror("bad displacement `"..disp.."'")
@@ -689,7 +684,7 @@ local function parse_index(idx)
if rt then
rt = parse_gpr(rt)
rs = parse_gpr(rs)
- return rt*2^16 + rs*2^21
+ return shl(rt, 16) + shl(rs, 21)
end
werror("bad index `"..idx.."'")
end
@@ -740,19 +735,19 @@ map_op[".template__"] = function(params, template, nparams)
-- Process each character.
for p in gmatch(sub(template, 9), ".") do
if p == "D" then
- op = op + parse_gpr(params[n]) * 2^11; n = n + 1
+ op = op + shl(parse_gpr(params[n]), 11); n = n + 1
elseif p == "T" then
- op = op + parse_gpr(params[n]) * 2^16; n = n + 1
+ op = op + shl(parse_gpr(params[n]), 16); n = n + 1
elseif p == "S" then
- op = op + parse_gpr(params[n]) * 2^21; n = n + 1
+ op = op + shl(parse_gpr(params[n]), 21); n = n + 1
elseif p == "F" then
- op = op + parse_fpr(params[n]) * 2^6; n = n + 1
+ op = op + shl(parse_fpr(params[n]), 6); n = n + 1
elseif p == "G" then
- op = op + parse_fpr(params[n]) * 2^11; n = n + 1
+ op = op + shl(parse_fpr(params[n]), 11); n = n + 1
elseif p == "H" then
- op = op + parse_fpr(params[n]) * 2^16; n = n + 1
+ op = op + shl(parse_fpr(params[n]), 16); n = n + 1
elseif p == "R" then
- op = op + parse_fpr(params[n]) * 2^21; n = n + 1
+ op = op + shl(parse_fpr(params[n]), 21); n = n + 1
elseif p == "I" then
op = op + parse_imm(params[n], 16, 0, 0, true); n = n + 1
elseif p == "U" then
@@ -783,8 +778,7 @@ map_op[".template__"] = function(params, template, nparams)
elseif p == "Z" then
op = op + parse_imm(params[n], 10, 6, 0, false); n = n + 1
elseif p == "=" then
- local d = ((op - op % 2^11) / 2^11) % 32
- op = op + d * 2^16 -- Copy D to T for clz, clo.
+ op = op + shl(band(op, 0xf800), 5) -- Copy D to T for clz, clo.
else
assert(false)
end
diff --git a/dynasm/dasm_ppc.lua b/dynasm/dasm_ppc.lua
index 7d64d81c..020ef0d9 100644
--- a/dynasm/dasm_ppc.lua
+++ b/dynasm/dasm_ppc.lua
@@ -26,6 +26,9 @@ local _s = string
local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
local match, gmatch = _s.match, _s.gmatch
local concat, sort = table.concat, table.sort
+local bit = bit or require("bit")
+local band, shl, shr, sar = bit.band, bit.lshift, bit.rshift, bit.arshift
+local tohex = bit.tohex
-- Inherited tables and callbacks.
local g_opt, g_arch
@@ -60,11 +63,6 @@ local secpos = 1
------------------------------------------------------------------------------
--- Return 8 digit hex number.
-local function tohex(x)
- return sub(format("%08x", x), -8) -- Avoid 64 bit portability problem in Lua.
-end
-
-- Dump action names and numbers.
local function dumpactions(out)
out:write("DynASM encoding engine action codes:\n")
@@ -837,7 +835,7 @@ end
-- Add more branch mnemonics.
for cond,c in pairs(map_cond) do
local b1 = "b"..cond
- local c1 = (c%4)*0x00010000 + (c < 4 and 0x01000000 or 0)
+ local c1 = shl(band(c, 3), 16) + (c < 4 and 0x01000000 or 0)
-- bX[l]
map_op[b1.."_1"] = tohex(0x40800000 + c1).."K"
map_op[b1.."y_1"] = tohex(0x40a00000 + c1).."K"
@@ -905,16 +903,14 @@ end
local function parse_imm(imm, bits, shift, scale, signed)
local n = tonumber(imm)
if n then
- if n % 2^scale == 0 then
- n = n / 2^scale
+ local m = sar(n, scale)
+ if shl(m, scale) == n then
if signed then
- if n >= 0 then
- if n < 2^(bits-1) then return n*2^shift end
- else
- if n >= -(2^(bits-1))-1 then return (n+2^bits)*2^shift end
- end
+ local s = sar(m, bits-1)
+ if s == 0 then return shl(m, shift)
+ elseif s == -1 then return shl(m + shl(1, bits), shift) end
else
- if n >= 0 and n <= 2^bits-1 then return n*2^shift end
+ if sar(m, bits) == 0 then return shl(m, shift) end
end
end
werror("out of range immediate `"..imm.."'")
@@ -930,10 +926,10 @@ end
local function parse_shiftmask(imm, isshift)
local n = tonumber(imm)
if n then
- if n % 1 == 0 and n >= 0 and n <= 63 then
- local lsb = imm % 32
+ if shr(n, 6) == 0 then
+ local lsb = band(imm, 31)
local msb = imm - lsb
- return isshift and (lsb*2048+msb/16) or (lsb*64+msb)
+ return isshift and (shl(lsb, 11)+shr(msb, 4)) or (shl(lsb, 6)+msb)
end
werror("out of range immediate `"..imm.."'")
elseif match(imm, "^r([1-3]?[0-9])$") or
@@ -949,7 +945,7 @@ local function parse_disp(disp)
if imm then
local r = parse_gpr(reg)
if r == 0 then werror("cannot use r0 in displacement") end
- return r*65536 + parse_imm(imm, 16, 0, 0, true)
+ return shl(r, 16) + parse_imm(imm, 16, 0, 0, true)
end
local reg, tailr = match(disp, "^([%w_:]+)%s*(.*)$")
if reg and tailr ~= "" then
@@ -957,7 +953,7 @@ local function parse_disp(disp)
if r == 0 then werror("cannot use r0 in displacement") end
if tp then
waction("IMM", 32768+16*32, format(tp.ctypefmt, tailr))
- return r*65536
+ return shl(r, 16)
end
end
werror("bad displacement `"..disp.."'")
@@ -968,7 +964,7 @@ local function parse_u5disp(disp, scale)
if imm then
local r = parse_gpr(reg)
if r == 0 then werror("cannot use r0 in displacement") end
- return r*65536 + parse_imm(imm, 5, 11, scale, false)
+ return shl(r, 16) + parse_imm(imm, 5, 11, scale, false)
end
local reg, tailr = match(disp, "^([%w_:]+)%s*(.*)$")
if reg and tailr ~= "" then
@@ -976,7 +972,7 @@ local function parse_u5disp(disp, scale)
if r == 0 then werror("cannot use r0 in displacement") end
if tp then
waction("IMM", scale*1024+5*32+11, format(tp.ctypefmt, tailr))
- return r*65536
+ return shl(r, 16)
end
end
werror("bad displacement `"..disp.."'")
@@ -1028,9 +1024,9 @@ map_op[".template__"] = function(params, template, nparams)
-- Process each character.
for p in gmatch(sub(template, 9), ".") do
if p == "R" then
- rs = rs - 5; op = op + parse_gpr(params[n]) * 2^rs; n = n + 1
+ rs = rs - 5; op = op + shl(parse_gpr(params[n]), rs); n = n + 1
elseif p == "F" then
- rs = rs - 5; op = op + parse_fpr(params[n]) * 2^rs; n = n + 1
+ rs = rs - 5; op = op + shl(parse_fpr(params[n]), rs); n = n + 1
elseif p == "A" then
rs = rs - 5; op = op + parse_imm(params[n], 5, rs, 0, false); n = n + 1
elseif p == "S" then
@@ -1048,9 +1044,9 @@ map_op[".template__"] = function(params, template, nparams)
elseif p == "8" then
op = op + parse_u5disp(params[n], 3); n = n + 1
elseif p == "C" then
- rs = rs - 5; op = op + parse_cond(params[n]) * 2^rs; n = n + 1
+ rs = rs - 5; op = op + shl(parse_cond(params[n]), rs); n = n + 1
elseif p == "X" then
- rs = rs - 5; op = op + parse_cr(params[n]) * 2^(rs+2); n = n + 1
+ rs = rs - 5; op = op + shl(parse_cr(params[n]), rs+2); n = n + 1
elseif p == "W" then
op = op + parse_cr(params[n]); n = n + 1
elseif p == "G" then
@@ -1065,22 +1061,16 @@ map_op[".template__"] = function(params, template, nparams)
waction("REL_"..mode, n, s, 1)
n = n + 1
elseif p == "0" then
- local mm = 2^rs
- local t = op % mm
- if ((op - t) / mm) % 32 == 0 then werror("cannot use r0") end
+ if band(shr(op, rs), 31) == 0 then werror("cannot use r0") end
elseif p == "=" or p == "%" then
- local mm = 2^(rs + (p == "%" and 5 or 0))
- local t = ((op - op % mm) / mm) % 32
+ local t = band(shr(op, p == "%" and rs+5 or rs), 31)
rs = rs - 5
- op = op + t * 2^rs
+ op = op + shl(t, rs)
elseif p == "~" then
- local mm = 2^rs
- local t1l = op % mm
- local t1h = (op - t1l) / mm
- local t2l = t1h % 32
- local t2h = (t1h - t2l) / 32
- local t3l = t2h % 32
- op = ((t2h - t3l + t2l)*32 + t3l)*mm + t1l
+ local mm = shl(31, rs)
+ local lo = band(op, mm)
+ local hi = band(op, shl(mm, 5))
+ op = op - lo - hi + shl(lo, 5) + shr(hi, 5)
elseif p == "-" then
rs = rs - 5
elseif p == "." then
diff --git a/dynasm/dasm_x86.lua b/dynasm/dasm_x86.lua
index 3bebb83c..a5f5c37d 100644
--- a/dynasm/dasm_x86.lua
+++ b/dynasm/dasm_x86.lua
@@ -28,6 +28,8 @@ local _s = string
local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
local find, match, gmatch, gsub = _s.find, _s.match, _s.gmatch, _s.gsub
local concat, sort = table.concat, table.sort
+local bit = bit or require("bit")
+local band, shl, shr = bit.band, bit.lshift, bit.rshift
-- Inherited tables and callbacks.
local g_opt, g_arch
@@ -426,10 +428,10 @@ end
-- Put unsigned word or arg.
local function wputwarg(n)
if type(n) == "number" then
- if n < 0 or n > 65535 then
+ if shr(n, 16) ~= 0 then
werror("unsigned immediate word out of range")
end
- local r = n%256; n = (n-r)/256; wputb(r); wputb(n);
+ wputb(band(n, 255)); wputb(shr(n, 8));
else waction("IMM_W", n) end
end
@@ -437,10 +439,10 @@ end
local function wputdarg(n)
local tn = type(n)
if tn == "number" then
- if n < 0 then n = n + 4294967296 end
- local r = n%256; n = (n-r)/256; wputb(r);
- r = n%256; n = (n-r)/256; wputb(r);
- r = n%256; n = (n-r)/256; wputb(r); wputb(n);
+ wputb(band(n, 255))
+ wputb(band(shr(n, 8), 255))
+ wputb(band(shr(n, 16), 255))
+ wputb(shr(n, 24))
elseif tn == "table" then
wputlabel("IMM_", n[1], 1)
else
@@ -464,24 +466,23 @@ local function wputop(sz, op, rex)
if sz == "w" then wputb(102) end
-- Needs >32 bit numbers, but only for crc32 eax, word [ebx]
if op >= 4294967296 then r = op%4294967296 wputb((op-r)/4294967296) op = r end
- if op >= 16777216 then r = op % 16777216 wputb((op-r) / 16777216) op = r end
+ if op >= 16777216 then wputb(shr(op, 24)); op = band(op, 0xffffff) end
if op >= 65536 then
if rex ~= 0 then
- local opc3 = op - op % 256
+ local opc3 = band(op, 0xffff00)
if opc3 == 0x0f3a00 or opc3 == 0x0f3800 then
- wputb(64 + rex % 16); rex = 0
+ wputb(64 + band(rex, 15)); rex = 0
end
end
- r = op % 65536 wputb((op-r) / 65536) op = r
+ wputb(shr(op, 16)); op = band(op, 0xffff)
end
if op >= 256 then
- r = op % 256
- local b = (op-r) / 256
- if b == 15 and rex ~= 0 then wputb(64 + rex % 16); rex = 0 end
+ local b = shr(op, 8)
+ if b == 15 and rex ~= 0 then wputb(64 + band(rex, 15)); rex = 0 end
wputb(b)
- op = r
+ op = band(op, 255)
end
- if rex ~= 0 then wputb(64 + rex % 16) end
+ if rex ~= 0 then wputb(64 + band(rex, 15)) end
if sz == "b" then op = op - 1 end
wputb(op)
end
@@ -489,7 +490,7 @@ end
-- Put ModRM or SIB formatted byte.
local function wputmodrm(m, s, rm, vs, vrm)
assert(m < 4 and s < 16 and rm < 16, "bad modrm operands")
- wputb(64*m + 8*(s%8) + (rm%8))
+ wputb(shl(m, 6) + shl(band(s, 7), 3) + band(rm, 7))
end
-- Put ModRM/SIB plus optional displacement.
@@ -548,7 +549,7 @@ local function wputmrmsib(t, imark, s, vsreg)
local m
if tdisp == "number" then -- Check displacement size at assembly time.
- if disp == 0 and (reg%8) ~= 5 then -- [ebp] -> [ebp+0] (in SIB, too)
+ if disp == 0 and band(reg, 7) ~= 5 then -- [ebp] -> [ebp+0] (in SIB, too)
if not vreg then m = 0 end -- Force DISP to allow [Rd(5)] -> [ebp+0]
elseif disp >= -128 and disp <= 127 then m = 1
else m = 2 end
@@ -557,7 +558,7 @@ local function wputmrmsib(t, imark, s, vsreg)
end
-- Index register present or esp as base register: need SIB encoding.
- if xreg or (reg%8) == 4 then
+ if xreg or band(reg, 7) == 4 then
wputmodrm(m or 2, s, 4) -- ModRM.
if m == nil or imark == "I" then waction("MARK") end
if vsreg then waction("VREG", vsreg); wputxb(2) end
@@ -1410,7 +1411,7 @@ local map_op = {
-- Arithmetic ops.
for name,n in pairs{ add = 0, ["or"] = 1, adc = 2, sbb = 3,
["and"] = 4, sub = 5, xor = 6, cmp = 7 } do
- local n8 = n * 8
+ local n8 = shl(n, 3)
map_op[name.."_2"] = format(
"mr:%02XRm|rm:%02XrM|mI1qdw:81%XmI|mS1qdw:83%XmS|Ri1qdwb:%02Xri|mi1qdwb:81%Xmi",
1+n8, 3+n8, n, n, 5+n8, n)
@@ -1432,7 +1433,7 @@ end
-- FP arithmetic ops.
for name,n in pairs{ add = 0, mul = 1, com = 2, comp = 3,
sub = 4, subr = 5, div = 6, divr = 7 } do
- local nc = 192 + n * 8
+ local nc = 0xc0 + shl(n, 3)
local nr = nc + (n < 4 and 0 or (n % 2 == 0 and 8 or -8))
local fn = "f"..name
map_op[fn.."_1"] = format("ff:D8%02Xr|xd:D8%Xm|xq:nDC%Xm", nc, n, n)
@@ -1448,8 +1449,7 @@ end
-- FP conditional moves.
for cc,n in pairs{ b=0, e=1, be=2, u=3, nb=4, ne=5, nbe=6, nu=7 } do
- local n4 = n % 4
- local nc = 56000 + n4 * 8 + (n-n4) * 64
+ local nc = 0xdac0 + shl(band(n, 3), 3) + shl(band(n, 4), 6)
map_op["fcmov"..cc.."_1"] = format("ff:%04Xr", nc) -- P6+
map_op["fcmov"..cc.."_2"] = format("Fff:%04XR", nc) -- P6+
end
@@ -1499,10 +1499,10 @@ local function dopattern(pat, args, sz, op, needrex)
local s
if addin then
s = addin.reg
- opcode = opcode - (s%8) -- Undo regno opcode merge.
+ opcode = opcode - band(s, 7) -- Undo regno opcode merge.
else
- s = opcode % 16 -- Undo last digit.
- opcode = (opcode - s) / 16
+ s = band(opcode, 15) -- Undo last digit.
+ opcode = shr(opcode, 4)
end
local nn = c == "m" and 1 or 2
local t = args[nn]
@@ -1699,7 +1699,7 @@ if x64 then
werror("bad operand mode")
end
op64 = params[2]
- opcode = 0xb8 + (a.reg%8) -- !x64: no VREG support.
+ opcode = 0xb8 + band(a.reg, 7) -- !x64: no VREG support.
rex = a.reg > 7 and 9 or 8
end
end