stop using MSR vfirst bit, move to SVSTATE bit 63 instead
[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], 1)
89 self.assertEqual(CR0[CRFields.LT], 0)
90 self.assertEqual(CR0[CRFields.GT], 0)
91 self.assertEqual(CR0[CRFields.SO], 0)
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], 1)
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__sv_add(self):
157 """sets VL=2 then adds:
158 * 1 = 5 + 9 => 0x5555 = 0x4321+0x1234
159 * 2 = 6 + 10 => 0x3334 = 0x2223+0x1111
160 """
161 isa = SVP64Asm(["setvl 3, 0, 2, 0, 1, 1",
162 'sv.add 1.v, 5.v, 9.v'
163 ])
164 lst = list(isa)
165 print ("listing", lst)
166
167 # initial values in GPR regfile
168 initial_regs = [0] * 32
169 initial_regs[9] = 0x1234
170 initial_regs[10] = 0x1111
171 initial_regs[5] = 0x4321
172 initial_regs[6] = 0x2223
173
174 # copy before running
175 expected_regs = deepcopy(initial_regs)
176 expected_regs[1] = 0x5555
177 expected_regs[2] = 0x3334
178 expected_regs[3] = 2 # setvl places copy of VL here
179
180 with Program(lst, bigendian=False) as program:
181 sim = self.run_tst_program(program, initial_regs)
182 self._check_regs(sim, expected_regs)
183
184 def test__svstep_add_1(self):
185 """tests svstep with an add, when it reaches VL
186 lst = SVP64Asm(["setvl 3, 0, 2, 1, 1, 1",
187 'sv.add 1.v, 5.v, 9.v',
188 "setvl. 0, 0, 1, 1, 0, 0",
189 'sv.add 1.v, 5.v, 9.v',
190 "setvl. 0, 0, 1, 1, 0, 0"
191 ])
192 sequence is as follows:
193 * setvl sets VL=2 but also "Vertical First" mode.
194 this sets MSR[SVF].
195 * first add, which has srcstep/dststep = 0, does add 1,5,9
196 * svstep EXPLICITLY walks srcstep/dststep to next element
197 * second add, which now has srcstep/dststep = 1, does add 2,6,10
198 * svstep EXPLICITLY walks srcstep/dststep to next element,
199 which now equals VL. srcstep and dststep are both set to
200 zero, and MSR[SVF] is cleared.
201 """
202 lst = SVP64Asm(["setvl 3, 0, 2, 1, 1, 1",
203 'sv.add 1.v, 5.v, 9.v',
204 "setvl. 0, 0, 1, 1, 0, 0", # svstep
205 'sv.add 1.v, 5.v, 9.v',
206 "setvl. 0, 0, 1, 1, 0, 0" # svstep
207 ])
208 lst = list(lst)
209
210 # SVSTATE (in this case, VL=2)
211 svstate = SVP64State()
212 svstate.vl = 2 # VL
213 svstate.maxvl = 2 # MAXVL
214 print ("SVSTATE", bin(svstate.asint()))
215
216 # initial values in GPR regfile
217 initial_regs = [0] * 32
218 initial_regs[9] = 0x1234
219 initial_regs[10] = 0x1111
220 initial_regs[5] = 0x4321
221 initial_regs[6] = 0x2223
222
223 # copy before running
224 expected_regs = deepcopy(initial_regs)
225 expected_regs[1] = 0x5555
226 expected_regs[2] = 0x3334
227 expected_regs[3] = 2 # setvl places copy of VL here
228
229 with Program(lst, bigendian=False) as program:
230 sim = self.run_tst_program(program, initial_regs, svstate=svstate)
231 print ("SVSTATE after", bin(sim.svstate.asint()))
232 print (" vl", bin(sim.svstate.vl))
233 print (" mvl", bin(sim.svstate.maxvl))
234 print (" srcstep", bin(sim.svstate.srcstep))
235 print (" dststep", bin(sim.svstate.dststep))
236 print (" vfirst", bin(sim.svstate. vfirst))
237 self.assertEqual(sim.svstate.vl, 2)
238 self.assertEqual(sim.svstate.maxvl, 2)
239 self.assertEqual(sim.svstate.srcstep, 0)
240 self.assertEqual(sim.svstate.dststep, 0)
241 # when end reached, vertical mode is exited
242 self.assertEqual(sim.svstate.vfirst, 0)
243 CR0 = sim.crl[0]
244 print(" CR0", bin(CR0.get_range().value))
245 self.assertEqual(CR0[CRFields.EQ], 1)
246 self.assertEqual(CR0[CRFields.LT], 0)
247 self.assertEqual(CR0[CRFields.GT], 0)
248 self.assertEqual(CR0[CRFields.SO], 0)
249
250 # check registers as expected
251 self._check_regs(sim, expected_regs)
252
253 def test__svstep_add_2(self):
254 """tests svstep with a branch.
255 lst = SVP64Asm(["setvl 3, 0, 2, 1, 1, 1",
256 'sv.add 1.v, 5.v, 9.v',
257 "setvl. 0, 0, 1, 1, 0, 0",
258 "bc 4, 2, -0xc"
259 ])
260 sequence is as follows:
261 * setvl sets VL=2 but also "Vertical First" mode.
262 this sets MSR[SVF].
263 * first time add, which has srcstep/dststep = 0, does add 1,5,9
264 * svstep EXPLICITLY walks srcstep/dststep to next element,
265 not yet met VL, so CR0.EQ is set to zero
266 * branch conditional checks bne on CR0, jumps back TWELVE bytes
267 because whilst branch is 32-bit the sv.add is 64-bit
268 * second time add, which now has srcstep/dststep = 1, does add 2,6,10
269 * svstep walks to next element, meets VL, so:
270 - srcstep and dststep set to zero
271 - CR0.EQ set to one
272 - MSR[SVF] is cleared
273 * branch conditional detects CR0.EQ=1 and FAILs the condition,
274 therefore loop ends.
275
276 we therefore have an explicit "Vertical-First" system which can
277 have **MULTIPLE* instructions inside a loop, running each element 0
278 first, then looping back and running all element 1, then all element 2
279 etc.
280 """
281 lst = SVP64Asm(["setvl 3, 0, 2, 1, 1, 1",
282 'sv.add 1.v, 5.v, 9.v',
283 "setvl. 0, 0, 1, 1, 0, 0", # svstep - this is 64-bit!
284 "bc 4, 2, -0xc" # branch to add (64-bit op so -0xc!)
285 ])
286 lst = list(lst)
287
288 # SVSTATE (in this case, VL=2)
289 svstate = SVP64State()
290 svstate.vl = 2 # VL
291 svstate.maxvl = 2 # MAXVL
292 print ("SVSTATE", bin(svstate.asint()))
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, svstate=svstate)
309 print ("SVSTATE after", bin(sim.svstate.asint()))
310 print (" vl", bin(sim.svstate.vl))
311 print (" mvl", bin(sim.svstate.maxvl))
312 print (" srcstep", bin(sim.svstate.srcstep))
313 print (" dststep", bin(sim.svstate.dststep))
314 print (" vfirst", bin(sim.svstate. vfirst))
315 self.assertEqual(sim.svstate.vl, 2)
316 self.assertEqual(sim.svstate.maxvl, 2)
317 self.assertEqual(sim.svstate.srcstep, 0)
318 self.assertEqual(sim.svstate.dststep, 0)
319 # when end reached, vertical mode is exited
320 self.assertEqual(sim.svstate.vfirst, 0)
321 CR0 = sim.crl[0]
322 print(" CR0", bin(CR0.get_range().value))
323 self.assertEqual(CR0[CRFields.EQ], 1)
324 self.assertEqual(CR0[CRFields.LT], 0)
325 self.assertEqual(CR0[CRFields.GT], 0)
326 self.assertEqual(CR0[CRFields.SO], 0)
327
328 # check registers as expected
329 self._check_regs(sim, expected_regs)
330
331 def test_svremap(self):
332 """svremap, see if values get set
333 """
334 lst = SVP64Asm(["svremap 11, 0, 1, 2, 3, 3, 1",
335 ])
336 lst = list(lst)
337
338 with Program(lst, bigendian=False) as program:
339 sim = self.run_tst_program(program)
340 svstate = sim.svstate
341 print ("SVREMAP after", bin(svstate.value))
342 print (" men", bin(svstate.SVme))
343 print (" mi0", bin(svstate.mi0))
344 print (" mi1", bin(svstate.mi1))
345 print (" mi2", bin(svstate.mi2))
346 print (" mo0", bin(svstate.mo0))
347 print (" mo1", bin(svstate.mo1))
348 print (" persist", bin(svstate.RMpst))
349 self.assertEqual(svstate.SVme, 11)
350 self.assertEqual(svstate.mi0, 0)
351 self.assertEqual(svstate.mi1, 1)
352 self.assertEqual(svstate.mi2, 2)
353 self.assertEqual(svstate.mo0, 3)
354 self.assertEqual(svstate.mo1, 3)
355 self.assertEqual(svstate.RMpst, 1)
356
357 def run_tst_program(self, prog, initial_regs=None,
358 svstate=None):
359 if initial_regs is None:
360 initial_regs = [0] * 32
361 simulator = run_tst(prog, initial_regs, svstate=svstate)
362 simulator.gpr.dump()
363 return simulator
364
365
366 if __name__ == "__main__":
367 unittest.main()
368