diff options
Diffstat (limited to 'parse-opcodes')
-rwxr-xr-x | parse-opcodes | 105 |
1 files changed, 59 insertions, 46 deletions
diff --git a/parse-opcodes b/parse-opcodes index 5a34318..4cf0b84 100755 --- a/parse-opcodes +++ b/parse-opcodes @@ -85,51 +85,64 @@ def make_disasm_table(match,mask): print '#define MATCH_%s %s' % (name2, hex(match)) print '#define MASK_%s %s' % (name2, hex(mask[name])) -def make_switch(match,mask): - opcode_mask = ((1<<(opcode_base+opcode_size))-(1<<opcode_base)) - funct_mask = ((1<<(funct_base+funct_size))-(1<<funct_base)) - - print '/* Automatically generated by parse-opcodes */' - print 'switch((insn.bits >> 0x%x) & 0x%x)' % (opcode_base,(1<<opcode_size)-1) - print '{' - - for opc in range(0,1<<opcode_size): - has_some_instruction = 0 - for name in match.iterkeys(): - if ((opc << opcode_base) & mask[name]) == (match[name] & mask[name] & opcode_mask): - has_some_instruction = 1 - if not has_some_instruction: continue - - print ' case 0x%x:' % opc - print ' {' - done = 0 - for name in match.iterkeys(): - name2 = name.replace('.','_') - # case 0: opcode fully describes insn - if ((opc << opcode_base) & mask[name]) == match[name] and (opcode_mask & mask[name]) == mask[name]: - print ' #include "insns/%s.h"' % name2 - done = 1 - break - - if not done: - if not done: - for name in match.iterkeys(): - name2 = name.replace('.','_') - # case 2: general case: opcode + funct incompletely describe insn - if ((opc << opcode_base) & mask[name]) == (match[name] & opcode_mask): - print ' if((insn.bits & 0x%x) == 0x%x)' % (mask[name],match[name]) - print ' {' - print ' #include "insns/%s.h"' % name2 - print ' break;' - print ' }' - print ' throw_illegal_instruction;' - print ' break;' - print ' }' - print ' default:' - print ' {' - print ' throw_illegal_instruction;' - print ' }' - print '}' +def make_switch(match, mask, dir): + switch_base = 0 + switch_size = 10 + switch_mask = ((1<<(switch_base+switch_size))-(1<<switch_base)) + + f = open('%s/dispatch_decl.h' % dir, 'w') + f.write('/* Automatically generated by parse-opcodes */\n') + f.write('#define dispatch_index(insn) (((insn).bits >> %d) & %d)\n' % (switch_base, (1<<switch_size)-1)) + for opc in range(0,1<<switch_size): + f.write('reg_t opcode_func_%03x(insn_t insn, reg_t pc);\n' % opc) + f.close() + + f = open('%s/dispatch.h' % dir, 'w') + f.write('/* Automatically generated by parse-opcodes */\n') + f.write('typedef reg_t (*insn_func_t)(processor_t*, insn_t, reg_t);\n') + f.write('const static insn_func_t dispatch_table[] = {\n') + for opc in range(0,1<<switch_size): + f.write(' (insn_func_t)&processor_t::opcode_func_%03x,\n' % opc) + f.write('};\n') + f.close() + + nfiles = 10 + for file in range(0, nfiles): + f = open('%s/dispatch_%x.cc' % (dir, file), 'w') + f.write('#include "insn_includes.h"\n\n') + + for opc in range(0, 1<<switch_size): + if opc % nfiles != file: + continue + f.write('reg_t processor_t::opcode_func_%03x(insn_t insn, reg_t pc)\n' % opc) + f.write('{\n') + + has_some_instruction = 0 + exact = 0 + for name in match.iterkeys(): + if ((opc << switch_base) & mask[name]) == (match[name] & mask[name] & switch_mask): + has_some_instruction = 1 + if ((opc << switch_base) & mask[name]) == match[name] and (switch_mask & mask[name]) == mask[name]: + exact = 1 + + for name in match.iterkeys(): + name2 = name.replace('.','_') + if ((opc << switch_base) & mask[name]) == (match[name] & mask[name] & switch_mask): + if not exact: + f.write(' if((insn.bits & 0x%x) == 0x%x)\n' % (mask[name],match[name])) + f.write(' {\n') + f.write(' reg_t npc = pc + insn_length(0x%08x);\n' % match[name]) + f.write(' #include "insns/%s.h"\n' % name2) + f.write(' return npc;\n') + if not exact: + f.write(' }\n') + + if not exact: + f.write(' throw trap_illegal_instruction;\n') + + f.write('}\n\n') + + f.close() def yank(num,start,len): return (num >> start) & ((1 << len) - 1) @@ -826,6 +839,6 @@ elif sys.argv[1] == '-verilog': elif sys.argv[1] == '-disasm': make_disasm_table(match,mask) elif sys.argv[1] == '-switch': - make_switch(match,mask) + make_switch(match,mask,sys.argv[2]) else: assert 0 |