add first chacha20 round test
[openpower-isa.git] / src / openpower / decoder / isa / test_caller_svindex.py
1 """SVP64 unit test for svindex
2 svindex SVG,rmm,SVd,ew,yx,mm,sk
3 """
4 from nmigen import Module, Signal
5 from nmigen.sim import Simulator, Delay, Settle
6 from nmutil.formaltest import FHDLTestCase
7 import unittest
8 from openpower.decoder.isa.caller import ISACaller
9 from openpower.decoder.power_decoder import (create_pdecode)
10 from openpower.decoder.power_decoder2 import (PowerDecode2)
11 from openpower.simulator.program import Program
12 from openpower.decoder.isa.caller import ISACaller, SVP64State, CRFields
13 from openpower.decoder.selectable_int import SelectableInt
14 from openpower.decoder.orderedset import OrderedSet
15 from openpower.decoder.isa.all import ISA
16 from openpower.decoder.isa.test_caller import Register, run_tst
17 from openpower.sv.trans.svp64 import SVP64Asm
18 from openpower.consts import SVP64CROffs
19 from copy import deepcopy
20
21
22 # originally from https://github.com/pts/chacha20
23 def quarter_round_schedule(x, a, b, c, d):
24 """collate list of reg-offsets for use with svindex/svremap
25 """
26 #x[a] = (x[a] + x[b]) & 0xffffffff
27 #x[d] = x[d] ^ x[a]
28 #x[d] = rotate(x[d], 16)
29 x.append((a, b, d, 16))
30
31 #x[c] = (x[c] + x[d]) & 0xffffffff
32 #x[b] = x[b] ^ x[c]
33 #x[b] = rotate(x[b], 12)
34 x.append((c, d, b, 12))
35
36 #x[a] = (x[a] + x[b]) & 0xffffffff
37 #x[d] = x[d] ^ x[a]
38 #x[d] = rotate(x[d], 8)
39 x.append((a, b, d, 8))
40
41 #x[c] = (x[c] + x[d]) & 0xffffffff
42 #x[b] = x[b] ^ x[c]
43 #x[b] = rotate(x[b], 7)
44 x.append((c, d, b, 7))
45
46
47 def rotl32(v, c):
48 c = c & 0x1f
49 res = ((v << c) & 0xffffffff) | v >> (32 - c)
50 print ("op rotl32", hex(res), hex(v), hex(c))
51 return res
52
53
54 def add(a, b):
55 res = (a + b) & 0xffffffff
56 print ("op add", hex(res), hex(a), hex(b))
57 return res
58
59
60 def xor(a, b):
61 res = a ^ b
62 print ("op xor", hex(res), hex(a), hex(b))
63 return res
64
65
66 def sthth_round(x, a, b, d, rot):
67 x[a] = add(x[a], x[b])
68 x[d] = xor(x[d], x[a])
69 x[d] = rotl32(x[d], rot)
70
71 def quarter_round(x, a, b, c, d):
72 """collate list of reg-offsets for use with svindex/svremap
73 """
74 sthth_round(x, a, b, d, 16)
75 sthth_round(x, c, d, b, 12)
76 sthth_round(x, a, b, d, 8)
77 sthth_round(x, c, d, b, 7)
78
79
80 def chacha_idx_schedule(x, fn=quarter_round_schedule):
81 fn(x, 0, 4, 8, 12)
82 fn(x, 1, 5, 9, 13)
83 fn(x, 2, 6, 10, 14)
84 fn(x, 3, 7, 11, 15)
85 fn(x, 0, 5, 10, 15)
86 fn(x, 1, 6, 11, 12)
87 fn(x, 2, 7, 8, 13)
88 fn(x, 3, 4, 9, 14)
89
90
91 def get_masked_reg(regs, base, offs, ew_bits):
92 # rrrright. start by breaking down into row/col, based on elwidth
93 gpr_offs = offs // (64//ew_bits)
94 gpr_col = offs % (64//ew_bits)
95 # compute the mask based on ew_bits
96 mask = (1<<ew_bits)-1
97 # now select the 64-bit register, but get its value (easier)
98 val = regs[base+gpr_offs]
99 # now mask out the bit we don't want
100 val = val & ~(mask << (gpr_col*ew_bits))
101 # then return the bits we want, shifted down
102 return val >> (gpr_col*ew_bits)
103
104
105 def set_masked_reg(regs, base, offs, ew_bits, value):
106 # rrrright. start by breaking down into row/col, based on elwidth
107 gpr_offs = offs // (64//ew_bits)
108 gpr_col = offs % (64//ew_bits)
109 # compute the mask based on ew_bits
110 mask = (1<<ew_bits)-1
111 # now select the 64-bit register, but get its value (easier)
112 val = regs[base+gpr_offs]
113 # now mask out the bit we don't want
114 val = val & ~(mask << (gpr_col*ew_bits))
115 # then wipe the bit we don't want from the value
116 value = value & mask
117 # OR the new value in, shifted up
118 val |= value << (gpr_col*ew_bits)
119 regs[base+gpr_offs] = val
120
121
122 class SVSTATETestCase(FHDLTestCase):
123
124 def _check_regs(self, sim, expected):
125 print ("GPR")
126 sim.gpr.dump()
127 for i in range(32):
128 self.assertEqual(sim.gpr(i), SelectableInt(expected[i], 64),
129 "GPR %d %x expected %x" % (i, sim.gpr(i).value, expected[i]))
130
131 def test_0_sv_index(self):
132 """sets VL=10 (via SVSTATE) then does svindex mm=0, checks SPRs after
133 """
134 isa = SVP64Asm(['svindex 1, 15, 5, 0, 0, 0, 0'
135 ])
136 lst = list(isa)
137 print ("listing", lst)
138
139 # initial values in GPR regfile
140 initial_regs = [0] * 32
141 initial_regs[9] = 0x1234
142 initial_regs[10] = 0x1111
143 initial_regs[5] = 0x4321
144 initial_regs[6] = 0x2223
145
146 # SVSTATE vl=10
147 svstate = SVP64State()
148 svstate.vl = 10 # VL
149 svstate.maxvl = 10 # MAXVL
150 print ("SVSTATE", bin(svstate.asint()))
151
152 # copy before running
153 expected_regs = deepcopy(initial_regs)
154 #expected_regs[1] = 0x3334
155
156 with Program(lst, bigendian=False) as program:
157 sim = self.run_tst_program(program, initial_regs, svstate=svstate)
158 self._check_regs(sim, expected_regs)
159
160 print (sim.spr)
161 SVSHAPE0 = sim.spr['SVSHAPE0']
162 print ("SVSTATE after", bin(sim.svstate.asint()))
163 print (" vl", bin(sim.svstate.vl))
164 print (" mvl", bin(sim.svstate.maxvl))
165 print (" srcstep", bin(sim.svstate.srcstep))
166 print (" dststep", bin(sim.svstate.dststep))
167 print (" RMpst", bin(sim.svstate.RMpst))
168 print (" SVme", bin(sim.svstate.SVme))
169 print (" mo0", bin(sim.svstate.mo0))
170 print (" mo1", bin(sim.svstate.mo1))
171 print (" mi0", bin(sim.svstate.mi0))
172 print (" mi1", bin(sim.svstate.mi1))
173 print (" mi2", bin(sim.svstate.mi2))
174 print ("STATE0svgpr", hex(SVSHAPE0.svgpr))
175 print ("STATE0 xdim", SVSHAPE0.xdimsz)
176 print ("STATE0 ydim", SVSHAPE0.ydimsz)
177 print ("STATE0 skip", bin(SVSHAPE0.skip))
178 print ("STATE0 inv", SVSHAPE0.invxyz)
179 print ("STATE0order", SVSHAPE0.order)
180 self.assertEqual(sim.svstate.RMpst, 0) # mm=0 so persist=0
181 self.assertEqual(sim.svstate.SVme, 0b01111) # same as rmm
182 # rmm is 0b01111 which means mi0=0 mi1=1 mi2=2 mo0=3 mo1=0
183 self.assertEqual(sim.svstate.mi0, 0)
184 self.assertEqual(sim.svstate.mi1, 1)
185 self.assertEqual(sim.svstate.mi2, 2)
186 self.assertEqual(sim.svstate.mo0, 3)
187 self.assertEqual(sim.svstate.mo1, 0)
188 for i in range(4):
189 shape = sim.spr['SVSHAPE%d' % i]
190 self.assertEqual(shape.svgpr, 2) # SVG is shifted up by 1
191
192 def test_1_sv_index(self):
193 """sets VL=10 (via SVSTATE) then does svindex mm=1, checks SPRs after
194 """
195 # rmm: bits 0-2 (MSB0) are 0b011 and bits 3-4 are 0b10.
196 # therefore rmm is 0b011 || 0b10 --> 0b01110 -> 14
197 isa = SVP64Asm(['svindex 1, 14, 5, 0, 0, 1, 0'
198 ])
199 lst = list(isa)
200 print ("listing", lst)
201
202 # initial values in GPR regfile
203 initial_regs = [0] * 32
204 initial_regs[9] = 0x1234
205 initial_regs[10] = 0x1111
206 initial_regs[5] = 0x4321
207 initial_regs[6] = 0x2223
208
209 # SVSTATE vl=10
210 svstate = SVP64State()
211 svstate.vl = 10 # VL
212 svstate.maxvl = 10 # MAXVL
213 print ("SVSTATE", bin(svstate.asint()))
214
215 # copy before running
216 expected_regs = deepcopy(initial_regs)
217 #expected_regs[1] = 0x3334
218
219 with Program(lst, bigendian=False) as program:
220 sim = self.run_tst_program(program, initial_regs, svstate=svstate)
221 self._check_regs(sim, expected_regs)
222
223 print (sim.spr)
224 SVSHAPE2 = sim.spr['SVSHAPE2']
225 print ("SVSTATE after", bin(sim.svstate.asint()))
226 print (" vl", bin(sim.svstate.vl))
227 print (" mvl", bin(sim.svstate.maxvl))
228 print (" srcstep", bin(sim.svstate.srcstep))
229 print (" dststep", bin(sim.svstate.dststep))
230 print (" RMpst", bin(sim.svstate.RMpst))
231 print (" SVme", bin(sim.svstate.SVme))
232 print (" mo0", bin(sim.svstate.mo0))
233 print (" mo1", bin(sim.svstate.mo1))
234 print (" mi0", bin(sim.svstate.mi0))
235 print (" mi1", bin(sim.svstate.mi1))
236 print (" mi2", bin(sim.svstate.mi2))
237 print ("STATE2svgpr", hex(SVSHAPE2.svgpr))
238 print ("STATE2 xdim", SVSHAPE2.xdimsz)
239 print ("STATE2 ydim", SVSHAPE2.ydimsz)
240 print ("STATE2 skip", bin(SVSHAPE2.skip))
241 print ("STATE2 inv", SVSHAPE2.invxyz)
242 print ("STATE2order", SVSHAPE2.order)
243 self.assertEqual(sim.svstate.RMpst, 1) # mm=1 so persist=1
244 # rmm is 0b01110 which means mo0 = 2
245 self.assertEqual(sim.svstate.mi0, 0)
246 self.assertEqual(sim.svstate.mi1, 0)
247 self.assertEqual(sim.svstate.mi2, 0)
248 self.assertEqual(sim.svstate.mo0, 2)
249 self.assertEqual(sim.svstate.mo1, 0)
250 # and mo0 should be activated
251 self.assertEqual(sim.svstate.SVme, 0b01000)
252 # now check the SVSHAPEs. 2 was the one targetted
253 self.assertEqual(SVSHAPE2.svgpr, 2) # SVG is shifted up by 1
254 self.assertEqual(SVSHAPE2.xdimsz, 5) # SHAPE2 xdim set to 5
255 self.assertEqual(SVSHAPE2.ydimsz, 1) # SHAPE2 ydim 1
256 # all others must be zero
257 for i in [0,1,3]:
258 shape = sim.spr['SVSHAPE%d' % i]
259 self.assertEqual(shape.asint(), 0) # all others zero
260
261 def test_0_sv_index_add(self):
262 """sets VL=6 (via SVSTATE) then does svindex, and an add.
263
264 only RA is re-mapped via Indexing, not RB or RT
265 """
266 isa = SVP64Asm(['svindex 8, 1, 1, 0, 0, 0, 0',
267 'sv.add *8, *0, *0',
268 ])
269 lst = list(isa)
270 print ("listing", lst)
271
272 # initial values in GPR regfile
273 initial_regs = [0] * 32
274 idxs = [1, 0, 5, 2, 4, 3] # random enough
275 for i in range(6):
276 initial_regs[16+i] = idxs[i]
277 initial_regs[i] = i
278
279 # SVSTATE vl=10
280 svstate = SVP64State()
281 svstate.vl = 6 # VL
282 svstate.maxvl = 6 # MAXVL
283 print ("SVSTATE", bin(svstate.asint()))
284
285 # copy before running
286 expected_regs = deepcopy(initial_regs)
287 for i in range(6):
288 RA = initial_regs[0+idxs[i]]
289 RB = initial_regs[0+i]
290 expected_regs[i+8] = RA+RB
291 print ("expected", i, expected_regs[i+8])
292
293 with Program(lst, bigendian=False) as program:
294 sim = self.run_tst_program(program, initial_regs, svstate=svstate)
295
296 print (sim.spr)
297 SVSHAPE0 = sim.spr['SVSHAPE0']
298 print ("SVSTATE after", bin(sim.svstate.asint()))
299 print (" vl", bin(sim.svstate.vl))
300 print (" mvl", bin(sim.svstate.maxvl))
301 print (" srcstep", bin(sim.svstate.srcstep))
302 print (" dststep", bin(sim.svstate.dststep))
303 print (" RMpst", bin(sim.svstate.RMpst))
304 print (" SVme", bin(sim.svstate.SVme))
305 print (" mo0", bin(sim.svstate.mo0))
306 print (" mo1", bin(sim.svstate.mo1))
307 print (" mi0", bin(sim.svstate.mi0))
308 print (" mi1", bin(sim.svstate.mi1))
309 print (" mi2", bin(sim.svstate.mi2))
310 print ("STATE0svgpr", hex(SVSHAPE0.svgpr))
311 print (sim.gpr.dump())
312 self.assertEqual(sim.svstate.RMpst, 0) # mm=0 so persist=0
313 self.assertEqual(sim.svstate.SVme, 0b00001) # same as rmm
314 # rmm is 0b00001 which means mi0=0 and all others inactive (0)
315 self.assertEqual(sim.svstate.mi0, 0)
316 self.assertEqual(sim.svstate.mi1, 0)
317 self.assertEqual(sim.svstate.mi2, 0)
318 self.assertEqual(sim.svstate.mo0, 0)
319 self.assertEqual(sim.svstate.mo1, 0)
320 self.assertEqual(SVSHAPE0.svgpr, 16) # SVG is shifted up by 1
321 for i in range(1,4):
322 shape = sim.spr['SVSHAPE%d' % i]
323 self.assertEqual(shape.svgpr, 0)
324 self._check_regs(sim, expected_regs)
325
326 def test_1_sv_index_add(self):
327 """sets VL=6 (via SVSTATE) then does modulo 3 svindex, and an add.
328
329 only RA is re-mapped via Indexing, not RB or RT
330 """
331 isa = SVP64Asm(['svindex 8, 1, 3, 0, 0, 0, 0',
332 'sv.add *8, *0, *0',
333 ])
334 lst = list(isa)
335 print ("listing", lst)
336
337 # initial values in GPR regfile
338 initial_regs = [0] * 32
339 idxs = [1, 0, 5, 2, 4, 3] # random enough
340 for i in range(6):
341 initial_regs[16+i] = idxs[i]
342 initial_regs[i] = i
343
344 # SVSTATE vl=10
345 svstate = SVP64State()
346 svstate.vl = 6 # VL
347 svstate.maxvl = 6 # MAXVL
348 print ("SVSTATE", bin(svstate.asint()))
349
350 # copy before running
351 expected_regs = deepcopy(initial_regs)
352 for i in range(6):
353 RA = initial_regs[0+idxs[i%3]] # modulo 3 but still indexed
354 RB = initial_regs[0+i]
355 expected_regs[i+8] = RA+RB
356 print ("expected", i, expected_regs[i+8])
357
358 with Program(lst, bigendian=False) as program:
359 sim = self.run_tst_program(program, initial_regs, svstate=svstate)
360
361 print (sim.spr)
362 SVSHAPE0 = sim.spr['SVSHAPE0']
363 print ("SVSTATE after", bin(sim.svstate.asint()))
364 print (" vl", bin(sim.svstate.vl))
365 print (" mvl", bin(sim.svstate.maxvl))
366 print (" srcstep", bin(sim.svstate.srcstep))
367 print (" dststep", bin(sim.svstate.dststep))
368 print (" RMpst", bin(sim.svstate.RMpst))
369 print (" SVme", bin(sim.svstate.SVme))
370 print (" mo0", bin(sim.svstate.mo0))
371 print (" mo1", bin(sim.svstate.mo1))
372 print (" mi0", bin(sim.svstate.mi0))
373 print (" mi1", bin(sim.svstate.mi1))
374 print (" mi2", bin(sim.svstate.mi2))
375 print ("STATE0svgpr", hex(SVSHAPE0.svgpr))
376 print ("STATE0 xdim", SVSHAPE0.xdimsz)
377 print ("STATE0 ydim", SVSHAPE0.ydimsz)
378 print ("STATE0 skip", bin(SVSHAPE0.skip))
379 print ("STATE0 inv", SVSHAPE0.invxyz)
380 print ("STATE0order", SVSHAPE0.order)
381 print (sim.gpr.dump())
382 self.assertEqual(sim.svstate.RMpst, 0) # mm=0 so persist=0
383 self.assertEqual(sim.svstate.SVme, 0b00001) # same as rmm
384 # rmm is 0b00001 which means mi0=0 and all others inactive (0)
385 self.assertEqual(sim.svstate.mi0, 0)
386 self.assertEqual(sim.svstate.mi1, 0)
387 self.assertEqual(sim.svstate.mi2, 0)
388 self.assertEqual(sim.svstate.mo0, 0)
389 self.assertEqual(sim.svstate.mo1, 0)
390 self.assertEqual(SVSHAPE0.svgpr, 16) # SVG is shifted up by 1
391 for i in range(1,4):
392 shape = sim.spr['SVSHAPE%d' % i]
393 self.assertEqual(shape.svgpr, 0)
394 self._check_regs(sim, expected_regs)
395
396 def test_2_sv_index_add(self):
397 """sets VL=6 (via SVSTATE) then does 2D remapped svindex, and an add.
398
399 dim=3,yx=1
400 only RA is re-mapped via Indexing, not RB or RT
401 """
402 isa = SVP64Asm(['svindex 8, 1, 3, 0, 1, 0, 0',
403 'sv.add *8, *0, *0',
404 ])
405 lst = list(isa)
406 print ("listing", lst)
407
408 # initial values in GPR regfile
409 initial_regs = [0] * 32
410 idxs = [1, 0, 5, 2, 4, 3] # random enough
411 for i in range(6):
412 initial_regs[16+i] = idxs[i]
413 initial_regs[i] = i
414
415 # SVSTATE vl=10
416 svstate = SVP64State()
417 svstate.vl = 6 # VL
418 svstate.maxvl = 6 # MAXVL
419 print ("SVSTATE", bin(svstate.asint()))
420
421 # copy before running
422 expected_regs = deepcopy(initial_regs)
423 for i in range(6):
424 xi = i % 3
425 yi = i // 3
426 remap = yi+xi*2
427 RA = initial_regs[0+idxs[remap]] # modulo 3 but still indexed
428 RB = initial_regs[0+i]
429 expected_regs[i+8] = RA+RB
430 print ("expected", i, expected_regs[i+8])
431
432 with Program(lst, bigendian=False) as program:
433 sim = self.run_tst_program(program, initial_regs, svstate=svstate)
434
435 print (sim.spr)
436 SVSHAPE0 = sim.spr['SVSHAPE0']
437 print ("SVSTATE after", bin(sim.svstate.asint()))
438 print (" vl", bin(sim.svstate.vl))
439 print (" mvl", bin(sim.svstate.maxvl))
440 print (" srcstep", bin(sim.svstate.srcstep))
441 print (" dststep", bin(sim.svstate.dststep))
442 print (" RMpst", bin(sim.svstate.RMpst))
443 print (" SVme", bin(sim.svstate.SVme))
444 print (" mo0", bin(sim.svstate.mo0))
445 print (" mo1", bin(sim.svstate.mo1))
446 print (" mi0", bin(sim.svstate.mi0))
447 print (" mi1", bin(sim.svstate.mi1))
448 print (" mi2", bin(sim.svstate.mi2))
449 print ("STATE0svgpr", hex(SVSHAPE0.svgpr))
450 print ("STATE0 xdim", SVSHAPE0.xdimsz)
451 print ("STATE0 ydim", SVSHAPE0.ydimsz)
452 print ("STATE0 skip", bin(SVSHAPE0.skip))
453 print ("STATE0 inv", SVSHAPE0.invxyz)
454 print ("STATE0order", SVSHAPE0.order)
455 print (sim.gpr.dump())
456 self.assertEqual(sim.svstate.RMpst, 0) # mm=0 so persist=0
457 self.assertEqual(sim.svstate.SVme, 0b00001) # same as rmm
458 # rmm is 0b00001 which means mi0=0 and all others inactive (0)
459 self.assertEqual(sim.svstate.mi0, 0)
460 self.assertEqual(sim.svstate.mi1, 0)
461 self.assertEqual(sim.svstate.mi2, 0)
462 self.assertEqual(sim.svstate.mo0, 0)
463 self.assertEqual(sim.svstate.mo1, 0)
464 self.assertEqual(SVSHAPE0.svgpr, 16) # SVG is shifted up by 1
465 for i in range(1,4):
466 shape = sim.spr['SVSHAPE%d' % i]
467 self.assertEqual(shape.svgpr, 0)
468 self._check_regs(sim, expected_regs)
469
470 def test_3_sv_index_add_elwidth(self):
471 """sets VL=6 (via SVSTATE) then does svindex with elwidth=8, and an add.
472
473 only RA is re-mapped via Indexing, not RB or RT
474 """
475 isa = SVP64Asm(['svindex 8, 1, 1, 3, 0, 0, 0',
476 'sv.add *8, *0, *0',
477 ])
478 lst = list(isa)
479 print ("listing", lst)
480
481 # initial values in GPR regfile
482 initial_regs = [0] * 32
483 idxs = [1, 0, 5, 2, 4, 3] # random enough
484 for i in range(6):
485 # 8-bit indices starting at reg 16
486 set_masked_reg(initial_regs, 16, i, ew_bits=8, value=idxs[i])
487 initial_regs[i] = i
488
489 # SVSTATE vl=10
490 svstate = SVP64State()
491 svstate.vl = 6 # VL
492 svstate.maxvl = 6 # MAXVL
493 print ("SVSTATE", bin(svstate.asint()))
494
495 # copy before running
496 expected_regs = deepcopy(initial_regs)
497 for i in range(6):
498 RA = initial_regs[0+idxs[i]]
499 RB = initial_regs[0+i]
500 expected_regs[i+8] = RA+RB
501 print ("expected", i, expected_regs[i+8])
502
503 with Program(lst, bigendian=False) as program:
504 sim = self.run_tst_program(program, initial_regs, svstate=svstate)
505
506 print (sim.spr)
507 SVSHAPE0 = sim.spr['SVSHAPE0']
508 print ("SVSTATE after", bin(sim.svstate.asint()))
509 print (" vl", bin(sim.svstate.vl))
510 print (" mvl", bin(sim.svstate.maxvl))
511 print (" srcstep", bin(sim.svstate.srcstep))
512 print (" dststep", bin(sim.svstate.dststep))
513 print (" RMpst", bin(sim.svstate.RMpst))
514 print (" SVme", bin(sim.svstate.SVme))
515 print (" mo0", bin(sim.svstate.mo0))
516 print (" mo1", bin(sim.svstate.mo1))
517 print (" mi0", bin(sim.svstate.mi0))
518 print (" mi1", bin(sim.svstate.mi1))
519 print (" mi2", bin(sim.svstate.mi2))
520 print ("STATE0svgpr", hex(SVSHAPE0.svgpr))
521 print (sim.gpr.dump())
522 self.assertEqual(sim.svstate.RMpst, 0) # mm=0 so persist=0
523 self.assertEqual(sim.svstate.SVme, 0b00001) # same as rmm
524 # rmm is 0b00001 which means mi0=0 and all others inactive (0)
525 self.assertEqual(sim.svstate.mi0, 0)
526 self.assertEqual(sim.svstate.mi1, 0)
527 self.assertEqual(sim.svstate.mi2, 0)
528 self.assertEqual(sim.svstate.mo0, 0)
529 self.assertEqual(sim.svstate.mo1, 0)
530 self.assertEqual(SVSHAPE0.svgpr, 16) # SVG is shifted up by 1
531 for i in range(1,4):
532 shape = sim.spr['SVSHAPE%d' % i]
533 self.assertEqual(shape.svgpr, 0)
534 self._check_regs(sim, expected_regs)
535
536 def test_1_sv_index_rot32(self):
537 """sets VL=8 (via SVSTATE) then does modulo 4 svindex, and a rotate.
538 RA is re-mapped via Indexing,
539 RB is re-mapped via different Indexing,
540
541 svremap RT=0,RA=1,RB=0
542 add r0, r1, r0 RT, RA, RB
543 svremap RS=2,RA=2,RB=0 # RB stays = 0
544 xor r2, r2, r0 RA, RS, RB
545 svremap RS=2,RA=2,RB=3 # RA stays = 2
546 rlwnm r2, r2, r3, 0, 31 rlwnm RA,RS,RB,MB,ME (Rc=0)
547 """
548 isa = SVP64Asm([
549 'setvl 17, 17, 32, 1, 1, 1', # vertical-first
550 'svindex 11, 0, 1, 3, 0, 1, 0', # SVSHAPE0, a
551 'svindex 15, 1, 1, 3, 0, 1, 0', # SVSHAPE1, b
552 'svindex 19, 2, 1, 3, 0, 1, 0', # SVSHAPE2, c
553 'svindex 21, 3, 4, 3, 0, 1, 0', # SVSHAPE3, shift amount, mod 4
554 'svremap 31, 1, 0, 0, 0, 0, 0', # RA=1, RB=0, RT=0 (0b01011)
555 'sv.add/w=32 *0, *0, *0',
556 'svremap 31, 2, 0, 2, 2, 0, 0', # RA=2, RB=0, RS=2 (0b00111)
557 'sv.xor/w=32 *0, *0, *0',
558 'svremap 31, 0, 3, 2, 2, 0, 0', # RA=2, RB=3, RS=2 (0b01110)
559 'sv.rlwnm/w=32 *0, *0, *18, 0, 31',
560 'svstep. 17, 1, 0', # step to next
561 'bc 6, 3, -0x28', # VF loop
562 ])
563 lst = list(isa)
564 print ("listing", lst)
565
566 schedule = []
567 chacha_idx_schedule(schedule, fn=quarter_round_schedule)
568
569 # initial values in GPR regfile
570 initial_regs = [0] * 128
571
572 # offsets for a b c
573 for i, (a,b,c,d) in enumerate(schedule):
574 set_masked_reg(initial_regs, 22, i, ew_bits=8, value=a)
575 set_masked_reg(initial_regs, 30, i, ew_bits=8, value=b)
576 set_masked_reg(initial_regs, 38, i, ew_bits=8, value=c)
577
578 # offsets for d (modulo 4 shift amount)
579 shifts = [16, 12, 8, 7] # chacha20 shifts
580 idxs2 = [0, 1, 2, 3] # cycle order (for fun)
581 for i in range(4):
582 set_masked_reg(initial_regs, 42, i, ew_bits=8, value=idxs2[i])
583 set_masked_reg(initial_regs, 18, i, ew_bits=32, value=shifts[i])
584
585 initial_regs[17] = 32 # VL=2
586 x = [0] * 16
587 for i in range(16):
588 x[i] = i<<1
589 for i in range(16):
590 set_masked_reg(initial_regs, 0, i, ew_bits=32, value=x[i])
591
592 # SVSTATE vl=10
593 svstate = SVP64State()
594 svstate.vl = 32 # VL
595 svstate.maxvl = 32 # MAXVL
596 print ("SVSTATE", bin(svstate.asint()))
597
598 # copy before running, compute expected results
599 expected_regs = deepcopy(initial_regs)
600 expected_regs[17] = 0 # reaches zero
601 expected = deepcopy(x)
602 chacha_idx_schedule(expected, fn=quarter_round)
603 for i in range(16):
604 set_masked_reg(expected_regs, 0, i, ew_bits=32, value=expected[i])
605
606 with Program(lst, bigendian=False) as program:
607 sim = self.run_tst_program(program, initial_regs, svstate=svstate)
608
609 # print out expected regs
610 for i in range(8):
611 RS = sim.gpr(i).value
612 print ("expected", i, hex(RS), hex(expected_regs[i]))
613
614 print (sim.spr)
615 SVSHAPE0 = sim.spr['SVSHAPE0']
616 SVSHAPE1 = sim.spr['SVSHAPE1']
617 print ("SVSTATE after", bin(sim.svstate.asint()))
618 print (" vl", bin(sim.svstate.vl))
619 print (" mvl", bin(sim.svstate.maxvl))
620 print (" srcstep", bin(sim.svstate.srcstep))
621 print (" dststep", bin(sim.svstate.dststep))
622 print (" RMpst", bin(sim.svstate.RMpst))
623 print (" SVme", bin(sim.svstate.SVme))
624 print (" mo0", bin(sim.svstate.mo0))
625 print (" mo1", bin(sim.svstate.mo1))
626 print (" mi0", bin(sim.svstate.mi0))
627 print (" mi1", bin(sim.svstate.mi1))
628 print (" mi2", bin(sim.svstate.mi2))
629 print ("STATE0svgpr", hex(SVSHAPE0.svgpr))
630 print ("STATE0 xdim", SVSHAPE0.xdimsz)
631 print ("STATE0 ydim", SVSHAPE0.ydimsz)
632 print ("STATE0 skip", bin(SVSHAPE0.skip))
633 print ("STATE0 inv", SVSHAPE0.invxyz)
634 print ("STATE0order", SVSHAPE0.order)
635 print (sim.gpr.dump())
636 self._check_regs(sim, expected_regs)
637 self.assertEqual(sim.svstate.RMpst, 0)
638 self.assertEqual(sim.svstate.SVme, 0b11111)
639 self.assertEqual(sim.svstate.mi0, 0)
640 self.assertEqual(sim.svstate.mi1, 3)
641 self.assertEqual(sim.svstate.mi2, 2)
642 self.assertEqual(sim.svstate.mo0, 2)
643 self.assertEqual(sim.svstate.mo1, 0)
644 self.assertEqual(SVSHAPE0.svgpr, 22)
645 self.assertEqual(SVSHAPE1.svgpr, 30)
646
647 def run_tst_program(self, prog, initial_regs=None,
648 svstate=None):
649 if initial_regs is None:
650 initial_regs = [0] * 32
651 simulator = run_tst(prog, initial_regs, svstate=svstate)
652 simulator.gpr.dump()
653 return simulator
654
655
656 if __name__ == "__main__":
657 unittest.main()
658