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