mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 15:14:08 +00:00
Change DynASM bit operations to use Lua BitOp.
This commit is contained in:
parent
e3dec0438d
commit
c00ffcb870
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user