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