from openpower.simulator.program import Program
from openpower.insndb.asm import SVP64Asm
from openpower.util import log
+from openpower.decoder.isa.maxloc import m2
-# example sv.cmpi/ff=lt 0, 1, *10, 5
+def cmpd(x, y):
+ class CRfield:
+ def __repr__(self):
+ return "<lt %d gt %d eq %d>" % (self.lt, self.gt, self.eq)
+ def __int__(self):
+ return (CRf.lt<<3) | (CRf.gt<<2) | (CRf.eq<<1)
+ CRf = CRfield()
+ CRf.lt = x < y
+ CRf.gt = x > y
+ CRf.eq = x == y
+ return CRf
+
+
+# example sv.minmax/ff=lt 0, 1, *10, 5
# see https://bugs.libre-soc.org/show_bug.cgi?id=1183#c3
-def sv_maxu(gpr, CR, vl, ra, rb, rt):
- i = 0
+def sv_maxu(gpr, vl, ra, rb, rt):
+ CR0, i = None, 0
while i < vl:
- CR[0] = cmpd(gpr[ra+i], gpr[rb])
- log("sv_maxss test", i, gpr[ra + i], gpr[rb], CR[0], int(CR[0]))
- gpr[rt] = gpr[ra+i] if CR[0].lt else gpr[rb]
- if not CR[0].gt:
+ CR0 = cmpd(gpr[ra+i], gpr[rb])
+ log("sv_maxss test", i, gpr[ra + i], gpr[rb], CR0, int(CR0))
+ gpr[rt] = gpr[ra+i] if CR0.lt else gpr[rb]
+ if not CR0.gt:
break
i += 1
- return i # new VL
+ return i, CR0 # new VL
class DDFFirstTestCase(FHDLTestCase):
self.assertEqual(sim.gpr(i), SelectableInt(expected[i], 64))
def test_sv_maxloc_1(self):
- self.sv_maxloc([1,2,3,4])
+ self.sv_maxloc([1,3,3,3])
def tst_sv_maxloc_2(self):
- self.sv_maxloc([3,4,1,0])
+ self.sv_maxloc([3,4,1,5])
def tst_sv_maxloc_3(self):
self.sv_maxloc([2,9,8,0])
self.sv_maxloc([2,1,3,0])
def sv_maxloc(self, ra):
- lst = SVP64Asm(["sv.minmax./ff=le 4, *10, 4, 1" # scalar RB=RT
+ """
+ m, nm, i, n = 0, 0, 0, len(a)
+ while (i<n):
+ while (i<n and a[i]<=m) : i += 1
+ while (i<n and a[i] > m): m, nm, i = a[i], i, i+1
+ return nm
+ """
+
+ lst = SVP64Asm([
+ "mtspr 9, 3", # move r3 to CTR
+ "addi 0, 0, 0", # r0=0
+ #"addi 5, 4, 0", # copy m(r4) to r5
+ # VL = MIN(CTR,MAXVL=4)
+ "mtcrf 255,0", # clear CR entirely
+ "setvl 2,0,4,0,1,1", # set MVL=4, VL=MIN(MVL,CTR)
+ # while (i<n and a[i]<=m) : i += 1
+ "sv.cmp/ff=gt/m=ge *0,0,*10,4", # truncates VL to min
+ "sv.creqv *16,*16,*16", # set mask on already-tested
+ "setvl 2,0,4,0,1,1", # set MVL=4, VL=MIN(MVL,CTR)
+ "mtcrf 128, 0", # clear CR0 (in case VL=0?)
+ # while (i<n and a[i]>m):
+ "sv.minmax./ff=le/m=ge 4, *10, 4, 1", # uses r4 as accumulator
+ #"crternlogi 0,1,2,127" # test greater/equal or VL=0
+ "cror 0,1,0", # test for greater or equal, or VL=0
+ "cror 0,2,0", # test for greater or equal, or VL=0
+ "sv.creqv *19,*16,*16", # set mask on already-tested
+ "sv.crand *19,*19,0", # clear if CR0=0
+ "sv.svstep/mr/m=so 1, 0, 6, 1", # svstep: get vector dststep
+ "sv.creqv *16,*16,*16", # set mask on already-tested
+ "bc 12,0, -0x4c" # CR0 lt bit clear, branch back
])
lst = list(lst)
print("SVSTATE", bin(svstate.asint()))
gprs = [0] * 32
- gprs[4] = rb # (RT&RB) accumulator in r4
+ gprs[3] = vl # variable n: to go into CTR
+ gprs[4] = 2 # variable m: max current number found
for i, ra in enumerate(ra): # vector in ra starts at r10
gprs[10+i] = ra
log("maxu ddff", i, gprs[10+i])
cr_res = [0]*8
res = deepcopy(gprs)
- expected_vl = sv_maxu(res, cr_res, vl, 10, 4, 4)
- log("sv_maxu", expected_vl, cr_res)
+ #expected_vl, expected_cr = sv_maxu(res, cr_res, vl, 10, 4, 4)
+ #log("sv_maxu", expected_vl, cr_res)
with Program(lst, bigendian=False) as program:
sim = self.run_tst_program(program, initial_regs=gprs,
svstate=svstate)
- for i in range(4):
+ for i in range(vl):
val = sim.gpr(i).value
res.append(val)
cr_res.append(0)
log("i", i, val)
+
+ for i in range(vl):
+ crf = sim.crl[i].get_range().value
+ log("crf", i, bin(crf))
+
# confirm that the results are as expected
+ return
for i, v in enumerate(cr_res[:vl]):
crf = sim.crl[i].get_range().value
for i, v in enumerate(res):
self.assertEqual(v, res[i])
- self.assertEqual(sim.svstate.vl, expected_vl)
- self.assertEqual(sim.svstate.maxvl, 4)
- self.assertEqual(sim.svstate.srcstep, 0)
- self.assertEqual(sim.svstate.dststep, 0)
-
- def test_1(self):
- lst = SVP64Asm(["sv.cmpi/ff=lt 0, 1, *10, 5"
- ])
- lst = list(lst)
-
- # SVSTATE
- svstate = SVP64State()
- vl = 3 # VL
- svstate.vl = vl # VL
- svstate.maxvl = vl # MAXVL
- print("SVSTATE", bin(svstate.asint()))
-
- gprs = [0] * 32
- gprs[10] = 7
- gprs[11] = 5
- gprs[12] = 12
-
- res = []
- cr_res = [0]*8
-
- newvl = sv_cmpi(gprs, cr_res, vl, 10, 5)
- log("sv_cmpi", newvl, cr_res)
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs=gprs,
- svstate=svstate)
- for i in range(4):
- val = sim.gpr(i).value
- res.append(val)
- cr_res.append(0)
- print("i", i, val)
- # confirm that the results are as expected
- expected = deepcopy(vec)
- expected_vl = 0
- for i in range(4):
- # calculate expected result and expected CR field
- result = vec[i] - gprs[8]
- crf = ((result==0)<<1) | ((result > 0)<<2) | ((result < 0) << 3)
- cr_res[i] = crf
- if result <= 0:
- break
- # VLi=0 - test comes FIRST!
- expected[i] = result
- # only write out if successful
- expected_vl += 1
-
- for i, v in enumerate(cr_res):
- crf = sim.crl[i].get_range().value
- print ("crf", i, res[i], bin(crf), bin(v))
- self.assertEqual(crf, v)
-
- for i, v in enumerate(res):
- self.assertEqual(v, expected[i])
-
- self.assertEqual(sim.svstate.vl, expected_vl)
- self.assertEqual(sim.svstate.maxvl, 4)
- self.assertEqual(sim.svstate.srcstep, 0)
- self.assertEqual(sim.svstate.dststep, 0)
-
- def test_sv_addi_ffirst_le(self):
- lst = SVP64Asm(["sv.subf./ff=le *0,8,*0"
- ])
- lst = list(lst)
-
- # SVSTATE
- svstate = SVP64State()
- svstate.vl = 4 # VL
- svstate.maxvl = 4 # MAXVL
- print("SVSTATE", bin(svstate.asint()))
-
- gprs = [0] * 64
- gprs[8] = 3
- vec = [9, 8, 3, 4]
-
- res = []
- cr_res = []
- # store GPRs
- for i, x in enumerate(vec):
- gprs[i] = x
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs=gprs,
- svstate=svstate)
- for i in range(4):
- val = sim.gpr(i).value
- res.append(val)
- cr_res.append(0)
- print("i", i, val)
- # confirm that the results are as expected
- expected = deepcopy(vec)
- expected_vl = 0
- for i in range(4):
- # calculate expected result and expected CR field
- result = vec[i] - gprs[8]
- crf = ((result==0)<<1) | ((result > 0)<<2) | ((result < 0) << 3)
- cr_res[i] = crf
- if result <= 0:
- break
- # VLi=0 - test comes FIRST!
- expected[i] = result
- # only write out if successful
- expected_vl += 1
-
- for i, v in enumerate(cr_res):
- crf = sim.crl[i].get_range().value
- print ("crf", i, res[i], bin(crf), bin(v))
- self.assertEqual(crf, v)
-
- for i, v in enumerate(res):
- self.assertEqual(v, expected[i])
-
- self.assertEqual(sim.svstate.vl, expected_vl)
- self.assertEqual(sim.svstate.maxvl, 4)
- self.assertEqual(sim.svstate.srcstep, 0)
- self.assertEqual(sim.svstate.dststep, 0)
-
- def test_sv_addi_ffirst(self):
- lst = SVP64Asm(["sv.subf./ff=eq *0,8,*0"
- ])
- lst = list(lst)
-
- # SVSTATE
- svstate = SVP64State()
- svstate.vl = 4 # VL
- svstate.maxvl = 4 # MAXVL
- print("SVSTATE", bin(svstate.asint()))
-
- gprs = [0] * 64
- gprs[8] = 3
- vec = [9, 8, 3, 4]
-
- res = []
- cr_res = []
- # store GPRs
- for i, x in enumerate(vec):
- gprs[i] = x
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs=gprs,
- svstate=svstate)
- for i in range(4):
- val = sim.gpr(i).value
- res.append(val)
- cr_res.append(0)
- print("i", i, val)
- # confirm that the results are as expected
- expected = deepcopy(vec)
- for i in range(4):
- result = vec[i] - gprs[8]
- crf = ((result==0)<<1) | ((result > 0)<<2) | ((result < 0) << 3)
- cr_res[i] = crf
- if result == 0:
- break
- # VLi=0 - test comes FIRST!
- expected[i] = result
- for i, v in enumerate(cr_res):
- crf = sim.crl[i].get_range().value
- print ("crf", i, res[i], bin(crf), bin(v))
- self.assertEqual(crf, v)
-
- for i, v in enumerate(res):
- self.assertEqual(v, expected[i])
-
- self.assertEqual(sim.svstate.vl, 2)
- self.assertEqual(sim.svstate.maxvl, 4)
- self.assertEqual(sim.svstate.srcstep, 0)
- self.assertEqual(sim.svstate.dststep, 0)
-
- def test_sv_addi_ffirst_rc1(self):
- lst = SVP64Asm(["sv.subf/ff=RC1 *0,8,*0" # RC1 auto-sets EQ (and Rc=1)
- ])
- lst = list(lst)
-
- # SVSTATE
- svstate = SVP64State()
- svstate.vl = 4 # VL
- svstate.maxvl = 4 # MAXVL
- print("SVSTATE", bin(svstate.asint()))
-
- gprs = [0] * 64
- gprs[8] = 3
- vec = [9, 8, 3, 4]
-
- res = []
- # store GPRs
- for i, x in enumerate(vec):
- gprs[i] = x
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs=gprs,
- svstate=svstate)
- for i in range(4):
- val = sim.gpr(i).value
- res.append(val)
- print("i", i, val)
- # confirm that the results are as expected
- expected = deepcopy(vec)
- for i in range(4):
- result = expected[i] - gprs[8]
- if result == 0:
- break
- # VLi=0 - test comes FIRST!
- expected[i] = result
- for i, v in enumerate(res):
- self.assertEqual(v, expected[i])
-
- self.assertEqual(sim.svstate.vl, 2)
- self.assertEqual(sim.svstate.maxvl, 4)
- self.assertEqual(sim.svstate.srcstep, 0)
- self.assertEqual(sim.svstate.dststep, 0)
-
- def test_sv_addi_ffirst_vli(self):
- """data-dependent fail-first with VLi=1, the test comes *after* write
- """
- lst = SVP64Asm(["sv.subf/ff=RC1/vli *0,8,*0"
- ])
- lst = list(lst)
-
- # SVSTATE
- svstate = SVP64State()
- svstate.vl = 4 # VL
- svstate.maxvl = 4 # MAXVL
- print("SVSTATE", bin(svstate.asint()))
-
- gprs = [0] * 64
- gprs[8] = 3
- vec = [9, 8, 3, 4]
-
- res = []
- # store GPRs
- for i, x in enumerate(vec):
- gprs[i] = x
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs=gprs,
- svstate=svstate)
- for i in range(4):
- val = sim.gpr(i).value
- res.append(val)
- print("i", i, val)
- # confirm that the results are as expected
- expected = deepcopy(vec)
- for i in range(4):
- # VLi=1 - test comes AFTER write!
- expected[i] -= gprs[8]
- if expected[i] == 0:
- break
- for i, v in enumerate(res):
- self.assertEqual(v, expected[i])
-
- self.assertEqual(sim.svstate.vl, 3)
- self.assertEqual(sim.svstate.maxvl, 4)
- self.assertEqual(sim.svstate.srcstep, 0)
- self.assertEqual(sim.svstate.dststep, 0)
+ #self.assertEqual(sim.svstate.vl, expected_vl)
+ #self.assertEqual(sim.svstate.maxvl, 4)
+ #self.assertEqual(sim.svstate.srcstep, 0)
+ #self.assertEqual(sim.svstate.dststep, 0)
def run_tst_program(self, prog, initial_regs=None,
svstate=None,