summaryrefslogtreecommitdiff
path: root/dynasm/dasm_arm.lua
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/dasm_arm.lua
parente3dec0438d50dbdf0184078d4e0233e399725787 (diff)
downloadluajit2-c00ffcb870cd51849ee2a0f1bf1862ac965026b7.tar.gz
Change DynASM bit operations to use Lua BitOp.
Diffstat (limited to 'dynasm/dasm_arm.lua')
-rw-r--r--dynasm/dasm_arm.lua73
1 files changed, 32 insertions, 41 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