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