Revert "skip broken test"
[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.isa.caller import inject
22 from openpower.decoder.helpers import (ISACallerHelper,
23 ne, eq, gt, ge, lt, le, ltu, gtu, length,
24 trunc_divs, trunc_rems, copy_assign_rhs,
25 )
26 from openpower.decoder.selectable_int import SelectableInt
27 from openpower.decoder.selectable_int import selectconcat as concat
28
29 # %s
30 """
31
32
33 class PyISAFnWriter(ISAFunctions):
34 def __init__(self):
35 ISAFunctions.__init__(self)
36 self.pages_written = []
37
38 def write_pysource(self, pagename):
39 self.pages_written.append(pagename)
40 function = self.fns[pagename]
41 isadir = get_isafn_src_dir()
42 os.makedirs(isadir, exist_ok=True)
43 fname = os.path.join(isadir, "%s.py" % pagename)
44 sourcecache = dict()
45 check_in_gitignore(fname)
46 with open(fname, "w") as f:
47 f.write(header % function['desc']) # write out header
48 # go through all instructions
49 pcode = function['pcode']
50 print(pcode)
51 # check if the code has already been compiled
52 phash = hash(pcode)
53 if phash in sourcecache:
54 pycode = sourcecache[phash]
55 else:
56 filename = os.path.join(get_isafn_dir(), pagename + ".mdwn")
57 pycode = convert_to_pure_python(pcode, True, filename=filename)
58 sourcecache[phash] = pycode
59 # sigh ok, anything as a function needs an "@inject()" in front
60 # but it is too late here: the code has already been written out.
61 # therefore scan lines looking for "def ..." at the front. it works.
62 res = []
63 for line in pycode.split('\n'):
64 if line.startswith("class ISACallerFnHelper("):
65 line = line.replace("(", "_%s(" % pagename)
66 elif line.startswith(" def "):
67 res.append(" @inject()")
68 res.append(line)
69 pycode = '\n'.join(res)
70 f.write(pycode)
71
72 def write_isa_class(self):
73 isadir = get_isafn_src_dir()
74 fname = os.path.join(isadir, "all.py")
75
76 with open(fname, "w") as f:
77 helpers = []
78 f.write('# auto-generated by pyfnwriter.py do not edit or commit\n')
79 f.write('from openpower.decoder.helpers import ISACallerHelper\n')
80 for page in self.pages_written:
81 module = 'openpower.decoder.isafunctions.' + page
82 helper = 'ISACallerFnHelper_' + page
83 helpers.append(helper)
84 f.write('from %s import ISACallerFnHelper_%s\n' % \
85 (module, page))
86 f.write('\n')
87 f.write('\n')
88 f.write('class ISACallerFnHelper(%s):\n' % ', '.join(helpers))
89 f.write(' pass\n')
90
91
92 def pyfnwriter():
93 isa = PyISAFnWriter()
94 write_isa_class = True
95 if len(sys.argv) == 1: # quick way to do it
96 print(dir(isa))
97 sources = isa.fns.keys()
98 else:
99 sources = sys.argv[1:]
100 if sources[0] == "noall": # don't rewrite all.py
101 write_isa_class = False
102 sources.pop(0)
103 print ("sources", write_isa_class, sources)
104 for source in sources:
105 isa.write_pysource(source)
106 if write_isa_class:
107 isa.write_isa_class()
108
109 if __name__ == '__main__':
110 pyfnwriter()