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