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