add fsubs unit test
[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 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):
262
263 gsc = GardenSnakeCompiler(form=None, incl_carry=False)
264
265 tree = gsc.compile(pcode, mode="exec", filename="string")
266 tree = ast.fix_missing_locations(tree)
267 return astor.to_source(tree)
268
269
270 def convert_to_python(pcode, form, incl_carry):
271
272 print("form", form)
273 gsc = GardenSnakeCompiler(form=form, incl_carry=incl_carry)
274
275 tree = gsc.compile(pcode, mode="exec", filename="string")
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 test():
286
287 gsc = GardenSnakeCompiler(debug=True)
288
289 gsc.regfile = {}
290 for i in range(32):
291 gsc.regfile[i] = i
292 gsc.gpr = GPR(None, None, None, gsc.regfile)
293 gsc.mem = Mem()
294
295 _compile = gsc.compile
296
297 tree = _compile(code, mode="single", filename="string")
298 tree = ast.fix_missing_locations(tree)
299 print(ast.dump(tree))
300
301 print("astor dump")
302 print(astor.dump_tree(tree))
303 print("to source")
304 source = astor.to_source(tree)
305 print(source)
306
307 # sys.exit(0)
308
309 # Set up the GardenSnake run-time environment
310 def print_(*args):
311 print("args", args)
312 print("-->", " ".join(map(str, args)))
313
314 from openpower.decoder.helpers import (EXTS64, EXTZ64, ROTL64, ROTL32, MASK,
315 trunc_div, trunc_rem)
316
317 d = {}
318 d["print"] = print_
319 d["EXTS64"] = EXTS64
320 d["EXTZ64"] = EXTZ64
321 d["trunc_div"] = trunc_div
322 d["trunc_rem"] = trunc_rem
323 d["SelectableInt"] = SelectableInt
324 d["concat"] = selectconcat
325 d["GPR"] = gsc.gpr
326 d["MEM"] = gsc.mem
327 d["memassign"] = gsc.mem.memassign
328
329 form = 'X'
330 gsc.gpr.set_form(form)
331 getform = gsc.parser.sd.sigforms[form]._asdict()
332 #print ("getform", form)
333 # for k, f in getform.items():
334 #print (k, f)
335 #d[k] = getform[k]
336
337 compiled_code = compile(source, mode="exec", filename="<string>")
338
339 m = Module()
340 comb = m.d.comb
341 instruction = Signal(32)
342
343 m.submodules.decode = decode = gsc.parser.sd
344 comb += decode.raw_opcode_in.eq(instruction)
345 sim = Simulator(m)
346
347 instr = [0x11111117]
348
349 def process():
350 for ins in instr:
351 print("0x{:X}".format(ins & 0xffffffff))
352
353 # ask the decoder to decode this binary data (endian'd)
354 yield decode.bigendian.eq(0) # little / big?
355 yield instruction.eq(ins) # raw binary instr.
356 yield Delay(1e-6)
357
358 # uninitialised regs, drop them into dict for function
359 for rname in gsc.parser.uninit_regs:
360 d[rname] = SelectableInt(0, 64) # uninitialised (to zero)
361 print("uninitialised", rname, hex(d[rname].value))
362
363 # read regs, drop them into dict for function
364 for rname in gsc.parser.read_regs:
365 regidx = yield getattr(decode.sigforms['X'], rname)
366 d[rname] = gsc.gpr[regidx] # contents of regfile
367 d["_%s" % rname] = regidx # actual register value
368 print("read reg", rname, regidx, hex(d[rname].value))
369
370 exec(compiled_code, d) # code gets executed here in dict "d"
371 print("Done")
372
373 print(d.keys()) # shows the variables that may have been created
374
375 print(decode.sigforms['X'])
376 x = yield decode.sigforms['X'].RS
377 ra = yield decode.sigforms['X'].RA
378 rb = yield decode.sigforms['X'].RB
379 print("RA", ra, d['RA'])
380 print("RB", rb, d['RB'])
381 print("RS", x)
382
383 for wname in gsc.parser.write_regs:
384 reg = getform[wname]
385 regidx = yield reg
386 print("write regs", regidx, wname, d[wname], reg)
387 gsc.gpr[regidx] = d[wname]
388
389 sim.add_process(process)
390 with sim.write_vcd("simulator.vcd", "simulator.gtkw",
391 traces=decode.ports()):
392 sim.run()
393
394 gsc.gpr.dump()
395
396 for i in range(0, len(gsc.mem.mem), 16):
397 hexstr = []
398 for j in range(16):
399 hexstr.append("%02x" % gsc.mem.mem[i+j])
400 hexstr = ' '.join(hexstr)
401 print("mem %4x" % i, hexstr)
402
403
404 if __name__ == '__main__':
405 test()