1 from openpower
.test
.common
import (TestAccumulatorBase
, skip_case
)
2 from openpower
.endian
import bigendian
3 from openpower
.simulator
.program
import Program
4 from openpower
.decoder
.isa
.caller
import SVP64State
, CRFields
5 from openpower
.insndb
.asm
import SVP64Asm
6 from openpower
.test
.state
import ExpectedState
7 from copy
import deepcopy
9 class SVP64ALUElwidthTestCase(TestAccumulatorBase
):
11 def case_1_sv_add_ew8(self
):
12 """>>> lst = ['sv.add/w=8 *1, *5, *9']
14 isa
= SVP64Asm(['sv.add/w=8 *1, *5, *9'])
18 # initial values in GPR regfile
19 initial_regs
= [0] * 32
20 initial_regs
[9] = 0x1220
21 initial_regs
[5] = 0x43ff
22 # SVSTATE (in this case, VL=2)
23 svstate
= SVP64State()
25 svstate
.maxvl
= 2 # MAXVL
26 print("SVSTATE", bin(svstate
.asint()))
28 # expected: each 8-bit add is completely independent
29 gprs
= deepcopy(initial_regs
)
30 gprs
[1] = 0x551f # 0x12+0x43 = 0x55, 0x20+0xff = 0x1f (8-bit)
31 e
= ExpectedState(pc
=8, int_regs
=gprs
)
33 self
.add_case(Program(lst
, bigendian
), initial_regs
,
34 initial_svstate
=svstate
, expected
=e
)
37 def case_2_sv_add_sw8(self
):
38 """>>> lst = ['sv.add/sw=8 *1, *5, *9']
40 isa
= SVP64Asm(['sv.add/sw=8 *1, *5, *9'])
44 # initial values in GPR regfile
45 initial_regs
= [0] * 32
46 initial_regs
[9] = 0x1220
47 initial_regs
[5] = 0x43ff
48 # SVSTATE (in this case, VL=2)
49 svstate
= SVP64State()
51 svstate
.maxvl
= 2 # MAXVL
52 print("SVSTATE", bin(svstate
.asint()))
54 # expected: each 8-bit add is completely independent
55 gprs
= deepcopy(initial_regs
)
56 gprs
[1] = 0x11f # 0x20+0xff = 0x11f (64-bit)
57 gprs
[2] = 0x55 # 0x12+0x43 = 0x55 (64-bit)
58 e
= ExpectedState(pc
=8, int_regs
=gprs
)
60 self
.add_case(Program(lst
, bigendian
), initial_regs
,
61 initial_svstate
=svstate
, expected
=e
)
64 def case_2_sv_add_ew32(self
):
65 """>>> lst = ['sv.add/w=32 *1, *5, *9']
67 isa
= SVP64Asm(['sv.add/w=32 *1, *5, *9'])
71 # initial values in GPR regfile
72 initial_regs
= [0] * 32
73 initial_regs
[9] = 0x1000_1000_f000_1220
74 initial_regs
[10] = 0x2000_2000_8000_1111
75 initial_regs
[5] = 0x8000_43ff
76 initial_regs
[6] = 0x9000_0000_0000_2223
77 initial_regs
[2] = 0x0000_0001_0000_0002
78 # SVSTATE (in this case, VL=2)
79 svstate
= SVP64State()
81 svstate
.maxvl
= 3 # MAXVL
82 print("SVSTATE", bin(svstate
.asint()))
84 # expected: each 32-bit add is completely independent
85 gprs
= deepcopy(initial_regs
)
87 # GPR(1) gets overwritten completely, lo-32 element 0, hi-32 element 1
88 gprs
[1] = ((initial_regs
[9]&mask
) + (initial_regs
[5]&mask
)) & mask
89 gprs
[1] += (((initial_regs
[9]>>32) + (initial_regs
[5]>>32)) & mask
)<<32
90 # GPR(2) is only overwritten in the lo-32 (element 2). hi-32 untouched
92 gprs
[2] += ((initial_regs
[10]&mask
) + (initial_regs
[6]&mask
)) & mask
93 e
= ExpectedState(pc
=8, int_regs
=gprs
)
95 self
.add_case(Program(lst
, bigendian
), initial_regs
,
96 initial_svstate
=svstate
, expected
=e
)
99 class SVP64ALUTestCase(TestAccumulatorBase
):
101 def case_1_sv_add(self
):
102 """>>> lst = ['sv.add *1, *5, *9']
105 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
106 * 2 = 6 + 10 => 0x3334 = 0x2223 + 0x1111
108 isa
= SVP64Asm(['sv.add *1, *5, *9'])
110 print("listing", lst
)
112 # initial values in GPR regfile
113 initial_regs
= [0] * 32
114 initial_regs
[9] = 0x1234
115 initial_regs
[10] = 0x1111
116 initial_regs
[5] = 0x4321
117 initial_regs
[6] = 0x2223
118 # SVSTATE (in this case, VL=2)
119 svstate
= SVP64State()
121 svstate
.maxvl
= 2 # MAXVL
122 print("SVSTATE", bin(svstate
.asint()))
124 self
.add_case(Program(lst
, bigendian
), initial_regs
,
125 initial_svstate
=svstate
)
127 def case_2_sv_add_scalar(self
):
128 """>>> lst = ['sv.add 1, 5, 9']
131 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
133 isa
= SVP64Asm(['sv.add 1, 5, 9'])
135 print("listing", lst
)
137 # initial values in GPR regfile
138 initial_regs
= [0] * 32
139 initial_regs
[9] = 0x1234
140 initial_regs
[5] = 0x4321
141 svstate
= SVP64State()
142 # SVSTATE (in this case, VL=1, so everything works as in v3.0B)
144 svstate
.maxvl
= 1 # MAXVL
145 print("SVSTATE", bin(svstate
.asint()))
147 self
.add_case(Program(lst
, bigendian
), initial_regs
,
148 initial_svstate
=svstate
)
150 def case_3_sv_check_extra(self
):
151 """>>> lst = ['sv.add *13, *10, *7']
154 * 13 = 10 + 7 => 0x4242 = 0x1230 + 0x3012
156 This case helps checking the encoding of the Extra field
157 It was built so the v3.0b registers are: 3, 2, 1
158 and the Extra field is: 101.110.111
159 The expected SVP64 register numbers are: 13, 10, 7
160 Any mistake in decoding will probably give a different answer
162 isa
= SVP64Asm(['sv.add *13, *10, *7'])
164 print("listing", lst
)
166 # initial values in GPR regfile
167 initial_regs
= [0] * 32
168 initial_regs
[7] = 0x3012
169 initial_regs
[10] = 0x1230
170 svstate
= SVP64State()
171 # SVSTATE (in this case, VL=1, so everything works as in v3.0B)
173 svstate
.maxvl
= 1 # MAXVL
174 print("SVSTATE", bin(svstate
.asint()))
176 self
.add_case(Program(lst
, bigendian
), initial_regs
,
177 initial_svstate
=svstate
)
179 def case_4_sv_add_(self
):
180 """>>> lst = ['sv.add. *1, *5, *9']
182 adds when Rc=1: TODO CRs higher up
183 * 1 = 5 + 9 => 0 = -1+1 CR0=0b100
184 * 2 = 6 + 10 => 0x3334 = 0x2223+0x1111 CR1=0b010
186 isa
= SVP64Asm(['sv.add. *1, *5, *9'])
188 print("listing", lst
)
190 # initial values in GPR regfile
191 initial_regs
= [0] * 32
192 initial_regs
[9] = 0xffffffffffffffff
193 initial_regs
[10] = 0x1111
194 initial_regs
[5] = 0x1
195 initial_regs
[6] = 0x2223
197 # SVSTATE (in this case, VL=2)
198 svstate
= SVP64State()
200 svstate
.maxvl
= 2 # MAXVL
201 print("SVSTATE", bin(svstate
.asint()))
203 self
.add_case(Program(lst
, bigendian
), initial_regs
,
204 initial_svstate
=svstate
)
206 def case_5_sv_check_vl_0(self
):
208 'sv.add *13, *10, *7', # skipped, because VL == 0
213 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
216 'sv.add *13, *10, *7', # skipped, because VL == 0
220 print("listing", lst
)
222 # initial values in GPR regfile
223 initial_regs
= [0] * 32
224 initial_regs
[9] = 0x1234
225 initial_regs
[5] = 0x4321
226 initial_regs
[7] = 0x3012
227 initial_regs
[10] = 0x1230
228 svstate
= SVP64State()
229 # SVSTATE (in this case, VL=0, so vector instructions are skipped)
231 svstate
.maxvl
= 0 # MAXVL
232 print("SVSTATE", bin(svstate
.asint()))
234 self
.add_case(Program(lst
, bigendian
), initial_regs
,
235 initial_svstate
=svstate
)
237 # checks that SRCSTEP was reset properly after an SV instruction
238 def case_6_sv_add_multiple(self
):
241 'sv.add *13, *10, *7'
245 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
246 * 2 = 6 + 10 => 0x3334 = 0x2223 + 0x1111
247 * 3 = 7 + 11 => 0x4242 = 0x3012 + 0x1230
248 * 13 = 10 + 7 => 0x2341 = 0x1111 + 0x1230
249 * 14 = 11 + 8 => 0x3012 = 0x3012 + 0x0000
250 * 15 = 12 + 9 => 0x1234 = 0x0000 + 0x1234
254 'sv.add *13, *10, *7'
257 print("listing", lst
)
259 # initial values in GPR regfile
260 initial_regs
= [0] * 32
261 initial_regs
[9] = 0x1234
262 initial_regs
[10] = 0x1111
263 initial_regs
[11] = 0x3012
264 initial_regs
[5] = 0x4321
265 initial_regs
[6] = 0x2223
266 initial_regs
[7] = 0x1230
267 # SVSTATE (in this case, VL=3)
268 svstate
= SVP64State()
270 svstate
.maxvl
= 3 # MAXVL
271 print("SVSTATE", bin(svstate
.asint()))
273 self
.add_case(Program(lst
, bigendian
), initial_regs
,
274 initial_svstate
=svstate
)
276 def case_7_sv_add_2(self
):
277 """>>> lst = ['sv.add 1, *5, *9']
280 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
282 # r1 is scalar so ENDS EARLY
283 isa
= SVP64Asm(['sv.add 1, *5, *9'])
285 print("listing", lst
)
287 # initial values in GPR regfile
288 initial_regs
= [0] * 32
289 initial_regs
[9] = 0x1234
290 initial_regs
[10] = 0x1111
291 initial_regs
[5] = 0x4321
292 initial_regs
[6] = 0x2223
293 # SVSTATE (in this case, VL=2)
294 svstate
= SVP64State()
296 svstate
.maxvl
= 2 # MAXVL
297 print("SVSTATE", bin(svstate
.asint()))
298 self
.add_case(Program(lst
, bigendian
), initial_regs
,
299 initial_svstate
=svstate
)
301 def case_8_sv_add_3(self
):
302 """>>> lst = ['sv.add *1, 5, *9']
305 * 1 = 5 + 9 => 0x5555 = 0x4321+0x1234
306 * 2 = 5 + 10 => 0x5432 = 0x4321+0x1111
308 isa
= SVP64Asm(['sv.add *1, 5, *9'])
310 print("listing", lst
)
312 # initial values in GPR regfile
313 initial_regs
= [0] * 32
314 initial_regs
[9] = 0x1234
315 initial_regs
[10] = 0x1111
316 initial_regs
[5] = 0x4321
317 initial_regs
[6] = 0x2223
318 # SVSTATE (in this case, VL=2)
319 svstate
= SVP64State()
321 svstate
.maxvl
= 2 # MAXVL
322 print("SVSTATE", bin(svstate
.asint()))
323 self
.add_case(Program(lst
, bigendian
), initial_regs
,
324 initial_svstate
=svstate
)
326 def case_13_sv_predicated_add(self
):
328 'sv.add/m=r30 *1, *5, *9',
329 'sv.add/m=~r30 *13, *10, *7'
332 checks integer predication using mask-invertmask.
333 real-world usage would be two different operations
334 (a masked-add and an inverted-masked-sub, where the
335 mask was set up as part of a parallel If-Then-Else)
338 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
340 * 3 = 7 + 11 => 0x4242 = 0x3012 + 0x1230
344 * 14 = 11 + 8 => 0xB063 = 0x3012 + 0x8051
348 'sv.add/m=r30 *1, *5, *9',
349 'sv.add/m=~r30 *13, *10, *7'
352 print("listing", lst
)
354 # initial values in GPR regfile
355 initial_regs
= [0] * 32
356 initial_regs
[30] = 0b101 # predicate mask
357 initial_regs
[9] = 0x1234
358 initial_regs
[10] = 0x1111
359 initial_regs
[11] = 0x3012
360 initial_regs
[5] = 0x4321
361 initial_regs
[6] = 0x2223
362 initial_regs
[7] = 0x1230
363 initial_regs
[8] = 0x8051
364 # SVSTATE (in this case, VL=3)
365 svstate
= SVP64State()
367 svstate
.maxvl
= 3 # MAXVL
368 print("SVSTATE", bin(svstate
.asint()))
370 self
.add_case(Program(lst
, bigendian
), initial_regs
,
371 initial_svstate
=svstate
)
373 def case_14_intpred_all_zeros_all_ones(self
):
375 'sv.add/m=r30 *1, *5, *9',
376 'sv.add/m=~r30 *13, *10, *7'
379 checks an instruction with no effect (all mask bits are zeros).
380 TODO: check completion time (number of cycles), although honestly
381 it is an implementation-specific optimisation to decide to skip
382 Vector operations with a fully-zero mask.
390 * 13 = 10 + 7 => 0x2341 = 0x1111 + 0x1230
391 * 14 = 11 + 8 => 0xB063 = 0x3012 + 0x8051
392 * 15 = 12 + 9 => 0x7736 = 0x6502 + 0x1234
395 'sv.add/m=r30 *1, *5, *9',
396 'sv.add/m=~r30 *13, *10, *7'
399 print("listing", lst
)
401 # initial values in GPR regfile
402 initial_regs
= [0] * 32
403 initial_regs
[30] = 0 # predicate mask
404 initial_regs
[9] = 0x1234
405 initial_regs
[10] = 0x1111
406 initial_regs
[11] = 0x3012
407 initial_regs
[12] = 0x6502
408 initial_regs
[5] = 0x4321
409 initial_regs
[6] = 0x2223
410 initial_regs
[7] = 0x1230
411 initial_regs
[8] = 0x8051
412 # SVSTATE (in this case, VL=3)
413 svstate
= SVP64State()
415 svstate
.maxvl
= 3 # MAXVL
416 print("SVSTATE", bin(svstate
.asint()))
418 self
.add_case(Program(lst
, bigendian
), initial_regs
,
419 initial_svstate
=svstate
)
421 def case_18_sv_add_cr_pred(self
):
422 """>>> lst = ['sv.add/m=ne *1, *5, *9']
424 adds, CR predicated mask CR4.eq = 1, CR5.eq = 0, invert (ne)
425 * 1 = 5 + 9 => not to be touched (skipped)
426 * 2 = 6 + 10 => 0x3334 = 0x2223+0x1111
429 * r1 = 0xbeef skipped since CR4 is 1 and test is inverted
430 * r2 = 0x3334 CR5 is 0, so this is used
432 isa
= SVP64Asm(['sv.add/m=ne *1, *5, *9'])
434 print("listing", lst
)
436 # initial values in GPR regfile
437 initial_regs
= [0] * 32
438 initial_regs
[1] = 0xbeef # not to be altered
439 initial_regs
[9] = 0x1234
440 initial_regs
[10] = 0x1111
441 initial_regs
[5] = 0x4321
442 initial_regs
[6] = 0x2223
443 # SVSTATE (in this case, VL=2)
444 svstate
= SVP64State()
446 svstate
.maxvl
= 2 # MAXVL
447 print("SVSTATE", bin(svstate
.asint()))
449 # set up CR predicate - CR4.eq=1 and CR5.eq=0
450 cr
= 0b0010 << ((7-4)*4) # CR4.eq (we hope)
452 self
.add_case(Program(lst
, bigendian
), initial_regs
,
453 initial_svstate
=svstate
, initial_cr
=cr
)