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