diff options
author | Andrew Waterman <waterman@s141.Millennium.Berkeley.EDU> | 2011-05-29 04:11:39 -0700 |
---|---|---|
committer | Andrew Waterman <waterman@s141.Millennium.Berkeley.EDU> | 2011-05-29 04:11:39 -0700 |
commit | 5e60fcf8088985b7dd8e6a5cd6e5d093e5b70399 (patch) | |
tree | ff2a7805b480f3ae7a66acba16c3471fab105cc7 | |
parent | af726e3d9d91e2ed942175085e5defaa2296fc44 (diff) | |
download | riscv-opcodes-5e60fcf8088985b7dd8e6a5cd6e5d093e5b70399.zip riscv-opcodes-5e60fcf8088985b7dd8e6a5cd6e5d093e5b70399.tar.gz riscv-opcodes-5e60fcf8088985b7dd8e6a5cd6e5d093e5b70399.tar.bz2 |
[sim,opcodes] improved sim build and run performance
-rwxr-xr-x | parse-opcodes | 105 | ||||
-rwxr-xr-x | update-opcodes | 2 |
2 files changed, 60 insertions, 47 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 diff --git a/update-opcodes b/update-opcodes index 75121e8..6f88671 100755 --- a/update-opcodes +++ b/update-opcodes @@ -3,4 +3,4 @@ ./parse-opcodes -verilog < opcodes > inst.v ./parse-opcodes -disasm < opcodes > ../xcc/src/include/opcode/mips-riscv-opc.h ./parse-opcodes -disasm < opcodes > ../pk/pk/riscv-opc.h -./parse-opcodes -switch < opcodes > ../sim/riscv/execute.h +./parse-opcodes -switch ../sim/riscv < opcodes |