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 diff --git a/src/Makefile b/src/Makefile index 13344a77..531f8bab 100644 --- a/src/Makefile +++ b/src/Makefile @@ -168,7 +168,7 @@ LDOPTIONS= $(CCDEBUG) $(LDFLAGS) HOST_CC= $(CC) HOST_RM= rm -f # If left blank, minilua is built and used. You can supply an installed -# copy of (plain) Lua 5.1 or 5.2, e.g. with: HOST_LUA=lua +# copy of (plain) Lua 5.1 or 5.2, plus Lua BitOp. E.g. with: HOST_LUA=lua HOST_LUA= HOST_XCFLAGS= -I.