Casio_asm/data/opcodes.lua

305 lines
11 KiB
Lua
Executable File

local patternInstruction="(E?)%s*(%d*)%s*([a-z_0-9]+)%s*(.*)"
local patternDecoderRule="(E?)%s*([a-z_0-9]+)%s+(-?%d[ds]?)"
local opcodeFile="opcode.list"
local decoderRuleFile="decoder.list"
local defineFile="../common/opcodeList.h"
local decoderSourceFile="../interpreter/decoder.c"
local decoderHeaderFile="../interpreter/decoder.h"
local decoderImpHeaderFile="../interpreter/decoderImp.h"
local executerSourceFile="../interpreter/executer.c"
local executerHeaderFile="../interpreter/executer.h"
local executerImpHeaderFile="../interpreter/executerImp.h"
local opcodeListSourceFile="../common/opcodeList.c"
-- first, parse instruction file
local instructions={}
local maxNameLen, maxDescLen=0, 0
local function readInstruction(line)
local extended, code, mnemonic, desc=line:match(patternInstruction)
local instruction={
extended=extended~='',
code=code~='' and tonumber(code) or nil,
mnemonic=mnemonic,
desc=#desc~=0 and desc or '[No description]'
}
if #instruction.mnemonic>maxNameLen then
maxNameLen=#instruction.mnemonic
end
if #instruction.desc>maxDescLen then
maxDescLen=#instruction.desc
end
table.insert(instructions, instruction)
return instruction
end
for line in io.lines(opcodeFile) do
if not (#line==0 or line:sub(1,1)=='#') then
readInstruction(line)
end
end
print("Total instruction count: "..#instructions)
-- second, parse decoder rules
local byRule={}
local function readDecoderRule(line)
local extended, mnemonic, rule=line:match(patternDecoderRule)
extended=extended~=''
local found=false
for i, instruction in ipairs(instructions) do
if instruction.mnemonic==mnemonic and instruction.extended==extended then
found=true
instruction.rule=rule
if not byRule[rule] then
byRule[rule]={}
end
table.insert(byRule[rule], instruction)
end
end
if not found then
error("Found rule for nonexistent instruction "..mnemonic)
end
end
for line in io.lines(decoderRuleFile) do
if not (#line==0 or line:sub(1,1)=='#') then
readDecoderRule(line)
end
end
for i, instruction in ipairs(instructions) do
if not instruction.rule then
error("Instruction "..instruction.mnemonic.." doesn't have a decoder rule")
end
end
-- now, let's assign them numbers
local normal={}
local extended={}
local function addInstruction(instruction, list, len)
if instruction.code then
list[instruction.code+1]=instruction
return instruction.code
end
local i
for i=1, len do
if not list[i] then
list[i]=instruction
instruction.code=i-1
return i-1
end
end
error("Not enough space in list to fit instruction "..instruction.mnemonic)
end
for k, instruction in ipairs(instructions) do
if instruction.extended then
addInstruction(instruction, extended, 256)
else
addInstruction(instruction, normal, 64)
end
end
-- now, let's write these goddamn files
defineFile=io.open(defineFile, "w+")
defineFile:write("#ifndef OPCODE_LIST\n#define OPCODE_LIST\n\n")
defineFile:write("void Opcode_registerOpcodes();\n\n")
local count, extendedCount=0, 0
for i=1, 64 do
local instruction=normal[i]
if instruction then
count=count+1
defineFile:write("#define OP_"..instruction.mnemonic.." "..instruction.code.."\n")
end
end
for i=1, 256 do
local instruction=extended[i]
if instruction then
extendedCount=extendedCount+1
defineFile:write("#define OP_E_"..instruction.mnemonic.." "..instruction.code.."\n")
end
end
defineFile:write("\n")
defineFile:write("#define OPCODE_COUNT "..count.."\n")
defineFile:write("#define OPCODE_EXT_COUNT "..extendedCount.."\n")
defineFile:write("#define OPCODE_NAME_LEN "..(maxNameLen+1).."\n")
defineFile:write("#define OPCODE_DESC_LEN "..(maxDescLen+1).."\n")
defineFile:write("\n#endif\n")
defineFile:close()
executerSourceFile=io.open(executerSourceFile, "w+")
executerSourceFile:write("#include \"executer.h\"\n\n")
executerSourceFile:write("void Proc_executeInstruction(proc_t *proc, opcode_data_t *instruction) {\n")
executerSourceFile:write("\tif(instruction->ext) {\n")
executerSourceFile:write("\t\tswitch(instruction->op) {\n")
for i=1, 256 do
local instruction=extended[i]
if instruction then
executerSourceFile:write("\t\t\tcase OP_E_"..instruction.mnemonic..":\n")
executerSourceFile:write("\t\t\t\tinstructionExt_"..instruction.mnemonic.."(proc, instruction);\n")
executerSourceFile:write("\t\t\t\tbreak;\n")
end
end
executerSourceFile:write("\t\t\tdefault:\n")
executerSourceFile:write("\t\t\t\tillegalInstruction(proc, instruction);\n")
executerSourceFile:write("\t\t}\n")
executerSourceFile:write("\t} else {\n")
executerSourceFile:write("\t\tswitch(instruction->op) {\n")
for i=1, 64 do
local instruction=normal[i]
if instruction then
executerSourceFile:write("\t\t\tcase OP_"..instruction.mnemonic..":\n")
executerSourceFile:write("\t\t\t\tinstruction_"..instruction.mnemonic.."(proc, instruction);\n")
executerSourceFile:write("\t\t\t\tbreak;\n")
end
end
executerSourceFile:write("\t\t\tdefault:\n")
executerSourceFile:write("\t\t\t\tillegalInstruction(proc, instruction);\n")
executerSourceFile:write("\t\t}\n")
executerSourceFile:write("\t}\n")
executerSourceFile:write("}\n")
executerSourceFile:close()
executerHeaderFile=io.open(executerHeaderFile, "w+")
executerHeaderFile:write("#ifndef EXECUTER_H\n")
executerHeaderFile:write("#define EXECUTER_H\n\n")
executerHeaderFile:write("#include \"../common/opcode.h\"\n")
executerHeaderFile:write("#include \"proc.h\"\n")
executerHeaderFile:write("#include \"executerImp.h\"\n\n")
executerHeaderFile:write("void Proc_executeInstruction(proc_t *proc, opcode_data_t *instruction);\n\n")
executerHeaderFile:write("#endif\n")
executerHeaderFile:close()
executerImpHeaderFile=io.open(executerImpHeaderFile, "w+")
executerImpHeaderFile:write("#ifndef EXECUTER_IMP_H\n")
executerImpHeaderFile:write("#define EXECUTER_IMP_H\n\n")
executerImpHeaderFile:write("#include \"proc.h\"\n")
executerImpHeaderFile:write("#include \"../common/opcode.h\"\n\n")
for i=1, 64 do
local instruction=normal[i]
if instruction then
executerImpHeaderFile:write("void instruction_"..instruction.mnemonic.."(proc_t *proc, opcode_data_t *instruction);\n")
end
end
executerImpHeaderFile:write("\n")
for i=1, 256 do
local instruction=extended[i]
if instruction then
executerImpHeaderFile:write("void instructionExt_"..instruction.mnemonic.."(proc_t *proc, opcode_data_t *instruction);\n")
end
end
executerImpHeaderFile:write("\n")
executerImpHeaderFile:write("void illegalInstruction(proc_t *proc, opcode_data_t *instruction);\n\n")
executerImpHeaderFile:write("#endif\n")
executerImpHeaderFile:close()
decoderSourceFile=io.open(decoderSourceFile, "w+")
decoderSourceFile:write("#include \"decoder.h\"\n")
decoderSourceFile:write("#include \"decoderImp.h\"\n\n")
decoderSourceFile:write("void Proc_decodeInstruction(proc_t *proc, opcode_t *op, opcode_data_t *instruction) {\n")
decoderSourceFile:write("\tinstruction->op=op->op;\n")
decoderSourceFile:write("\tinstruction->nArgs=op->nArgs;\n")
decoderSourceFile:write("\tinstruction->ext=0;\n")
decoderSourceFile:write("\tswitch(op->op) {\n")
for rule, list in pairs(byRule) do
local found=false
if rule:sub(1,1)~='-' then
for i, instruction in ipairs(list) do
if not instruction.extended then
decoderSourceFile:write("\t\tcase OP_"..instruction.mnemonic..":\n")
found=true
end
end
if found then
decoderSourceFile:write("\t\t\t// rule is "..rule.."\n")
decoderSourceFile:write("\t\t\tdecodeInstructionImp(proc, op, instruction, RULE_"..rule..");\n")
decoderSourceFile:write("\t\t\tbreak;\n")
end
end
end
decoderSourceFile:write("\t}\n")
decoderSourceFile:write("}\n\n")
decoderSourceFile:write("void Proc_decodeInstructionExt(proc_t *proc, opcode_ext_t *op, opcode_data_t *instruction) {\n")
decoderSourceFile:write("\tinstruction->op=op->op;\n")
decoderSourceFile:write("\tinstruction->nArgs=op->nArgs;\n")
decoderSourceFile:write("\tinstruction->ext=1;\n")
decoderSourceFile:write("\tswitch(op->op) {\n")
for rule, list in pairs(byRule) do
if rule:sub(1,1)~='-' then
local found=false
for i, instruction in ipairs(list) do
if instruction.extended then
decoderSourceFile:write("\t\tcase OP_E_"..instruction.mnemonic..":\n")
found=true
end
end
if found then
decoderSourceFile:write("\t\t\t// rule is "..rule.."\n")
decoderSourceFile:write("\t\t\tdecodeInstructionExtImp(proc, op, instruction, RULE_"..rule..");\n")
decoderSourceFile:write("\t\t\tbreak;\n")
end
end
end
decoderSourceFile:write("\t}\n")
decoderSourceFile:write("}\n")
decoderSourceFile:close()
decoderHeaderFile=io.open(decoderHeaderFile, "w+")
decoderHeaderFile:write("#ifndef DECODER_H\n")
decoderHeaderFile:write("#define DECODER_H\n\n")
decoderHeaderFile:write("#include \"proc.h\"\n")
decoderHeaderFile:write("#include \"../common/opcode.h\"\n\n")
decoderHeaderFile:write("void Proc_decodeInstruction(proc_t *proc, opcode_t *op, opcode_data_t *instruction);\n")
decoderHeaderFile:write("void Proc_decodeInstructionExt(proc_t *proc, opcode_ext_t *op, opcode_data_t *instruction);\n\n")
decoderHeaderFile:write("\n")
decoderHeaderFile:write("#endif\n")
decoderHeaderFile:close()
decoderImpHeaderFile=io.open(decoderImpHeaderFile, "w+")
decoderImpHeaderFile:write("#ifndef DECODER_IMP_H\n")
decoderImpHeaderFile:write("#define DECODER_IMP_H\n\n")
decoderImpHeaderFile:write("#include \"proc.h\"\n")
decoderImpHeaderFile:write("#include \"../common/opcode.h\"\n\n")
decoderImpHeaderFile:write("#include \"stack.h\"\n\n")
decoderImpHeaderFile:write("void decodeInstructionImp(proc_t *proc, opcode_t *op, opcode_data_t *instruction, char mode);\n")
decoderImpHeaderFile:write("void decodeInstructionExtImp(proc_t *proc, opcode_ext_t *op, opcode_data_t *instruction, char mode);\n\n")
local i=0
for rule in pairs(byRule) do
if rule:sub(1,1)~='-' then
decoderImpHeaderFile:write("#define RULE_"..rule.." "..i.."\n")
i=i+1
end
end
decoderImpHeaderFile:write("\n")
decoderImpHeaderFile:write("#endif\n")
decoderImpHeaderFile:close()
opcodeListSourceFile=io.open(opcodeListSourceFile, "w+")
opcodeListSourceFile:write("#include \"opcodeList.h\"\n")
opcodeListSourceFile:write("#include \"opcodeInfo.h\"\n\n")
opcodeListSourceFile:write("void Opcode_registerOpcodes() {\n")
opcodeListSourceFile:write("\tOpcode_init();\n")
for i=1, 64 do
local instruction=normal[i]
if instruction then
opcodeListSourceFile:write("\tOpcode_register(OP_"..instruction.mnemonic..", \""..instruction.mnemonic.."\", OPCODE_TYPE_NORMAL, \""..instruction.desc.."\");\n")
end
end
for i=1, 256 do
local instruction=extended[i]
if instruction then
opcodeListSourceFile:write("\tOpcode_register(OP_E_"..instruction.mnemonic..", \""..instruction.mnemonic.."\", OPCODE_TYPE_EXT, \""..instruction.desc.."\");\n")
end
end
opcodeListSourceFile:write("}\n")
opcodeListSourceFile:close()