reformat SVP64 docstrings to vaguely resemble something useful in sphinx-doc
[openpower-isa.git] / src / openpower / test / logical / 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.sv.trans.svp64 import SVP64Asm
6
7
8 class SVP64LogicalTestCase(TestAccumulatorBase):
9
10 def case_9_sv_extsw_intpred(self):
11 """>>> lst = ['sv.extsb/sm=~r3/dm=r3 5.v, 9.v']
12
13 extsb, integer twin-pred mask: source is ~r3 (0b01), dest r3 (0b10)
14 works as follows, where any zeros indicate "skip element"
15
16 * sources are 9 and 10
17 * dests are 5 and 6
18 * source mask says "pick first element from source (5)
19 * dest mask says "pick *second* element from dest (10)
20
21 therefore the operation that's carried out is::
22
23 GPR(10) = extsb(GPR(5))
24
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
27 ascii graphic::
28
29 reg num 0 1 2 3 4 5 6 7 8 9 10
30 predicate src ~r3=0b01 Y N
31 |
32 +-----+
33 |
34 predicate dest r3=0b10 N Y
35
36 expected results:
37 * r5 = 0x0 dest r3 is 0b10: skip
38 * r6 = 0xffff_ffff_ffff_ff91 2nd bit of r3 is 1
39 """
40 isa = SVP64Asm(['sv.extsb/sm=~r3/dm=r3 5.v, 9.v'])
41 lst = list(isa)
42 print("listing", lst)
43
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()))
54
55 self.add_case(Program(lst, bigendian), initial_regs,
56 initial_svstate=svstate)
57
58 def case_10_intpred_vcompress(self):
59 """>>> lst = ['sv.extsb/sm=r3 5.v, 9.v']
60
61 ascii graphic::
62
63 reg num 0 1 2 3 4 5 6 7 8 9 10 11
64 predicate src r3=0b101 Y N Y
65 | |
66 +-------+ |
67 | +-----------+
68 | |
69 predicate dest always Y Y Y
70
71 expected results:
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)
75 """
76 isa = SVP64Asm(['sv.extsb/sm=r3 5.v, 9.v'])
77 lst = list(isa)
78 print("listing", lst)
79
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()))
91
92 self.add_case(Program(lst, bigendian), initial_regs,
93 initial_svstate=svstate)
94
95 def case_11_intpred_vexpand(self):
96 """>>> lst = ['sv.extsb/dm=r3 5.v, 9.v']
97
98 ascii graphic::
99
100 reg num 0 1 2 3 4 5 6 7 8 9 10 11
101 predicate src always Y Y Y
102 | |
103 +-------+ |
104 | +------+
105 | |
106 predicate dest r3=0b101 Y N Y
107
108 expected results:
109 * r5 = 0xffff_ffff_ffff_ff90 1st bit of r3 is 1
110 * r6 = 0x0 skip
111 * r7 = 0xffff_ffff_ffff_ff91 3nd bit of r3 is 1
112 """
113 isa = SVP64Asm(['sv.extsb/dm=r3 5.v, 9.v'])
114 lst = list(isa)
115 print("listing", lst)
116
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()))
128
129 self.add_case(Program(lst, bigendian), initial_regs,
130 initial_svstate=svstate)
131
132 def case_12_sv_twinpred(self):
133 """>>> lst = ['sv.extsb/sm=r3/dm=~r3 5.v, 9.v']
134
135 ascii graphic::
136
137 reg num 0 1 2 3 4 5 6 7 8 9 10 11
138 predicate src r3=0b101 Y N Y
139 |
140 +-----+
141 |
142 predicate dest ~r3=0b010 N Y N
143
144 expected results:
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
148 """
149 isa = SVP64Asm(['sv.extsb/sm=r3/dm=~r3 5.v, 9.v'])
150 lst = list(isa)
151 print("listing", lst)
152
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()))
164
165 self.add_case(Program(lst, bigendian), initial_regs,
166 initial_svstate=svstate)
167
168 def case_15_intpred_reentrant(self):
169 """>>> lst = ['sv.extsb/sm=r3/dm=~r3 5.v, 9.v']
170
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
176
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.
180
181 ascii graphic::
182
183 reg num 0 1 2 3 4 5 6 7 8 9 10 11 12
184 srcstep=1 v
185 src r3=0b0101 Y N Y N
186 : |
187 + - - + |
188 : +-------+
189 : |
190 dest ~r3=0b1010 N Y N Y
191 dststep=2 ^
192
193 expected results:
194 * r5 = 0x0 # skip
195 * r6 = 0x0 # dststep starts at 3, so this gets skipped
196 * r7 = 0x0 # skip
197 * r8 = 0xffff_ffff_ffff_ff92 # this will be used
198 """
199 isa = SVP64Asm(['sv.extsb/sm=r3/dm=~r3 5.v, 9.v'])
200 lst = list(isa)
201 print("listing", lst)
202
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
210
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()))
219
220 self.add_case(Program(lst, bigendian), initial_regs,
221 initial_svstate=svstate)
222
223 def case_16_shift_one_by_r3_dest(self):
224 """>>> lst = ['sv.extsb/dm=1<<r3/sm=r30 5.v, 9.v']
225
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
229
230 ascii graphic::
231
232 reg num 0 1 2 3 4 5 6 7 8 9 10 11
233 src r30=0b100 N N Y
234 |
235 +-----------+
236 |
237 dest r3=1: 1<<r3=0b010 N Y N
238
239 expected results:
240 * r5 = 0x0 skipped
241 * r6 = 0xffff_ffff_ffff_ff92 r3 is 1, so this is used
242 * r7 = 0x0 skipped
243 """
244 isa = SVP64Asm(['sv.extsb/dm=1<<r3/sm=r30 5.v, 9.v'])
245 lst = list(isa)
246 print("listing", lst)
247
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()))
260
261 self.add_case(Program(lst, bigendian), initial_regs,
262 initial_svstate=svstate)
263
264 def case_17_shift_one_by_r3_source(self):
265 """>>> lst = ['sv.extsb/sm=1<<r3/dm=r30 5.v, 9.v']
266
267 ascii graphic::
268
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
271 |
272 +-----------+
273 |
274 dest r30=0b010 N Y N
275
276 expected results:
277 * r5 = 0x0 skipped
278 * r6 = 0xffff_ffff_ffff_ff92 2nd bit of r30 is 1
279 * r7 = 0x0 skipped
280 """
281 isa = SVP64Asm(['sv.extsb/sm=1<<r3/dm=r30 5.v, 9.v'])
282 lst = list(isa)
283 print("listing", lst)
284
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()))
297
298 self.add_case(Program(lst, bigendian), initial_regs,
299 initial_svstate=svstate)
300
301 def case_19_crpred_reentrant(self):
302 """>>> lst = ['sv.extsb/sm=eq/dm=lt 5.v, 9.v']
303
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.
307
308 * cr4.lt is zero, cr7.lt is zero AND
309 * cr5.eq is zero, cr6.eq is zero.
310
311 ascii graphic::
312
313 reg num 0 1 2 3 4 5 6 7 8 9 10 11 12
314 srcstep=1 v
315 src cr4.eq=1 Y N Y N
316 cr6.eq=1 : |
317 + - - + |
318 : +-------+
319 dest cr5.lt=1 : |
320 cr7.lt=1 N Y N Y
321 dststep=2 ^
322
323 expected results:
324 * r5 = 0x0 skip
325 * r6 = 0x0 dststep starts at 3, so this gets skipped
326 * r7 = 0x0 skip
327 * r8 = 0xffff_ffff_ffff_ff92 this will be used
328 """
329 isa = SVP64Asm(['sv.extsb/sm=eq/dm=lt 5.v, 9.v'])
330 lst = list(isa)
331 print("listing", lst)
332
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
339
340 cr = CRFields()
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()))
360
361 self.add_case(Program(lst, bigendian), initial_regs,
362 initial_svstate=svstate, initial_cr=cr.cr.asint())