move logical SVP64 test cases to separate file/directory
[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 - sources are 9 and 10
16 - dests are 5 and 6
17 - source mask says "pick first element from source (5)
18 - dest mask says "pick *second* element from dest (10)
19
20 therefore the operation that's carried out is:
21 GPR(10) = extsb(GPR(5))
22
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
25 ascii graphic:
26
27 reg num 0 1 2 3 4 5 6 7 8 9 10
28 predicate src ~r3=0b01 Y N
29 |
30 +-----+
31 |
32 predicate dest r3=0b10 N Y
33
34 expected results:
35 r5 = 0x0 dest r3 is 0b10: skip
36 r6 = 0xffff_ffff_ffff_ff91 2nd bit of r3 is 1
37 """
38 isa = SVP64Asm(['sv.extsb/sm=~r3/dm=r3 5.v, 9.v'])
39 lst = list(isa)
40 print("listing", lst)
41
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()))
52
53 self.add_case(Program(lst, bigendian), initial_regs,
54 initial_svstate=svstate)
55
56 def case_10_intpred_vcompress(self):
57 """lst = ['sv.extsb/sm=r3 5.v, 9.v']
58
59 reg num 0 1 2 3 4 5 6 7 8 9 10 11
60 predicate src r3=0b101 Y N Y
61 | |
62 +-------+ |
63 | +-----------+
64 | |
65 predicate dest always Y Y Y
66
67 expected results:
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)
71 """
72 isa = SVP64Asm(['sv.extsb/sm=r3 5.v, 9.v'])
73 lst = list(isa)
74 print("listing", lst)
75
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()))
87
88 self.add_case(Program(lst, bigendian), initial_regs,
89 initial_svstate=svstate)
90
91 def case_11_intpred_vexpand(self):
92 """lst = ['sv.extsb/dm=r3 5.v, 9.v']
93
94 reg num 0 1 2 3 4 5 6 7 8 9 10 11
95 predicate src always Y Y Y
96 | |
97 +-------+ |
98 | +------+
99 | |
100 predicate dest r3=0b101 Y N Y
101
102 expected results:
103 r5 = 0xffff_ffff_ffff_ff90 1st bit of r3 is 1
104 r6 = 0x0 skip
105 r7 = 0xffff_ffff_ffff_ff91 3nd bit of r3 is 1
106 """
107 isa = SVP64Asm(['sv.extsb/dm=r3 5.v, 9.v'])
108 lst = list(isa)
109 print("listing", lst)
110
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()))
122
123 self.add_case(Program(lst, bigendian), initial_regs,
124 initial_svstate=svstate)
125
126 def case_12_sv_twinpred(self):
127 """lst = ['sv.extsb/sm=r3/dm=~r3 5.v, 9.v']
128
129 reg num 0 1 2 3 4 5 6 7 8 9 10 11
130 predicate src r3=0b101 Y N Y
131 |
132 +-----+
133 |
134 predicate dest ~r3=0b010 N Y N
135
136 expected results:
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
140 """
141 isa = SVP64Asm(['sv.extsb/sm=r3/dm=~r3 5.v, 9.v'])
142 lst = list(isa)
143 print("listing", lst)
144
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()))
156
157 self.add_case(Program(lst, bigendian), initial_regs,
158 initial_svstate=svstate)
159
160 def case_15_intpred_reentrant(self):
161 """lst = ['sv.extsb/sm=r3/dm=~r3 5.v, 9.v']
162
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
168
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.
172
173 reg num 0 1 2 3 4 5 6 7 8 9 10 11 12
174 srcstep=1 v
175 src r3=0b0101 Y N Y N
176 : |
177 + - - + |
178 : +-------+
179 : |
180 dest ~r3=0b1010 N Y N Y
181 dststep=2 ^
182
183 expected results:
184 r5 = 0x0 # skip
185 r6 = 0x0 # dststep starts at 3, so this gets skipped
186 r7 = 0x0 # skip
187 r8 = 0xffff_ffff_ffff_ff92 # this will be used
188 """
189 isa = SVP64Asm(['sv.extsb/sm=r3/dm=~r3 5.v, 9.v'])
190 lst = list(isa)
191 print("listing", lst)
192
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
200
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()))
209
210 self.add_case(Program(lst, bigendian), initial_regs,
211 initial_svstate=svstate)
212
213 def case_16_shift_one_by_r3_dest(self):
214 """lst = ['sv.extsb/dm=1<<r3/sm=r30 5.v, 9.v']
215
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
219
220 reg num 0 1 2 3 4 5 6 7 8 9 10 11
221 src r30=0b100 N N Y
222 |
223 +-----------+
224 |
225 dest r3=1: 1<<r3=0b010 N Y N
226
227 expected results:
228 r5 = 0x0 skipped
229 r6 = 0xffff_ffff_ffff_ff92 r3 is 1, so this is used
230 r7 = 0x0 skipped
231 """
232 isa = SVP64Asm(['sv.extsb/dm=1<<r3/sm=r30 5.v, 9.v'])
233 lst = list(isa)
234 print("listing", lst)
235
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()))
248
249 self.add_case(Program(lst, bigendian), initial_regs,
250 initial_svstate=svstate)
251
252 def case_17_shift_one_by_r3_source(self):
253 """lst = ['sv.extsb/sm=1<<r3/dm=r30 5.v, 9.v']
254
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
257 |
258 +-----------+
259 |
260 dest r30=0b010 N Y N
261
262 expected results:
263 r5 = 0x0 skipped
264 r6 = 0xffff_ffff_ffff_ff92 2nd bit of r30 is 1
265 r7 = 0x0 skipped
266 """
267 isa = SVP64Asm(['sv.extsb/sm=1<<r3/dm=r30 5.v, 9.v'])
268 lst = list(isa)
269 print("listing", lst)
270
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()))
283
284 self.add_case(Program(lst, bigendian), initial_regs,
285 initial_svstate=svstate)
286
287 def case_19_crpred_reentrant(self):
288 """lst = ['sv.extsb/sm=eq/dm=lt 5.v, 9.v']
289
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.
295
296 reg num 0 1 2 3 4 5 6 7 8 9 10 11 12
297 srcstep=1 v
298 src cr4.eq=1 Y N Y N
299 cr6.eq=1 : |
300 + - - + |
301 : +-------+
302 dest cr5.lt=1 : |
303 cr7.lt=1 N Y N Y
304 dststep=2 ^
305
306 expected results:
307 r5 = 0x0 skip
308 r6 = 0x0 dststep starts at 3, so this gets skipped
309 r7 = 0x0 skip
310 r8 = 0xffff_ffff_ffff_ff92 this will be used
311 """
312 isa = SVP64Asm(['sv.extsb/sm=eq/dm=lt 5.v, 9.v'])
313 lst = list(isa)
314 print("listing", lst)
315
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
322
323 cr = CRFields()
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()))
343
344 self.add_case(Program(lst, bigendian), initial_regs,
345 initial_svstate=svstate, initial_cr=cr.cr.asint())