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