whoops, use cache of pseudocode rather than attempt to truncate
[openpower-isa.git] / src / openpower / decoder / pseudo / pyfnwriter.py
1 # python code-writer for OpenPOWER ISA pseudo-code parsing
2
3 import os
4 import sys
5 import shutil
6 import subprocess
7 from openpower.decoder.pseudo.functionreader import ISAFunctions
8 from openpower.decoder.power_pseudo import convert_to_pure_python
9
10
11 def get_isafn_src_dir():
12 fdir = os.path.abspath(os.path.dirname(__file__))
13 fdir = os.path.split(fdir)[0]
14 return os.path.join(fdir, "isafunctions")
15
16
17 header = """\
18 # auto-generated by pyfnwriter.py, do not edit or commit
19
20 from openpower.decoder.helpers import (ISACallerHelper,
21 ne, eq, gt, ge, lt, le, ltu, gtu, length,
22 trunc_divs, trunc_rems,
23 )
24 from openpower.decoder.selectable_int import SelectableInt
25 from openpower.decoder.selectable_int import selectconcat as concat
26
27 # %s
28 """
29
30
31 class PyISAFnWriter(ISAFunctions):
32 def __init__(self):
33 ISAFunctions.__init__(self)
34 self.pages_written = []
35
36 def write_pysource(self, pagename):
37 self.pages_written.append(pagename)
38 function = self.fns[pagename]
39 isadir = get_isafn_src_dir()
40 os.makedirs(isadir, exist_ok=True)
41 fname = os.path.join(isadir, "%s.py" % pagename)
42 sourcecache = dict()
43 with open(fname, "w") as f:
44 f.write(header % function['desc']) # write out header
45 # go through all instructions
46 pcode = function['pcode']
47 print(pcode)
48 # check if the code has already been compiled
49 phash = hash(pcode)
50 if phash in sourcecache:
51 pycode = sourcecache[phash]
52 else:
53 pycode = convert_to_pure_python(pcode, True)
54 sourcecache[phash] = pycode
55 f.write(pycode)
56
57 def write_isa_class(self):
58 isadir = get_isafn_src_dir()
59 fname = os.path.join(isadir, "all.py")
60
61 with open(fname, "w") as f:
62 helpers = []
63 f.write('# auto-generated by pyfnwriter.py: do not edit or commit\n')
64 f.write('from openpower.decoder.helpers import ISACallerHelper\n')
65 for page in self.pages_written:
66 module = 'openpower.decoder.isafunctions.' + page
67 helper = 'ISACallerFnHelper_' + page
68 helpers.append(helper)
69 f.write('from %s import ISACallerFnHelper as %s\n' % (module, helper))
70 f.write('\n')
71 f.write('\n')
72 f.write('class ISACallerFnHelper(%s):\n' % ', '.join(helpers + ['ISACallerHelper']))
73 f.write(' pass\n')
74
75
76 def pyfnwriter():
77 isa = PyISAFnWriter()
78 write_isa_class = True
79 if len(sys.argv) == 1: # quick way to do it
80 print(dir(isa))
81 sources = isa.fns.keys()
82 else:
83 sources = sys.argv[1:]
84 if sources[0] == "noall": # don't rewrite all.py
85 write_isa_class = False
86 sources.pop(0)
87 print ("sources", write_isa_class, sources)
88 for source in sources:
89 isa.write_pysource(source)
90 if write_isa_class:
91 isa.write_isa_class()
92
93 if __name__ == '__main__':
94 pyfnwriter()