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
.sv
.trans
.svp64
import SVP64Asm
8 class SVP64ALUTestCase(TestAccumulatorBase
):
10 def case_1_sv_add(self
):
11 """>>> lst = ['sv.add 1.v, 5.v, 9.v']
14 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
15 * 2 = 6 + 10 => 0x3334 = 0x2223 + 0x1111
17 isa
= SVP64Asm(['sv.add 1.v, 5.v, 9.v'])
21 # initial values in GPR regfile
22 initial_regs
= [0] * 32
23 initial_regs
[9] = 0x1234
24 initial_regs
[10] = 0x1111
25 initial_regs
[5] = 0x4321
26 initial_regs
[6] = 0x2223
27 # SVSTATE (in this case, VL=2)
28 svstate
= SVP64State()
29 svstate
.vl
[0:7] = 2 # VL
30 svstate
.maxvl
[0:7] = 2 # MAXVL
31 print("SVSTATE", bin(svstate
.spr
.asint()))
33 self
.add_case(Program(lst
, bigendian
), initial_regs
,
34 initial_svstate
=svstate
)
36 def case_2_sv_add_scalar(self
):
37 """>>> lst = ['sv.add 1, 5, 9']
40 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
42 isa
= SVP64Asm(['sv.add 1, 5, 9'])
46 # initial values in GPR regfile
47 initial_regs
= [0] * 32
48 initial_regs
[9] = 0x1234
49 initial_regs
[5] = 0x4321
50 svstate
= SVP64State()
51 # SVSTATE (in this case, VL=1, so everything works as in v3.0B)
52 svstate
.vl
[0:7] = 1 # VL
53 svstate
.maxvl
[0:7] = 1 # MAXVL
54 print("SVSTATE", bin(svstate
.spr
.asint()))
56 self
.add_case(Program(lst
, bigendian
), initial_regs
,
57 initial_svstate
=svstate
)
59 def case_3_sv_check_extra(self
):
60 """>>> lst = ['sv.add 13.v, 10.v, 7.v']
63 * 13 = 10 + 7 => 0x4242 = 0x1230 + 0x3012
65 This case helps checking the encoding of the Extra field
66 It was built so the v3.0b registers are: 3, 2, 1
67 and the Extra field is: 101.110.111
68 The expected SVP64 register numbers are: 13, 10, 7
69 Any mistake in decoding will probably give a different answer
71 isa
= SVP64Asm(['sv.add 13.v, 10.v, 7.v'])
75 # initial values in GPR regfile
76 initial_regs
= [0] * 32
77 initial_regs
[7] = 0x3012
78 initial_regs
[10] = 0x1230
79 svstate
= SVP64State()
80 # SVSTATE (in this case, VL=1, so everything works as in v3.0B)
81 svstate
.vl
[0:7] = 1 # VL
82 svstate
.maxvl
[0:7] = 1 # MAXVL
83 print("SVSTATE", bin(svstate
.spr
.asint()))
85 self
.add_case(Program(lst
, bigendian
), initial_regs
,
86 initial_svstate
=svstate
)
88 def case_4_sv_add_(self
):
89 """>>> lst = ['sv.add. 1.v, 5.v, 9.v']
91 adds when Rc=1: TODO CRs higher up
92 * 1 = 5 + 9 => 0 = -1+1 CR0=0b100
93 * 2 = 6 + 10 => 0x3334 = 0x2223+0x1111 CR1=0b010
95 isa
= SVP64Asm(['sv.add. 1.v, 5.v, 9.v'])
99 # initial values in GPR regfile
100 initial_regs
= [0] * 32
101 initial_regs
[9] = 0xffffffffffffffff
102 initial_regs
[10] = 0x1111
103 initial_regs
[5] = 0x1
104 initial_regs
[6] = 0x2223
106 # SVSTATE (in this case, VL=2)
107 svstate
= SVP64State()
108 svstate
.vl
[0:7] = 2 # VL
109 svstate
.maxvl
[0:7] = 2 # MAXVL
110 print("SVSTATE", bin(svstate
.spr
.asint()))
112 self
.add_case(Program(lst
, bigendian
), initial_regs
,
113 initial_svstate
=svstate
)
115 def case_5_sv_check_vl_0(self
):
117 'sv.add 13.v, 10.v, 7.v', # skipped, because VL == 0
122 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
125 'sv.add 13.v, 10.v, 7.v', # skipped, because VL == 0
129 print("listing", lst
)
131 # initial values in GPR regfile
132 initial_regs
= [0] * 32
133 initial_regs
[9] = 0x1234
134 initial_regs
[5] = 0x4321
135 initial_regs
[7] = 0x3012
136 initial_regs
[10] = 0x1230
137 svstate
= SVP64State()
138 # SVSTATE (in this case, VL=0, so vector instructions are skipped)
139 svstate
.vl
[0:7] = 0 # VL
140 svstate
.maxvl
[0:7] = 0 # MAXVL
141 print("SVSTATE", bin(svstate
.spr
.asint()))
143 self
.add_case(Program(lst
, bigendian
), initial_regs
,
144 initial_svstate
=svstate
)
146 # checks that SRCSTEP was reset properly after an SV instruction
147 def case_6_sv_add_multiple(self
):
149 'sv.add 1.v, 5.v, 9.v',
150 'sv.add 13.v, 10.v, 7.v'
154 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
155 * 2 = 6 + 10 => 0x3334 = 0x2223 + 0x1111
156 * 3 = 7 + 11 => 0x4242 = 0x3012 + 0x1230
157 * 13 = 10 + 7 => 0x2341 = 0x1111 + 0x1230
158 * 14 = 11 + 8 => 0x3012 = 0x3012 + 0x0000
159 * 15 = 12 + 9 => 0x1234 = 0x0000 + 0x1234
162 'sv.add 1.v, 5.v, 9.v',
163 'sv.add 13.v, 10.v, 7.v'
166 print("listing", lst
)
168 # initial values in GPR regfile
169 initial_regs
= [0] * 32
170 initial_regs
[9] = 0x1234
171 initial_regs
[10] = 0x1111
172 initial_regs
[11] = 0x3012
173 initial_regs
[5] = 0x4321
174 initial_regs
[6] = 0x2223
175 initial_regs
[7] = 0x1230
176 # SVSTATE (in this case, VL=3)
177 svstate
= SVP64State()
178 svstate
.vl
[0:7] = 3 # VL
179 svstate
.maxvl
[0:7] = 3 # MAXVL
180 print("SVSTATE", bin(svstate
.spr
.asint()))
182 self
.add_case(Program(lst
, bigendian
), initial_regs
,
183 initial_svstate
=svstate
)
185 def case_7_sv_add_2(self
):
186 """>>> lst = ['sv.add 1, 5.v, 9.v']
189 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
191 # r1 is scalar so ENDS EARLY
192 isa
= SVP64Asm(['sv.add 1, 5.v, 9.v'])
194 print("listing", lst
)
196 # initial values in GPR regfile
197 initial_regs
= [0] * 32
198 initial_regs
[9] = 0x1234
199 initial_regs
[10] = 0x1111
200 initial_regs
[5] = 0x4321
201 initial_regs
[6] = 0x2223
202 # SVSTATE (in this case, VL=2)
203 svstate
= SVP64State()
204 svstate
.vl
[0:7] = 2 # VL
205 svstate
.maxvl
[0:7] = 2 # MAXVL
206 print("SVSTATE", bin(svstate
.spr
.asint()))
207 self
.add_case(Program(lst
, bigendian
), initial_regs
,
208 initial_svstate
=svstate
)
210 def case_8_sv_add_3(self
):
211 """>>> lst = ['sv.add 1.v, 5, 9.v']
214 * 1 = 5 + 9 => 0x5555 = 0x4321+0x1234
215 * 2 = 5 + 10 => 0x5432 = 0x4321+0x1111
217 isa
= SVP64Asm(['sv.add 1.v, 5, 9.v'])
219 print("listing", lst
)
221 # initial values in GPR regfile
222 initial_regs
= [0] * 32
223 initial_regs
[9] = 0x1234
224 initial_regs
[10] = 0x1111
225 initial_regs
[5] = 0x4321
226 initial_regs
[6] = 0x2223
227 # SVSTATE (in this case, VL=2)
228 svstate
= SVP64State()
229 svstate
.vl
[0:7] = 2 # VL
230 svstate
.maxvl
[0:7] = 2 # MAXVL
231 print("SVSTATE", bin(svstate
.spr
.asint()))
232 self
.add_case(Program(lst
, bigendian
), initial_regs
,
233 initial_svstate
=svstate
)
235 def case_13_sv_predicated_add(self
):
237 'sv.add/m=r30 1.v, 5.v, 9.v',
238 'sv.add/m=~r30 13.v, 10.v, 7.v'
241 checks integer predication using mask-invertmask.
242 real-world usage would be two different operations
243 (a masked-add and an inverted-masked-sub, where the
244 mask was set up as part of a parallel If-Then-Else)
247 * 1 = 5 + 9 => 0x5555 = 0x4321 + 0x1234
249 * 3 = 7 + 11 => 0x4242 = 0x3012 + 0x1230
253 * 14 = 11 + 8 => 0xB063 = 0x3012 + 0x8051
257 'sv.add/m=r30 1.v, 5.v, 9.v',
258 'sv.add/m=~r30 13.v, 10.v, 7.v'
261 print("listing", lst
)
263 # initial values in GPR regfile
264 initial_regs
= [0] * 32
265 initial_regs
[30] = 0b101 # predicate mask
266 initial_regs
[9] = 0x1234
267 initial_regs
[10] = 0x1111
268 initial_regs
[11] = 0x3012
269 initial_regs
[5] = 0x4321
270 initial_regs
[6] = 0x2223
271 initial_regs
[7] = 0x1230
272 initial_regs
[8] = 0x8051
273 # SVSTATE (in this case, VL=3)
274 svstate
= SVP64State()
275 svstate
.vl
[0:7] = 3 # VL
276 svstate
.maxvl
[0:7] = 3 # MAXVL
277 print("SVSTATE", bin(svstate
.spr
.asint()))
279 self
.add_case(Program(lst
, bigendian
), initial_regs
,
280 initial_svstate
=svstate
)
282 def case_14_intpred_all_zeros_all_ones(self
):
284 'sv.add/m=r30 1.v, 5.v, 9.v',
285 'sv.add/m=~r30 13.v, 10.v, 7.v'
288 checks an instruction with no effect (all mask bits are zeros).
289 TODO: check completion time (number of cycles), although honestly
290 it is an implementation-specific optimisation to decide to skip
291 Vector operations with a fully-zero mask.
299 * 13 = 10 + 7 => 0x2341 = 0x1111 + 0x1230
300 * 14 = 11 + 8 => 0xB063 = 0x3012 + 0x8051
301 * 15 = 12 + 9 => 0x7736 = 0x6502 + 0x1234
304 'sv.add/m=r30 1.v, 5.v, 9.v',
305 'sv.add/m=~r30 13.v, 10.v, 7.v'
308 print("listing", lst
)
310 # initial values in GPR regfile
311 initial_regs
= [0] * 32
312 initial_regs
[30] = 0 # predicate mask
313 initial_regs
[9] = 0x1234
314 initial_regs
[10] = 0x1111
315 initial_regs
[11] = 0x3012
316 initial_regs
[12] = 0x6502
317 initial_regs
[5] = 0x4321
318 initial_regs
[6] = 0x2223
319 initial_regs
[7] = 0x1230
320 initial_regs
[8] = 0x8051
321 # SVSTATE (in this case, VL=3)
322 svstate
= SVP64State()
323 svstate
.vl
[0:7] = 3 # VL
324 svstate
.maxvl
[0:7] = 3 # MAXVL
325 print("SVSTATE", bin(svstate
.spr
.asint()))
327 self
.add_case(Program(lst
, bigendian
), initial_regs
,
328 initial_svstate
=svstate
)
330 def case_18_sv_add_cr_pred(self
):
331 """>>> lst = ['sv.add/m=ne 1.v, 5.v, 9.v']
333 adds, CR predicated mask CR4.eq = 1, CR5.eq = 0, invert (ne)
334 * 1 = 5 + 9 => not to be touched (skipped)
335 * 2 = 6 + 10 => 0x3334 = 0x2223+0x1111
338 * r1 = 0xbeef skipped since CR4 is 1 and test is inverted
339 * r2 = 0x3334 CR5 is 0, so this is used
341 isa
= SVP64Asm(['sv.add/m=ne 1.v, 5.v, 9.v'])
343 print("listing", lst
)
345 # initial values in GPR regfile
346 initial_regs
= [0] * 32
347 initial_regs
[1] = 0xbeef # not to be altered
348 initial_regs
[9] = 0x1234
349 initial_regs
[10] = 0x1111
350 initial_regs
[5] = 0x4321
351 initial_regs
[6] = 0x2223
352 # SVSTATE (in this case, VL=2)
353 svstate
= SVP64State()
354 svstate
.vl
[0:7] = 2 # VL
355 svstate
.maxvl
[0:7] = 2 # MAXVL
356 print("SVSTATE", bin(svstate
.spr
.asint()))
358 # set up CR predicate - CR4.eq=1 and CR5.eq=0
359 cr
= 0b0010 << ((7-4)*4) # CR4.eq (we hope)
361 self
.add_case(Program(lst
, bigendian
), initial_regs
,
362 initial_svstate
=svstate
, initial_cr
=cr
)