fix elwidth overrides when sw=8
[openpower-isa.git] / src / openpower / test / alu / svp64_cases.py
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
8
9 class SVP64ALUElwidthTestCase(TestAccumulatorBase):
10
11 def case_1_sv_add_ew8(self):
12 """>>> lst = ['sv.add/w=8 *1, *5, *9']
13 """
14 isa = SVP64Asm(['sv.add/w=8 *1, *5, *9'])
15 lst = list(isa)
16 print("listing", lst)
17
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()
24 svstate.vl = 2 # VL
25 svstate.maxvl = 2 # MAXVL
26 print("SVSTATE", bin(svstate.asint()))
27
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)
32
33 self.add_case(Program(lst, bigendian), initial_regs,
34 initial_svstate=svstate, expected=e)
35
36
37 def case_2_sv_add_sw8(self):
38 """>>> lst = ['sv.add/sw=8 *1, *5, *9']
39 """
40 isa = SVP64Asm(['sv.add/sw=8 *1, *5, *9'])
41 lst = list(isa)
42 print("listing", lst)
43
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()
50 svstate.vl = 2 # VL
51 svstate.maxvl = 2 # MAXVL
52 print("SVSTATE", bin(svstate.asint()))
53
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)
59
60 self.add_case(Program(lst, bigendian), initial_regs,
61 initial_svstate=svstate, expected=e)
62
63
64 def case_2_sv_add_ew32(self):
65 """>>> lst = ['sv.add/w=32 *1, *5, *9']
66 """
67 isa = SVP64Asm(['sv.add/w=32 *1, *5, *9'])
68 lst = list(isa)
69 print("listing", lst)
70
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()
80 svstate.vl = 3 # VL
81 svstate.maxvl = 3 # MAXVL
82 print("SVSTATE", bin(svstate.asint()))
83
84 # expected: each 32-bit add is completely independent
85 gprs = deepcopy(initial_regs)
86 mask = 0xffff_ffff
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
91 gprs[2] &= ~mask
92 gprs[2] += ((initial_regs[10]&mask) + (initial_regs[6]&mask)) & mask
93 e = ExpectedState(pc=8, int_regs=gprs)
94
95 self.add_case(Program(lst, bigendian), initial_regs,
96 initial_svstate=svstate, expected=e)
97
98
99 class SVP64ALUTestCase(TestAccumulatorBase):
100
101 def case_1_sv_add(self):
102 """>>> lst = ['sv.add *1, *5, *9']
103
104 adds:
105 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
106 * 2 = 6 + 10 => 0x3334 = 0x2223 + 0x1111
107 """
108 isa = SVP64Asm(['sv.add *1, *5, *9'])
109 lst = list(isa)
110 print("listing", lst)
111
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()
120 svstate.vl = 2 # VL
121 svstate.maxvl = 2 # MAXVL
122 print("SVSTATE", bin(svstate.asint()))
123
124 self.add_case(Program(lst, bigendian), initial_regs,
125 initial_svstate=svstate)
126
127 def case_2_sv_add_scalar(self):
128 """>>> lst = ['sv.add 1, 5, 9']
129
130 adds:
131 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
132 """
133 isa = SVP64Asm(['sv.add 1, 5, 9'])
134 lst = list(isa)
135 print("listing", lst)
136
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)
143 svstate.vl = 1 # VL
144 svstate.maxvl = 1 # MAXVL
145 print("SVSTATE", bin(svstate.asint()))
146
147 self.add_case(Program(lst, bigendian), initial_regs,
148 initial_svstate=svstate)
149
150 def case_3_sv_check_extra(self):
151 """>>> lst = ['sv.add *13, *10, *7']
152
153 adds:
154 * 13 = 10 + 7 => 0x4242 = 0x1230 + 0x3012
155
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
161 """
162 isa = SVP64Asm(['sv.add *13, *10, *7'])
163 lst = list(isa)
164 print("listing", lst)
165
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)
172 svstate.vl = 1 # VL
173 svstate.maxvl = 1 # MAXVL
174 print("SVSTATE", bin(svstate.asint()))
175
176 self.add_case(Program(lst, bigendian), initial_regs,
177 initial_svstate=svstate)
178
179 def case_4_sv_add_(self):
180 """>>> lst = ['sv.add. *1, *5, *9']
181
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
185 """
186 isa = SVP64Asm(['sv.add. *1, *5, *9'])
187 lst = list(isa)
188 print("listing", lst)
189
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
196
197 # SVSTATE (in this case, VL=2)
198 svstate = SVP64State()
199 svstate.vl = 2 # VL
200 svstate.maxvl = 2 # MAXVL
201 print("SVSTATE", bin(svstate.asint()))
202
203 self.add_case(Program(lst, bigendian), initial_regs,
204 initial_svstate=svstate)
205
206 def case_5_sv_check_vl_0(self):
207 """>>> lst = [
208 'sv.add *13, *10, *7', # skipped, because VL == 0
209 'add 1, 5, 9'
210 ]
211
212 adds:
213 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
214 """
215 isa = SVP64Asm([
216 'sv.add *13, *10, *7', # skipped, because VL == 0
217 'add 1, 5, 9'
218 ])
219 lst = list(isa)
220 print("listing", lst)
221
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)
230 svstate.vl = 0 # VL
231 svstate.maxvl = 0 # MAXVL
232 print("SVSTATE", bin(svstate.asint()))
233
234 self.add_case(Program(lst, bigendian), initial_regs,
235 initial_svstate=svstate)
236
237 # checks that SRCSTEP was reset properly after an SV instruction
238 def case_6_sv_add_multiple(self):
239 """>>> lst = [
240 'sv.add *1, *5, *9',
241 'sv.add *13, *10, *7'
242 ]
243
244 adds:
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
251 """
252 isa = SVP64Asm([
253 'sv.add *1, *5, *9',
254 'sv.add *13, *10, *7'
255 ])
256 lst = list(isa)
257 print("listing", lst)
258
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()
269 svstate.vl = 3 # VL
270 svstate.maxvl = 3 # MAXVL
271 print("SVSTATE", bin(svstate.asint()))
272
273 self.add_case(Program(lst, bigendian), initial_regs,
274 initial_svstate=svstate)
275
276 def case_7_sv_add_2(self):
277 """>>> lst = ['sv.add 1, *5, *9']
278
279 adds:
280 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
281 """
282 # r1 is scalar so ENDS EARLY
283 isa = SVP64Asm(['sv.add 1, *5, *9'])
284 lst = list(isa)
285 print("listing", lst)
286
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()
295 svstate.vl = 2 # VL
296 svstate.maxvl = 2 # MAXVL
297 print("SVSTATE", bin(svstate.asint()))
298 self.add_case(Program(lst, bigendian), initial_regs,
299 initial_svstate=svstate)
300
301 def case_8_sv_add_3(self):
302 """>>> lst = ['sv.add *1, 5, *9']
303
304 adds:
305 * 1 = 5 + 9 => 0x5555 = 0x4321+0x1234
306 * 2 = 5 + 10 => 0x5432 = 0x4321+0x1111
307 """
308 isa = SVP64Asm(['sv.add *1, 5, *9'])
309 lst = list(isa)
310 print("listing", lst)
311
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()
320 svstate.vl = 2 # VL
321 svstate.maxvl = 2 # MAXVL
322 print("SVSTATE", bin(svstate.asint()))
323 self.add_case(Program(lst, bigendian), initial_regs,
324 initial_svstate=svstate)
325
326 def case_13_sv_predicated_add(self):
327 """>>> lst = [
328 'sv.add/m=r30 *1, *5, *9',
329 'sv.add/m=~r30 *13, *10, *7'
330 ]
331
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)
336
337 first add:
338 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
339 * 2 = 0 (skipped)
340 * 3 = 7 + 11 => 0x4242 = 0x3012 + 0x1230
341
342 second add:
343 * 13 = 0 (skipped)
344 * 14 = 11 + 8 => 0xB063 = 0x3012 + 0x8051
345 * 15 = 0 (skipped)
346 """
347 isa = SVP64Asm([
348 'sv.add/m=r30 *1, *5, *9',
349 'sv.add/m=~r30 *13, *10, *7'
350 ])
351 lst = list(isa)
352 print("listing", lst)
353
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()
366 svstate.vl = 3 # VL
367 svstate.maxvl = 3 # MAXVL
368 print("SVSTATE", bin(svstate.asint()))
369
370 self.add_case(Program(lst, bigendian), initial_regs,
371 initial_svstate=svstate)
372
373 def case_14_intpred_all_zeros_all_ones(self):
374 """>>> lst = [
375 'sv.add/m=r30 *1, *5, *9',
376 'sv.add/m=~r30 *13, *10, *7'
377 ]
378
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.
383
384 first add:
385 * 1 = 0 (skipped)
386 * 2 = 0 (skipped)
387 * 3 = 0 (skipped)
388
389 second add:
390 * 13 = 10 + 7 => 0x2341 = 0x1111 + 0x1230
391 * 14 = 11 + 8 => 0xB063 = 0x3012 + 0x8051
392 * 15 = 12 + 9 => 0x7736 = 0x6502 + 0x1234
393 """
394 isa = SVP64Asm([
395 'sv.add/m=r30 *1, *5, *9',
396 'sv.add/m=~r30 *13, *10, *7'
397 ])
398 lst = list(isa)
399 print("listing", lst)
400
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()
414 svstate.vl = 3 # VL
415 svstate.maxvl = 3 # MAXVL
416 print("SVSTATE", bin(svstate.asint()))
417
418 self.add_case(Program(lst, bigendian), initial_regs,
419 initial_svstate=svstate)
420
421 def case_18_sv_add_cr_pred(self):
422 """>>> lst = ['sv.add/m=ne *1, *5, *9']
423
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
427
428 expected results:
429 * r1 = 0xbeef skipped since CR4 is 1 and test is inverted
430 * r2 = 0x3334 CR5 is 0, so this is used
431 """
432 isa = SVP64Asm(['sv.add/m=ne *1, *5, *9'])
433 lst = list(isa)
434 print("listing", lst)
435
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()
445 svstate.vl = 2 # VL
446 svstate.maxvl = 2 # MAXVL
447 print("SVSTATE", bin(svstate.asint()))
448
449 # set up CR predicate - CR4.eq=1 and CR5.eq=0
450 cr = 0b0010 << ((7-4)*4) # CR4.eq (we hope)
451
452 self.add_case(Program(lst, bigendian), initial_regs,
453 initial_svstate=svstate, initial_cr=cr)
454