1 """SVP64 unit test for svindex
2 svindex SVG,rmm,SVd,ew,yx,mm,sk
4 from nmigen
import Module
, Signal
5 from nmigen
.sim
import Simulator
, Delay
, Settle
6 from nmutil
.formaltest
import FHDLTestCase
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
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
26 #x[a] = (x[a] + x[b]) & 0xffffffff
28 #x[d] = rotate(x[d], 16)
29 x
.append((a
, b
, d
, 16))
31 #x[c] = (x[c] + x[d]) & 0xffffffff
33 #x[b] = rotate(x[b], 12)
34 x
.append((c
, d
, b
, 12))
36 #x[a] = (x[a] + x[b]) & 0xffffffff
38 #x[d] = rotate(x[d], 8)
39 x
.append((a
, b
, d
, 8))
41 #x[c] = (x[c] + x[d]) & 0xffffffff
43 #x[b] = rotate(x[b], 7)
44 x
.append((c
, d
, b
, 7))
49 res
= ((v
<< c
) & 0xffffffff) | v
>> (32 - c
)
50 print ("op rotl32", hex(res
), hex(v
), hex(c
))
55 res
= (a
+ b
) & 0xffffffff
56 print ("op add", hex(res
), hex(a
), hex(b
))
62 print ("op xor", hex(res
), hex(a
), hex(b
))
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
)
71 def quarter_round(x
, a
, b
, c
, d
):
72 """collate list of reg-offsets for use with svindex/svremap
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)
80 def chacha_idx_schedule(x
, fn
=quarter_round_schedule
):
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
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
)
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
117 # OR the new value in, shifted up
118 val |
= value
<< (gpr_col
*ew_bits
)
119 regs
[base
+gpr_offs
] = val
122 class SVSTATETestCase(FHDLTestCase
):
124 def _check_regs(self
, sim
, expected
):
128 self
.assertEqual(sim
.gpr(i
), SelectableInt(expected
[i
], 64),
129 "GPR %d %x expected %x" % (i
, sim
.gpr(i
).value
, expected
[i
]))
131 def test_0_sv_index(self
):
132 """sets VL=10 (via SVSTATE) then does svindex mm=0, checks SPRs after
134 isa
= SVP64Asm(['svindex 1, 15, 5, 0, 0, 0, 0'
137 print ("listing", lst
)
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
147 svstate
= SVP64State()
149 svstate
.maxvl
= 10 # MAXVL
150 print ("SVSTATE", bin(svstate
.asint()))
152 # copy before running
153 expected_regs
= deepcopy(initial_regs
)
154 #expected_regs[1] = 0x3334
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
)
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)
189 shape
= sim
.spr
['SVSHAPE%d' % i
]
190 self
.assertEqual(shape
.svgpr
, 2) # SVG is shifted up by 1
192 def test_1_sv_index(self
):
193 """sets VL=10 (via SVSTATE) then does svindex mm=1, checks SPRs after
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'
200 print ("listing", lst
)
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
210 svstate
= SVP64State()
212 svstate
.maxvl
= 10 # MAXVL
213 print ("SVSTATE", bin(svstate
.asint()))
215 # copy before running
216 expected_regs
= deepcopy(initial_regs
)
217 #expected_regs[1] = 0x3334
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
)
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
258 shape
= sim
.spr
['SVSHAPE%d' % i
]
259 self
.assertEqual(shape
.asint(), 0) # all others zero
261 def test_0_sv_index_add(self
):
262 """sets VL=6 (via SVSTATE) then does svindex, and an add.
264 only RA is re-mapped via Indexing, not RB or RT
266 isa
= SVP64Asm(['svindex 8, 1, 1, 0, 0, 0, 0',
270 print ("listing", lst
)
272 # initial values in GPR regfile
273 initial_regs
= [0] * 32
274 idxs
= [1, 0, 5, 2, 4, 3] # random enough
276 initial_regs
[16+i
] = idxs
[i
]
280 svstate
= SVP64State()
282 svstate
.maxvl
= 6 # MAXVL
283 print ("SVSTATE", bin(svstate
.asint()))
285 # copy before running
286 expected_regs
= deepcopy(initial_regs
)
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])
293 with
Program(lst
, bigendian
=False) as program
:
294 sim
= self
.run_tst_program(program
, initial_regs
, svstate
=svstate
)
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
322 shape
= sim
.spr
['SVSHAPE%d' % i
]
323 self
.assertEqual(shape
.svgpr
, 0)
324 self
._check
_regs
(sim
, expected_regs
)
326 def test_1_sv_index_add(self
):
327 """sets VL=6 (via SVSTATE) then does modulo 3 svindex, and an add.
329 only RA is re-mapped via Indexing, not RB or RT
331 isa
= SVP64Asm(['svindex 8, 1, 3, 0, 0, 0, 0',
335 print ("listing", lst
)
337 # initial values in GPR regfile
338 initial_regs
= [0] * 32
339 idxs
= [1, 0, 5, 2, 4, 3] # random enough
341 initial_regs
[16+i
] = idxs
[i
]
345 svstate
= SVP64State()
347 svstate
.maxvl
= 6 # MAXVL
348 print ("SVSTATE", bin(svstate
.asint()))
350 # copy before running
351 expected_regs
= deepcopy(initial_regs
)
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])
358 with
Program(lst
, bigendian
=False) as program
:
359 sim
= self
.run_tst_program(program
, initial_regs
, svstate
=svstate
)
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
392 shape
= sim
.spr
['SVSHAPE%d' % i
]
393 self
.assertEqual(shape
.svgpr
, 0)
394 self
._check
_regs
(sim
, expected_regs
)
396 def test_2_sv_index_add(self
):
397 """sets VL=6 (via SVSTATE) then does 2D remapped svindex, and an add.
400 only RA is re-mapped via Indexing, not RB or RT
402 isa
= SVP64Asm(['svindex 8, 1, 3, 0, 1, 0, 0',
406 print ("listing", lst
)
408 # initial values in GPR regfile
409 initial_regs
= [0] * 32
410 idxs
= [1, 0, 5, 2, 4, 3] # random enough
412 initial_regs
[16+i
] = idxs
[i
]
416 svstate
= SVP64State()
418 svstate
.maxvl
= 6 # MAXVL
419 print ("SVSTATE", bin(svstate
.asint()))
421 # copy before running
422 expected_regs
= deepcopy(initial_regs
)
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])
432 with
Program(lst
, bigendian
=False) as program
:
433 sim
= self
.run_tst_program(program
, initial_regs
, svstate
=svstate
)
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
466 shape
= sim
.spr
['SVSHAPE%d' % i
]
467 self
.assertEqual(shape
.svgpr
, 0)
468 self
._check
_regs
(sim
, expected_regs
)
470 def test_3_sv_index_add_elwidth(self
):
471 """sets VL=6 (via SVSTATE) then does svindex with elwidth=8, and an add.
473 only RA is re-mapped via Indexing, not RB or RT
475 isa
= SVP64Asm(['svindex 8, 1, 1, 3, 0, 0, 0',
479 print ("listing", lst
)
481 # initial values in GPR regfile
482 initial_regs
= [0] * 32
483 idxs
= [1, 0, 5, 2, 4, 3] # random enough
485 # 8-bit indices starting at reg 16
486 set_masked_reg(initial_regs
, 16, i
, ew_bits
=8, value
=idxs
[i
])
490 svstate
= SVP64State()
492 svstate
.maxvl
= 6 # MAXVL
493 print ("SVSTATE", bin(svstate
.asint()))
495 # copy before running
496 expected_regs
= deepcopy(initial_regs
)
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])
503 with
Program(lst
, bigendian
=False) as program
:
504 sim
= self
.run_tst_program(program
, initial_regs
, svstate
=svstate
)
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
532 shape
= sim
.spr
['SVSHAPE%d' % i
]
533 self
.assertEqual(shape
.svgpr
, 0)
534 self
._check
_regs
(sim
, expected_regs
)
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,
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)
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
564 print ("listing", lst
)
567 chacha_idx_schedule(schedule
, fn
=quarter_round_schedule
)
569 # initial values in GPR regfile
570 initial_regs
= [0] * 128
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
)
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)
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
])
585 initial_regs
[17] = 32 # VL=2
590 set_masked_reg(initial_regs
, 0, i
, ew_bits
=32, value
=x
[i
])
593 svstate
= SVP64State()
595 svstate
.maxvl
= 32 # MAXVL
596 print ("SVSTATE", bin(svstate
.asint()))
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
)
604 set_masked_reg(expected_regs
, 0, i
, ew_bits
=32, value
=expected
[i
])
606 with
Program(lst
, bigendian
=False) as program
:
607 sim
= self
.run_tst_program(program
, initial_regs
, svstate
=svstate
)
609 # print out expected regs
611 RS
= sim
.gpr(i
).value
612 print ("expected", i
, hex(RS
), hex(expected_regs
[i
]))
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)
647 def run_tst_program(self
, prog
, initial_regs
=None,
649 if initial_regs
is None:
650 initial_regs
= [0] * 32
651 simulator
= run_tst(prog
, initial_regs
, svstate
=svstate
)
656 if __name__
== "__main__":