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