From: Luke Kenneth Casson Leighton Date: Mon, 26 Sep 2022 19:19:49 +0000 (+0100) Subject: finally got pack/unpack working X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=12a7e7b6d7b589d5227fa4863d8e7aeac81ec936;p=openpower-isa.git finally got pack/unpack working https://bugs.libre-soc.org/show_bug.cgi?id=871 --- diff --git a/src/openpower/decoder/isa/caller.py b/src/openpower/decoder/isa/caller.py index 23845911..7e60dbce 100644 --- a/src/openpower/decoder/isa/caller.py +++ b/src/openpower/decoder/isa/caller.py @@ -633,7 +633,9 @@ class StepLoop: if pack: # pack advances subvl in *outer* loop if end_src: - if not end_ssub: + if end_ssub: + self.loopend = True + else: self.svstate.ssubstep += SelectableInt(1, 2) self.svstate.srcstep = SelectableInt(0, 7) # reset else: @@ -653,22 +655,6 @@ class StepLoop: log(" advance src", self.svstate.srcstep, self.svstate.ssubstep, self.loopend) - def at_loopend(self): - """tells if this is the last possible element. uses the cached values - for src/dst-step and sub-steps - """ - subvl = self.subvl - vl = self.svstate.vl - srcstep, dststep = self.new_srcstep, self.new_dststep - ssubstep, dsubstep = self.new_ssubstep, self.new_dsubstep - end_ssub = ssubstep == subvl - end_dsub = dsubstep == subvl - if srcstep == vl-1 and end_ssub: - return True - if dststep == vl-1 and end_dsub: - return True - return False - def dst_iterate(self): """dest step iterator """ @@ -686,7 +672,9 @@ class StepLoop: if unpack: # unpack advances subvl in *outer* loop if end_dst: - if not end_dsub: + if end_dsub: + self.loopend = True + else: self.svstate.dsubstep += SelectableInt(1, 2) self.svstate.dststep = SelectableInt(0, 7) # reset else: @@ -705,6 +693,22 @@ class StepLoop: log(" advance dst", self.svstate.dststep, self.svstate.dsubstep, self.loopend) + def at_loopend(self): + """tells if this is the last possible element. uses the cached values + for src/dst-step and sub-steps + """ + subvl = self.subvl + vl = self.svstate.vl + srcstep, dststep = self.new_srcstep, self.new_dststep + ssubstep, dsubstep = self.new_ssubstep, self.new_dsubstep + end_ssub = ssubstep == subvl + end_dsub = dsubstep == subvl + if srcstep == vl-1 and end_ssub: + return True + if dststep == vl-1 and end_dsub: + return True + return False + def advance_svstate_steps(self): """ advance sub/steps. note that Pack/Unpack *INVERTS* the order. TODO when Pack/Unpack is set, substep becomes the *outer* loop @@ -2067,6 +2071,12 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop): if self.svstate_next_mode == 6: self.svstate_next_mode = 0 return SelectableInt(self.svstate.dststep, 7) + if self.svstate_next_mode == 7: + self.svstate_next_mode = 0 + return SelectableInt(self.svstate.ssubstep, 7) + if self.svstate_next_mode == 8: + self.svstate_next_mode = 0 + return SelectableInt(self.svstate.dsubstep, 7) return SelectableInt(0, 7) def get_src_dststeps(self): diff --git a/src/openpower/decoder/isa/test_caller_svp64_pack.py b/src/openpower/decoder/isa/test_caller_svp64_pack.py new file mode 100644 index 00000000..4c7f93eb --- /dev/null +++ b/src/openpower/decoder/isa/test_caller_svp64_pack.py @@ -0,0 +1,137 @@ +from nmigen import Module, Signal +from nmigen.sim import Simulator, Delay, Settle +from nmutil.formaltest import FHDLTestCase +import unittest +from openpower.decoder.isa.caller import ISACaller +from openpower.decoder.power_decoder import (create_pdecode) +from openpower.decoder.power_decoder2 import (PowerDecode2) +from openpower.simulator.program import Program +from openpower.decoder.isa.caller import ISACaller, SVP64State, CRFields +from openpower.decoder.selectable_int import SelectableInt +from openpower.decoder.orderedset import OrderedSet +from openpower.decoder.isa.all import ISA +from openpower.decoder.isa.test_caller import Register, run_tst +from openpower.sv.trans.svp64 import SVP64Asm +from openpower.consts import SVP64CROffs +from copy import deepcopy + +class DecoderTestCase(FHDLTestCase): + + def _check_regs(self, sim, expected): + print ("GPR") + sim.gpr.dump() + for i in range(32): + self.assertEqual(sim.gpr(i), SelectableInt(expected[i], 64)) + + def test_svstep_pack(self): + """tests pack mode + """ + lst = SVP64Asm(["setvl 0, 0, 4, 0, 1, 1", + "svstep 0, 15, 0", # set dst-pack + "sv.svstep./vec2 *0, 5, 1", # svstep get vector srcstep + "sv.svstep./vec2 *8, 6, 1", # svstep get vector dststep + "sv.svstep./vec2 *16, 7, 1", # svstep get src substep + "sv.svstep./vec2 *24, 8, 1", # svstep get dst substep + ]) + lst = list(lst) + + # SVSTATE + svstate = SVP64State() + #svstate.vl = 2 # VL + #svstate.maxvl = 2 # MAXVL + print ("SVSTATE", bin(svstate.asint())) + + with Program(lst, bigendian=False) as program: + sim = self.run_tst_program(program, svstate=svstate) + print ("SVSTATE after", bin(sim.svstate.asint())) + print (" vl", bin(sim.svstate.vl)) + print (" mvl", bin(sim.svstate.maxvl)) + print (" srcstep", bin(sim.svstate.srcstep)) + print (" dststep", bin(sim.svstate.dststep)) + print (" vfirst", bin(sim.svstate. vfirst)) + sim.gpr.dump() + self.assertEqual(sim.svstate.vl, 4) + self.assertEqual(sim.svstate.maxvl, 4) + # svstep called four times, reset occurs, srcstep zero + self.assertEqual(sim.svstate.srcstep, 0) + self.assertEqual(sim.svstate.dststep, 0) + for j in range(2): + for i in range(4): + offs = j*4+i + skew = i*2+j + self.assertEqual(sim.gpr(0+offs), SelectableInt(i, 64)) + self.assertEqual(sim.gpr(8+skew), SelectableInt(i, 64)) + self.assertEqual(sim.gpr(16+offs), SelectableInt(j, 64)) + self.assertEqual(sim.gpr(24+skew), SelectableInt(j, 64)) + self.assertEqual(sim.svstate.vfirst, 0) + CR0 = sim.crl[0] + print(" CR0", bin(CR0.get_range().value)) + self.assertEqual(CR0[CRFields.EQ], 0) + self.assertEqual(CR0[CRFields.LT], 0) + self.assertEqual(CR0[CRFields.GT], 0) + self.assertEqual(CR0[CRFields.SO], 1) + + def tst_svstep_unpack(self): + """tests unpack mode + oh ha ha very funny, the dest indices are themselves put *into* + the vector output in the order of their own values. + """ + lst = SVP64Asm(["setvl 0, 0, 4, 0, 1, 1", + "svstep 0, 14, 0", # set src-pack + "sv.svstep./vec2 *8, 5, 1", # svstep get vector dststep + "sv.svstep./vec2 *0, 6, 1", # svstep get vector srcstep + "sv.svstep./vec2 *24, 7, 1", # svstep get dst substep + "sv.svstep./vec2 *16, 8, 1", # svstep get src substep + ]) + lst = list(lst) + + # SVSTATE + svstate = SVP64State() + #svstate.vl = 2 # VL + #svstate.maxvl = 2 # MAXVL + print ("SVSTATE", bin(svstate.asint())) + + with Program(lst, bigendian=False) as program: + sim = self.run_tst_program(program, svstate=svstate) + print ("SVSTATE after", bin(sim.svstate.asint())) + print (" vl", bin(sim.svstate.vl)) + print (" mvl", bin(sim.svstate.maxvl)) + print (" srcstep", bin(sim.svstate.srcstep)) + print (" dststep", bin(sim.svstate.dststep)) + print (" vfirst", bin(sim.svstate. vfirst)) + sim.gpr.dump() + self.assertEqual(sim.svstate.vl, 4) + self.assertEqual(sim.svstate.maxvl, 4) + # svstep called four times, reset occurs, srcstep zero + self.assertEqual(sim.svstate.srcstep, 0) + self.assertEqual(sim.svstate.dststep, 0) + for j in range(2): + for i in range(4): + offs = j*4+i + skew = i*2+j + self.assertEqual(sim.gpr(0+offs), SelectableInt(i, 64)) + self.assertEqual(sim.gpr(8+skew), SelectableInt(i, 64)) + self.assertEqual(sim.gpr(16+offs), SelectableInt(j, 64)) + self.assertEqual(sim.gpr(24+skew), SelectableInt(j, 64)) + self.assertEqual(sim.svstate.vfirst, 0) + CR0 = sim.crl[0] + print(" CR0", bin(CR0.get_range().value)) + self.assertEqual(CR0[CRFields.EQ], 0) + self.assertEqual(CR0[CRFields.LT], 0) + self.assertEqual(CR0[CRFields.GT], 0) + self.assertEqual(CR0[CRFields.SO], 1) + + def run_tst_program(self, prog, initial_regs=None, + svstate=None, + initial_sprs=None): + if initial_regs is None: + initial_regs = [0] * 32 + simulator = run_tst(prog, initial_regs, svstate=svstate, + initial_sprs=initial_sprs) + simulator.gpr.dump() + return simulator + + +if __name__ == "__main__": + unittest.main() +