no python files to be committed in isafunctions
[openpower-isa.git] / src / openpower / decoder / isa / test_caller.py
1 from nmigen import Module, Signal
2 from nmigen.back.pysim import Simulator, Delay, Settle
3 from nmutil.formaltest import FHDLTestCase
4 import unittest
5 from openpower.decoder.isa.caller import ISACaller
6 from openpower.decoder.power_decoder import create_pdecode
7 from openpower.decoder.power_decoder2 import (PowerDecode2)
8 from openpower.simulator.program import Program
9 from openpower.decoder.isa.caller import ISACaller, inject
10 from openpower.decoder.selectable_int import SelectableInt
11 from openpower.decoder.orderedset import OrderedSet
12 from openpower.decoder.isa.all import ISA
13 from nmutil.formaltest import FHDLTestCase
14
15
16 class Register:
17 def __init__(self, num):
18 self.num = num
19
20
21 class ISATestRunner(FHDLTestCase):
22 def __init__(self, tst_data, include_fp=True):
23 super().__init__("run_all")
24 self.test_data = tst_data
25 self.include_fp = include_fp
26
27 def run_all(self):
28 m = Module()
29 comb = m.d.comb
30 instruction = Signal(32)
31
32 pdecode = create_pdecode(include_fp=self.include_fp)
33 m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
34
35 comb += pdecode2.dec.raw_opcode_in.eq(instruction)
36 sim = Simulator(m)
37
38 def process():
39
40 for test in self.test_data:
41
42 with self.subTest(test.name):
43 generator = test.program
44
45 gen = list(generator.generate_instructions())
46 insncode = generator.assembly.splitlines()
47 instructions = list(zip(gen, insncode))
48
49 simulator = ISA(pdecode2, test.regs,
50 test.sprs,
51 test.cr,
52 initial_insns=gen, respect_pc=True,
53 initial_svstate=test.svstate,
54 initial_mem=test.mem,
55 fpregfile=None,
56 disassembly=insncode,
57 bigendian=0,
58 mmu=False)
59
60 print ("GPRs")
61 simulator.gpr.dump()
62 print ("FPRs")
63 simulator.fpr.dump()
64
65 yield pdecode2.dec.bigendian.eq(0) # little / big?
66 pc = simulator.pc.CIA.value
67 index = pc//4
68 while index < len(instructions):
69 print("instr pc", pc)
70 try:
71 yield from simulator.setup_one()
72 except KeyError: # instruction not in imem: stop
73 break
74 yield Settle()
75
76 ins, code = instructions[index]
77 print(" 0x{:X}".format(ins & 0xffffffff))
78 opname = code.split(' ')[0]
79 print(code, opname)
80
81 # ask the decoder to decode this binary data (endian'd)
82 yield from simulator.execute_one()
83 pc = simulator.pc.CIA.value
84 index = pc//4
85
86 # run simulator multiple times, using the same PowerDecoder2,
87 # with multiple sub-tests
88 sim.add_process(process)
89 with sim.write_vcd("simulator.vcd", "simulator.gtkw",
90 traces=[]):
91 sim.run()
92
93
94 def run_tst(generator, initial_regs, initial_sprs=None, svstate=0, mmu=False,
95 initial_cr=0, mem=None,
96 initial_fprs=None):
97 if initial_sprs is None:
98 initial_sprs = {}
99 m = Module()
100 comb = m.d.comb
101 instruction = Signal(32)
102
103 pdecode = create_pdecode(include_fp=initial_fprs is not None)
104
105 gen = list(generator.generate_instructions())
106 insncode = generator.assembly.splitlines()
107 instructions = list(zip(gen, insncode))
108
109 m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
110 simulator = ISA(pdecode2, initial_regs, initial_sprs, initial_cr,
111 initial_insns=gen, respect_pc=True,
112 initial_svstate=svstate,
113 initial_mem=mem,
114 fpregfile=initial_fprs,
115 disassembly=insncode,
116 bigendian=0,
117 mmu=mmu)
118 comb += pdecode2.dec.raw_opcode_in.eq(instruction)
119 sim = Simulator(m)
120
121 def process():
122
123 print ("GPRs")
124 simulator.gpr.dump()
125 print ("FPRs")
126 simulator.fpr.dump()
127
128 yield pdecode2.dec.bigendian.eq(0) # little / big?
129 pc = simulator.pc.CIA.value
130 index = pc//4
131 while index < len(instructions):
132 print("instr pc", pc)
133 try:
134 yield from simulator.setup_one()
135 except KeyError: # indicates instruction not in imem: stop
136 break
137 yield Settle()
138
139 ins, code = instructions[index]
140 print(" 0x{:X}".format(ins & 0xffffffff))
141 opname = code.split(' ')[0]
142 print(code, opname)
143
144 # ask the decoder to decode this binary data (endian'd)
145 yield from simulator.execute_one()
146 pc = simulator.pc.CIA.value
147 index = pc//4
148
149 sim.add_process(process)
150 with sim.write_vcd("simulator.vcd", "simulator.gtkw",
151 traces=[]):
152 sim.run()
153 return simulator
154
155
156 class DecoderTestCase(FHDLTestCase):
157
158 def test_add(self):
159 lst = ["add 1, 3, 2"]
160 initial_regs = [0] * 32
161 initial_regs[3] = 0x1234
162 initial_regs[2] = 0x4321
163 with Program(lst, bigendian=False) as program:
164 sim = self.run_tst_program(program, initial_regs)
165 self.assertEqual(sim.gpr(1), SelectableInt(0x5555, 64))
166
167 def test_addi(self):
168 lst = ["addi 3, 0, 0x1234",
169 "addi 2, 0, 0x4321",
170 "add 1, 3, 2"]
171 with Program(lst, bigendian=False) as program:
172 sim = self.run_tst_program(program)
173 print(sim.gpr(1))
174 self.assertEqual(sim.gpr(1), SelectableInt(0x5555, 64))
175
176 def test_load_store(self):
177 lst = ["addi 1, 0, 0x0010",
178 "addi 2, 0, 0x1234",
179 "stw 2, 0(1)",
180 "lwz 3, 0(1)"]
181 with Program(lst, bigendian=False) as program:
182 sim = self.run_tst_program(program)
183 print(sim.gpr(1))
184 self.assertEqual(sim.gpr(3), SelectableInt(0x1234, 64))
185
186 @unittest.skip("broken")
187 def test_addpcis(self):
188 lst = ["addpcis 1, 0x1",
189 "addpcis 2, 0x1",
190 "addpcis 3, 0x1"]
191 with Program(lst, bigendian=False) as program:
192 sim = self.run_tst_program(program)
193 self.assertEqual(sim.gpr(1), SelectableInt(0x10004, 64))
194 self.assertEqual(sim.gpr(2), SelectableInt(0x10008, 64))
195 self.assertEqual(sim.gpr(3), SelectableInt(0x1000c, 64))
196
197 def test_branch(self):
198 lst = ["ba 0xc", # branch to line 4
199 "addi 1, 0, 0x1234", # Should never execute
200 "ba 0x1000", # exit the program
201 "addi 2, 0, 0x1234", # line 4
202 "ba 0x8"] # branch to line 3
203 with Program(lst, bigendian=False) as program:
204 sim = self.run_tst_program(program)
205 self.assertEqual(sim.pc.CIA, SelectableInt(0x1000, 64))
206 self.assertEqual(sim.gpr(1), SelectableInt(0x0, 64))
207 self.assertEqual(sim.gpr(2), SelectableInt(0x1234, 64))
208
209 def test_branch_link(self):
210 lst = ["bl 0xc",
211 "addi 2, 1, 0x1234",
212 "ba 0x1000",
213 "addi 1, 0, 0x1234",
214 "bclr 20, 0, 0"]
215 with Program(lst, bigendian=False) as program:
216 sim = self.run_tst_program(program)
217 self.assertEqual(sim.spr['LR'], SelectableInt(0x4, 64))
218
219 def test_branch_ctr(self):
220 lst = ["addi 1, 0, 0x10", # target of jump
221 "mtspr 9, 1", # mtctr 1
222 "bcctr 20, 0, 0", # bctr
223 "addi 2, 0, 0x1", # should never execute
224 "addi 1, 0, 0x1234"] # target of ctr
225 with Program(lst, bigendian=False) as program:
226 sim = self.run_tst_program(program)
227 self.assertEqual(sim.spr['CTR'], SelectableInt(0x10, 64))
228 self.assertEqual(sim.gpr(1), SelectableInt(0x1234, 64))
229 self.assertEqual(sim.gpr(2), SelectableInt(0, 64))
230
231 def test_branch_cond(self):
232 for i in [0, 10]:
233 lst = [f"addi 1, 0, {i}", # set r1 to i
234 "cmpi cr0, 1, 1, 10", # compare r1 with 10 and store to cr0
235 "bc 12, 2, 0x8", # beq 0x8 -
236 # branch if r1 equals 10 to the nop below
237 "addi 2, 0, 0x1234", # if r1 == 10 this shouldn't execute
238 "or 0, 0, 0"] # branch target
239 with Program(lst, bigendian=False) as program:
240 sim = self.run_tst_program(program)
241 if i == 10:
242 self.assertEqual(sim.gpr(2), SelectableInt(0, 64))
243 else:
244 self.assertEqual(sim.gpr(2), SelectableInt(0x1234, 64))
245
246 def test_branch_loop(self):
247 lst = ["addi 1, 0, 0",
248 "addi 1, 0, 0",
249 "addi 1, 1, 1",
250 "add 2, 2, 1",
251 "cmpi cr0, 1, 1, 10",
252 "bc 12, 0, -0xc"]
253 with Program(lst, bigendian=False) as program:
254 sim = self.run_tst_program(program)
255 # Verified with qemu
256 self.assertEqual(sim.gpr(2), SelectableInt(0x37, 64))
257
258 def test_branch_loop_ctr(self):
259 lst = ["addi 1, 0, 0",
260 "addi 2, 0, 7",
261 "mtspr 9, 2", # set ctr to 7
262 "addi 1, 1, 5",
263 "bc 16, 0, -0x4"] # bdnz to the addi above
264 with Program(lst, bigendian=False) as program:
265 sim = self.run_tst_program(program)
266 # Verified with qemu
267 self.assertEqual(sim.gpr(1), SelectableInt(0x23, 64))
268
269
270
271 def test_add_compare(self):
272 lst = ["addis 1, 0, 0xffff",
273 "addis 2, 0, 0xffff",
274 "add. 1, 1, 2",
275 "mfcr 3"]
276 with Program(lst, bigendian=False) as program:
277 sim = self.run_tst_program(program)
278 # Verified with QEMU
279 self.assertEqual(sim.gpr(3), SelectableInt(0x80000000, 64))
280
281 def test_cmp(self):
282 lst = ["addis 1, 0, 0xffff",
283 "addis 2, 0, 0xffff",
284 "cmp cr2, 0, 1, 2",
285 "mfcr 3"]
286 with Program(lst, bigendian=False) as program:
287 sim = self.run_tst_program(program)
288 self.assertEqual(sim.gpr(3), SelectableInt(0x200000, 64))
289
290 def test_slw(self):
291 lst = ["slw 1, 3, 2"]
292 initial_regs = [0] * 32
293 initial_regs[3] = 0xdeadbeefcafebabe
294 initial_regs[2] = 5
295 with Program(lst, bigendian=False) as program:
296 sim = self.run_tst_program(program, initial_regs)
297 self.assertEqual(sim.gpr(1), SelectableInt(0x5fd757c0, 64))
298
299 def test_srw(self):
300 lst = ["srw 1, 3, 2"]
301 initial_regs = [0] * 32
302 initial_regs[3] = 0xdeadbeefcafebabe
303 initial_regs[2] = 5
304 with Program(lst, bigendian=False) as program:
305 sim = self.run_tst_program(program, initial_regs)
306 self.assertEqual(sim.gpr(1), SelectableInt(0x657f5d5, 64))
307
308 def test_rlwinm(self):
309 lst = ["rlwinm 3, 1, 5, 20, 6"]
310 initial_regs = [0] * 32
311 initial_regs[1] = -1
312 with Program(lst, bigendian=False) as program:
313 sim = self.run_tst_program(program, initial_regs)
314 self.assertEqual(sim.gpr(3), SelectableInt(0xfffffffffe000fff, 64))
315
316 def test_rlwimi(self):
317 lst = ["rlwimi 3, 1, 5, 20, 6"]
318 initial_regs = [0] * 32
319 initial_regs[1] = 0xffffffffdeadbeef
320 initial_regs[3] = 0x12345678
321 with Program(lst, bigendian=False) as program:
322 sim = self.run_tst_program(program, initial_regs)
323 self.assertEqual(sim.gpr(3), SelectableInt(0xd5b7ddfbd4345dfb, 64))
324
325 def test_rldic(self):
326 lst = ["rldic 3, 1, 5, 20"]
327 initial_regs = [0] * 32
328 initial_regs[1] = 0xdeadbeefcafec0de
329 with Program(lst, bigendian=False) as program:
330 sim = self.run_tst_program(program, initial_regs)
331 self.assertEqual(sim.gpr(3), SelectableInt(0xdf95fd81bc0, 64))
332
333 def test_prty(self):
334 lst = ["prtyw 2, 1"]
335 initial_regs = [0] * 32
336 initial_regs[1] = 0xdeadbeeecaffc0de
337 with Program(lst, bigendian=False) as program:
338 sim = self.run_tst_program(program, initial_regs)
339 self.assertEqual(sim.gpr(2), SelectableInt(0x100000001, 64))
340
341 def test_popcnt(self):
342 lst = ["popcntb 2, 1",
343 "popcntw 3, 1",
344 "popcntd 4, 1"
345 ]
346 initial_regs = [0] * 32
347 initial_regs[1] = 0xdeadbeefcafec0de
348 with Program(lst, bigendian=False) as program:
349 sim = self.run_tst_program(program, initial_regs)
350 self.assertEqual(sim.gpr(2),
351 SelectableInt(0x605060704070206, 64))
352 self.assertEqual(sim.gpr(3),
353 SelectableInt(0x1800000013, 64))
354 self.assertEqual(sim.gpr(4),
355 SelectableInt(0x2b, 64))
356
357 def test_cntlz(self):
358 lst = ["cntlzd 2, 1",
359 "cntlzw 4, 3"]
360 initial_regs = [0] * 32
361 initial_regs[1] = 0x0000beeecaffc0de
362 initial_regs[3] = 0x0000000000ffc0de
363 with Program(lst, bigendian=False) as program:
364 sim = self.run_tst_program(program, initial_regs)
365 self.assertEqual(sim.gpr(2), SelectableInt(16, 64))
366 self.assertEqual(sim.gpr(4), SelectableInt(8, 64))
367
368 def test_cmpeqb(self):
369 lst = ["cmpeqb cr0, 2, 1",
370 "cmpeqb cr1, 3, 1"]
371 initial_regs = [0] * 32
372 initial_regs[1] = 0x0102030405060708
373 initial_regs[2] = 0x04
374 initial_regs[3] = 0x10
375 with Program(lst, bigendian=False) as program:
376 sim = self.run_tst_program(program, initial_regs)
377 self.assertEqual(sim.crl[0].get_range().value,
378 SelectableInt(4, 4))
379 self.assertEqual(sim.crl[1].get_range().value,
380 SelectableInt(0, 4))
381
382
383
384 def test_mtcrf(self):
385 for i in range(4):
386 # 0x76540000 gives expected (3+4) (2+4) (1+4) (0+4) for
387 # i=0, 1, 2, 3
388 # The positions of the CR fields have been verified using
389 # QEMU and 'cmp crx, a, b' instructions
390 lst = ["addis 1, 0, 0x7654",
391 "mtcrf %d, 1" % (1 << (7-i)),
392 ]
393 with Program(lst, bigendian=False) as program:
394 sim = self.run_tst_program(program)
395 print("cr", sim.cr)
396 expected = (7-i)
397 # check CR[0]/1/2/3 as well
398 print("cr%d" % i, sim.crl[i].asint(True))
399 self.assertTrue(SelectableInt(expected, 4) == sim.crl[i])
400 # check CR itself
401 self.assertEqual(sim.cr, SelectableInt(expected << ((7-i)*4), 64))
402
403 def run_tst_program(self, prog, initial_regs=[0] * 32):
404 simulator = run_tst(prog, initial_regs)
405 simulator.gpr.dump()
406 return simulator
407
408
409 if __name__ == "__main__":
410 unittest.main()