ack/plat/linuxppc/emu/mkdispatcher.lua
2018-06-14 03:07:36 -07:00

78 lines
1.6 KiB
Lua

local function decode(line)
local _, _, bits = line:find("^([^ ]+) ")
if #bits ~= 32 then
error("'"..bits.."' isn't 32 bits long")
end
local fields = {}
local i = 1
while i ~= 33 do
local c = line:sub(i, i)
if c ~= "." then
local f = { pos=i }
if c:find("%w") then
f.size = 1
f.value = c
elseif c == "<" then
local _, newi, name = line:find("^<%-*(%w+)%-*>", i)
f.size = 1 + newi - i
f.value = name
i = newi
else
error("bad field char '"..c.."' in '"..line.."'")
end
if f.value:find("[0-9]+") then
f.literal = true
f.variable = false
else
f.literal = false
f.variable = true
end
-- Convert from PowerPC numbering to sane numbering
f.pos = 33-(f.pos + f.size)
fields[#fields+1] = f
end
i = i + 1
end
return fields
end
local function emit(fields, code)
local mask = 0
local value = 0
for _, f in ipairs(fields) do
if f.literal then
local s = math.pow(2, f.pos)
local m = math.pow(2, f.size) - 1
mask = mask + m*s
value = value + f.value*s
end
end
print(string.format("if ((value & 0x%x) == 0x%x) {", mask, value))
for _, f in ipairs(fields) do
if f.variable then
local m = math.pow(2, f.size) - 1
print(string.format("uint32_t %s = (value >> %d) & 0x%x;", f.value, f.pos, m))
end
end
print(code)
print("return;")
print("}")
end
while true do
local line = io.stdin:read("*l")
if not line then
break
end
line = line:gsub("#.*$", "")
line = line:gsub(" *$", "")
if line ~= "" then
local fields = decode(line)
emit(fields, line:sub(34, #line))
end
end