9e4bc81ddb0bd780ac79d7ad338d702cf6ad6bfc
[openpower-isa.git] / src / openpower / decoder / power_pseudo.py
1 # Based on GardenSnake - a parser generator demonstration program
2 # GardenSnake was released into the Public Domain by Andrew Dalke.
3
4 # Portions of this work are derived from Python's Grammar definition
5 # and may be covered under the Python copyright and license
6 #
7 # Andrew Dalke / Dalke Scientific Software, LLC
8 # 30 August 2006 / Cape Town, South Africa
9
10 # Modifications for inclusion in PLY distribution
11 import sys
12 from pprint import pprint
13 from copy import copy
14 from ply import lex, yacc
15 import astor
16 import ast
17
18 from openpower.decoder.power_decoder import create_pdecode
19 from nmigen.back.pysim import Simulator, Delay
20 from nmigen import Module, Signal
21
22 from openpower.decoder.pseudo.parser import GardenSnakeCompiler
23 from openpower.decoder.selectable_int import SelectableInt, selectconcat
24 from openpower.decoder.isa.caller import GPR, Mem
25
26
27 ####### Test code #######
28
29 bpermd = r"""
30 perm <- [0] * 8
31 if index < 64:
32 index <- (RS)[8*i:8*i+7]
33 RA <- [0]*56 || perm[0:7]
34 print (RA)
35 """
36
37 bpermd = r"""
38 if index < 64 then index <- 0
39 else index <- 5
40 do while index < 5
41 index <- 0
42 leave
43 for i = 0 to 7
44 index <- 0
45 """
46
47 _bpermd = r"""
48 for i = 0 to 7
49 index <- (RS)[8*i:8*i+7]
50 if index < 64 then
51 permi <- (RB)[index]
52 else
53 permi <- 0
54 RA <- [0]*56|| perm[0:7]
55 """
56
57 cnttzd = """
58 n <- 0
59 do while n < 64
60 print (n)
61 if (RS)[63-n] = 0b1 then
62 leave
63 n <- n + 1
64 RA <- EXTZ64(n)
65 print (RA)
66 """
67
68 cmpi = """
69 if a < EXTS(SI) then
70 c <- 0b100
71 else if a > EXTS(SI) then
72 c <- 0b010
73 """
74
75 cmpi = """
76 RA[0:1] <- 0b11
77 """
78
79 cmpi = """
80 in_range <- ((x | y) &
81 (a | b))
82 in_range <- (x + y) - (a + b)
83 """
84
85 cmpi = """
86 (RA)[0:1] <- 1
87 src1 <- EXTZ((RA)[56:63])
88 CR[4*BF+32] <- 0b0
89 in_range <- src21lo <= src1 & src1 <= src21hi
90 """
91
92 cmpeqb = """
93 src1 <- GPR[RA]
94 src1 <- src1[0:56]
95 """
96
97 addpcis = """
98 D <- d0||d1||d2
99 """
100
101 testmul = """
102 x <- [0] * 16
103 RT <- (RA) + EXTS(SI || [0]*16)
104 """
105
106 testgetzero = """
107 RS <- (RA|0)
108 RS <- RS + 1
109 print(RS)
110 """
111
112 testcat = """
113 RT <- (load_data[56:63] || load_data[48:55]
114 || load_data[40:47] || load_data[32:39]
115 || load_data[24:31] || load_data[16:23]
116 || load_data[8:15] || load_data[0:7])
117 """
118
119 testgpr = """
120 GPR(5) <- x
121 """
122 testmem = """
123 a <- (RA|0)
124 b <- (RB|0)
125 RA <- MEM(RB, 2)
126 EA <- a + 1
127 MEM(EA, 1) <- (RS)[56:63]
128 RB <- RA
129 RA <- EA
130 """
131
132 testgprslice = """
133 MEM(EA, 4) <- GPR(r)[32:63]
134 #x <- x[0][32:63]
135 """
136
137 testdo = r"""
138 do i = 0 to 7
139 print(i)
140 """
141
142 testcond = """
143 ctr_ok <- BO[2] | ((CTR[M:63] != 0) ^ BO[3])
144 cond_ok <- BO[0] | ¬(CR[BI+32] ^ BO[1])
145 """
146
147 lswx = """
148 if RA = 0 then EA <- 0
149 else EA <- (RA)
150 if NB = 0 then n <- 32
151 else n <- NB
152 r <- RT - 1
153 i <- 32
154 do while n > 0
155 if i = 32 then
156 r <- (r + 1) % 32
157 GPR(r) <- 0
158 GPR(r)[i:i+7] <- MEM(EA, 1)
159 i <- i + 8
160 if i = 64 then i <- 32
161 EA <- EA + 1
162 n <- n - 1
163 """
164
165 _lswx = """
166 GPR(r)[x] <- 1
167 """
168
169 switchtest = """
170 switch (n)
171 case(1): x <- 5
172 case(2): fallthrough
173 case(3):
174 x <- 3
175 case(4): fallthrough
176 default:
177 x <- 9
178 """
179
180 hextest = """
181 RT <- 0x0001_a000_0000_0000
182 """
183
184 code = hextest
185 #code = lswx
186 #code = testcond
187 #code = testdo
188 #code = _bpermd
189 #code = testmul
190 #code = testgetzero
191 #code = testcat
192 #code = testgpr
193 #code = testmem
194 #code = testgprslice
195 #code = testreg
196 #code = cnttzd
197 #code = cmpi
198 #code = cmpeqb
199 #code = addpcis
200 #code = bpermd
201
202
203 def tolist(num):
204 l = []
205 for i in range(64):
206 l.append(1 if (num & (1 << i)) else 0)
207 l.reverse()
208 return l
209
210
211 def get_reg_hex(reg):
212 return hex(reg.value)
213
214
215 def convert_to_pure_python(pcode):
216
217 gsc = GardenSnakeCompiler(form=None, incl_carry=False)
218
219 tree = gsc.compile(pcode, mode="exec", filename="string")
220 tree = ast.fix_missing_locations(tree)
221 return astor.to_source(tree)
222
223
224 def convert_to_python(pcode, form, incl_carry):
225
226 print("form", form)
227 gsc = GardenSnakeCompiler(form=form, incl_carry=incl_carry)
228
229 tree = gsc.compile(pcode, mode="exec", filename="string")
230 tree = ast.fix_missing_locations(tree)
231 regsused = {'read_regs': gsc.parser.read_regs,
232 'write_regs': gsc.parser.write_regs,
233 'uninit_regs': gsc.parser.uninit_regs,
234 'special_regs': gsc.parser.special_regs,
235 'op_fields': gsc.parser.op_fields}
236 return astor.to_source(tree), regsused
237
238
239 def test():
240
241 gsc = GardenSnakeCompiler(debug=True)
242
243 gsc.regfile = {}
244 for i in range(32):
245 gsc.regfile[i] = i
246 gsc.gpr = GPR(gsc.parser.sd, gsc.regfile)
247 gsc.mem = Mem()
248
249 _compile = gsc.compile
250
251 tree = _compile(code, mode="single", filename="string")
252 tree = ast.fix_missing_locations(tree)
253 print(ast.dump(tree))
254
255 print("astor dump")
256 print(astor.dump_tree(tree))
257 print("to source")
258 source = astor.to_source(tree)
259 print(source)
260
261 # sys.exit(0)
262
263 # Set up the GardenSnake run-time environment
264 def print_(*args):
265 print("args", args)
266 print("-->", " ".join(map(str, args)))
267
268 from openpower.decoder.helpers import (EXTS64, EXTZ64, ROTL64, ROTL32, MASK,
269 trunc_div, trunc_rem)
270
271 d = {}
272 d["print"] = print_
273 d["EXTS64"] = EXTS64
274 d["EXTZ64"] = EXTZ64
275 d["trunc_div"] = trunc_div
276 d["trunc_rem"] = trunc_rem
277 d["SelectableInt"] = SelectableInt
278 d["concat"] = selectconcat
279 d["GPR"] = gsc.gpr
280 d["MEM"] = gsc.mem
281 d["memassign"] = gsc.mem.memassign
282
283 form = 'X'
284 gsc.gpr.set_form(form)
285 getform = gsc.parser.sd.sigforms[form]._asdict()
286 #print ("getform", form)
287 # for k, f in getform.items():
288 #print (k, f)
289 #d[k] = getform[k]
290
291 compiled_code = compile(source, mode="exec", filename="<string>")
292
293 m = Module()
294 comb = m.d.comb
295 instruction = Signal(32)
296
297 m.submodules.decode = decode = gsc.parser.sd
298 comb += decode.raw_opcode_in.eq(instruction)
299 sim = Simulator(m)
300
301 instr = [0x11111117]
302
303 def process():
304 for ins in instr:
305 print("0x{:X}".format(ins & 0xffffffff))
306
307 # ask the decoder to decode this binary data (endian'd)
308 yield decode.bigendian.eq(0) # little / big?
309 yield instruction.eq(ins) # raw binary instr.
310 yield Delay(1e-6)
311
312 # uninitialised regs, drop them into dict for function
313 for rname in gsc.parser.uninit_regs:
314 d[rname] = SelectableInt(0, 64) # uninitialised (to zero)
315 print("uninitialised", rname, hex(d[rname].value))
316
317 # read regs, drop them into dict for function
318 for rname in gsc.parser.read_regs:
319 regidx = yield getattr(decode.sigforms['X'], rname)
320 d[rname] = gsc.gpr[regidx] # contents of regfile
321 d["_%s" % rname] = regidx # actual register value
322 print("read reg", rname, regidx, hex(d[rname].value))
323
324 exec(compiled_code, d) # code gets executed here in dict "d"
325 print("Done")
326
327 print(d.keys()) # shows the variables that may have been created
328
329 print(decode.sigforms['X'])
330 x = yield decode.sigforms['X'].RS
331 ra = yield decode.sigforms['X'].RA
332 rb = yield decode.sigforms['X'].RB
333 print("RA", ra, d['RA'])
334 print("RB", rb, d['RB'])
335 print("RS", x)
336
337 for wname in gsc.parser.write_regs:
338 reg = getform[wname]
339 regidx = yield reg
340 print("write regs", regidx, wname, d[wname], reg)
341 gsc.gpr[regidx] = d[wname]
342
343 sim.add_process(process)
344 with sim.write_vcd("simulator.vcd", "simulator.gtkw",
345 traces=decode.ports()):
346 sim.run()
347
348 gsc.gpr.dump()
349
350 for i in range(0, len(gsc.mem.mem), 16):
351 hexstr = []
352 for j in range(16):
353 hexstr.append("%02x" % gsc.mem.mem[i+j])
354 hexstr = ' '.join(hexstr)
355 print("mem %4x" % i, hexstr)
356
357
358 if __name__ == '__main__':
359 test()