a22b0d6d8bf64ea2a435705927a0e4c123bf0315
[openpower-isa.git] / src / openpower / decoder / isa / test_caller_svp64_maxloc.py
1 """Implementation of FORTRAN MAXLOC SVP64
2 Copyright (C) 2022,2023 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
3 Licensed under the LGPLv3+
4 Funded by NLnet NGI-ASSURE under EU grant agreement No 957073.
5 * https://nlnet.nl/project/Libre-SOC-OpenPOWER-ISA
6 * https://bugs.libre-soc.org/show_bug.cgi?id=676
7 * https://libre-soc.org/openpower/sv/cookbook/fortran_maxloc/
8 """
9
10 import unittest
11 from copy import deepcopy
12
13 from nmutil.formaltest import FHDLTestCase
14 from openpower.decoder.isa.caller import SVP64State
15 from openpower.decoder.isa.test_caller import run_tst
16 from openpower.decoder.selectable_int import SelectableInt
17 from openpower.simulator.program import Program
18 from openpower.insndb.asm import SVP64Asm
19 from openpower.util import log
20
21
22
23 # example sv.cmpi/ff=lt 0, 1, *10, 5
24 # see https://bugs.libre-soc.org/show_bug.cgi?id=1183#c3
25 def sv_maxu(gpr, CR, vl, ra, rb, rt):
26 i = 0
27 while i < vl:
28 CR[0] = cmpd(gpr[ra+i], gpr[rb])
29 log("sv_maxss test", i, gpr[ra + i], gpr[rb], CR[0], int(CR[0]))
30 gpr[rt] = gpr[ra+i] if CR[0].lt else gpr[rb]
31 if not CR[0].gt:
32 break
33 i += 1
34 return i # new VL
35
36
37 class DDFFirstTestCase(FHDLTestCase):
38
39 def _check_regs(self, sim, expected):
40 for i in range(32):
41 self.assertEqual(sim.gpr(i), SelectableInt(expected[i], 64))
42
43 def test_sv_maxloc_1(self):
44 self.sv_maxloc([1,2,3,4])
45
46 def tst_sv_maxloc_2(self):
47 self.sv_maxloc([3,4,1,0])
48
49 def tst_sv_maxloc_3(self):
50 self.sv_maxloc([2,9,8,0])
51
52 def tst_sv_maxloc_4(self):
53 self.sv_maxloc([2,1,3,0])
54
55 def sv_maxloc(self, ra):
56 lst = SVP64Asm(["sv.minmax./ff=le 4, *10, 4, 1" # scalar RB=RT
57 ])
58 lst = list(lst)
59
60 # SVSTATE
61 svstate = SVP64State()
62 vl = len(ra) # VL is length of array ra
63 svstate.vl = vl # VL
64 svstate.maxvl = vl # MAXVL
65 print("SVSTATE", bin(svstate.asint()))
66
67 gprs = [0] * 32
68 gprs[4] = rb # (RT&RB) accumulator in r4
69 for i, ra in enumerate(ra): # vector in ra starts at r10
70 gprs[10+i] = ra
71 log("maxu ddff", i, gprs[10+i])
72
73 cr_res = [0]*8
74 res = deepcopy(gprs)
75
76 expected_vl = sv_maxu(res, cr_res, vl, 10, 4, 4)
77 log("sv_maxu", expected_vl, cr_res)
78
79 with Program(lst, bigendian=False) as program:
80 sim = self.run_tst_program(program, initial_regs=gprs,
81 svstate=svstate)
82 for i in range(4):
83 val = sim.gpr(i).value
84 res.append(val)
85 cr_res.append(0)
86 log("i", i, val)
87 # confirm that the results are as expected
88
89 for i, v in enumerate(cr_res[:vl]):
90 crf = sim.crl[i].get_range().value
91 log("crf", i, res[i], bin(crf), bin(int(v)))
92 self.assertEqual(crf, int(v))
93
94 for i, v in enumerate(res):
95 self.assertEqual(v, res[i])
96
97 self.assertEqual(sim.svstate.vl, expected_vl)
98 self.assertEqual(sim.svstate.maxvl, 4)
99 self.assertEqual(sim.svstate.srcstep, 0)
100 self.assertEqual(sim.svstate.dststep, 0)
101
102 def test_1(self):
103 lst = SVP64Asm(["sv.cmpi/ff=lt 0, 1, *10, 5"
104 ])
105 lst = list(lst)
106
107 # SVSTATE
108 svstate = SVP64State()
109 vl = 3 # VL
110 svstate.vl = vl # VL
111 svstate.maxvl = vl # MAXVL
112 print("SVSTATE", bin(svstate.asint()))
113
114 gprs = [0] * 32
115 gprs[10] = 7
116 gprs[11] = 5
117 gprs[12] = 12
118
119 res = []
120 cr_res = [0]*8
121
122 newvl = sv_cmpi(gprs, cr_res, vl, 10, 5)
123 log("sv_cmpi", newvl, cr_res)
124
125 with Program(lst, bigendian=False) as program:
126 sim = self.run_tst_program(program, initial_regs=gprs,
127 svstate=svstate)
128 for i in range(4):
129 val = sim.gpr(i).value
130 res.append(val)
131 cr_res.append(0)
132 print("i", i, val)
133 # confirm that the results are as expected
134 expected = deepcopy(vec)
135 expected_vl = 0
136 for i in range(4):
137 # calculate expected result and expected CR field
138 result = vec[i] - gprs[8]
139 crf = ((result==0)<<1) | ((result > 0)<<2) | ((result < 0) << 3)
140 cr_res[i] = crf
141 if result <= 0:
142 break
143 # VLi=0 - test comes FIRST!
144 expected[i] = result
145 # only write out if successful
146 expected_vl += 1
147
148 for i, v in enumerate(cr_res):
149 crf = sim.crl[i].get_range().value
150 print ("crf", i, res[i], bin(crf), bin(v))
151 self.assertEqual(crf, v)
152
153 for i, v in enumerate(res):
154 self.assertEqual(v, expected[i])
155
156 self.assertEqual(sim.svstate.vl, expected_vl)
157 self.assertEqual(sim.svstate.maxvl, 4)
158 self.assertEqual(sim.svstate.srcstep, 0)
159 self.assertEqual(sim.svstate.dststep, 0)
160
161 def test_sv_addi_ffirst_le(self):
162 lst = SVP64Asm(["sv.subf./ff=le *0,8,*0"
163 ])
164 lst = list(lst)
165
166 # SVSTATE
167 svstate = SVP64State()
168 svstate.vl = 4 # VL
169 svstate.maxvl = 4 # MAXVL
170 print("SVSTATE", bin(svstate.asint()))
171
172 gprs = [0] * 64
173 gprs[8] = 3
174 vec = [9, 8, 3, 4]
175
176 res = []
177 cr_res = []
178 # store GPRs
179 for i, x in enumerate(vec):
180 gprs[i] = x
181
182 with Program(lst, bigendian=False) as program:
183 sim = self.run_tst_program(program, initial_regs=gprs,
184 svstate=svstate)
185 for i in range(4):
186 val = sim.gpr(i).value
187 res.append(val)
188 cr_res.append(0)
189 print("i", i, val)
190 # confirm that the results are as expected
191 expected = deepcopy(vec)
192 expected_vl = 0
193 for i in range(4):
194 # calculate expected result and expected CR field
195 result = vec[i] - gprs[8]
196 crf = ((result==0)<<1) | ((result > 0)<<2) | ((result < 0) << 3)
197 cr_res[i] = crf
198 if result <= 0:
199 break
200 # VLi=0 - test comes FIRST!
201 expected[i] = result
202 # only write out if successful
203 expected_vl += 1
204
205 for i, v in enumerate(cr_res):
206 crf = sim.crl[i].get_range().value
207 print ("crf", i, res[i], bin(crf), bin(v))
208 self.assertEqual(crf, v)
209
210 for i, v in enumerate(res):
211 self.assertEqual(v, expected[i])
212
213 self.assertEqual(sim.svstate.vl, expected_vl)
214 self.assertEqual(sim.svstate.maxvl, 4)
215 self.assertEqual(sim.svstate.srcstep, 0)
216 self.assertEqual(sim.svstate.dststep, 0)
217
218 def test_sv_addi_ffirst(self):
219 lst = SVP64Asm(["sv.subf./ff=eq *0,8,*0"
220 ])
221 lst = list(lst)
222
223 # SVSTATE
224 svstate = SVP64State()
225 svstate.vl = 4 # VL
226 svstate.maxvl = 4 # MAXVL
227 print("SVSTATE", bin(svstate.asint()))
228
229 gprs = [0] * 64
230 gprs[8] = 3
231 vec = [9, 8, 3, 4]
232
233 res = []
234 cr_res = []
235 # store GPRs
236 for i, x in enumerate(vec):
237 gprs[i] = x
238
239 with Program(lst, bigendian=False) as program:
240 sim = self.run_tst_program(program, initial_regs=gprs,
241 svstate=svstate)
242 for i in range(4):
243 val = sim.gpr(i).value
244 res.append(val)
245 cr_res.append(0)
246 print("i", i, val)
247 # confirm that the results are as expected
248 expected = deepcopy(vec)
249 for i in range(4):
250 result = vec[i] - gprs[8]
251 crf = ((result==0)<<1) | ((result > 0)<<2) | ((result < 0) << 3)
252 cr_res[i] = crf
253 if result == 0:
254 break
255 # VLi=0 - test comes FIRST!
256 expected[i] = result
257 for i, v in enumerate(cr_res):
258 crf = sim.crl[i].get_range().value
259 print ("crf", i, res[i], bin(crf), bin(v))
260 self.assertEqual(crf, v)
261
262 for i, v in enumerate(res):
263 self.assertEqual(v, expected[i])
264
265 self.assertEqual(sim.svstate.vl, 2)
266 self.assertEqual(sim.svstate.maxvl, 4)
267 self.assertEqual(sim.svstate.srcstep, 0)
268 self.assertEqual(sim.svstate.dststep, 0)
269
270 def test_sv_addi_ffirst_rc1(self):
271 lst = SVP64Asm(["sv.subf/ff=RC1 *0,8,*0" # RC1 auto-sets EQ (and Rc=1)
272 ])
273 lst = list(lst)
274
275 # SVSTATE
276 svstate = SVP64State()
277 svstate.vl = 4 # VL
278 svstate.maxvl = 4 # MAXVL
279 print("SVSTATE", bin(svstate.asint()))
280
281 gprs = [0] * 64
282 gprs[8] = 3
283 vec = [9, 8, 3, 4]
284
285 res = []
286 # store GPRs
287 for i, x in enumerate(vec):
288 gprs[i] = x
289
290 with Program(lst, bigendian=False) as program:
291 sim = self.run_tst_program(program, initial_regs=gprs,
292 svstate=svstate)
293 for i in range(4):
294 val = sim.gpr(i).value
295 res.append(val)
296 print("i", i, val)
297 # confirm that the results are as expected
298 expected = deepcopy(vec)
299 for i in range(4):
300 result = expected[i] - gprs[8]
301 if result == 0:
302 break
303 # VLi=0 - test comes FIRST!
304 expected[i] = result
305 for i, v in enumerate(res):
306 self.assertEqual(v, expected[i])
307
308 self.assertEqual(sim.svstate.vl, 2)
309 self.assertEqual(sim.svstate.maxvl, 4)
310 self.assertEqual(sim.svstate.srcstep, 0)
311 self.assertEqual(sim.svstate.dststep, 0)
312
313 def test_sv_addi_ffirst_vli(self):
314 """data-dependent fail-first with VLi=1, the test comes *after* write
315 """
316 lst = SVP64Asm(["sv.subf/ff=RC1/vli *0,8,*0"
317 ])
318 lst = list(lst)
319
320 # SVSTATE
321 svstate = SVP64State()
322 svstate.vl = 4 # VL
323 svstate.maxvl = 4 # MAXVL
324 print("SVSTATE", bin(svstate.asint()))
325
326 gprs = [0] * 64
327 gprs[8] = 3
328 vec = [9, 8, 3, 4]
329
330 res = []
331 # store GPRs
332 for i, x in enumerate(vec):
333 gprs[i] = x
334
335 with Program(lst, bigendian=False) as program:
336 sim = self.run_tst_program(program, initial_regs=gprs,
337 svstate=svstate)
338 for i in range(4):
339 val = sim.gpr(i).value
340 res.append(val)
341 print("i", i, val)
342 # confirm that the results are as expected
343 expected = deepcopy(vec)
344 for i in range(4):
345 # VLi=1 - test comes AFTER write!
346 expected[i] -= gprs[8]
347 if expected[i] == 0:
348 break
349 for i, v in enumerate(res):
350 self.assertEqual(v, expected[i])
351
352 self.assertEqual(sim.svstate.vl, 3)
353 self.assertEqual(sim.svstate.maxvl, 4)
354 self.assertEqual(sim.svstate.srcstep, 0)
355 self.assertEqual(sim.svstate.dststep, 0)
356
357 def run_tst_program(self, prog, initial_regs=None,
358 svstate=None,
359 initial_mem=None,
360 initial_fprs=None):
361 if initial_regs is None:
362 initial_regs = [0] * 32
363 simulator = run_tst(prog, initial_regs, mem=initial_mem,
364 initial_fprs=initial_fprs,
365 svstate=svstate)
366
367 print("GPRs")
368 simulator.gpr.dump()
369 print("FPRs")
370 simulator.fpr.dump()
371
372 return simulator
373
374
375 if __name__ == "__main__":
376 unittest.main()