summaryrefslogtreecommitdiff
path: root/parse-opcodes
diff options
context:
space:
mode:
authorGravatar Andrew Waterman <waterman@s141.Millennium.Berkeley.EDU>2010-07-18 18:28:05 -0700
committerGravatar Andrew Waterman <waterman@s141.Millennium.Berkeley.EDU>2010-07-18 18:28:05 -0700
commit491e8f77c1e8fb1d2dce0df5e7f12000ce1da859 (patch)
tree798c1e7bab3f0fbdd2c5731956cc61242e9fd2a7 /parse-opcodes
Reorganized directory structure
Moved cross-compiler to /xcc/ rather than / Added ISA sim in /sim/ Added Proxy Kernel in /pk/ (to be cleaned up) Added opcode map to /opcodes/ (ditto) Added documentation to /doc/
Diffstat (limited to 'parse-opcodes')
-rwxr-xr-xparse-opcodes115
1 files changed, 115 insertions, 0 deletions
diff --git a/parse-opcodes b/parse-opcodes
new file mode 100755
index 0000000..6c735d3
--- /dev/null
+++ b/parse-opcodes
@@ -0,0 +1,115 @@
+#!/usr/bin/python
+
+import math
+import sys
+import tokenize
+
+opcode_base = 26
+opcode_size = 6
+funct_base = 0
+funct_size = 6
+
+nopcode = 1 << opcode_size
+nfunct = 1 << funct_size
+opcodes = nopcode*[None]
+
+def binary(n, digits=0):
+ rep = bin(n)[2:]
+ return rep if digits == 0 else ('0' * (digits - len(rep))) + rep
+
+def make_latex_table(opcodes, captions, labels, upper_opcode=None):
+ if upper_opcode is None: print '% Automatically generated by parse-opcodes'
+ print '\\begin{table}[h]'
+ print '\\begin{center}'
+ print '\\begin{tabular}{r|c|c|c|c|c|c|c|c|}'
+ cols = 8
+ print '\\multicolumn{1}{r}{}&',
+ for i in range(cols):
+ print '\\multicolumn{1}{c}{%s}' % binary(i,int(math.log(cols,2))),('&' if i < cols-1 else '\\\\\n'),
+ print '\\cline{2-%d}' % (cols+1)
+ for opcode, insn in enumerate(opcodes):
+ if not opcode % cols: print binary(opcode/cols,int(math.log(nopcode/cols,2))),'&',
+ if isinstance(insn, list):
+ print 'Table \\ref{table:%s}' % labels[1] % {'opcode':opcode},
+ else:
+ print ' ' if insn is None else insn,
+ print '&' if (opcode+1) % cols else '\\\\\\cline{2-%d}\n' % (cols+1),
+ print '\\end{tabular}'
+ print '\\end{center}'
+ print '\\caption{%s}' % captions[0] % {'opcode':upper_opcode}
+ print '\\label{table:%s}' % labels[0] % {'opcode':upper_opcode}
+ print '\\end{table}'
+
+ for opcode, insn in enumerate(opcodes):
+ if isinstance(insn, list):
+ make_latex_table(insn, captions[1:], labels[1:], opcode)
+
+def make_disasm_table(opcodes, upper_opcode=None):
+ if upper_opcode is None: print '/* Automatically generated by parse-opcodes */'
+ for opcode, insn in enumerate(opcodes):
+ if isinstance(insn, list):
+ make_disasm_table(insn, opcode)
+ elif isinstance(insn, basestring):
+ mask = ((1 << opcode_size)-1) << opcode_base
+ if upper_opcode is None:
+ match = opcode << opcode_base
+ else:
+ mask |= ((1 << funct_size)-1) << funct_base
+ match = (upper_opcode << opcode_base) | (opcode << funct_base)
+ insn = insn.upper().replace('.','_')
+ print '#define MATCH_%s %s' % (insn, hex(match))
+ print '#define MASK_%s %s' % (insn, hex(mask))
+
+def make_switch(opcodes, upper_opcode=None):
+ if upper_opcode is None: print '/* Automatically generated by parse-opcodes */'
+ pad = '' if upper_opcode is None else ' '
+ print '%sswitch(%s)' % (pad,'opcode' if upper_opcode is None else 'funct')
+ print '%s{' % pad
+ for opcode, insn in enumerate(opcodes):
+ if insn is None: continue
+ print '%s case %d:' % (pad,opcode)
+ print '%s {' % pad
+ if isinstance(insn, list):
+ make_switch(insn, opcode)
+ else:
+ insn = insn.lower().replace('.','_')
+ print '%s #include "insns/%s.h"' % (pad,insn)
+ print '%s }' % pad
+ print '%s break;' % pad
+ print '%s default:' % pad
+ print '%s {' % pad
+ print '%s #include "insns/unimp.h"' % pad
+ print '%s }' % pad
+ print '%s break;' % pad
+ print '%s }' % pad
+
+for line in sys.stdin:
+ line = line.partition('#')
+ tokens = line[0].split()
+
+ if len(tokens) == 0:
+ continue
+ assert len(tokens) in [2,3]
+
+ opcode = int(tokens[1],0)
+ name = tokens[0].strip()
+ assert opcode < nopcode
+ assert not isinstance(opcodes[opcode], basestring)
+
+ if len(tokens) == 3:
+ funct = int(tokens[2],0)
+ if opcodes[opcode] is None:
+ opcodes[opcode] = nfunct*[None]
+ assert not isinstance(opcodes[opcode][funct], basestring)
+ opcodes[opcode][funct] = name
+ else:
+ opcodes[opcode] = name
+
+if sys.argv[1] == '-tex':
+ make_latex_table(opcodes, ['Instructions encoded by opcode field','Instructions encoded by funct field when opcode = %(opcode)d'], ['opcodes','opcode%(opcode)d'])
+elif sys.argv[1] == '-disasm':
+ make_disasm_table(opcodes)
+elif sys.argv[1] == '-switch':
+ make_switch(opcodes)
+else:
+ assert 0