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"
15 - sources are 9 and 10
17 - source mask says "pick first element from source (5)
18 - dest mask says "pick *second* element from dest (10)
20 therefore the operation that's carried out is:
21 GPR(10) = extsb(GPR(5))
23 this is a type of back-to-back VREDUCE and VEXPAND but it applies
24 to *operations*, not just MVs like in traditional Vector ISAs
27 reg num 0 1 2 3 4 5 6 7 8 9 10
28 predicate src ~r3=0b01 Y N
32 predicate dest r3=0b10 N Y
35 r5 = 0x0 dest r3 is 0b10: skip
36 r6 = 0xffff_ffff_ffff_ff91 2nd bit of r3 is 1
38 isa
= SVP64Asm(['sv.extsb/sm=~r3/dm=r3 5.v, 9.v'])
42 # initial values in GPR regfile
43 initial_regs
= [0] * 32
44 initial_regs
[3] = 0b10 # predicate mask
45 initial_regs
[9] = 0x91 # source ~r3 is 0b01 so this will be used
46 initial_regs
[10] = 0x90 # this gets skipped
47 # SVSTATE (in this case, VL=2)
48 svstate
= SVP64State()
49 svstate
.vl
[0:7] = 2 # VL
50 svstate
.maxvl
[0:7] = 2 # MAXVL
51 print("SVSTATE", bin(svstate
.spr
.asint()))
53 self
.add_case(Program(lst
, bigendian
), initial_regs
,
54 initial_svstate
=svstate
)
56 def case_10_intpred_vcompress(self
):
57 """>>> lst = ['sv.extsb/sm=r3 5.v, 9.v']
59 reg num 0 1 2 3 4 5 6 7 8 9 10 11
60 predicate src r3=0b101 Y N Y
65 predicate dest always Y Y Y
68 r5 = 0xffff_ffff_ffff_ff90 (from r9)
69 r6 = 0xffff_ffff_ffff_ff92 (from r11)
70 r7 = 0x0 (VL loop runs out before we can use it)
72 isa
= SVP64Asm(['sv.extsb/sm=r3 5.v, 9.v'])
76 # initial values in GPR regfile
77 initial_regs
= [0] * 32
78 initial_regs
[3] = 0b101 # predicate mask
79 initial_regs
[9] = 0x90 # source r3 is 0b101 so this will be used
80 initial_regs
[10] = 0x91 # this gets skipped
81 initial_regs
[11] = 0x92 # source r3 is 0b101 so this will be used
82 # SVSTATE (in this case, VL=3)
83 svstate
= SVP64State()
84 svstate
.vl
[0:7] = 3 # VL
85 svstate
.maxvl
[0:7] = 3 # MAXVL
86 print("SVSTATE", bin(svstate
.spr
.asint()))
88 self
.add_case(Program(lst
, bigendian
), initial_regs
,
89 initial_svstate
=svstate
)
91 def case_11_intpred_vexpand(self
):
92 """>>> lst = ['sv.extsb/dm=r3 5.v, 9.v']
94 reg num 0 1 2 3 4 5 6 7 8 9 10 11
95 predicate src always Y Y Y
100 predicate dest r3=0b101 Y N Y
103 r5 = 0xffff_ffff_ffff_ff90 1st bit of r3 is 1
105 r7 = 0xffff_ffff_ffff_ff91 3nd bit of r3 is 1
107 isa
= SVP64Asm(['sv.extsb/dm=r3 5.v, 9.v'])
109 print("listing", lst
)
111 # initial values in GPR regfile
112 initial_regs
= [0] * 32
113 initial_regs
[3] = 0b101 # predicate mask
114 initial_regs
[9] = 0x90 # source is "always", so this will be used
115 initial_regs
[10] = 0x91 # likewise
116 initial_regs
[11] = 0x92 # the VL loop runs out before we can use it
117 # SVSTATE (in this case, VL=3)
118 svstate
= SVP64State()
119 svstate
.vl
[0:7] = 3 # VL
120 svstate
.maxvl
[0:7] = 3 # MAXVL
121 print("SVSTATE", bin(svstate
.spr
.asint()))
123 self
.add_case(Program(lst
, bigendian
), initial_regs
,
124 initial_svstate
=svstate
)
126 def case_12_sv_twinpred(self
):
127 """>>> lst = ['sv.extsb/sm=r3/dm=~r3 5.v, 9.v']
129 reg num 0 1 2 3 4 5 6 7 8 9 10 11
130 predicate src r3=0b101 Y N Y
134 predicate dest ~r3=0b010 N Y N
137 r5 = 0x0 dest ~r3 is 0b010: skip
138 r6 = 0xffff_ffff_ffff_ff90 2nd bit of ~r3 is 1
139 r7 = 0x0 dest ~r3 is 0b010: skip
141 isa
= SVP64Asm(['sv.extsb/sm=r3/dm=~r3 5.v, 9.v'])
143 print("listing", lst
)
145 # initial values in GPR regfile
146 initial_regs
= [0] * 32
147 initial_regs
[3] = 0b101 # predicate mask
148 initial_regs
[9] = 0x90 # source r3 is 0b101 so this will be used
149 initial_regs
[10] = 0x91 # this gets skipped
150 initial_regs
[11] = 0x92 # VL loop runs out before we can use it
151 # SVSTATE (in this case, VL=3)
152 svstate
= SVP64State()
153 svstate
.vl
[0:7] = 3 # VL
154 svstate
.maxvl
[0:7] = 3 # MAXVL
155 print("SVSTATE", bin(svstate
.spr
.asint()))
157 self
.add_case(Program(lst
, bigendian
), initial_regs
,
158 initial_svstate
=svstate
)
160 def case_15_intpred_reentrant(self
):
161 """>>> lst = ['sv.extsb/sm=r3/dm=~r3 5.v, 9.v']
163 checks that we are able to resume in the middle of a VL loop,
164 after an interrupt, or after the user has updated src/dst step
165 let's assume the user has prepared src/dst step before running this
166 vector instruction. this is legal but unusual: normally it would
167 be an interrupt return that would have non-zero step values
169 note to hardware implementors: inside the hardware,
170 make sure to skip mask bits before the initial step,
171 to save clock cycles. or not. your choice.
173 reg num 0 1 2 3 4 5 6 7 8 9 10 11 12
175 src r3=0b0101 Y N Y N
180 dest ~r3=0b1010 N Y N Y
185 r6 = 0x0 # dststep starts at 3, so this gets skipped
187 r8 = 0xffff_ffff_ffff_ff92 # this will be used
189 isa
= SVP64Asm(['sv.extsb/sm=r3/dm=~r3 5.v, 9.v'])
191 print("listing", lst
)
193 # initial values in GPR regfile
194 initial_regs
= [0] * 32
195 initial_regs
[3] = 0b0101 # mask
196 initial_regs
[9] = 0x90 # srcstep starts at 2, so this gets skipped
197 initial_regs
[10] = 0x91 # skip
198 initial_regs
[11] = 0x92 # this will be used
199 initial_regs
[12] = 0x93 # skip
201 # SVSTATE (in this case, VL=4)
202 svstate
= SVP64State()
203 svstate
.vl
[0:7] = 4 # VL
204 svstate
.maxvl
[0:7] = 4 # MAXVL
205 # set src/dest step on the middle of the loop
206 svstate
.srcstep
[0:7] = 1
207 svstate
.dststep
[0:7] = 2
208 print("SVSTATE", bin(svstate
.spr
.asint()))
210 self
.add_case(Program(lst
, bigendian
), initial_regs
,
211 initial_svstate
=svstate
)
213 def case_16_shift_one_by_r3_dest(self
):
214 """>>> lst = ['sv.extsb/dm=1<<r3/sm=r30 5.v, 9.v']
216 one option for predicate masks is a single-bit set: 1<<r3.
217 lots of opportunity for hardware optimisation, it effectively
218 allows dynamic indexing of the register file
220 reg num 0 1 2 3 4 5 6 7 8 9 10 11
225 dest r3=1: 1<<r3=0b010 N Y N
229 r6 = 0xffff_ffff_ffff_ff92 r3 is 1, so this is used
232 isa
= SVP64Asm(['sv.extsb/dm=1<<r3/sm=r30 5.v, 9.v'])
234 print("listing", lst
)
236 # initial values in GPR regfile
237 initial_regs
= [0] * 32
238 initial_regs
[3] = 1 # dest mask = 1<<r3 = 0b010
239 initial_regs
[30] = 0b100 # source mask
240 initial_regs
[9] = 0x90 # skipped
241 initial_regs
[10] = 0x91 # skipped
242 initial_regs
[11] = 0x92 # 3rd bit of r30 is 1
243 # SVSTATE (in this case, VL=3)
244 svstate
= SVP64State()
245 svstate
.vl
[0:7] = 3 # VL
246 svstate
.maxvl
[0:7] = 3 # MAXVL
247 print("SVSTATE", bin(svstate
.spr
.asint()))
249 self
.add_case(Program(lst
, bigendian
), initial_regs
,
250 initial_svstate
=svstate
)
252 def case_17_shift_one_by_r3_source(self
):
253 """>>> lst = ['sv.extsb/sm=1<<r3/dm=r30 5.v, 9.v']
255 reg num 0 1 2 3 4 5 6 7 8 9 10 11
256 src r3=2: 1<<r3=0b100 N N Y
264 r6 = 0xffff_ffff_ffff_ff92 2nd bit of r30 is 1
267 isa
= SVP64Asm(['sv.extsb/sm=1<<r3/dm=r30 5.v, 9.v'])
269 print("listing", lst
)
271 # initial values in GPR regfile
272 initial_regs
= [0] * 32
273 initial_regs
[3] = 2 # source mask = 1<<r3 = 0b100
274 initial_regs
[30] = 0b010 # dest mask
275 initial_regs
[9] = 0x90 # skipped
276 initial_regs
[10] = 0x91 # skipped
277 initial_regs
[11] = 0x92 # r3 is 2, so this will be used
278 # SVSTATE (in this case, VL=3)
279 svstate
= SVP64State()
280 svstate
.vl
[0:7] = 3 # VL
281 svstate
.maxvl
[0:7] = 3 # MAXVL
282 print("SVSTATE", bin(svstate
.spr
.asint()))
284 self
.add_case(Program(lst
, bigendian
), initial_regs
,
285 initial_svstate
=svstate
)
287 def case_19_crpred_reentrant(self
):
288 """>>> lst = ['sv.extsb/sm=eq/dm=lt 5.v, 9.v']
290 checks reentrant CR predication. note that the source CR-mask
291 and destination CR-mask use *different bits* of the CR fields,
292 despite both predicates starting from the same CR field number.
293 cr4.lt is zero, cr7.lt is zero AND
294 cr5.eq is zero, cr6.eq is zero.
296 reg num 0 1 2 3 4 5 6 7 8 9 10 11 12
308 r6 = 0x0 dststep starts at 3, so this gets skipped
310 r8 = 0xffff_ffff_ffff_ff92 this will be used
312 isa
= SVP64Asm(['sv.extsb/sm=eq/dm=lt 5.v, 9.v'])
314 print("listing", lst
)
316 # initial values in GPR regfile
317 initial_regs
= [0] * 32
318 initial_regs
[9] = 0x90 # srcstep starts at 2, so this gets skipped
319 initial_regs
[10] = 0x91 # skip
320 initial_regs
[11] = 0x92 # this will be used
321 initial_regs
[12] = 0x93 # skip
324 # set up CR predicate
325 # CR4.eq=1 and CR6.eq=1
326 cr
.crl
[4][CRFields
.EQ
] = 1
327 cr
.crl
[5][CRFields
.EQ
] = 0
328 cr
.crl
[6][CRFields
.EQ
] = 1
329 cr
.crl
[7][CRFields
.EQ
] = 0
330 # CR5.lt=1 and CR7.lt=1
331 cr
.crl
[4][CRFields
.LT
] = 0
332 cr
.crl
[5][CRFields
.LT
] = 1
333 cr
.crl
[6][CRFields
.LT
] = 0
334 cr
.crl
[7][CRFields
.LT
] = 1
335 # SVSTATE (in this case, VL=4)
336 svstate
= SVP64State()
337 svstate
.vl
[0:7] = 4 # VL
338 svstate
.maxvl
[0:7] = 4 # MAXVL
339 # set src/dest step on the middle of the loop
340 svstate
.srcstep
[0:7] = 1
341 svstate
.dststep
[0:7] = 2
342 print("SVSTATE", bin(svstate
.spr
.asint()))
344 self
.add_case(Program(lst
, bigendian
), initial_regs
,
345 initial_svstate
=svstate
, initial_cr
=cr
.cr
.asint())