comments
[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 SVSTATE_next = """
185 SVSTATE_NEXT(5)
186 """
187
188 code = SVSTATE_next
189 #code = hextest
190 #code = lswx
191 #code = testcond
192 #code = testdo
193 #code = _bpermd
194 #code = testmul
195 #code = testgetzero
196 #code = testcat
197 #code = testgpr
198 #code = testmem
199 #code = testgprslice
200 #code = testreg
201 #code = cnttzd
202 #code = cmpi
203 #code = cmpeqb
204 #code = addpcis
205 #code = bpermd
206
207
208 def tolist(num):
209 l = []
210 for i in range(64):
211 l.append(1 if (num & (1 << i)) else 0)
212 l.reverse()
213 return l
214
215
216 def get_reg_hex(reg):
217 return hex(reg.value)
218
219
220 def convert_to_pure_python(pcode):
221
222 gsc = GardenSnakeCompiler(form=None, incl_carry=False)
223
224 tree = gsc.compile(pcode, mode="exec", filename="string")
225 tree = ast.fix_missing_locations(tree)
226 return astor.to_source(tree)
227
228
229 def convert_to_python(pcode, form, incl_carry):
230
231 print("form", form)
232 gsc = GardenSnakeCompiler(form=form, incl_carry=incl_carry)
233
234 tree = gsc.compile(pcode, mode="exec", filename="string")
235 tree = ast.fix_missing_locations(tree)
236 regsused = {'read_regs': gsc.parser.read_regs,
237 'write_regs': gsc.parser.write_regs,
238 'uninit_regs': gsc.parser.uninit_regs,
239 'special_regs': gsc.parser.special_regs,
240 'op_fields': gsc.parser.op_fields}
241 return astor.to_source(tree), regsused
242
243
244 def test():
245
246 gsc = GardenSnakeCompiler(debug=True)
247
248 gsc.regfile = {}
249 for i in range(32):
250 gsc.regfile[i] = i
251 gsc.gpr = GPR(None, None, None, gsc.regfile)
252 gsc.mem = Mem()
253
254 _compile = gsc.compile
255
256 tree = _compile(code, mode="single", filename="string")
257 tree = ast.fix_missing_locations(tree)
258 print(ast.dump(tree))
259
260 print("astor dump")
261 print(astor.dump_tree(tree))
262 print("to source")
263 source = astor.to_source(tree)
264 print(source)
265
266 # sys.exit(0)
267
268 # Set up the GardenSnake run-time environment
269 def print_(*args):
270 print("args", args)
271 print("-->", " ".join(map(str, args)))
272
273 from openpower.decoder.helpers import (EXTS64, EXTZ64, ROTL64, ROTL32, MASK,
274 trunc_div, trunc_rem)
275
276 d = {}
277 d["print"] = print_
278 d["EXTS64"] = EXTS64
279 d["EXTZ64"] = EXTZ64
280 d["trunc_div"] = trunc_div
281 d["trunc_rem"] = trunc_rem
282 d["SelectableInt"] = SelectableInt
283 d["concat"] = selectconcat
284 d["GPR"] = gsc.gpr
285 d["MEM"] = gsc.mem
286 d["memassign"] = gsc.mem.memassign
287
288 form = 'X'
289 gsc.gpr.set_form(form)
290 getform = gsc.parser.sd.sigforms[form]._asdict()
291 #print ("getform", form)
292 # for k, f in getform.items():
293 #print (k, f)
294 #d[k] = getform[k]
295
296 compiled_code = compile(source, mode="exec", filename="<string>")
297
298 m = Module()
299 comb = m.d.comb
300 instruction = Signal(32)
301
302 m.submodules.decode = decode = gsc.parser.sd
303 comb += decode.raw_opcode_in.eq(instruction)
304 sim = Simulator(m)
305
306 instr = [0x11111117]
307
308 def process():
309 for ins in instr:
310 print("0x{:X}".format(ins & 0xffffffff))
311
312 # ask the decoder to decode this binary data (endian'd)
313 yield decode.bigendian.eq(0) # little / big?
314 yield instruction.eq(ins) # raw binary instr.
315 yield Delay(1e-6)
316
317 # uninitialised regs, drop them into dict for function
318 for rname in gsc.parser.uninit_regs:
319 d[rname] = SelectableInt(0, 64) # uninitialised (to zero)
320 print("uninitialised", rname, hex(d[rname].value))
321
322 # read regs, drop them into dict for function
323 for rname in gsc.parser.read_regs:
324 regidx = yield getattr(decode.sigforms['X'], rname)
325 d[rname] = gsc.gpr[regidx] # contents of regfile
326 d["_%s" % rname] = regidx # actual register value
327 print("read reg", rname, regidx, hex(d[rname].value))
328
329 exec(compiled_code, d) # code gets executed here in dict "d"
330 print("Done")
331
332 print(d.keys()) # shows the variables that may have been created
333
334 print(decode.sigforms['X'])
335 x = yield decode.sigforms['X'].RS
336 ra = yield decode.sigforms['X'].RA
337 rb = yield decode.sigforms['X'].RB
338 print("RA", ra, d['RA'])
339 print("RB", rb, d['RB'])
340 print("RS", x)
341
342 for wname in gsc.parser.write_regs:
343 reg = getform[wname]
344 regidx = yield reg
345 print("write regs", regidx, wname, d[wname], reg)
346 gsc.gpr[regidx] = d[wname]
347
348 sim.add_process(process)
349 with sim.write_vcd("simulator.vcd", "simulator.gtkw",
350 traces=decode.ports()):
351 sim.run()
352
353 gsc.gpr.dump()
354
355 for i in range(0, len(gsc.mem.mem), 16):
356 hexstr = []
357 for j in range(16):
358 hexstr.append("%02x" % gsc.mem.mem[i+j])
359 hexstr = ' '.join(hexstr)
360 print("mem %4x" % i, hexstr)
361
362
363 if __name__ == '__main__':
364 test()