2 from copy
import deepcopy
4 from nmutil
.formaltest
import FHDLTestCase
5 from openpower
.decoder
.isa
.caller
import CRFields
, SVP64State
6 from openpower
.decoder
.isa
.test_caller
import run_tst
7 from openpower
.decoder
.selectable_int
import SelectableInt
8 from openpower
.simulator
.program
import Program
9 from openpower
.insndb
.asm
import SVP64Asm
12 class DecoderTestCase(FHDLTestCase
):
14 def _check_regs(self
, sim
, expected
):
16 self
.assertEqual(sim
.gpr(i
), SelectableInt(expected
[i
], 64),
17 "reg %d expected %x got %x" %
18 (i
, sim
.gpr(i
).value
, expected
[i
]))
20 def tst_sv_load_store(self
):
21 lst
= SVP64Asm(["addi 1, 0, 0x0010",
29 # SVSTATE (in this case, VL=2)
30 svstate
= SVP64State()
32 svstate
.maxvl
= 2 # MAXVL
33 print("SVSTATE", bin(svstate
.asint()))
35 with
Program(lst
, bigendian
=False) as program
:
36 sim
= self
.run_tst_program(program
, svstate
=svstate
)
38 self
.assertEqual(sim
.gpr(9), SelectableInt(0x1234, 64))
39 self
.assertEqual(sim
.gpr(10), SelectableInt(0x1235, 64))
41 def test_sv_extsw_intpred(self
):
42 # extsb, integer twin-pred mask: source is ~r3 (0b01), dest r3 (0b10)
43 # works as follows, where any zeros indicate "skip element"
44 # - sources are 9 and 10
46 # - source mask says "pick first element from source (5)
47 # - dest mask says "pick *second* element from dest (10)
49 # therefore the operation that's carried out is:
50 # GPR(10) = extsb(GPR(5))
52 # this is a type of back-to-back VREDUCE and VEXPAND but it applies
53 # to *operations*, not just MVs like in traditional Vector ISAs
56 # reg num 0 1 2 3 4 5 6 7 8 9 10
63 isa
= SVP64Asm(['sv.extsb/sm=~r3/dm=r3 *5, *9'
68 # initial values in GPR regfile
69 initial_regs
= [0] * 32
70 initial_regs
[3] = 0b10 # predicate mask
71 initial_regs
[9] = 0x91 # source ~r3 is 0b01 so this will be used
72 initial_regs
[10] = 0x90 # this gets skipped
73 # SVSTATE (in this case, VL=2)
74 svstate
= SVP64State()
76 svstate
.maxvl
= 2 # MAXVL
77 print("SVSTATE", bin(svstate
.asint()))
79 expected_regs
= deepcopy(initial_regs
)
80 expected_regs
[5] = 0x0 # dest r3 is 0b10: skip
81 expected_regs
[6] = 0xffff_ffff_ffff_ff91 # 2nd bit of r3 is 1
83 with
Program(lst
, bigendian
=False) as program
:
84 sim
= self
.run_tst_program(program
, initial_regs
, svstate
)
85 self
._check
_regs
(sim
, expected_regs
)
87 def test_sv_extsw_intpred_dz(self
):
88 # extsb, integer twin-pred mask: dest is r3 (0b01), zeroing on dest
89 isa
= SVP64Asm(['sv.extsb/dm=r3/dz *5, *9'
94 # initial values in GPR regfile
95 initial_regs
= [0] * 32
96 initial_regs
[3] = 0b01 # predicate mask (dest)
97 initial_regs
[5] = 0xfeed # going to be overwritten
98 initial_regs
[6] = 0xbeef # going to be overwritten (with zero)
99 initial_regs
[9] = 0x91 # dest r3 is 0b01 so this will be used
100 initial_regs
[10] = 0x90 # this gets read but the output gets zero'd
101 # SVSTATE (in this case, VL=2)
102 svstate
= SVP64State()
104 svstate
.maxvl
= 2 # MAXVL
105 print("SVSTATE", bin(svstate
.asint()))
106 # copy before running
107 expected_regs
= deepcopy(initial_regs
)
108 expected_regs
[5] = 0xffff_ffff_ffff_ff91 # dest r3 is 0b01: store
109 expected_regs
[6] = 0 # 2nd bit of r3 is 1: zero
111 with
Program(lst
, bigendian
=False) as program
:
112 sim
= self
.run_tst_program(program
, initial_regs
, svstate
)
113 self
._check
_regs
(sim
, expected_regs
)
115 def test_sv_add_intpred(self
):
116 # adds, integer predicated mask r3=0b10
117 # 1 = 5 + 9 => not to be touched (skipped)
118 # 2 = 6 + 10 => 0x3334 = 0x2223+0x1111
119 # reg num 0 1 2 3 4 5 6 7 8 9 10 11
120 # src r3=0b10 N Y N Y
122 # +-------+ | add + |
123 # | +-------+ add --+
126 isa
= SVP64Asm(['sv.add/m=r3 *1, *5, *9'
129 print("listing", lst
)
131 # initial values in GPR regfile
132 initial_regs
= [0] * 32
133 initial_regs
[1] = 0xbeef # not to be altered
134 initial_regs
[3] = 0b10 # predicate mask
135 initial_regs
[9] = 0x1234
136 initial_regs
[10] = 0x1111
137 initial_regs
[5] = 0x4321
138 initial_regs
[6] = 0x2223
139 # SVSTATE (in this case, VL=2)
140 svstate
= SVP64State()
142 svstate
.maxvl
= 2 # MAXVL
143 print("SVSTATE", bin(svstate
.asint()))
144 # copy before running
145 expected_regs
= deepcopy(initial_regs
)
146 expected_regs
[1] = 0xbeef
147 expected_regs
[2] = 0x3334
149 with
Program(lst
, bigendian
=False) as program
:
150 sim
= self
.run_tst_program(program
, initial_regs
, svstate
)
151 self
._check
_regs
(sim
, expected_regs
)
153 def test_sv_add_cr_pred(self
):
154 # adds, CR predicated mask CR4.eq = 1, CR5.eq = 0, invert (ne)
155 # 1 = 5 + 9 => not to be touched (skipped)
156 # 2 = 6 + 10 => 0x3334 = 0x2223+0x1111
157 isa
= SVP64Asm(['sv.add/m=ne *1, *5, *9'
160 print("listing", lst
)
162 # initial values in GPR regfile
163 initial_regs
= [0] * 32
164 initial_regs
[1] = 0xbeef # not to be altered
165 initial_regs
[9] = 0x1234
166 initial_regs
[10] = 0x1111
167 initial_regs
[5] = 0x4321
168 initial_regs
[6] = 0x2223
169 # SVSTATE (in this case, VL=2)
170 svstate
= SVP64State()
172 svstate
.maxvl
= 2 # MAXVL
173 print("SVSTATE", bin(svstate
.asint()))
174 # copy before running
175 expected_regs
= deepcopy(initial_regs
)
176 expected_regs
[1] = 0xbeef
177 expected_regs
[2] = 0x3334
179 # set up CR predicate - CR4.eq=1 and CR5.eq=0
180 cr
= (0b0010) << ((7-4)*4) # CR4.eq (we hope)
182 with
Program(lst
, bigendian
=False) as program
:
183 sim
= self
.run_tst_program(program
, initial_regs
, svstate
,
185 self
._check
_regs
(sim
, expected_regs
)
187 def test_intpred_vcompress(self
):
188 # reg num 0 1 2 3 4 5 6 7 8 9 10 11
196 isa
= SVP64Asm(['sv.extsb/sm=r3 *5, *9'])
198 print("listing", lst
)
200 # initial values in GPR regfile
201 initial_regs
= [0] * 32
202 initial_regs
[3] = 0b101 # predicate mask
203 initial_regs
[9] = 0x90 # source r3 is 0b101 so this will be used
204 initial_regs
[10] = 0x91 # this gets skipped
205 initial_regs
[11] = 0x92 # source r3 is 0b101 so this will be used
206 # SVSTATE (in this case, VL=3)
207 svstate
= SVP64State()
209 svstate
.maxvl
= 3 # MAXVL
210 print("SVSTATE", bin(svstate
.asint()))
211 # copy before running
212 expected_regs
= deepcopy(initial_regs
)
213 expected_regs
[5] = 0xffff_ffff_ffff_ff90 # (from r9)
214 expected_regs
[6] = 0xffff_ffff_ffff_ff92 # (from r11)
215 expected_regs
[7] = 0x0 # (VL loop runs out before we can use it)
217 with
Program(lst
, bigendian
=False) as program
:
218 sim
= self
.run_tst_program(program
, initial_regs
, svstate
)
219 self
._check
_regs
(sim
, expected_regs
)
221 def test_intpred_vexpand(self
):
222 # reg num 0 1 2 3 4 5 6 7 8 9 10 11
228 # dest r3=0b101 Y N Y
230 isa
= SVP64Asm(['sv.extsb/dm=r3 *5, *9'])
232 print("listing", lst
)
234 # initial values in GPR regfile
235 initial_regs
= [0] * 32
236 initial_regs
[3] = 0b101 # predicate mask
237 initial_regs
[9] = 0x90 # source is "always", so this will be used
238 initial_regs
[10] = 0x91 # likewise
239 initial_regs
[11] = 0x92 # the VL loop runs out before we can use it
240 # SVSTATE (in this case, VL=3)
241 svstate
= SVP64State()
243 svstate
.maxvl
= 3 # MAXVL
244 print("SVSTATE", bin(svstate
.asint()))
245 # copy before running
246 expected_regs
= deepcopy(initial_regs
)
247 expected_regs
[5] = 0xffff_ffff_ffff_ff90 # 1st bit of r3 is 1
248 expected_regs
[6] = 0x0 # skip
249 expected_regs
[7] = 0xffff_ffff_ffff_ff91 # 3nd bit of r3 is 1
251 with
Program(lst
, bigendian
=False) as program
:
252 sim
= self
.run_tst_program(program
, initial_regs
, svstate
)
253 self
._check
_regs
(sim
, expected_regs
)
255 def test_intpred_twinpred(self
):
256 # reg num 0 1 2 3 4 5 6 7 8 9 10 11
261 # dest ~r3=0b010 N Y N
263 isa
= SVP64Asm(['sv.extsb/sm=r3/dm=~r3 *5, *9'])
265 print("listing", lst
)
267 # initial values in GPR regfile
268 initial_regs
= [0] * 32
269 initial_regs
[3] = 0b101 # predicate mask
270 initial_regs
[9] = 0x90 # source r3 is 0b101 so this will be used
271 initial_regs
[10] = 0x91 # this gets skipped
272 initial_regs
[11] = 0x92 # VL loop runs out before we can use it
273 # SVSTATE (in this case, VL=3)
274 svstate
= SVP64State()
276 svstate
.maxvl
= 3 # MAXVL
277 print("SVSTATE", bin(svstate
.asint()))
278 # copy before running
279 expected_regs
= deepcopy(initial_regs
)
280 expected_regs
[5] = 0x0 # dest ~r3 is 0b010: skip
281 expected_regs
[6] = 0xffff_ffff_ffff_ff90 # 2nd bit of ~r3 is 1
282 expected_regs
[7] = 0x0 # dest ~r3 is 0b010: skip
284 with
Program(lst
, bigendian
=False) as program
:
285 sim
= self
.run_tst_program(program
, initial_regs
, svstate
)
286 self
._check
_regs
(sim
, expected_regs
)
288 # checks that we are able to resume in the middle of a VL loop,
289 # after an interrupt, or after the user has updated src/dst step
290 # let's assume the user has prepared src/dst step before running this
292 def test_intpred_reentrant(self
):
293 # reg num 0 1 2 3 4 5 6 7 8 9 10 11 12
295 # src r3=0b0101 Y N Y N
300 # dest ~r3=0b1010 N Y N Y
303 isa
= SVP64Asm(['sv.extsb/sm=r3/dm=~r3 *5, *9'])
305 print("listing", lst
)
307 # initial values in GPR regfile
308 initial_regs
= [0] * 32
309 initial_regs
[3] = 0b0101 # mask
310 initial_regs
[9] = 0x90 # srcstep starts at 2, so this gets skipped
311 initial_regs
[10] = 0x91 # skip
312 initial_regs
[11] = 0x92 # this will be used
313 initial_regs
[12] = 0x93 # skip
315 # SVSTATE (in this case, VL=4)
316 svstate
= SVP64State()
318 svstate
.maxvl
= 4 # MAXVL
319 # set src/dest step on the middle of the loop
322 print("SVSTATE", bin(svstate
.asint()))
323 # copy before running
324 expected_regs
= deepcopy(initial_regs
)
325 expected_regs
[5] = 0x0 # skip
326 expected_regs
[6] = 0x0 # dststep starts at 3, so this gets skipped
327 expected_regs
[7] = 0x0 # skip
328 expected_regs
[8] = 0xffff_ffff_ffff_ff92 # this will be used
330 with
Program(lst
, bigendian
=False) as program
:
331 sim
= self
.run_tst_program(program
, initial_regs
, svstate
)
332 self
._check
_regs
(sim
, expected_regs
)
334 def test_shift_one_by_r3_dest(self
):
335 # reg num 0 1 2 3 4 5 6 7 8 9 10 11
336 # src r30=0b100 N N Y
340 # dest r3=1: 1<<r3=0b010 N Y N
342 isa
= SVP64Asm(['sv.extsb/dm=1<<r3/sm=r30 *5, *9'])
344 print("listing", lst
)
346 # initial values in GPR regfile
347 initial_regs
= [0] * 32
348 initial_regs
[3] = 1 # dest mask = 1<<r3 = 0b010
349 initial_regs
[30] = 0b100 # source mask
350 initial_regs
[9] = 0x90 # skipped
351 initial_regs
[10] = 0x91 # skipped
352 initial_regs
[11] = 0x92 # 3rd bit of r30 is 1
353 # SVSTATE (in this case, VL=3)
354 svstate
= SVP64State()
356 svstate
.maxvl
= 3 # MAXVL
357 print("SVSTATE", bin(svstate
.asint()))
358 # copy before running
359 expected_regs
= deepcopy(initial_regs
)
360 expected_regs
[5] = 0x0 # skip
361 expected_regs
[6] = 0xffff_ffff_ffff_ff92 # r3 is 1, so this is used
362 expected_regs
[7] = 0x0 # skip
364 with
Program(lst
, bigendian
=False) as program
:
365 sim
= self
.run_tst_program(program
, initial_regs
, svstate
)
366 self
._check
_regs
(sim
, expected_regs
)
368 def test_shift_one_by_r3_source(self
):
369 # reg num 0 1 2 3 4 5 6 7 8 9 10 11
370 # src r3=2: 1<<r3=0b100 N N Y
374 # dest r30=0b010 N Y N
376 isa
= SVP64Asm(['sv.extsb/sm=1<<r3/dm=r30 *5, *9'])
378 print("listing", lst
)
380 # initial values in GPR regfile
381 initial_regs
= [0] * 32
382 initial_regs
[3] = 2 # source mask = 1<<r3 = 0b100
383 initial_regs
[30] = 0b010 # dest mask
384 initial_regs
[9] = 0x90 # skipped
385 initial_regs
[10] = 0x91 # skipped
386 initial_regs
[11] = 0x92 # r3 is 2, so this will be used
387 # SVSTATE (in this case, VL=3)
388 svstate
= SVP64State()
390 svstate
.maxvl
= 3 # MAXVL
391 print("SVSTATE", bin(svstate
.asint()))
392 # copy before running
393 expected_regs
= deepcopy(initial_regs
)
394 expected_regs
[5] = 0x0 # skip
395 expected_regs
[6] = 0xffff_ffff_ffff_ff92 # 2nd bit of r30 is 1
396 expected_regs
[7] = 0x0 # skip
398 with
Program(lst
, bigendian
=False) as program
:
399 sim
= self
.run_tst_program(program
, initial_regs
, svstate
)
400 self
._check
_regs
(sim
, expected_regs
)
402 # checks reentrant CR predication
403 def test_crpred_reentrant(self
):
404 # reg num 0 1 2 3 4 5 6 7 8 9 10 11 12
406 # src cr4.eq=1 Y N Y N
414 isa
= SVP64Asm(['sv.extsb/sm=eq/dm=lt *5, *9'])
416 print("listing", lst
)
418 # initial values in GPR regfile
419 initial_regs
= [0] * 32
420 initial_regs
[9] = 0x90 # srcstep starts at 2, so this gets skipped
421 initial_regs
[10] = 0x91 # skip
422 initial_regs
[11] = 0x92 # this will be used
423 initial_regs
[12] = 0x93 # skip
426 # set up CR predicate
427 # CR4.eq=1 and CR6.eq=1
428 cr
.crl
[4][CRFields
.EQ
] = 1
429 cr
.crl
[6][CRFields
.EQ
] = 1
430 # CR5.lt=1 and CR7.lt=1
431 cr
.crl
[5][CRFields
.LT
] = 1
432 cr
.crl
[7][CRFields
.LT
] = 1
433 # SVSTATE (in this case, VL=4)
434 svstate
= SVP64State()
436 svstate
.maxvl
= 4 # MAXVL
437 # set src/dest step on the middle of the loop
440 print("SVSTATE", bin(svstate
.asint()))
441 # copy before running
442 expected_regs
= deepcopy(initial_regs
)
443 expected_regs
[5] = 0x0 # skip
444 expected_regs
[6] = 0x0 # dststep starts at 3, so this gets skipped
445 expected_regs
[7] = 0x0 # skip
446 expected_regs
[8] = 0xffff_ffff_ffff_ff92 # this will be used
448 with
Program(lst
, bigendian
=False) as program
:
449 sim
= self
.run_tst_program(program
, initial_regs
, svstate
,
450 initial_cr
=cr
.cr
.asint())
451 self
._check
_regs
(sim
, expected_regs
)
453 def run_tst_program(self
, prog
, initial_regs
=None,
456 if initial_regs
is None:
457 initial_regs
= [0] * 32
458 simulator
= run_tst(prog
, initial_regs
, svstate
=svstate
,
459 initial_cr
=initial_cr
)
464 if __name__
== "__main__":