b86a1d120cf7fb3fee27cd575bf257bc34d11935
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_ew32(self
):
38 """>>> lst = ['sv.add/w=32 *1, *5, *9']
40 isa
= SVP64Asm(['sv.add/w=32 *1, *5, *9'])
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()
54 svstate
.maxvl
= 3 # MAXVL
55 print("SVSTATE", bin(svstate
.asint()))
57 # expected: each 32-bit add is completely independent
58 gprs
= deepcopy(initial_regs
)
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
65 gprs
[2] += ((initial_regs
[10]&mask
) + (initial_regs
[6]&mask
)) & mask
66 e
= ExpectedState(pc
=8, int_regs
=gprs
)
68 self
.add_case(Program(lst
, bigendian
), initial_regs
,
69 initial_svstate
=svstate
, expected
=e
)
72 class SVP64ALUTestCase(TestAccumulatorBase
):
74 def case_1_sv_add(self
):
75 """>>> lst = ['sv.add *1, *5, *9']
78 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
79 * 2 = 6 + 10 => 0x3334 = 0x2223 + 0x1111
81 isa
= SVP64Asm(['sv.add *1, *5, *9'])
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()
94 svstate
.maxvl
= 2 # MAXVL
95 print("SVSTATE", bin(svstate
.asint()))
97 self
.add_case(Program(lst
, bigendian
), initial_regs
,
98 initial_svstate
=svstate
)
100 def case_2_sv_add_scalar(self
):
101 """>>> lst = ['sv.add 1, 5, 9']
104 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
106 isa
= SVP64Asm(['sv.add 1, 5, 9'])
108 print("listing", lst
)
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)
117 svstate
.maxvl
= 1 # MAXVL
118 print("SVSTATE", bin(svstate
.asint()))
120 self
.add_case(Program(lst
, bigendian
), initial_regs
,
121 initial_svstate
=svstate
)
123 def case_3_sv_check_extra(self
):
124 """>>> lst = ['sv.add *13, *10, *7']
127 * 13 = 10 + 7 => 0x4242 = 0x1230 + 0x3012
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
135 isa
= SVP64Asm(['sv.add *13, *10, *7'])
137 print("listing", lst
)
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)
146 svstate
.maxvl
= 1 # MAXVL
147 print("SVSTATE", bin(svstate
.asint()))
149 self
.add_case(Program(lst
, bigendian
), initial_regs
,
150 initial_svstate
=svstate
)
152 def case_4_sv_add_(self
):
153 """>>> lst = ['sv.add. *1, *5, *9']
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
159 isa
= SVP64Asm(['sv.add. *1, *5, *9'])
161 print("listing", lst
)
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
170 # SVSTATE (in this case, VL=2)
171 svstate
= SVP64State()
173 svstate
.maxvl
= 2 # MAXVL
174 print("SVSTATE", bin(svstate
.asint()))
176 self
.add_case(Program(lst
, bigendian
), initial_regs
,
177 initial_svstate
=svstate
)
179 def case_5_sv_check_vl_0(self
):
181 'sv.add *13, *10, *7', # skipped, because VL == 0
186 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
189 'sv.add *13, *10, *7', # skipped, because VL == 0
193 print("listing", lst
)
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)
204 svstate
.maxvl
= 0 # MAXVL
205 print("SVSTATE", bin(svstate
.asint()))
207 self
.add_case(Program(lst
, bigendian
), initial_regs
,
208 initial_svstate
=svstate
)
210 # checks that SRCSTEP was reset properly after an SV instruction
211 def case_6_sv_add_multiple(self
):
214 'sv.add *13, *10, *7'
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
227 'sv.add *13, *10, *7'
230 print("listing", lst
)
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()
243 svstate
.maxvl
= 3 # MAXVL
244 print("SVSTATE", bin(svstate
.asint()))
246 self
.add_case(Program(lst
, bigendian
), initial_regs
,
247 initial_svstate
=svstate
)
249 def case_7_sv_add_2(self
):
250 """>>> lst = ['sv.add 1, *5, *9']
253 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
255 # r1 is scalar so ENDS EARLY
256 isa
= SVP64Asm(['sv.add 1, *5, *9'])
258 print("listing", lst
)
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()
269 svstate
.maxvl
= 2 # MAXVL
270 print("SVSTATE", bin(svstate
.asint()))
271 self
.add_case(Program(lst
, bigendian
), initial_regs
,
272 initial_svstate
=svstate
)
274 def case_8_sv_add_3(self
):
275 """>>> lst = ['sv.add *1, 5, *9']
278 * 1 = 5 + 9 => 0x5555 = 0x4321+0x1234
279 * 2 = 5 + 10 => 0x5432 = 0x4321+0x1111
281 isa
= SVP64Asm(['sv.add *1, 5, *9'])
283 print("listing", lst
)
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()
294 svstate
.maxvl
= 2 # MAXVL
295 print("SVSTATE", bin(svstate
.asint()))
296 self
.add_case(Program(lst
, bigendian
), initial_regs
,
297 initial_svstate
=svstate
)
299 def case_13_sv_predicated_add(self
):
301 'sv.add/m=r30 *1, *5, *9',
302 'sv.add/m=~r30 *13, *10, *7'
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)
311 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
313 * 3 = 7 + 11 => 0x4242 = 0x3012 + 0x1230
317 * 14 = 11 + 8 => 0xB063 = 0x3012 + 0x8051
321 'sv.add/m=r30 *1, *5, *9',
322 'sv.add/m=~r30 *13, *10, *7'
325 print("listing", lst
)
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()
340 svstate
.maxvl
= 3 # MAXVL
341 print("SVSTATE", bin(svstate
.asint()))
343 self
.add_case(Program(lst
, bigendian
), initial_regs
,
344 initial_svstate
=svstate
)
346 def case_14_intpred_all_zeros_all_ones(self
):
348 'sv.add/m=r30 *1, *5, *9',
349 'sv.add/m=~r30 *13, *10, *7'
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.
363 * 13 = 10 + 7 => 0x2341 = 0x1111 + 0x1230
364 * 14 = 11 + 8 => 0xB063 = 0x3012 + 0x8051
365 * 15 = 12 + 9 => 0x7736 = 0x6502 + 0x1234
368 'sv.add/m=r30 *1, *5, *9',
369 'sv.add/m=~r30 *13, *10, *7'
372 print("listing", lst
)
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()
388 svstate
.maxvl
= 3 # MAXVL
389 print("SVSTATE", bin(svstate
.asint()))
391 self
.add_case(Program(lst
, bigendian
), initial_regs
,
392 initial_svstate
=svstate
)
394 def case_18_sv_add_cr_pred(self
):
395 """>>> lst = ['sv.add/m=ne *1, *5, *9']
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
402 * r1 = 0xbeef skipped since CR4 is 1 and test is inverted
403 * r2 = 0x3334 CR5 is 0, so this is used
405 isa
= SVP64Asm(['sv.add/m=ne *1, *5, *9'])
407 print("listing", lst
)
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()
419 svstate
.maxvl
= 2 # MAXVL
420 print("SVSTATE", bin(svstate
.asint()))
422 # set up CR predicate - CR4.eq=1 and CR5.eq=0
423 cr
= 0b0010 << ((7-4)*4) # CR4.eq (we hope)
425 self
.add_case(Program(lst
, bigendian
), initial_regs
,
426 initial_svstate
=svstate
, initial_cr
=cr
)