78 lines
1.6 KiB
Lua
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
|
||
|
|