test_caller_svp64_powmod: rename to test_aaa_caller_svp64_powmod so pytest tries...
[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
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 SVSTATE_next = """
185 SVSTATE_NEXT(5)
186 """
187
188 logictest = """
189 x <- (y * 5) + 3
190 y <- (z + 5) * 3
191 """
192
193 XLEN_test = """
194 RA[XLEN:XLEN - 1]
195 """
196
197 concat_test1 = """
198 [0]*16
199 """
200
201 concat_test2 = """
202 [0]*(XLEN-16)
203 """
204
205 concat_test3 = """
206 [0]*XLEN
207 """
208
209 assign_test = """
210 prod[0:63] <- 5
211 prod[0:XLEN-1] <- 5
212 """
213
214 assign_test2 = """
215 prod[0:XLEN-1] <- 5
216 """
217
218 assign_test = """
219 prod[0:XLEN-1] <- MULS((RA)[XLEN/2:XLEN-1], (RB)[XLEN/2:XLEN-1])
220 RT[XLEN/2:XLEN-1] <- prod[0:(XLEN/2)-1]
221 RT[0:(XLEN/2)-1] <- undefined(prod[0:(XLEN/2)-1])
222 """
223
224 code = assign_test
225 #code = concat_test3
226 #code = concat_test1
227 #code = XLEN_test
228 #code = logictest
229 #code = SVSTATE_next
230 #code = hextest
231 #code = lswx
232 #code = testcond
233 #code = testdo
234 #code = _bpermd
235 #code = testmul
236 #code = testgetzero
237 #code = testcat
238 #code = testgpr
239 #code = testmem
240 #code = testgprslice
241 #code = testreg
242 #code = cnttzd
243 #code = cmpi
244 #code = cmpeqb
245 #code = addpcis
246 #code = bpermd
247
248
249 def tolist(num):
250 l = []
251 for i in range(64):
252 l.append(1 if (num & (1 << i)) else 0)
253 l.reverse()
254 return l
255
256
257 def get_reg_hex(reg):
258 return hex(reg.value)
259
260
261 def convert_to_pure_python(pcode, helper=False, filename="string"):
262
263 gsc = GardenSnakeCompiler(form=None, incl_carry=False, helper=helper)
264
265 tree = gsc.compile(pcode, mode="exec", filename=filename)
266 tree = ast.fix_missing_locations(tree)
267 return astor.to_source(tree)
268
269
270 def convert_to_python(pcode, form, incl_carry, helper=False, filename="string"):
271
272 print("form", form)
273 gsc = GardenSnakeCompiler(form=form, incl_carry=incl_carry, helper=helper)
274
275 tree = gsc.compile(pcode, mode="exec", filename=filename)
276 tree = ast.fix_missing_locations(tree)
277 regsused = {'read_regs': gsc.parser.read_regs,
278 'write_regs': gsc.parser.write_regs,
279 'uninit_regs': gsc.parser.uninit_regs,
280 'special_regs': gsc.parser.special_regs,
281 'op_fields': gsc.parser.op_fields}
282 return astor.to_source(tree), regsused
283
284
285 def check_in_gitignore(output_file):
286 gitignore_file = os.path.join(os.path.dirname(output_file), ".gitignore")
287 base_name = os.path.basename(output_file)
288 with open(gitignore_file, "r") as f:
289 for l in f.readlines():
290 l = l.strip()
291 if "/" + base_name == l:
292 return
293 if l == "*.py":
294 if base_name.endswith(".py"):
295 return
296 raise ValueError(f"generated output file not in .gitignore:\n"
297 f"output file: {output_file}\n"
298 f".gitignore file: {gitignore_file}")
299
300
301 def test():
302
303 gsc = GardenSnakeCompiler(debug=True)
304
305 gsc.regfile = {}
306 for i in range(32):
307 gsc.regfile[i] = i
308 gsc.gpr = GPR(None, None, None, gsc.regfile)
309 gsc.mem = Mem()
310
311 _compile = gsc.compile
312
313 tree = _compile(code, mode="single", filename="string")
314 tree = ast.fix_missing_locations(tree)
315 print(ast.dump(tree))
316
317 print("astor dump")
318 print(astor.dump_tree(tree))
319 print("to source")
320 source = astor.to_source(tree)
321 print(source)
322
323 # sys.exit(0)
324
325 # Set up the GardenSnake run-time environment
326 def print_(*args):
327 print("args", args)
328 print("-->", " ".join(map(str, args)))
329
330 from openpower.decoder.helpers import (EXTS64, EXTZ64, ROTL64, ROTL32, MASK,
331 trunc_div, trunc_rem)
332
333 d = {}
334 d["print"] = print_
335 d["EXTS64"] = EXTS64
336 d["EXTZ64"] = EXTZ64
337 d["trunc_div"] = trunc_div
338 d["trunc_rem"] = trunc_rem
339 d["SelectableInt"] = SelectableInt
340 d["concat"] = selectconcat
341 d["GPR"] = gsc.gpr
342 d["MEM"] = gsc.mem
343 d["memassign"] = gsc.mem.memassign
344
345 form = 'X'
346 gsc.gpr.set_form(form)
347 getform = gsc.parser.sd.sigforms[form]._asdict()
348 #print ("getform", form)
349 # for k, f in getform.items():
350 #print (k, f)
351 #d[k] = getform[k]
352
353 compiled_code = compile(source, mode="exec", filename="<string>")
354
355 m = Module()
356 comb = m.d.comb
357 instruction = Signal(32)
358
359 m.submodules.decode = decode = gsc.parser.sd
360 comb += decode.raw_opcode_in.eq(instruction)
361 sim = Simulator(m)
362
363 instr = [0x11111117]
364
365 def process():
366 for ins in instr:
367 print("0x{:X}".format(ins & 0xffffffff))
368
369 # ask the decoder to decode this binary data (endian'd)
370 yield decode.bigendian.eq(0) # little / big?
371 yield instruction.eq(ins) # raw binary instr.
372 yield Delay(1e-6)
373
374 # uninitialised regs, drop them into dict for function
375 for rname in gsc.parser.uninit_regs:
376 d[rname] = SelectableInt(0, 64) # uninitialised (to zero)
377 print("uninitialised", rname, hex(d[rname].value))
378
379 # read regs, drop them into dict for function
380 for rname in gsc.parser.read_regs:
381 regidx = yield getattr(decode.sigforms['X'], rname)
382 d[rname] = gsc.gpr[regidx] # contents of regfile
383 d["_%s" % rname] = regidx # actual register value
384 print("read reg", rname, regidx, hex(d[rname].value))
385
386 exec(compiled_code, d) # code gets executed here in dict "d"
387 print("Done")
388
389 print(d.keys()) # shows the variables that may have been created
390
391 print(decode.sigforms['X'])
392 x = yield decode.sigforms['X'].RS
393 ra = yield decode.sigforms['X'].RA
394 rb = yield decode.sigforms['X'].RB
395 print("RA", ra, d['RA'])
396 print("RB", rb, d['RB'])
397 print("RS", x)
398
399 for wname in gsc.parser.write_regs:
400 reg = getform[wname]
401 regidx = yield reg
402 print("write regs", regidx, wname, d[wname], reg)
403 gsc.gpr[regidx] = d[wname]
404
405 sim.add_process(process)
406 with sim.write_vcd("simulator.vcd", "simulator.gtkw",
407 traces=decode.ports()):
408 sim.run()
409
410 gsc.gpr.dump()
411
412 for i in range(0, len(gsc.mem.mem), 16):
413 hexstr = []
414 for j in range(16):
415 hexstr.append("%02x" % gsc.mem.mem[i+j])
416 hexstr = ' '.join(hexstr)
417 print("mem %4x" % i, hexstr)
418
419
420 if __name__ == '__main__':
421 test()