Change DynASM bit operations to use Lua BitOp.
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user