#!/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