2afc2d3c937f603ce71f24331c92a579d982cf11
[soc.git] / src / soc / decoder / pseudo / pywriter.py
1 # python code-writer for OpenPOWER ISA pseudo-code parsing
2
3 import os
4 import sys
5 from soc.decoder.pseudo.pagereader import ISA
6 from soc.decoder.power_pseudo import convert_to_python
7 from soc.decoder.orderedset import OrderedSet
8 from soc.decoder.isa.caller import create_args
9
10 def get_isasrc_dir():
11 fdir = os.path.abspath(os.path.dirname(__file__))
12 fdir = os.path.split(fdir)[0]
13 return os.path.join(fdir, "isa")
14
15
16 header = """\
17 # auto-generated by pywriter.py, do not edit or commit
18
19 from soc.decoder.isa.caller import inject
20 from soc.decoder.helpers import (EXTS, EXTS64, EXTZ64, ROTL64, ROTL32, MASK,)
21 from soc.decoder.selectable_int import SelectableInt
22 from soc.decoder.selectable_int import selectconcat as concat
23 from soc.decoder.orderedset import OrderedSet
24
25 class %s:
26
27 """
28
29 class PyISAWriter(ISA):
30 def __init__(self):
31 ISA.__init__(self)
32 self.pages_written = []
33
34 def write_pysource(self, pagename):
35 self.pages_written.append(pagename)
36 instrs = isa.page[pagename]
37 isadir = get_isasrc_dir()
38 fname = os.path.join(isadir, "%s.py" % pagename)
39 with open(fname, "w") as f:
40 iinf = ''
41 f.write(header % pagename) # write out header
42 # go through all instructions
43 for page in instrs:
44 d = self.instr[page]
45 print (fname, d.opcode)
46 pcode = '\n'.join(d.pcode) + '\n'
47 print (pcode)
48 pycode, rused = convert_to_python(pcode, d.form)
49 # create list of arguments to call
50 regs = list(rused['read_regs']) + list(rused['uninit_regs'])
51 args = ', '.join(create_args(regs, 'self'))
52 # create list of arguments to return
53 retargs = ', '.join(create_args(rused['write_regs']))
54 # write out function. pre-pend "op_" because some instrs are
55 # also python keywords (cmp). also replace "." with "_"
56 op_fname ="op_%s" % page.replace(".", "_")
57 f.write(" @inject()\n")
58 f.write(" def %s(%s):\n" % (op_fname, args))
59 pycode = pycode.split("\n")
60 pycode = '\n'.join(map(lambda x: " %s" % x, pycode))
61 pycode = pycode.rstrip()
62 f.write(pycode + '\n')
63 if retargs:
64 f.write(" return (%s,)\n\n" % retargs)
65 else:
66 f.write("\n")
67 # accumulate the instruction info
68 ops = repr(rused['op_fields'])
69 iinfo = """(%s, %s,
70 %s, %s,
71 %s, '%s')""" % (op_fname, rused['read_regs'],
72 rused['uninit_regs'], rused['write_regs'],
73 ops, d.form)
74 iinf += " %s_instrs['%s'] = %s\n" % (pagename, page, iinfo)
75 # write out initialisation of info, for ISACaller to use
76 f.write(" %s_instrs = {}\n" % pagename)
77 f.write(iinf)
78
79 def write_isa_class(self):
80 isadir = get_isasrc_dir()
81 fname = os.path.join(isadir, "all.py")
82
83 with open(fname, "w") as f:
84 f.write('from soc.decoder.isa.caller import ISACaller\n')
85 for page in self.pages_written:
86 f.write('from soc.decoder.isa.%s import %s\n' % (page, page))
87 f.write('\n')
88
89 classes = ', '.join(['ISACaller'] + self.pages_written)
90 f.write('class ISA(%s):\n' % classes)
91 f.write(' def __init__(self, dec, regs):\n')
92 f.write(' super().__init__(dec, regs)\n')
93 f.write(' self.instrs = {\n')
94 for page in self.pages_written:
95 f.write(' **self.%s_instrs,\n' % page)
96 f.write(' }\n')
97
98
99
100
101
102 if __name__ == '__main__':
103 isa = PyISAWriter()
104 if len(sys.argv) == 1: # quick way to do it
105 print (dir(isa))
106 sources = isa.page.keys()
107 else:
108 sources = sys.argv[1:]
109 for source in sources:
110 isa.write_pysource(source)
111 isa.write_isa_class()