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 SVP64LogicalTestCase(TestAccumulatorBase
):
10 def case_9_sv_extsw_intpred(self
):
11 """>>> lst = ['sv.extsb/sm=~r3/dm=r3 5.v, 9.v']
13 extsb, integer twin-pred mask: source is ~r3 (0b01), dest r3 (0b10)
14 works as follows, where any zeros indicate "skip element"
16 * sources are 9 and 10
18 * source mask says "pick first element from source (5)
19 * dest mask says "pick *second* element from dest (10)
21 therefore the operation that's carried out is::
23 GPR(10) = extsb(GPR(5))
25 this is a type of back-to-back VREDUCE and VEXPAND but it applies
26 to *operations*, not just MVs like in traditional Vector ISAs
29 reg num 0 1 2 3 4 5 6 7 8 9 10
30 predicate src ~r3=0b01 Y N
34 predicate dest r3=0b10 N Y
37 * r5 = 0x0 dest r3 is 0b10: skip
38 * r6 = 0xffff_ffff_ffff_ff91 2nd bit of r3 is 1
40 isa
= SVP64Asm(['sv.extsb/sm=~r3/dm=r3 5.v, 9.v'])
44 # initial values in GPR regfile
45 initial_regs
= [0] * 32
46 initial_regs
[3] = 0b10 # predicate mask
47 initial_regs
[9] = 0x91 # source ~r3 is 0b01 so this will be used
48 initial_regs
[10] = 0x90 # this gets skipped
49 # SVSTATE (in this case, VL=2)
50 svstate
= SVP64State()
51 svstate
.vl
[0:7] = 2 # VL
52 svstate
.maxvl
[0:7] = 2 # MAXVL
53 print("SVSTATE", bin(svstate
.spr
.asint()))
55 self
.add_case(Program(lst
, bigendian
), initial_regs
,
56 initial_svstate
=svstate
)
58 def case_10_intpred_vcompress(self
):
59 """>>> lst = ['sv.extsb/sm=r3 5.v, 9.v']
63 reg num 0 1 2 3 4 5 6 7 8 9 10 11
64 predicate src r3=0b101 Y N Y
69 predicate dest always Y Y Y
72 * r5 = 0xffff_ffff_ffff_ff90 (from r9)
73 * r6 = 0xffff_ffff_ffff_ff92 (from r11)
74 * r7 = 0x0 (VL loop runs out before we can use it)
76 isa
= SVP64Asm(['sv.extsb/sm=r3 5.v, 9.v'])
80 # initial values in GPR regfile
81 initial_regs
= [0] * 32
82 initial_regs
[3] = 0b101 # predicate mask
83 initial_regs
[9] = 0x90 # source r3 is 0b101 so this will be used
84 initial_regs
[10] = 0x91 # this gets skipped
85 initial_regs
[11] = 0x92 # source r3 is 0b101 so this will be used
86 # SVSTATE (in this case, VL=3)
87 svstate
= SVP64State()
88 svstate
.vl
[0:7] = 3 # VL
89 svstate
.maxvl
[0:7] = 3 # MAXVL
90 print("SVSTATE", bin(svstate
.spr
.asint()))
92 self
.add_case(Program(lst
, bigendian
), initial_regs
,
93 initial_svstate
=svstate
)
95 def case_11_intpred_vexpand(self
):
96 """>>> lst = ['sv.extsb/dm=r3 5.v, 9.v']
100 reg num 0 1 2 3 4 5 6 7 8 9 10 11
101 predicate src always Y Y Y
106 predicate dest r3=0b101 Y N Y
109 * r5 = 0xffff_ffff_ffff_ff90 1st bit of r3 is 1
111 * r7 = 0xffff_ffff_ffff_ff91 3nd bit of r3 is 1
113 isa
= SVP64Asm(['sv.extsb/dm=r3 5.v, 9.v'])
115 print("listing", lst
)
117 # initial values in GPR regfile
118 initial_regs
= [0] * 32
119 initial_regs
[3] = 0b101 # predicate mask
120 initial_regs
[9] = 0x90 # source is "always", so this will be used
121 initial_regs
[10] = 0x91 # likewise
122 initial_regs
[11] = 0x92 # the VL loop runs out before we can use it
123 # SVSTATE (in this case, VL=3)
124 svstate
= SVP64State()
125 svstate
.vl
[0:7] = 3 # VL
126 svstate
.maxvl
[0:7] = 3 # MAXVL
127 print("SVSTATE", bin(svstate
.spr
.asint()))
129 self
.add_case(Program(lst
, bigendian
), initial_regs
,
130 initial_svstate
=svstate
)
132 def case_12_sv_twinpred(self
):
133 """>>> lst = ['sv.extsb/sm=r3/dm=~r3 5.v, 9.v']
137 reg num 0 1 2 3 4 5 6 7 8 9 10 11
138 predicate src r3=0b101 Y N Y
142 predicate dest ~r3=0b010 N Y N
145 * r5 = 0x0 dest ~r3 is 0b010: skip
146 * r6 = 0xffff_ffff_ffff_ff90 2nd bit of ~r3 is 1
147 * r7 = 0x0 dest ~r3 is 0b010: skip
149 isa
= SVP64Asm(['sv.extsb/sm=r3/dm=~r3 5.v, 9.v'])
151 print("listing", lst
)
153 # initial values in GPR regfile
154 initial_regs
= [0] * 32
155 initial_regs
[3] = 0b101 # predicate mask
156 initial_regs
[9] = 0x90 # source r3 is 0b101 so this will be used
157 initial_regs
[10] = 0x91 # this gets skipped
158 initial_regs
[11] = 0x92 # VL loop runs out before we can use it
159 # SVSTATE (in this case, VL=3)
160 svstate
= SVP64State()
161 svstate
.vl
[0:7] = 3 # VL
162 svstate
.maxvl
[0:7] = 3 # MAXVL
163 print("SVSTATE", bin(svstate
.spr
.asint()))
165 self
.add_case(Program(lst
, bigendian
), initial_regs
,
166 initial_svstate
=svstate
)
168 def case_15_intpred_reentrant(self
):
169 """>>> lst = ['sv.extsb/sm=r3/dm=~r3 5.v, 9.v']
171 checks that we are able to resume in the middle of a VL loop,
172 after an interrupt, or after the user has updated src/dst step
173 let's assume the user has prepared src/dst step before running this
174 vector instruction. this is legal but unusual: normally it would
175 be an interrupt return that would have non-zero step values
177 note to hardware implementors: inside the hardware,
178 make sure to skip mask bits before the initial step,
179 to save clock cycles. or not. your choice.
183 reg num 0 1 2 3 4 5 6 7 8 9 10 11 12
185 src r3=0b0101 Y N Y N
190 dest ~r3=0b1010 N Y N Y
195 * r6 = 0x0 # dststep starts at 3, so this gets skipped
197 * r8 = 0xffff_ffff_ffff_ff92 # this will be used
199 isa
= SVP64Asm(['sv.extsb/sm=r3/dm=~r3 5.v, 9.v'])
201 print("listing", lst
)
203 # initial values in GPR regfile
204 initial_regs
= [0] * 32
205 initial_regs
[3] = 0b0101 # mask
206 initial_regs
[9] = 0x90 # srcstep starts at 2, so this gets skipped
207 initial_regs
[10] = 0x91 # skip
208 initial_regs
[11] = 0x92 # this will be used
209 initial_regs
[12] = 0x93 # skip
211 # SVSTATE (in this case, VL=4)
212 svstate
= SVP64State()
213 svstate
.vl
[0:7] = 4 # VL
214 svstate
.maxvl
[0:7] = 4 # MAXVL
215 # set src/dest step on the middle of the loop
216 svstate
.srcstep
[0:7] = 1
217 svstate
.dststep
[0:7] = 2
218 print("SVSTATE", bin(svstate
.spr
.asint()))
220 self
.add_case(Program(lst
, bigendian
), initial_regs
,
221 initial_svstate
=svstate
)
223 def case_16_shift_one_by_r3_dest(self
):
224 """>>> lst = ['sv.extsb/dm=1<<r3/sm=r30 5.v, 9.v']
226 one option for predicate masks is a single-bit set: 1<<r3.
227 lots of opportunity for hardware optimisation, it effectively
228 allows dynamic indexing of the register file
232 reg num 0 1 2 3 4 5 6 7 8 9 10 11
237 dest r3=1: 1<<r3=0b010 N Y N
241 * r6 = 0xffff_ffff_ffff_ff92 r3 is 1, so this is used
244 isa
= SVP64Asm(['sv.extsb/dm=1<<r3/sm=r30 5.v, 9.v'])
246 print("listing", lst
)
248 # initial values in GPR regfile
249 initial_regs
= [0] * 32
250 initial_regs
[3] = 1 # dest mask = 1<<r3 = 0b010
251 initial_regs
[30] = 0b100 # source mask
252 initial_regs
[9] = 0x90 # skipped
253 initial_regs
[10] = 0x91 # skipped
254 initial_regs
[11] = 0x92 # 3rd bit of r30 is 1
255 # SVSTATE (in this case, VL=3)
256 svstate
= SVP64State()
257 svstate
.vl
[0:7] = 3 # VL
258 svstate
.maxvl
[0:7] = 3 # MAXVL
259 print("SVSTATE", bin(svstate
.spr
.asint()))
261 self
.add_case(Program(lst
, bigendian
), initial_regs
,
262 initial_svstate
=svstate
)
264 def case_17_shift_one_by_r3_source(self
):
265 """>>> lst = ['sv.extsb/sm=1<<r3/dm=r30 5.v, 9.v']
269 reg num 0 1 2 3 4 5 6 7 8 9 10 11
270 src r3=2: 1<<r3=0b100 N N Y
278 * r6 = 0xffff_ffff_ffff_ff92 2nd bit of r30 is 1
281 isa
= SVP64Asm(['sv.extsb/sm=1<<r3/dm=r30 5.v, 9.v'])
283 print("listing", lst
)
285 # initial values in GPR regfile
286 initial_regs
= [0] * 32
287 initial_regs
[3] = 2 # source mask = 1<<r3 = 0b100
288 initial_regs
[30] = 0b010 # dest mask
289 initial_regs
[9] = 0x90 # skipped
290 initial_regs
[10] = 0x91 # skipped
291 initial_regs
[11] = 0x92 # r3 is 2, so this will be used
292 # SVSTATE (in this case, VL=3)
293 svstate
= SVP64State()
294 svstate
.vl
[0:7] = 3 # VL
295 svstate
.maxvl
[0:7] = 3 # MAXVL
296 print("SVSTATE", bin(svstate
.spr
.asint()))
298 self
.add_case(Program(lst
, bigendian
), initial_regs
,
299 initial_svstate
=svstate
)
301 def case_19_crpred_reentrant(self
):
302 """>>> lst = ['sv.extsb/sm=eq/dm=lt 5.v, 9.v']
304 checks reentrant CR predication. note that the source CR-mask
305 and destination CR-mask use *different bits* of the CR fields,
306 despite both predicates starting from the same CR field number.
308 * cr4.lt is zero, cr7.lt is zero AND
309 * cr5.eq is zero, cr6.eq is zero.
313 reg num 0 1 2 3 4 5 6 7 8 9 10 11 12
325 * r6 = 0x0 dststep starts at 3, so this gets skipped
327 * r8 = 0xffff_ffff_ffff_ff92 this will be used
329 isa
= SVP64Asm(['sv.extsb/sm=eq/dm=lt 5.v, 9.v'])
331 print("listing", lst
)
333 # initial values in GPR regfile
334 initial_regs
= [0] * 32
335 initial_regs
[9] = 0x90 # srcstep starts at 2, so this gets skipped
336 initial_regs
[10] = 0x91 # skip
337 initial_regs
[11] = 0x92 # this will be used
338 initial_regs
[12] = 0x93 # skip
341 # set up CR predicate
342 # CR4.eq=1 and CR6.eq=1
343 cr
.crl
[4][CRFields
.EQ
] = 1
344 cr
.crl
[5][CRFields
.EQ
] = 0
345 cr
.crl
[6][CRFields
.EQ
] = 1
346 cr
.crl
[7][CRFields
.EQ
] = 0
347 # CR5.lt=1 and CR7.lt=1
348 cr
.crl
[4][CRFields
.LT
] = 0
349 cr
.crl
[5][CRFields
.LT
] = 1
350 cr
.crl
[6][CRFields
.LT
] = 0
351 cr
.crl
[7][CRFields
.LT
] = 1
352 # SVSTATE (in this case, VL=4)
353 svstate
= SVP64State()
354 svstate
.vl
[0:7] = 4 # VL
355 svstate
.maxvl
[0:7] = 4 # MAXVL
356 # set src/dest step on the middle of the loop
357 svstate
.srcstep
[0:7] = 1
358 svstate
.dststep
[0:7] = 2
359 print("SVSTATE", bin(svstate
.spr
.asint()))
361 self
.add_case(Program(lst
, bigendian
), initial_regs
,
362 initial_svstate
=svstate
, initial_cr
=cr
.cr
.asint())