finally got pack/unpack working
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 26 Sep 2022 19:19:49 +0000 (20:19 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 26 Sep 2022 19:19:49 +0000 (20:19 +0100)
https://bugs.libre-soc.org/show_bug.cgi?id=871

src/openpower/decoder/isa/caller.py
src/openpower/decoder/isa/test_caller_svp64_pack.py [new file with mode: 0644]

index 23845911cf99a6774e79c26a592c034788b104eb..7e60dbcea0298fa5199ee792cb58eec97d2ea08b 100644 (file)
@@ -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 (file)
index 0000000..4c7f93e
--- /dev/null
@@ -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()
+