b86a1d120cf7fb3fee27cd575bf257bc34d11935
[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_ew32(self):
38 """>>> lst = ['sv.add/w=32 *1, *5, *9']
39 """
40 isa = SVP64Asm(['sv.add/w=32 *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] = 0x1000_1000_f000_1220
47 initial_regs[10] = 0x2000_2000_8000_1111
48 initial_regs[5] = 0x8000_43ff
49 initial_regs[6] = 0x9000_0000_0000_2223
50 initial_regs[2] = 0x0000_0001_0000_0002
51 # SVSTATE (in this case, VL=2)
52 svstate = SVP64State()
53 svstate.vl = 3 # VL
54 svstate.maxvl = 3 # MAXVL
55 print("SVSTATE", bin(svstate.asint()))
56
57 # expected: each 32-bit add is completely independent
58 gprs = deepcopy(initial_regs)
59 mask = 0xffff_ffff
60 # GPR(1) gets overwritten completely, lo-32 element 0, hi-32 element 1
61 gprs[1] = ((initial_regs[9]&mask) + (initial_regs[5]&mask)) & mask
62 gprs[1] += (((initial_regs[9]>>32) + (initial_regs[5]>>32)) & mask)<<32
63 # GPR(2) is only overwritten in the lo-32 (element 2). hi-32 untouched
64 gprs[2] &= ~mask
65 gprs[2] += ((initial_regs[10]&mask) + (initial_regs[6]&mask)) & mask
66 e = ExpectedState(pc=8, int_regs=gprs)
67
68 self.add_case(Program(lst, bigendian), initial_regs,
69 initial_svstate=svstate, expected=e)
70
71
72 class SVP64ALUTestCase(TestAccumulatorBase):
73
74 def case_1_sv_add(self):
75 """>>> lst = ['sv.add *1, *5, *9']
76
77 adds:
78 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
79 * 2 = 6 + 10 => 0x3334 = 0x2223 + 0x1111
80 """
81 isa = SVP64Asm(['sv.add *1, *5, *9'])
82 lst = list(isa)
83 print("listing", lst)
84
85 # initial values in GPR regfile
86 initial_regs = [0] * 32
87 initial_regs[9] = 0x1234
88 initial_regs[10] = 0x1111
89 initial_regs[5] = 0x4321
90 initial_regs[6] = 0x2223
91 # SVSTATE (in this case, VL=2)
92 svstate = SVP64State()
93 svstate.vl = 2 # VL
94 svstate.maxvl = 2 # MAXVL
95 print("SVSTATE", bin(svstate.asint()))
96
97 self.add_case(Program(lst, bigendian), initial_regs,
98 initial_svstate=svstate)
99
100 def case_2_sv_add_scalar(self):
101 """>>> lst = ['sv.add 1, 5, 9']
102
103 adds:
104 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
105 """
106 isa = SVP64Asm(['sv.add 1, 5, 9'])
107 lst = list(isa)
108 print("listing", lst)
109
110 # initial values in GPR regfile
111 initial_regs = [0] * 32
112 initial_regs[9] = 0x1234
113 initial_regs[5] = 0x4321
114 svstate = SVP64State()
115 # SVSTATE (in this case, VL=1, so everything works as in v3.0B)
116 svstate.vl = 1 # VL
117 svstate.maxvl = 1 # MAXVL
118 print("SVSTATE", bin(svstate.asint()))
119
120 self.add_case(Program(lst, bigendian), initial_regs,
121 initial_svstate=svstate)
122
123 def case_3_sv_check_extra(self):
124 """>>> lst = ['sv.add *13, *10, *7']
125
126 adds:
127 * 13 = 10 + 7 => 0x4242 = 0x1230 + 0x3012
128
129 This case helps checking the encoding of the Extra field
130 It was built so the v3.0b registers are: 3, 2, 1
131 and the Extra field is: 101.110.111
132 The expected SVP64 register numbers are: 13, 10, 7
133 Any mistake in decoding will probably give a different answer
134 """
135 isa = SVP64Asm(['sv.add *13, *10, *7'])
136 lst = list(isa)
137 print("listing", lst)
138
139 # initial values in GPR regfile
140 initial_regs = [0] * 32
141 initial_regs[7] = 0x3012
142 initial_regs[10] = 0x1230
143 svstate = SVP64State()
144 # SVSTATE (in this case, VL=1, so everything works as in v3.0B)
145 svstate.vl = 1 # VL
146 svstate.maxvl = 1 # MAXVL
147 print("SVSTATE", bin(svstate.asint()))
148
149 self.add_case(Program(lst, bigendian), initial_regs,
150 initial_svstate=svstate)
151
152 def case_4_sv_add_(self):
153 """>>> lst = ['sv.add. *1, *5, *9']
154
155 adds when Rc=1: TODO CRs higher up
156 * 1 = 5 + 9 => 0 = -1+1 CR0=0b100
157 * 2 = 6 + 10 => 0x3334 = 0x2223+0x1111 CR1=0b010
158 """
159 isa = SVP64Asm(['sv.add. *1, *5, *9'])
160 lst = list(isa)
161 print("listing", lst)
162
163 # initial values in GPR regfile
164 initial_regs = [0] * 32
165 initial_regs[9] = 0xffffffffffffffff
166 initial_regs[10] = 0x1111
167 initial_regs[5] = 0x1
168 initial_regs[6] = 0x2223
169
170 # SVSTATE (in this case, VL=2)
171 svstate = SVP64State()
172 svstate.vl = 2 # VL
173 svstate.maxvl = 2 # 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_5_sv_check_vl_0(self):
180 """>>> lst = [
181 'sv.add *13, *10, *7', # skipped, because VL == 0
182 'add 1, 5, 9'
183 ]
184
185 adds:
186 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
187 """
188 isa = SVP64Asm([
189 'sv.add *13, *10, *7', # skipped, because VL == 0
190 'add 1, 5, 9'
191 ])
192 lst = list(isa)
193 print("listing", lst)
194
195 # initial values in GPR regfile
196 initial_regs = [0] * 32
197 initial_regs[9] = 0x1234
198 initial_regs[5] = 0x4321
199 initial_regs[7] = 0x3012
200 initial_regs[10] = 0x1230
201 svstate = SVP64State()
202 # SVSTATE (in this case, VL=0, so vector instructions are skipped)
203 svstate.vl = 0 # VL
204 svstate.maxvl = 0 # MAXVL
205 print("SVSTATE", bin(svstate.asint()))
206
207 self.add_case(Program(lst, bigendian), initial_regs,
208 initial_svstate=svstate)
209
210 # checks that SRCSTEP was reset properly after an SV instruction
211 def case_6_sv_add_multiple(self):
212 """>>> lst = [
213 'sv.add *1, *5, *9',
214 'sv.add *13, *10, *7'
215 ]
216
217 adds:
218 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
219 * 2 = 6 + 10 => 0x3334 = 0x2223 + 0x1111
220 * 3 = 7 + 11 => 0x4242 = 0x3012 + 0x1230
221 * 13 = 10 + 7 => 0x2341 = 0x1111 + 0x1230
222 * 14 = 11 + 8 => 0x3012 = 0x3012 + 0x0000
223 * 15 = 12 + 9 => 0x1234 = 0x0000 + 0x1234
224 """
225 isa = SVP64Asm([
226 'sv.add *1, *5, *9',
227 'sv.add *13, *10, *7'
228 ])
229 lst = list(isa)
230 print("listing", lst)
231
232 # initial values in GPR regfile
233 initial_regs = [0] * 32
234 initial_regs[9] = 0x1234
235 initial_regs[10] = 0x1111
236 initial_regs[11] = 0x3012
237 initial_regs[5] = 0x4321
238 initial_regs[6] = 0x2223
239 initial_regs[7] = 0x1230
240 # SVSTATE (in this case, VL=3)
241 svstate = SVP64State()
242 svstate.vl = 3 # VL
243 svstate.maxvl = 3 # MAXVL
244 print("SVSTATE", bin(svstate.asint()))
245
246 self.add_case(Program(lst, bigendian), initial_regs,
247 initial_svstate=svstate)
248
249 def case_7_sv_add_2(self):
250 """>>> lst = ['sv.add 1, *5, *9']
251
252 adds:
253 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
254 """
255 # r1 is scalar so ENDS EARLY
256 isa = SVP64Asm(['sv.add 1, *5, *9'])
257 lst = list(isa)
258 print("listing", lst)
259
260 # initial values in GPR regfile
261 initial_regs = [0] * 32
262 initial_regs[9] = 0x1234
263 initial_regs[10] = 0x1111
264 initial_regs[5] = 0x4321
265 initial_regs[6] = 0x2223
266 # SVSTATE (in this case, VL=2)
267 svstate = SVP64State()
268 svstate.vl = 2 # VL
269 svstate.maxvl = 2 # MAXVL
270 print("SVSTATE", bin(svstate.asint()))
271 self.add_case(Program(lst, bigendian), initial_regs,
272 initial_svstate=svstate)
273
274 def case_8_sv_add_3(self):
275 """>>> lst = ['sv.add *1, 5, *9']
276
277 adds:
278 * 1 = 5 + 9 => 0x5555 = 0x4321+0x1234
279 * 2 = 5 + 10 => 0x5432 = 0x4321+0x1111
280 """
281 isa = SVP64Asm(['sv.add *1, 5, *9'])
282 lst = list(isa)
283 print("listing", lst)
284
285 # initial values in GPR regfile
286 initial_regs = [0] * 32
287 initial_regs[9] = 0x1234
288 initial_regs[10] = 0x1111
289 initial_regs[5] = 0x4321
290 initial_regs[6] = 0x2223
291 # SVSTATE (in this case, VL=2)
292 svstate = SVP64State()
293 svstate.vl = 2 # VL
294 svstate.maxvl = 2 # MAXVL
295 print("SVSTATE", bin(svstate.asint()))
296 self.add_case(Program(lst, bigendian), initial_regs,
297 initial_svstate=svstate)
298
299 def case_13_sv_predicated_add(self):
300 """>>> lst = [
301 'sv.add/m=r30 *1, *5, *9',
302 'sv.add/m=~r30 *13, *10, *7'
303 ]
304
305 checks integer predication using mask-invertmask.
306 real-world usage would be two different operations
307 (a masked-add and an inverted-masked-sub, where the
308 mask was set up as part of a parallel If-Then-Else)
309
310 first add:
311 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
312 * 2 = 0 (skipped)
313 * 3 = 7 + 11 => 0x4242 = 0x3012 + 0x1230
314
315 second add:
316 * 13 = 0 (skipped)
317 * 14 = 11 + 8 => 0xB063 = 0x3012 + 0x8051
318 * 15 = 0 (skipped)
319 """
320 isa = SVP64Asm([
321 'sv.add/m=r30 *1, *5, *9',
322 'sv.add/m=~r30 *13, *10, *7'
323 ])
324 lst = list(isa)
325 print("listing", lst)
326
327 # initial values in GPR regfile
328 initial_regs = [0] * 32
329 initial_regs[30] = 0b101 # predicate mask
330 initial_regs[9] = 0x1234
331 initial_regs[10] = 0x1111
332 initial_regs[11] = 0x3012
333 initial_regs[5] = 0x4321
334 initial_regs[6] = 0x2223
335 initial_regs[7] = 0x1230
336 initial_regs[8] = 0x8051
337 # SVSTATE (in this case, VL=3)
338 svstate = SVP64State()
339 svstate.vl = 3 # VL
340 svstate.maxvl = 3 # MAXVL
341 print("SVSTATE", bin(svstate.asint()))
342
343 self.add_case(Program(lst, bigendian), initial_regs,
344 initial_svstate=svstate)
345
346 def case_14_intpred_all_zeros_all_ones(self):
347 """>>> lst = [
348 'sv.add/m=r30 *1, *5, *9',
349 'sv.add/m=~r30 *13, *10, *7'
350 ]
351
352 checks an instruction with no effect (all mask bits are zeros).
353 TODO: check completion time (number of cycles), although honestly
354 it is an implementation-specific optimisation to decide to skip
355 Vector operations with a fully-zero mask.
356
357 first add:
358 * 1 = 0 (skipped)
359 * 2 = 0 (skipped)
360 * 3 = 0 (skipped)
361
362 second add:
363 * 13 = 10 + 7 => 0x2341 = 0x1111 + 0x1230
364 * 14 = 11 + 8 => 0xB063 = 0x3012 + 0x8051
365 * 15 = 12 + 9 => 0x7736 = 0x6502 + 0x1234
366 """
367 isa = SVP64Asm([
368 'sv.add/m=r30 *1, *5, *9',
369 'sv.add/m=~r30 *13, *10, *7'
370 ])
371 lst = list(isa)
372 print("listing", lst)
373
374 # initial values in GPR regfile
375 initial_regs = [0] * 32
376 initial_regs[30] = 0 # predicate mask
377 initial_regs[9] = 0x1234
378 initial_regs[10] = 0x1111
379 initial_regs[11] = 0x3012
380 initial_regs[12] = 0x6502
381 initial_regs[5] = 0x4321
382 initial_regs[6] = 0x2223
383 initial_regs[7] = 0x1230
384 initial_regs[8] = 0x8051
385 # SVSTATE (in this case, VL=3)
386 svstate = SVP64State()
387 svstate.vl = 3 # VL
388 svstate.maxvl = 3 # MAXVL
389 print("SVSTATE", bin(svstate.asint()))
390
391 self.add_case(Program(lst, bigendian), initial_regs,
392 initial_svstate=svstate)
393
394 def case_18_sv_add_cr_pred(self):
395 """>>> lst = ['sv.add/m=ne *1, *5, *9']
396
397 adds, CR predicated mask CR4.eq = 1, CR5.eq = 0, invert (ne)
398 * 1 = 5 + 9 => not to be touched (skipped)
399 * 2 = 6 + 10 => 0x3334 = 0x2223+0x1111
400
401 expected results:
402 * r1 = 0xbeef skipped since CR4 is 1 and test is inverted
403 * r2 = 0x3334 CR5 is 0, so this is used
404 """
405 isa = SVP64Asm(['sv.add/m=ne *1, *5, *9'])
406 lst = list(isa)
407 print("listing", lst)
408
409 # initial values in GPR regfile
410 initial_regs = [0] * 32
411 initial_regs[1] = 0xbeef # not to be altered
412 initial_regs[9] = 0x1234
413 initial_regs[10] = 0x1111
414 initial_regs[5] = 0x4321
415 initial_regs[6] = 0x2223
416 # SVSTATE (in this case, VL=2)
417 svstate = SVP64State()
418 svstate.vl = 2 # VL
419 svstate.maxvl = 2 # MAXVL
420 print("SVSTATE", bin(svstate.asint()))
421
422 # set up CR predicate - CR4.eq=1 and CR5.eq=0
423 cr = 0b0010 << ((7-4)*4) # CR4.eq (we hope)
424
425 self.add_case(Program(lst, bigendian), initial_regs,
426 initial_svstate=svstate, initial_cr=cr)
427