replace print() with log()
[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 os
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.sim 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 from openpower.util import log
26
27
28 ####### Test code #######
29
30 bpermd = r"""
31 perm <- [0] * 8
32 if index < 64:
33 index <- (RS)[8*i:8*i+7]
34 RA <- [0]*56 || perm[0:7]
35 print (RA)
36 """
37
38 bpermd = r"""
39 if index < 64 then index <- 0
40 else index <- 5
41 do while index < 5
42 index <- 0
43 leave
44 for i = 0 to 7
45 index <- 0
46 """
47
48 _bpermd = r"""
49 for i = 0 to 7
50 index <- (RS)[8*i:8*i+7]
51 if index < 64 then
52 permi <- (RB)[index]
53 else
54 permi <- 0
55 RA <- [0]*56|| perm[0:7]
56 """
57
58 cnttzd = """
59 n <- 0
60 do while n < 64
61 print (n)
62 if (RS)[63-n] = 0b1 then
63 leave
64 n <- n + 1
65 RA <- EXTZ64(n)
66 print (RA)
67 """
68
69 cmpi = """
70 if a < EXTS(SI) then
71 c <- 0b100
72 else if a > EXTS(SI) then
73 c <- 0b010
74 """
75
76 cmpi = """
77 RA[0:1] <- 0b11
78 """
79
80 cmpi = """
81 in_range <- ((x | y) &
82 (a | b))
83 in_range <- (x + y) - (a + b)
84 """
85
86 cmpi = """
87 (RA)[0:1] <- 1
88 src1 <- EXTZ((RA)[56:63])
89 CR[4*BF+32] <- 0b0
90 in_range <- src21lo <= src1 & src1 <= src21hi
91 """
92
93 cmpeqb = """
94 src1 <- GPR[RA]
95 src1 <- src1[0:56]
96 """
97
98 addpcis = """
99 D <- d0||d1||d2
100 """
101
102 testmul = """
103 x <- [0] * 16
104 RT <- (RA) + EXTS(SI || [0]*16)
105 """
106
107 testgetzero = """
108 RS <- (RA|0)
109 RS <- RS + 1
110 print(RS)
111 """
112
113 testcat = """
114 RT <- (load_data[56:63] || load_data[48:55]
115 || load_data[40:47] || load_data[32:39]
116 || load_data[24:31] || load_data[16:23]
117 || load_data[8:15] || load_data[0:7])
118 """
119
120 testgpr = """
121 GPR(5) <- x
122 """
123 testmem = """
124 a <- (RA|0)
125 b <- (RB|0)
126 RA <- MEM(RB, 2)
127 EA <- a + 1
128 MEM(EA, 1) <- (RS)[56:63]
129 RB <- RA
130 RA <- EA
131 """
132
133 testgprslice = """
134 MEM(EA, 4) <- GPR(r)[32:63]
135 #x <- x[0][32:63]
136 """
137
138 testdo = r"""
139 do i = 0 to 7
140 print(i)
141 """
142
143 testcond = """
144 ctr_ok <- BO[2] | ((CTR[M:63] != 0) ^ BO[3])
145 cond_ok <- BO[0] | ¬(CR[BI+32] ^ BO[1])
146 """
147
148 lswx = """
149 if RA = 0 then EA <- 0
150 else EA <- (RA)
151 if NB = 0 then n <- 32
152 else n <- NB
153 r <- RT - 1
154 i <- 32
155 do while n > 0
156 if i = 32 then
157 r <- (r + 1) % 32
158 GPR(r) <- 0
159 GPR(r)[i:i+7] <- MEM(EA, 1)
160 i <- i + 8
161 if i = 64 then i <- 32
162 EA <- EA + 1
163 n <- n - 1
164 """
165
166 _lswx = """
167 GPR(r)[x] <- 1
168 """
169
170 switchtest = """
171 switch (n)
172 case(1): x <- 5
173 case(2): fallthrough
174 case(3):
175 x <- 3
176 case(4): fallthrough
177 default:
178 x <- 9
179 """
180
181 hextest = """
182 RT <- 0x0001_a000_0000_0000
183 """
184
185 SVSTATE_next = """
186 SVSTATE_NEXT(5)
187 """
188
189 logictest = """
190 x <- (y * 5) + 3
191 y <- (z + 5) * 3
192 """
193
194 XLEN_test = """
195 RA[XLEN:XLEN - 1]
196 """
197
198 concat_test1 = """
199 [0]*16
200 """
201
202 concat_test2 = """
203 [0]*(XLEN-16)
204 """
205
206 concat_test3 = """
207 [0]*XLEN
208 """
209
210 assign_test = """
211 prod[0:63] <- 5
212 prod[0:XLEN-1] <- 5
213 """
214
215 assign_test2 = """
216 prod[0:XLEN-1] <- 5
217 """
218
219 assign_test = """
220 prod[0:XLEN-1] <- MULS((RA)[XLEN/2:XLEN-1], (RB)[XLEN/2:XLEN-1])
221 RT[XLEN/2:XLEN-1] <- prod[0:(XLEN/2)-1]
222 RT[0:(XLEN/2)-1] <- undefined(prod[0:(XLEN/2)-1])
223 """
224
225 code = assign_test
226 #code = concat_test3
227 #code = concat_test1
228 #code = XLEN_test
229 #code = logictest
230 #code = SVSTATE_next
231 #code = hextest
232 #code = lswx
233 #code = testcond
234 #code = testdo
235 #code = _bpermd
236 #code = testmul
237 #code = testgetzero
238 #code = testcat
239 #code = testgpr
240 #code = testmem
241 #code = testgprslice
242 #code = testreg
243 #code = cnttzd
244 #code = cmpi
245 #code = cmpeqb
246 #code = addpcis
247 #code = bpermd
248
249
250 def tolist(num):
251 l = []
252 for i in range(64):
253 l.append(1 if (num & (1 << i)) else 0)
254 l.reverse()
255 return l
256
257
258 def get_reg_hex(reg):
259 return hex(reg.value)
260
261
262 def convert_to_pure_python(pcode, helper=False, filename="string"):
263
264 gsc = GardenSnakeCompiler(form=None, incl_carry=False, helper=helper)
265
266 tree = gsc.compile(pcode, mode="exec", filename=filename)
267 tree = ast.fix_missing_locations(tree)
268 return astor.to_source(tree)
269
270
271 def convert_to_python(pcode, form, incl_carry, helper=False, filename="string"):
272
273 log("form", form)
274 gsc = GardenSnakeCompiler(form=form, incl_carry=incl_carry, helper=helper)
275
276 tree = gsc.compile(pcode, mode="exec", filename=filename)
277 tree = ast.fix_missing_locations(tree)
278 regsused = {'read_regs': gsc.parser.read_regs,
279 'write_regs': gsc.parser.write_regs,
280 'uninit_regs': gsc.parser.uninit_regs,
281 'special_regs': gsc.parser.special_regs,
282 'op_fields': gsc.parser.op_fields}
283 return astor.to_source(tree), regsused
284
285
286 def check_in_gitignore(output_file):
287 gitignore_file = os.path.join(os.path.dirname(output_file), ".gitignore")
288 base_name = os.path.basename(output_file)
289 with open(gitignore_file, "r") as f:
290 for l in f.readlines():
291 l = l.strip()
292 if "/" + base_name == l:
293 return
294 if l == "*.py":
295 if base_name.endswith(".py"):
296 return
297 raise ValueError(f"generated output file not in .gitignore:\n"
298 f"output file: {output_file}\n"
299 f".gitignore file: {gitignore_file}")
300
301
302 def test():
303
304 gsc = GardenSnakeCompiler(debug=True)
305
306 gsc.regfile = {}
307 for i in range(32):
308 gsc.regfile[i] = i
309 gsc.gpr = GPR(None, None, None, gsc.regfile)
310 gsc.mem = Mem()
311
312 _compile = gsc.compile
313
314 tree = _compile(code, mode="single", filename="string")
315 tree = ast.fix_missing_locations(tree)
316 log(ast.dump(tree))
317
318 log("astor dump")
319 log(astor.dump_tree(tree))
320 log("to source")
321 source = astor.to_source(tree)
322 log(source)
323
324 # sys.exit(0)
325
326 # Set up the GardenSnake run-time environment
327 def print_(*args):
328 print("args", args)
329 print("-->", " ".join(map(str, args)))
330
331 from openpower.decoder.helpers import (EXTS64, EXTZ64, ROTL64, ROTL32, MASK,
332 trunc_div, trunc_rem)
333
334 d = {}
335 d["print"] = print_
336 d["EXTS64"] = EXTS64
337 d["EXTZ64"] = EXTZ64
338 d["trunc_div"] = trunc_div
339 d["trunc_rem"] = trunc_rem
340 d["SelectableInt"] = SelectableInt
341 d["concat"] = selectconcat
342 d["GPR"] = gsc.gpr
343 d["MEM"] = gsc.mem
344 d["memassign"] = gsc.mem.memassign
345
346 form = 'X'
347 gsc.gpr.set_form(form)
348 getform = gsc.parser.sd.sigforms[form]._asdict()
349 #print ("getform", form)
350 # for k, f in getform.items():
351 #print (k, f)
352 #d[k] = getform[k]
353
354 compiled_code = compile(source, mode="exec", filename="<string>")
355
356 m = Module()
357 comb = m.d.comb
358 instruction = Signal(32)
359
360 m.submodules.decode = decode = gsc.parser.sd
361 comb += decode.raw_opcode_in.eq(instruction)
362 sim = Simulator(m)
363
364 instr = [0x11111117]
365
366 def process():
367 for ins in instr:
368 log("0x{:X}".format(ins & 0xffffffff))
369
370 # ask the decoder to decode this binary data (endian'd)
371 yield decode.bigendian.eq(0) # little / big?
372 yield instruction.eq(ins) # raw binary instr.
373 yield Delay(1e-6)
374
375 # uninitialised regs, drop them into dict for function
376 for rname in gsc.parser.uninit_regs:
377 d[rname] = SelectableInt(0, 64) # uninitialised (to zero)
378 log("uninitialised", rname, hex(d[rname].value))
379
380 # read regs, drop them into dict for function
381 for rname in gsc.parser.read_regs:
382 regidx = yield getattr(decode.sigforms['X'], rname)
383 d[rname] = gsc.gpr[regidx] # contents of regfile
384 d["_%s" % rname] = regidx # actual register value
385 log("read reg", rname, regidx, hex(d[rname].value))
386
387 exec(compiled_code, d) # code gets executed here in dict "d"
388 log("Done")
389
390 log(d.keys()) # shows the variables that may have been created
391
392 log(decode.sigforms['X'])
393 x = yield decode.sigforms['X'].RS
394 ra = yield decode.sigforms['X'].RA
395 rb = yield decode.sigforms['X'].RB
396 log("RA", ra, d['RA'])
397 log("RB", rb, d['RB'])
398 log("RS", x)
399
400 for wname in gsc.parser.write_regs:
401 reg = getform[wname]
402 regidx = yield reg
403 log("write regs", regidx, wname, d[wname], reg)
404 gsc.gpr[regidx] = d[wname]
405
406 sim.add_process(process)
407 with sim.write_vcd("simulator.vcd", "simulator.gtkw",
408 traces=decode.ports()):
409 sim.run()
410
411 gsc.gpr.dump()
412
413 for i in range(0, len(gsc.mem.mem), 16):
414 hexstr = []
415 for j in range(16):
416 hexstr.append("%02x" % gsc.mem.mem[i+j])
417 hexstr = ' '.join(hexstr)
418 log("mem %4x" % i, hexstr)
419
420
421 if __name__ == '__main__':
422 test()