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/
11 from copy
import deepcopy
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 from openpower
.decoder
.isa
.maxloc
import m2
27 return "<lt %d gt %d eq %d>" % (self
.lt
, self
.gt
, self
.eq
)
29 return (CRf
.lt
<<3) |
(CRf
.gt
<<2) |
(CRf
.eq
<<1)
37 # example sv.minmax/ff=lt 0, 1, *10, 5
38 # see https://bugs.libre-soc.org/show_bug.cgi?id=1183#c3
39 def sv_maxu(gpr
, vl
, ra
, rb
, rt
):
42 CR0
= cmpd(gpr
[ra
+i
], gpr
[rb
])
43 log("sv_maxss test", i
, gpr
[ra
+ i
], gpr
[rb
], CR0
, int(CR0
))
44 gpr
[rt
] = gpr
[ra
+i
] if CR0
.lt
else gpr
[rb
]
48 return i
, CR0
# new VL
51 class DDFFirstTestCase(FHDLTestCase
):
53 def _check_regs(self
, sim
, expected
):
55 self
.assertEqual(sim
.gpr(i
), SelectableInt(expected
[i
], 64))
57 def test_sv_maxloc_1(self
):
58 self
.sv_maxloc([2,3,0,7])
60 def tst_sv_maxloc_2(self
):
61 self
.sv_maxloc([3,4,1,5])
63 def tst_sv_maxloc_3(self
):
64 self
.sv_maxloc([2,9,8,0])
66 def tst_sv_maxloc_4(self
):
67 self
.sv_maxloc([2,1,3,0])
69 def sv_maxloc(self
, ra
):
71 m, nm, i, n = 0, 0, 0, len(a)
73 while (i<n and a[i]<=m) : i += 1
74 while (i<n and a[i] > m): m, nm, i = a[i], i, i+1
79 "mtspr 9, 3", # move r3 to CTR
80 "addi 0, 0, 0", # r0=0
81 #"addi 5, 4, 0", # copy m(r4) to r5
82 # VL = MIN(CTR,MAXVL=4)
83 "mtcrf 255,0", # clear CR entirely
84 "setvl 2,0,4,0,1,1", # set MVL=4, VL=MIN(MVL,CTR)
85 # load VL bytes (update r4 addr) but compressed (dw=8)
86 #"addi 6, 0, 0", # initialise r6 to zero
87 #"sv.lbzu/pi/dw=8 *6, 1(4)", # should be /lf here as well
88 # while (i<n and a[i]<=m) : i += 1
89 "sv.cmp/ff=gt/m=ge *0,0,*10,4", # truncates VL to min
90 "sv.creqv *16,*16,*16", # set mask on already-tested
91 "setvl 2,0,4,0,1,1", # set MVL=4, VL=MIN(MVL,CTR)
92 #"sv.addi/mr/sm=ge/dm=ns 4, *4, 0", # r4 = last non-masked value
93 "mtcrf 128, 0", # clear CR0 (in case VL=0?)
94 "sv.minmax./ff=lt/m=ge 4, *10, 4, 1", # uses r4 as accumulator
95 "sv.creqv *16,*16,*16", # set mask on already-tested
96 "sv.crand *19,*16,0", # set mask on less-than
97 "sv.cror *19,*19,2", # and equal
98 "sv.svstep/mr/m=so 3, 0, 6, 1", # svstep: get vector dststep
99 "add 1,1,3", # accumulate dststep
100 #"sv.addi/dm=1<<r3 *5, 4, 0", # put r4 into vector at r5
101 "bc 12,0, -0x48" # CR0 lt bit clear, branch back
102 #"setvl 3,0,4,0,1,1", # set MVL=4, VL=MIN(MVL,CTR)
103 #"sv.bc/m=ge 16, 19, -0x3c", # until r10[i]>r4 (and dec CTR)
108 svstate
= SVP64State()
109 vl
= len(ra
) # VL is length of array ra
111 svstate
.maxvl
= vl
# MAXVL
112 print("SVSTATE", bin(svstate
.asint()))
115 gprs
[3] = vl
# variable n: to go into CTR
116 gprs
[4] = 2 # variable m: max current number found
117 for i
, ra
in enumerate(ra
): # vector in ra starts at r10
119 log("maxu ddff", i
, gprs
[10+i
])
124 #expected_vl, expected_cr = sv_maxu(res, cr_res, vl, 10, 4, 4)
125 #log("sv_maxu", expected_vl, cr_res)
127 with
Program(lst
, bigendian
=False) as program
:
128 sim
= self
.run_tst_program(program
, initial_regs
=gprs
,
131 val
= sim
.gpr(i
).value
137 crf
= sim
.crl
[i
].get_range().value
138 log("crf", i
, bin(crf
))
140 # confirm that the results are as expected
143 for i
, v
in enumerate(cr_res
[:vl
]):
144 crf
= sim
.crl
[i
].get_range().value
145 log("crf", i
, res
[i
], bin(crf
), bin(int(v
)))
146 self
.assertEqual(crf
, int(v
))
148 for i
, v
in enumerate(res
):
149 self
.assertEqual(v
, res
[i
])
151 #self.assertEqual(sim.svstate.vl, expected_vl)
152 #self.assertEqual(sim.svstate.maxvl, 4)
153 #self.assertEqual(sim.svstate.srcstep, 0)
154 #self.assertEqual(sim.svstate.dststep, 0)
156 def run_tst_program(self
, prog
, initial_regs
=None,
160 if initial_regs
is None:
161 initial_regs
= [0] * 32
162 simulator
= run_tst(prog
, initial_regs
, mem
=initial_mem
,
163 initial_fprs
=initial_fprs
,
174 if __name__
== "__main__":