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