add first scalar mapreduce SVP64 example
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 9 Jun 2021 17:19:40 +0000 (18:19 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 9 Jun 2021 17:19:40 +0000 (18:19 +0100)
src/openpower/decoder/isa/caller.py
src/openpower/decoder/isa/test_caller_svp64_mapreduce.py [new file with mode: 0644]
src/openpower/decoder/power_decoder2.py

index 55e07ddd3ae8c2da2d59ce38ca243377b8fa49cc..495bd173fc80c1f3b8fdc99dc3f91dbae9edfc17 100644 (file)
@@ -1339,24 +1339,26 @@ class ISACaller:
             mvl = self.svstate.maxvl.asint(msb0=True)
             srcstep = self.svstate.srcstep.asint(msb0=True)
             dststep = self.svstate.dststep.asint(msb0=True)
+            rm_mode = yield self.dec2.rm_dec.mode
             sv_ptype = yield self.dec2.dec.op.SV_Ptype
-            no_out_vec = not (yield self.dec2.no_out_vec)
-            no_in_vec = not (yield self.dec2.no_in_vec)
+            out_vec = not (yield self.dec2.no_out_vec)
+            in_vec = not (yield self.dec2.no_in_vec)
             log ("    svstate.vl", vl)
             log ("    svstate.mvl", mvl)
             log ("    svstate.srcstep", srcstep)
             log ("    svstate.dststep", dststep)
-            log ("    no_out_vec", no_out_vec)
-            log ("    no_in_vec", no_in_vec)
+            log ("    mode", rm_mode)
+            log ("    out_vec", out_vec)
+            log ("    in_vec", in_vec)
             log ("    sv_ptype", sv_ptype, sv_ptype == SVPtype.P2.value)
             # check if srcstep needs incrementing by one, stop PC advancing
             # svp64 loop can end early if the dest is scalar for single-pred
             # but for 2-pred both src/dest have to be checked.
             # XXX this might not be true! it may just be LD/ST
             if sv_ptype == SVPtype.P2.value:
-                svp64_is_vector = (no_out_vec or no_in_vec)
+                svp64_is_vector = (out_vec or in_vec)
             else:
-                svp64_is_vector = no_out_vec
+                svp64_is_vector = out_vec
             if svp64_is_vector and srcstep != vl-1 and dststep != vl-1:
                 self.svstate.srcstep += SelectableInt(1, 7)
                 self.svstate.dststep += SelectableInt(1, 7)
diff --git a/src/openpower/decoder/isa/test_caller_svp64_mapreduce.py b/src/openpower/decoder/isa/test_caller_svp64_mapreduce.py
new file mode 100644 (file)
index 0000000..1c969c7
--- /dev/null
@@ -0,0 +1,67 @@
+from nmigen import Module, Signal
+from nmigen.back.pysim 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
+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):
+        for i in range(32):
+            self.assertEqual(sim.gpr(i), SelectableInt(expected[i], 64))
+
+    def test_sv_add_scalar_reduce(self):
+        """>>> lst = ['sv.add/mr 1, 5.v, 1'
+                       ]
+        adds:
+            * 1 starts at 0x0101
+            * 1 = 5 + 1  => 0x101 + 0x202 => 0x303
+            * 1 = 6 + 1  => 0x303 + 0x404 => 0x707
+        """
+        isa = SVP64Asm(['sv.add/mr 1, 5.v, 1'
+                       ])
+        lst = list(isa)
+        print ("listing", lst)
+
+        # initial values in GPR regfile
+        initial_regs = [0] * 32
+        initial_regs[1] = 0x0101
+        initial_regs[5] = 0x0202
+        initial_regs[6] = 0x0404
+        # SVSTATE (in this case, VL=2)
+        svstate = SVP64State()
+        svstate.vl[0:7] = 2 # VL
+        svstate.maxvl[0:7] = 2 # MAXVL
+        print ("SVSTATE", bin(svstate.spr.asint()))
+        # copy before running, then compute answers
+        expected_regs = deepcopy(initial_regs)
+        expected_regs[1] = (initial_regs[1] + initial_regs[5] +
+                            initial_regs[6])  # 0x0707
+
+        with Program(lst, bigendian=False) as program:
+            sim = self.run_tst_program(program, initial_regs, svstate)
+            self._check_regs(sim, expected_regs)
+
+    def run_tst_program(self, prog, initial_regs=None,
+                              svstate=None):
+        if initial_regs is None:
+            initial_regs = [0] * 32
+        simulator = run_tst(prog, initial_regs, svstate=svstate)
+        simulator.gpr.dump()
+        return simulator
+
+
+if __name__ == "__main__":
+    unittest.main()
index d0770862b633475a267c9ca696b93027401377c0..3b854bdd0a98f8d736a9c8f8547de26c6a17738b 100644 (file)
@@ -1198,7 +1198,7 @@ class PowerDecode2(PowerDecodeSubset):
             comb += self.no_in_vec.eq(~Cat(*l).bool()) # all input scalar
             l = map(lambda svdec: svdec.isvec, [o2_svdec, o_svdec, crout_svdec])
             # in mapreduce mode, scalar out is *allowed*
-            with m.If(self.rm_dec.mode == SVP64RMMode.MAPREDUCE):
+            with m.If(self.rm_dec.mode == SVP64RMMode.MAPREDUCE.value):
                 comb += self.no_out_vec.eq(0)
             with m.Else():
                 comb += self.no_out_vec.eq(~Cat(*l).bool()) # all output scalar