aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>2011-05-29 04:11:39 -0700
committerAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>2011-05-29 04:11:39 -0700
commit5e60fcf8088985b7dd8e6a5cd6e5d093e5b70399 (patch)
treeff2a7805b480f3ae7a66acba16c3471fab105cc7
parentaf726e3d9d91e2ed942175085e5defaa2296fc44 (diff)
downloadriscv-opcodes-5e60fcf8088985b7dd8e6a5cd6e5d093e5b70399.zip
riscv-opcodes-5e60fcf8088985b7dd8e6a5cd6e5d093e5b70399.tar.gz
riscv-opcodes-5e60fcf8088985b7dd8e6a5cd6e5d093e5b70399.tar.bz2
[sim,opcodes] improved sim build and run performance
-rwxr-xr-xparse-opcodes105
-rwxr-xr-xupdate-opcodes2
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