add inner sub-loop testing from svstep Rc=1
[openpower-isa.git] / src / openpower / decoder / isa / test_caller_setvl.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 openpower.decoder.isa.caller import ISACaller
6 from openpower.decoder.power_decoder import (create_pdecode)
7 from openpower.decoder.power_decoder2 import (PowerDecode2)
8 from openpower.simulator.program import Program
9 from openpower.decoder.isa.caller import ISACaller, SVP64State, CRFields
10 from openpower.decoder.selectable_int import SelectableInt
11 from openpower.decoder.orderedset import OrderedSet
12 from openpower.decoder.isa.all import ISA
13 from openpower.decoder.isa.test_caller import Register, run_tst
14 from openpower.sv.trans.svp64 import SVP64Asm
15 from openpower.consts import SVP64CROffs
16 from copy import deepcopy
17
18 class DecoderTestCase(FHDLTestCase):
19
20 def _check_regs(self, sim, expected):
21 print ("GPR")
22 sim.gpr.dump()
23 for i in range(32):
24 self.assertEqual(sim.gpr(i), SelectableInt(expected[i], 64))
25
26 def test_svstep_1(self):
27 lst = SVP64Asm(["setvl 0, 0, 10, 1, 1, 1", # actual setvl (VF mode)
28 "setvl 0, 0, 1, 1, 0, 0", # svstep
29 "setvl 0, 0, 1, 1, 0, 0" # svstep
30 ])
31 lst = list(lst)
32
33 # SVSTATE (in this case, VL=4) which is going to get erased by setvl
34 svstate = SVP64State()
35 svstate.vl = 4 # VL
36 svstate.maxvl = 4 # MAXVL
37 print ("SVSTATE", bin(svstate.asint()))
38
39 with Program(lst, bigendian=False) as program:
40 sim = self.run_tst_program(program, svstate=svstate)
41 print ("SVSTATE after", bin(sim.svstate.asint()))
42 print (" vl", bin(sim.svstate.vl))
43 print (" mvl", bin(sim.svstate.maxvl))
44 print (" srcstep", bin(sim.svstate.srcstep))
45 print (" dststep", bin(sim.svstate.dststep))
46 print (" vfirst", bin(sim.svstate.vfirst))
47 self.assertEqual(sim.svstate.vl, 10)
48 self.assertEqual(sim.svstate.maxvl, 10)
49 self.assertEqual(sim.svstate.srcstep, 2)
50 self.assertEqual(sim.svstate.dststep, 2)
51 self.assertEqual(sim.svstate.vfirst, 1)
52 print(" gpr1", sim.gpr(0))
53 self.assertEqual(sim.gpr(0), SelectableInt(0, 64))
54
55 def test_svstep_2(self):
56 """tests svstep when it reaches VL
57 """
58 lst = SVP64Asm(["setvl 0, 0, 2, 1, 1, 1", # actual setvl (VF mode)
59 "setvl. 0, 0, 1, 1, 0, 0", # svstep (Rc=1)
60 "setvl. 0, 0, 1, 1, 0, 0" # svstep (Rc=1)
61 ])
62 lst = list(lst)
63
64 # SVSTATE (in this case, VL=2)
65 svstate = SVP64State()
66 svstate.vl = 2 # VL
67 svstate.maxvl = 2 # MAXVL
68 print ("SVSTATE", bin(svstate.asint()))
69
70 with Program(lst, bigendian=False) as program:
71 sim = self.run_tst_program(program, svstate=svstate)
72 print ("SVSTATE after", bin(sim.svstate.asint()))
73 print (" vl", bin(sim.svstate.vl))
74 print (" mvl", bin(sim.svstate.maxvl))
75 print (" srcstep", bin(sim.svstate.srcstep))
76 print (" dststep", bin(sim.svstate.dststep))
77 print (" vfirst", bin(sim.svstate.vfirst))
78 self.assertEqual(sim.svstate.vl, 2)
79 self.assertEqual(sim.svstate.maxvl, 2)
80 self.assertEqual(sim.svstate.srcstep, 0)
81 self.assertEqual(sim.svstate.dststep, 0)
82 # when end reached, vertical mode is exited
83 self.assertEqual(sim.svstate.vfirst, 0)
84 print(" gpr1", sim.gpr(0))
85 self.assertEqual(sim.gpr(0), SelectableInt(0, 64))
86 CR0 = sim.crl[0]
87 print(" CR0", bin(CR0.get_range().value))
88 self.assertEqual(CR0[CRFields.EQ], 0)
89 self.assertEqual(CR0[CRFields.LT], 0)
90 self.assertEqual(CR0[CRFields.GT], 0)
91 self.assertEqual(CR0[CRFields.SO], 1)
92
93 def test_svstep_3(self):
94 """tests svstep when it *doesn't* reach VL
95 """
96 lst = SVP64Asm(["setvl 0, 0, 3, 1, 1, 1", # actual setvl (VF mode)
97 "setvl. 0, 0, 1, 1, 0, 0", # svstep (Rc=1)
98 "setvl. 0, 0, 1, 1, 0, 0" # svstep (Rc=1)
99 ])
100 lst = list(lst)
101
102 # SVSTATE (in this case, VL=2)
103 svstate = SVP64State()
104 svstate.vl = 2 # VL
105 svstate.maxvl = 2 # MAXVL
106 print ("SVSTATE", bin(svstate.asint()))
107
108 with Program(lst, bigendian=False) as program:
109 sim = self.run_tst_program(program, svstate=svstate)
110 print ("SVSTATE after", bin(sim.svstate.asint()))
111 print (" vl", bin(sim.svstate.vl))
112 print (" mvl", bin(sim.svstate.maxvl))
113 print (" srcstep", bin(sim.svstate.srcstep))
114 print (" dststep", bin(sim.svstate.dststep))
115 print (" vfirst", bin(sim.svstate. vfirst))
116 self.assertEqual(sim.svstate.vl, 3)
117 self.assertEqual(sim.svstate.maxvl, 3)
118 # svstep called twice, didn't reach VL, so srcstep/dststep both 2
119 self.assertEqual(sim.svstate.srcstep, 2)
120 self.assertEqual(sim.svstate.dststep, 2)
121 print(" gpr1", sim.gpr(0))
122 self.assertEqual(sim.gpr(0), SelectableInt(0, 64))
123 self.assertEqual(sim.svstate.vfirst, 1)
124 CR0 = sim.crl[0]
125 print(" CR0", bin(CR0.get_range().value))
126 self.assertEqual(CR0[CRFields.EQ], 0)
127 self.assertEqual(CR0[CRFields.LT], 0)
128 self.assertEqual(CR0[CRFields.GT], 0)
129 self.assertEqual(CR0[CRFields.SO], 0)
130
131
132 def test_setvl_1(self):
133 """straight setvl, testing if VL and MVL are over-ridden
134 """
135 lst = SVP64Asm(["setvl 1, 0, 10, 0, 1, 1",
136 ])
137 lst = list(lst)
138
139 # SVSTATE (in this case, VL=2), want to see if these get changed
140 svstate = SVP64State()
141 svstate.vl = 2 # VL
142 svstate.maxvl = 2 # MAXVL
143 print ("SVSTATE", bin(svstate.asint()))
144
145 with Program(lst, bigendian=False) as program:
146 sim = self.run_tst_program(program, svstate=svstate)
147 print ("SVSTATE after", bin(sim.svstate.asint()))
148 print (" vl", bin(sim.svstate.vl))
149 print (" mvl", bin(sim.svstate.maxvl))
150 self.assertEqual(sim.svstate.vl, 10)
151 self.assertEqual(sim.svstate.maxvl, 10)
152 self.assertEqual(sim.svstate.maxvl, 10)
153 print(" gpr1", sim.gpr(1))
154 self.assertEqual(sim.gpr(1), SelectableInt(10, 64))
155
156 def test_svstep_inner_loop_6(self):
157 """tests svstep inner loop, running 6 times, looking for "k"
158 """
159 lst = SVP64Asm([
160 # set triple butterfly mode with persistent "REMAP"
161 "svshape 8, 1, 1, 1, 1",
162 "svremap 31, 1, 0, 2, 0, 1, 1",
163 "setvl. 0, 0, 2, 1, 0, 0",# svstep (Rc=1)
164 "setvl. 0, 0, 2, 1, 0, 0",# svstep (Rc=1)
165 "setvl. 0, 0, 2, 1, 0, 0",# svstep (Rc=1)
166 "setvl. 0, 0, 2, 1, 0, 0",# svstep (Rc=1)
167 "setvl. 0, 0, 2, 1, 0, 0",# svstep (Rc=1)
168 "setvl. 0, 0, 2, 1, 0, 0",# svstep (Rc=1)
169 ])
170 lst = list(lst)
171
172 # SVSTATE
173 svstate = SVP64State()
174 #svstate.vl = 2 # VL
175 #svstate.maxvl = 2 # MAXVL
176 print ("SVSTATE", bin(svstate.asint()))
177
178 with Program(lst, bigendian=False) as program:
179 sim = self.run_tst_program(program, svstate=svstate)
180 print ("SVSTATE after", bin(sim.svstate.asint()))
181 print (" vl", bin(sim.svstate.vl))
182 print (" mvl", bin(sim.svstate.maxvl))
183 print (" srcstep", bin(sim.svstate.srcstep))
184 print (" dststep", bin(sim.svstate.dststep))
185 print (" vfirst", bin(sim.svstate. vfirst))
186 self.assertEqual(sim.svstate.vl, 12)
187 self.assertEqual(sim.svstate.maxvl, 12)
188 # svstep called twice, didn't reach VL, so srcstep/dststep both 2
189 self.assertEqual(sim.svstate.srcstep, 6)
190 self.assertEqual(sim.svstate.dststep, 6)
191 self.assertEqual(sim.gpr(0), SelectableInt(0, 64))
192 self.assertEqual(sim.svstate.vfirst, 1)
193 CR0 = sim.crl[0]
194 print(" CR0", bin(CR0.get_range().value))
195 self.assertEqual(CR0[CRFields.EQ], 0)
196 self.assertEqual(CR0[CRFields.LT], 1)
197 self.assertEqual(CR0[CRFields.GT], 1)
198 self.assertEqual(CR0[CRFields.SO], 0)
199
200 def test_svstep_inner_loop_3(self):
201 """tests svstep inner loop, running 3 times
202 """
203 lst = SVP64Asm([
204 # set triple butterfly mode with persistent "REMAP"
205 "svshape 8, 1, 1, 1, 1",
206 "svremap 31, 1, 0, 2, 0, 1, 1",
207 "setvl. 0, 0, 2, 1, 0, 0",# svstep (Rc=1)
208 "setvl. 0, 0, 2, 1, 0, 0",# svstep (Rc=1)
209 "setvl. 0, 0, 2, 1, 0, 0", # svstep (Rc=1)
210 ])
211 lst = list(lst)
212
213 # SVSTATE
214 svstate = SVP64State()
215 #svstate.vl = 2 # VL
216 #svstate.maxvl = 2 # MAXVL
217 print ("SVSTATE", bin(svstate.asint()))
218
219 with Program(lst, bigendian=False) as program:
220 sim = self.run_tst_program(program, svstate=svstate)
221 print ("SVSTATE after", bin(sim.svstate.asint()))
222 print (" vl", bin(sim.svstate.vl))
223 print (" mvl", bin(sim.svstate.maxvl))
224 print (" srcstep", bin(sim.svstate.srcstep))
225 print (" dststep", bin(sim.svstate.dststep))
226 print (" vfirst", bin(sim.svstate. vfirst))
227 self.assertEqual(sim.svstate.vl, 12)
228 self.assertEqual(sim.svstate.maxvl, 12)
229 # svstep called twice, didn't reach VL, so srcstep/dststep both 2
230 self.assertEqual(sim.svstate.srcstep, 3)
231 self.assertEqual(sim.svstate.dststep, 3)
232 self.assertEqual(sim.gpr(0), SelectableInt(0, 64))
233 self.assertEqual(sim.svstate.vfirst, 1)
234 CR0 = sim.crl[0]
235 print(" CR0", bin(CR0.get_range().value))
236 self.assertEqual(CR0[CRFields.EQ], 0)
237 self.assertEqual(CR0[CRFields.LT], 1)
238 self.assertEqual(CR0[CRFields.GT], 1)
239 self.assertEqual(CR0[CRFields.SO], 0)
240
241 def test_svstep_inner_loop_4(self):
242 """tests svstep inner loop, running 4 times
243 """
244 lst = SVP64Asm([
245 # set triple butterfly mode with persistent "REMAP"
246 "svshape 8, 1, 1, 1, 1",
247 "svremap 31, 1, 0, 2, 0, 1, 1",
248 "setvl. 0, 0, 2, 1, 0, 0",# svstep (Rc=1)
249 "setvl. 0, 0, 2, 1, 0, 0",# svstep (Rc=1)
250 "setvl. 0, 0, 2, 1, 0, 0", # svstep (Rc=1)
251 "setvl. 0, 0, 2, 1, 0, 0", # svstep (Rc=1)
252 ])
253 lst = list(lst)
254
255 # SVSTATE
256 svstate = SVP64State()
257 #svstate.vl = 2 # VL
258 #svstate.maxvl = 2 # MAXVL
259 print ("SVSTATE", bin(svstate.asint()))
260
261 with Program(lst, bigendian=False) as program:
262 sim = self.run_tst_program(program, svstate=svstate)
263 print ("SVSTATE after", bin(sim.svstate.asint()))
264 print (" vl", bin(sim.svstate.vl))
265 print (" mvl", bin(sim.svstate.maxvl))
266 print (" srcstep", bin(sim.svstate.srcstep))
267 print (" dststep", bin(sim.svstate.dststep))
268 print (" vfirst", bin(sim.svstate. vfirst))
269 self.assertEqual(sim.svstate.vl, 12)
270 self.assertEqual(sim.svstate.maxvl, 12)
271 # svstep called twice, didn't reach VL, so srcstep/dststep both 2
272 self.assertEqual(sim.svstate.srcstep, 4)
273 self.assertEqual(sim.svstate.dststep, 4)
274 self.assertEqual(sim.gpr(0), SelectableInt(0, 64))
275 self.assertEqual(sim.svstate.vfirst, 1)
276 CR0 = sim.crl[0]
277 print(" CR0", bin(CR0.get_range().value))
278 self.assertEqual(CR0[CRFields.EQ], 0)
279 self.assertEqual(CR0[CRFields.LT], 1)
280 self.assertEqual(CR0[CRFields.GT], 0)
281 self.assertEqual(CR0[CRFields.SO], 0)
282
283 def test_sv_add(self):
284 """sets VL=2 then adds:
285 * 1 = 5 + 9 => 0x5555 = 0x4321+0x1234
286 * 2 = 6 + 10 => 0x3334 = 0x2223+0x1111
287 """
288 isa = SVP64Asm(["setvl 3, 0, 2, 0, 1, 1",
289 'sv.add 1.v, 5.v, 9.v'
290 ])
291 lst = list(isa)
292 print ("listing", lst)
293
294 # initial values in GPR regfile
295 initial_regs = [0] * 32
296 initial_regs[9] = 0x1234
297 initial_regs[10] = 0x1111
298 initial_regs[5] = 0x4321
299 initial_regs[6] = 0x2223
300
301 # copy before running
302 expected_regs = deepcopy(initial_regs)
303 expected_regs[1] = 0x5555
304 expected_regs[2] = 0x3334
305 expected_regs[3] = 2 # setvl places copy of VL here
306
307 with Program(lst, bigendian=False) as program:
308 sim = self.run_tst_program(program, initial_regs)
309 self._check_regs(sim, expected_regs)
310
311 def test_svstep_add_1(self):
312 """tests svstep with an add, when it reaches VL
313 lst = SVP64Asm(["setvl 3, 0, 2, 1, 1, 1",
314 'sv.add 1.v, 5.v, 9.v',
315 "setvl. 0, 0, 1, 1, 0, 0",
316 'sv.add 1.v, 5.v, 9.v',
317 "setvl. 0, 0, 1, 1, 0, 0"
318 ])
319 sequence is as follows:
320 * setvl sets VL=2 but also "Vertical First" mode.
321 this sets MSR[SVF].
322 * first add, which has srcstep/dststep = 0, does add 1,5,9
323 * svstep EXPLICITLY walks srcstep/dststep to next element
324 * second add, which now has srcstep/dststep = 1, does add 2,6,10
325 * svstep EXPLICITLY walks srcstep/dststep to next element,
326 which now equals VL. srcstep and dststep are both set to
327 zero, and MSR[SVF] is cleared.
328 """
329 lst = SVP64Asm(["setvl 3, 0, 2, 1, 1, 1",
330 'sv.add 1.v, 5.v, 9.v',
331 "setvl. 0, 0, 1, 1, 0, 0", # svstep
332 'sv.add 1.v, 5.v, 9.v',
333 "setvl. 0, 0, 1, 1, 0, 0" # svstep
334 ])
335 lst = list(lst)
336
337 # SVSTATE (in this case, VL=2)
338 svstate = SVP64State()
339 svstate.vl = 2 # VL
340 svstate.maxvl = 2 # MAXVL
341 print ("SVSTATE", bin(svstate.asint()))
342
343 # initial values in GPR regfile
344 initial_regs = [0] * 32
345 initial_regs[9] = 0x1234
346 initial_regs[10] = 0x1111
347 initial_regs[5] = 0x4321
348 initial_regs[6] = 0x2223
349
350 # copy before running
351 expected_regs = deepcopy(initial_regs)
352 expected_regs[1] = 0x5555
353 expected_regs[2] = 0x3334
354 expected_regs[3] = 2 # setvl places copy of VL here
355
356 with Program(lst, bigendian=False) as program:
357 sim = self.run_tst_program(program, initial_regs, svstate=svstate)
358 print ("SVSTATE after", bin(sim.svstate.asint()))
359 print (" vl", bin(sim.svstate.vl))
360 print (" mvl", bin(sim.svstate.maxvl))
361 print (" srcstep", bin(sim.svstate.srcstep))
362 print (" dststep", bin(sim.svstate.dststep))
363 print (" vfirst", bin(sim.svstate. vfirst))
364 self.assertEqual(sim.svstate.vl, 2)
365 self.assertEqual(sim.svstate.maxvl, 2)
366 self.assertEqual(sim.svstate.srcstep, 0)
367 self.assertEqual(sim.svstate.dststep, 0)
368 # when end reached, vertical mode is exited
369 self.assertEqual(sim.svstate.vfirst, 0)
370 CR0 = sim.crl[0]
371 print(" CR0", bin(CR0.get_range().value))
372 self.assertEqual(CR0[CRFields.EQ], 0)
373 self.assertEqual(CR0[CRFields.LT], 0)
374 self.assertEqual(CR0[CRFields.GT], 0)
375 self.assertEqual(CR0[CRFields.SO], 1)
376
377 # check registers as expected
378 self._check_regs(sim, expected_regs)
379
380 def test_svstep_add_2(self):
381 """tests svstep with a branch.
382 lst = SVP64Asm(["setvl 3, 0, 2, 1, 1, 1",
383 'sv.add 1.v, 5.v, 9.v',
384 "setvl. 0, 0, 1, 1, 0, 0",
385 "bc 6, 3, -0xc"
386 ])
387 sequence is as follows:
388 * setvl sets VL=2 but also "Vertical First" mode.
389 this sets MSR[SVF].
390 * first time add, which has srcstep/dststep = 0, does add 1,5,9
391 * svstep EXPLICITLY walks srcstep/dststep to next element,
392 not yet met VL, so CR0.EQ is set to zero
393 * branch conditional checks bne on CR0, jumps back TWELVE bytes
394 because whilst branch is 32-bit the sv.add is 64-bit
395 * second time add, which now has srcstep/dststep = 1, does add 2,6,10
396 * svstep walks to next element, meets VL, so:
397 - srcstep and dststep set to zero
398 - CR0.EQ set to one
399 - MSR[SVF] is cleared
400 * branch conditional detects CR0.EQ=1 and FAILs the condition,
401 therefore loop ends.
402
403 we therefore have an explicit "Vertical-First" system which can
404 have **MULTIPLE* instructions inside a loop, running each element 0
405 first, then looping back and running all element 1, then all element 2
406 etc.
407 """
408 lst = SVP64Asm(["setvl 3, 0, 2, 1, 1, 1",
409 'sv.add 1.v, 5.v, 9.v',
410 "setvl. 0, 0, 1, 1, 0, 0", # svstep - this is 64-bit!
411 "bc 6, 3, -0xc" # branch to add (64-bit op so -0xc!)
412 ])
413 lst = list(lst)
414
415 # SVSTATE (in this case, VL=2)
416 svstate = SVP64State()
417 svstate.vl = 2 # VL
418 svstate.maxvl = 2 # MAXVL
419 print ("SVSTATE", bin(svstate.asint()))
420
421 # initial values in GPR regfile
422 initial_regs = [0] * 32
423 initial_regs[9] = 0x1234
424 initial_regs[10] = 0x1111
425 initial_regs[5] = 0x4321
426 initial_regs[6] = 0x2223
427
428 # copy before running
429 expected_regs = deepcopy(initial_regs)
430 expected_regs[1] = 0x5555
431 expected_regs[2] = 0x3334
432 expected_regs[3] = 2 # setvl places copy of VL here
433
434 with Program(lst, bigendian=False) as program:
435 sim = self.run_tst_program(program, initial_regs, svstate=svstate)
436 print ("SVSTATE after", bin(sim.svstate.asint()))
437 print (" vl", bin(sim.svstate.vl))
438 print (" mvl", bin(sim.svstate.maxvl))
439 print (" srcstep", bin(sim.svstate.srcstep))
440 print (" dststep", bin(sim.svstate.dststep))
441 print (" vfirst", bin(sim.svstate. vfirst))
442 self.assertEqual(sim.svstate.vl, 2)
443 self.assertEqual(sim.svstate.maxvl, 2)
444 self.assertEqual(sim.svstate.srcstep, 0)
445 self.assertEqual(sim.svstate.dststep, 0)
446 # when end reached, vertical mode is exited
447 self.assertEqual(sim.svstate.vfirst, 0)
448 CR0 = sim.crl[0]
449 print(" CR0", bin(CR0.get_range().value))
450 self.assertEqual(CR0[CRFields.EQ], 0)
451 self.assertEqual(CR0[CRFields.LT], 0)
452 self.assertEqual(CR0[CRFields.GT], 0)
453 self.assertEqual(CR0[CRFields.SO], 1)
454
455 # check registers as expected
456 self._check_regs(sim, expected_regs)
457
458 def test_svremap(self):
459 """svremap, see if values get set
460 """
461 lst = SVP64Asm(["svremap 11, 0, 1, 2, 3, 3, 1",
462 ])
463 lst = list(lst)
464
465 with Program(lst, bigendian=False) as program:
466 sim = self.run_tst_program(program)
467 svstate = sim.svstate
468 print ("SVREMAP after", bin(svstate.value))
469 print (" men", bin(svstate.SVme))
470 print (" mi0", bin(svstate.mi0))
471 print (" mi1", bin(svstate.mi1))
472 print (" mi2", bin(svstate.mi2))
473 print (" mo0", bin(svstate.mo0))
474 print (" mo1", bin(svstate.mo1))
475 print (" persist", bin(svstate.RMpst))
476 self.assertEqual(svstate.SVme, 11)
477 self.assertEqual(svstate.mi0, 0)
478 self.assertEqual(svstate.mi1, 1)
479 self.assertEqual(svstate.mi2, 2)
480 self.assertEqual(svstate.mo0, 3)
481 self.assertEqual(svstate.mo1, 3)
482 self.assertEqual(svstate.RMpst, 1)
483
484 def run_tst_program(self, prog, initial_regs=None,
485 svstate=None):
486 if initial_regs is None:
487 initial_regs = [0] * 32
488 simulator = run_tst(prog, initial_regs, svstate=svstate)
489 simulator.gpr.dump()
490 return simulator
491
492
493 if __name__ == "__main__":
494 unittest.main()
495