sh-dis/generate.py

89 lines
3.4 KiB
Python

from instruction_table import untabulate_instructions
mode_name = {
'': 'no_operand',
'Rn': 'destination_operand_only',
'Rm': 'destination_operand_only',
'Rm,Rn': 'source_and_destination_operands',
'Rm,SR': 'transfer_to_sr',
'Rm,GBR': 'transfer_to_gbr',
'Rm,VBR': 'transfer_to_vbr',
'Rm,MACH': 'transfer_to_mach',
'Rm,MACL': 'transfer_to_macl',
'Rm,PR': 'transfer_to_pr',
'SR,Rn': 'transfer_from_sr',
'GBR,Rn': 'transfer_from_gbr',
'VBR,Rn': 'transfer_from_vbr',
'MACH,Rn': 'transfer_from_mach',
'MACL,Rn': 'transfer_from_macl',
'PR,Rn': 'transfer_from_pr',
'@Rn': 'destination_operand_only',
'Rm,@Rn': 'store_register_direct_data_transfer',
'@Rm,Rn': 'load_register_direct_data_transfer',
'@Rm+,@Rn+': 'multiply_and_accumulate_operation',
'@Rm+,Rn': 'load_direct_data_transfer_from_register',
'@Rm+,SR': 'load_to_sr',
'@Rm+,GBR': 'load_to_gbr',
'@Rm+,VBR': 'load_to_vbr',
'@Rm+,MACH': 'load_to_mach',
'@Rm+,MACL': 'load_to_macl',
'@Rm+,PR': 'load_to_pr',
'Rm,@–Rn': 'store_direct_data_transfer_from_register',
'SR,@–Rn': 'store_from_sr',
'GBR,@–Rn': 'store_from_gbr',
'VBR,@–Rn': 'store_from_vbr',
'MACH,@–Rn': 'store_from_mach',
'MACL,@–Rn': 'store_from_macl',
'PR,@–Rn': 'store_from_pr',
'R0,@(disp,Rn)': 'store_register_indirect_with_displacement',
'Rm,@(disp,Rn)': 'store_register_indirect_with_displacement',
'@(disp,Rm),R0': 'load_register_indirect_with_displacement',
'@(disp,Rm),Rn': 'load_register_indirect_with_displacement',
'Rm,@(R0,Rn)': 'store_indexed_register_indirect',
'@(R0,Rm),Rn': 'load_indexed_register_indirect',
'R0,@(disp,GBR)': 'store_gbr_indirect_with_displacement',
'@(disp,GBR),R0': 'load_gbr_indirect_with_displacement',
'#imm,@(R0,GBR)': 'store_indexed_gbr_indirect',
'@(R0,GBR),#imm': 'load_indexed_gbr_indirect',
'@(disp,PC),Rn': 'pc_relative_with_displacement',
'@(disp,PC),R0': 'pc_relative_with_displacement',
'label': 'pc_relative',
'#imm,Rn': 'immediate',
'#imm,R0': 'immediate',
'#imm': 'immediate',
}
def sanitize_instruction(ins):
name = ins.instruction.replace('.', '_').replace('/', '_').lower()
assert ins.operands in mode_name, (ins.instruction, ins.operands)
mode = mode_name[ins.operands]
return '__'.join([name, mode])
def main():
function_names = {}
instruction_table = untabulate_instructions()
for ins in instruction_table:
function_name = sanitize_instruction(ins)
instruction_operands = (ins.instruction, ins.operands)
assert function_name not in function_names, (instruction_operands, names[name])
function_names[function_name] = instruction_operands
if ins.variables:
args = f', {", ".join(ins.variables)}'
else:
args = ''
print(f"def {function_name}(cpu, mem{args}):")
print(f" # {ins.instruction} {ins.operands}")
print(f" raise NotImplementedError()")
print()
print("lookup = {")
for ins in instruction_table:
function_name = sanitize_instruction(ins)
i_space = ' ' * (len('CMP/STR') - len(ins.instruction))
o_space = ' ' * (len('@(disp,GBR),R0') - len(ins.operands))
print(f" ('{ins.instruction}'{i_space}, '{ins.operands}'{o_space}): {function_name},")
print("}")
if __name__ == "__main__":
main()