add test_caller_svshape2.py and make corrections to csv and fields.txt
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 2 Sep 2022 20:46:53 +0000 (21:46 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 2 Sep 2022 20:46:53 +0000 (21:46 +0100)
yx needed to be SVM2-form and was in a different bitposition
offs needed to be 6:9 not 6:10
XO was off-by-one in minor_22.csv

openpower/isatables/fields.text
openpower/isatables/minor_22.csv
src/openpower/decoder/isa/test_caller_svshape2.py [new file with mode: 0644]
src/openpower/sv/trans/svp64.py

index a8fb5bf4d0d9254c4fa7fc2c65ad902198251581..5a08d23eb60385a7ef6d7503a2254721fac8caa3 100644 (file)
         Field used to specify the number of bytes to move
         in an immediate Move Assist instruction.
         Formats: X
-    offs (6:10)
+    offs (6:9)
         Field used by the svshape2 instruction as an offset
         Formats: SVM2
     OC (6:20)
     yx (23)
         Field used to specify loop dimension order in svindex
         Formats: SVI
+    yx (10)
+        Field used to specify loop dimension order in svshape2
+        Formats: SVM2
index 8f29693b12ed9f45335b024eb1ae9cf8265fb251..30a636da235fa7b0f912614bfd3f42041e6881b9 100644 (file)
@@ -22,7 +22,7 @@ opcode,unit,internal op,in1,in2,in3,out,CR in,CR out,inv A,inv out,cry in,cry ou
 1110-011001,VL,OP_SVSHAPE,NONE,NONE,NONE,NONE,NONE,NONE,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,svshape,SVM,,1,unofficial until submitted and approved/renumbered by the opf isa wg
 1111-011001,VL,OP_SVSHAPE,NONE,NONE,NONE,NONE,NONE,NONE,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,svshape,SVM,,1,unofficial until submitted and approved/renumbered by the opf isa wg
 # svshape2: {-100,mm,011001}
--100-011001,VL,OP_SVSHAPE,NONE,NONE,NONE,NONE,NONE,NONE,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,svshape2,SVM,,1,unofficial until submitted and approved/renumbered by the opf isa wg
+100--011001,VL,OP_SVSHAPE,NONE,NONE,NONE,NONE,NONE,NONE,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,svshape2,SVM,,1,unofficial until submitted and approved/renumbered by the opf isa wg
 # A/V bitmanip
 0111001110-,ALU,OP_MINMAX,RA,RB,NONE,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,0,0,RC_ONLY,0,0,maxs,X,,1,unofficial until submitted and approved/renumbered by the opf isa wg
 0011001110-,ALU,OP_MINMAX,RA,RB,NONE,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,0,0,RC_ONLY,0,0,maxu,X,,1,unofficial until submitted and approved/renumbered by the opf isa wg
diff --git a/src/openpower/decoder/isa/test_caller_svshape2.py b/src/openpower/decoder/isa/test_caller_svshape2.py
new file mode 100644 (file)
index 0000000..fdef4ed
--- /dev/null
@@ -0,0 +1,385 @@
+"""SVP64 unit test for svshape2
+svshape2 offs,yx,rmm,SVd,sk,mm
+"""
+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 SVSTATETestCase(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),
+            "GPR %d %x expected %x" % (i, sim.gpr(i).value, expected[i]))
+
+    def test_0_sv_shape2(self):
+        """sets VL=10 (via SVSTATE) then does svshape mm=0, checks SPRs after
+        """
+        isa = SVP64Asm(['svshape2 12, 1, 15, 5, 0, 0'
+                       ])
+        lst = list(isa)
+        print ("listing", lst)
+
+        # initial values in GPR regfile
+        initial_regs = [0] * 32
+        initial_regs[9] = 0x1234
+        initial_regs[10] = 0x1111
+        initial_regs[5] = 0x4321
+        initial_regs[6] = 0x2223
+
+        # SVSTATE vl=10
+        svstate = SVP64State()
+        svstate.vl = 10 # VL
+        svstate.maxvl = 10 # MAXVL
+        print ("SVSTATE", bin(svstate.asint()))
+
+        # copy before running
+        expected_regs = deepcopy(initial_regs)
+        #expected_regs[1] = 0x3334
+
+        with Program(lst, bigendian=False) as program:
+            sim = self.run_tst_program(program, initial_regs, svstate=svstate)
+            self._check_regs(sim, expected_regs)
+
+            print (sim.spr)
+            SVSHAPE0 = sim.spr['SVSHAPE0']
+            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 ("      RMpst", bin(sim.svstate.RMpst))
+            print ("       SVme", bin(sim.svstate.SVme))
+            print ("        mo0", bin(sim.svstate.mo0))
+            print ("        mo1", bin(sim.svstate.mo1))
+            print ("        mi0", bin(sim.svstate.mi0))
+            print ("        mi1", bin(sim.svstate.mi1))
+            print ("        mi2", bin(sim.svstate.mi2))
+            print ("STATE0     ", SVSHAPE0)
+            print ("STATE0 offs", SVSHAPE0.offset)
+            print ("STATE0 xdim", SVSHAPE0.xdimsz)
+            print ("STATE0 ydim", SVSHAPE0.ydimsz)
+            print ("STATE0 skip", bin(SVSHAPE0.skip))
+            print ("STATE0  inv", SVSHAPE0.invxyz)
+            print ("STATE0order", SVSHAPE0.order)
+            self.assertEqual(SVSHAPE0.xdimsz, 5) # set
+            self.assertEqual(SVSHAPE0.ydimsz, 2) # calculated from MVL/xdimsz
+            self.assertEqual(SVSHAPE0.skip, 0)   # no skip
+            self.assertEqual(SVSHAPE0.invxyz, 0) # (no inversion possible)
+            self.assertEqual(SVSHAPE0.offset, 12)
+            self.assertEqual(SVSHAPE0.order, (1, 0, 2)) # y,x(,z)
+            self.assertEqual(sim.svstate.RMpst, 0) # mm=0 so persist=0
+            self.assertEqual(sim.svstate.SVme, 0b01111) # same as rmm
+            # rmm is 0b01111 which means mi0=0 mi1=1 mi2=2 mo0=3 mo1=0
+            self.assertEqual(sim.svstate.mi0, 0)
+            self.assertEqual(sim.svstate.mi1, 1)
+            self.assertEqual(sim.svstate.mi2, 2)
+            self.assertEqual(sim.svstate.mo0, 3)
+            self.assertEqual(sim.svstate.mo1, 0)
+
+    def tst_1_sv_index(self):
+        """sets VL=10 (via SVSTATE) then does svindex mm=1, checks SPRs after
+        """
+        # rmm: bits 0-2 (MSB0) are 0b011 and bits 3-4 are 0b10.
+        #      therefore rmm is 0b011 || 0b10 --> 0b01110 -> 14
+        isa = SVP64Asm(['svindex 1, 14, 5, 0, 0, 1, 0'
+                       ])
+        lst = list(isa)
+        print ("listing", lst)
+
+        # initial values in GPR regfile
+        initial_regs = [0] * 32
+        initial_regs[9] = 0x1234
+        initial_regs[10] = 0x1111
+        initial_regs[5] = 0x4321
+        initial_regs[6] = 0x2223
+
+        # SVSTATE vl=10
+        svstate = SVP64State()
+        svstate.vl = 10 # VL
+        svstate.maxvl = 10 # MAXVL
+        print ("SVSTATE", bin(svstate.asint()))
+
+        # copy before running
+        expected_regs = deepcopy(initial_regs)
+        #expected_regs[1] = 0x3334
+
+        with Program(lst, bigendian=False) as program:
+            sim = self.run_tst_program(program, initial_regs, svstate=svstate)
+            self._check_regs(sim, expected_regs)
+
+            print (sim.spr)
+            SVSHAPE2 = sim.spr['SVSHAPE2']
+            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 ("      RMpst", bin(sim.svstate.RMpst))
+            print ("       SVme", bin(sim.svstate.SVme))
+            print ("        mo0", bin(sim.svstate.mo0))
+            print ("        mo1", bin(sim.svstate.mo1))
+            print ("        mi0", bin(sim.svstate.mi0))
+            print ("        mi1", bin(sim.svstate.mi1))
+            print ("        mi2", bin(sim.svstate.mi2))
+            print ("STATE2svgpr", hex(SVSHAPE2.svgpr))
+            print ("STATE2 xdim", SVSHAPE2.xdimsz)
+            print ("STATE2 ydim", SVSHAPE2.ydimsz)
+            print ("STATE2 skip", bin(SVSHAPE2.skip))
+            print ("STATE2  inv", SVSHAPE2.invxyz)
+            print ("STATE2order", SVSHAPE2.order)
+            self.assertEqual(sim.svstate.RMpst, 1) # mm=1 so persist=1
+            # rmm is 0b01110 which means mo0 = 2
+            self.assertEqual(sim.svstate.mi0, 0)
+            self.assertEqual(sim.svstate.mi1, 0)
+            self.assertEqual(sim.svstate.mi2, 0)
+            self.assertEqual(sim.svstate.mo0, 2)
+            self.assertEqual(sim.svstate.mo1, 0)
+            # and mo0 should be activated
+            self.assertEqual(sim.svstate.SVme, 0b01000)
+            # now check the SVSHAPEs. 2 was the one targetted
+            self.assertEqual(SVSHAPE2.svgpr, 2) # SVG is shifted up by 1
+            self.assertEqual(SVSHAPE2.xdimsz, 5)  # SHAPE2 xdim set to 5
+            self.assertEqual(SVSHAPE2.ydimsz, 1)  # SHAPE2 ydim 1
+            # all others must be zero
+            for i in [0,1,3]:
+                shape = sim.spr['SVSHAPE%d' % i]
+                self.assertEqual(shape.asint(), 0) # all others zero
+
+    def tst_0_sv_index_add(self):
+        """sets VL=6 (via SVSTATE) then does svindex, and an add.
+
+        only RA is re-mapped via Indexing, not RB or RT
+        """
+        isa = SVP64Asm(['svindex 8, 1, 1, 0, 0, 0, 0',
+                        'sv.add *8, *0, *0',
+                       ])
+        lst = list(isa)
+        print ("listing", lst)
+
+        # initial values in GPR regfile
+        initial_regs = [0] * 32
+        idxs = [1, 0, 5, 2, 4, 3] # random enough
+        for i in range(6):
+            initial_regs[16+i] = idxs[i]
+            initial_regs[i] = i
+
+        # SVSTATE vl=10
+        svstate = SVP64State()
+        svstate.vl = 6 # VL
+        svstate.maxvl = 6 # MAXVL
+        print ("SVSTATE", bin(svstate.asint()))
+
+        # copy before running
+        expected_regs = deepcopy(initial_regs)
+        for i in range(6):
+            RA = initial_regs[0+idxs[i]]
+            RB = initial_regs[0+i]
+            expected_regs[i+8] = RA+RB
+            print ("expected", i, expected_regs[i+8])
+
+        with Program(lst, bigendian=False) as program:
+            sim = self.run_tst_program(program, initial_regs, svstate=svstate)
+
+            print (sim.spr)
+            SVSHAPE0 = sim.spr['SVSHAPE0']
+            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 ("      RMpst", bin(sim.svstate.RMpst))
+            print ("       SVme", bin(sim.svstate.SVme))
+            print ("        mo0", bin(sim.svstate.mo0))
+            print ("        mo1", bin(sim.svstate.mo1))
+            print ("        mi0", bin(sim.svstate.mi0))
+            print ("        mi1", bin(sim.svstate.mi1))
+            print ("        mi2", bin(sim.svstate.mi2))
+            print ("STATE0svgpr", hex(SVSHAPE0.svgpr))
+            print (sim.gpr.dump())
+            self.assertEqual(sim.svstate.RMpst, 0) # mm=0 so persist=0
+            self.assertEqual(sim.svstate.SVme, 0b00001) # same as rmm
+            # rmm is 0b00001 which means mi0=0 and all others inactive (0)
+            self.assertEqual(sim.svstate.mi0, 0)
+            self.assertEqual(sim.svstate.mi1, 0)
+            self.assertEqual(sim.svstate.mi2, 0)
+            self.assertEqual(sim.svstate.mo0, 0)
+            self.assertEqual(sim.svstate.mo1, 0)
+            self.assertEqual(SVSHAPE0.svgpr, 16) # SVG is shifted up by 1
+            for i in range(1,4):
+                shape = sim.spr['SVSHAPE%d' % i]
+                self.assertEqual(shape.svgpr, 0) 
+            self._check_regs(sim, expected_regs)
+
+    def tst_1_sv_index_add(self):
+        """sets VL=6 (via SVSTATE) then does modulo 3 svindex, and an add.
+
+        only RA is re-mapped via Indexing, not RB or RT
+        """
+        isa = SVP64Asm(['svindex 8, 1, 3, 0, 0, 0, 0',
+                        'sv.add *8, *0, *0',
+                       ])
+        lst = list(isa)
+        print ("listing", lst)
+
+        # initial values in GPR regfile
+        initial_regs = [0] * 32
+        idxs = [1, 0, 5, 2, 4, 3] # random enough
+        for i in range(6):
+            initial_regs[16+i] = idxs[i]
+            initial_regs[i] = i
+
+        # SVSTATE vl=10
+        svstate = SVP64State()
+        svstate.vl = 6 # VL
+        svstate.maxvl = 6 # MAXVL
+        print ("SVSTATE", bin(svstate.asint()))
+
+        # copy before running
+        expected_regs = deepcopy(initial_regs)
+        for i in range(6):
+            RA = initial_regs[0+idxs[i%3]] # modulo 3 but still indexed
+            RB = initial_regs[0+i]
+            expected_regs[i+8] = RA+RB
+            print ("expected", i, expected_regs[i+8])
+
+        with Program(lst, bigendian=False) as program:
+            sim = self.run_tst_program(program, initial_regs, svstate=svstate)
+
+            print (sim.spr)
+            SVSHAPE0 = sim.spr['SVSHAPE0']
+            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 ("      RMpst", bin(sim.svstate.RMpst))
+            print ("       SVme", bin(sim.svstate.SVme))
+            print ("        mo0", bin(sim.svstate.mo0))
+            print ("        mo1", bin(sim.svstate.mo1))
+            print ("        mi0", bin(sim.svstate.mi0))
+            print ("        mi1", bin(sim.svstate.mi1))
+            print ("        mi2", bin(sim.svstate.mi2))
+            print ("STATE0svgpr", hex(SVSHAPE0.svgpr))
+            print ("STATE0 xdim", SVSHAPE0.xdimsz)
+            print ("STATE0 ydim", SVSHAPE0.ydimsz)
+            print ("STATE0 skip", bin(SVSHAPE0.skip))
+            print ("STATE0  inv", SVSHAPE0.invxyz)
+            print ("STATE0order", SVSHAPE0.order)
+            print (sim.gpr.dump())
+            self.assertEqual(sim.svstate.RMpst, 0) # mm=0 so persist=0
+            self.assertEqual(sim.svstate.SVme, 0b00001) # same as rmm
+            # rmm is 0b00001 which means mi0=0 and all others inactive (0)
+            self.assertEqual(sim.svstate.mi0, 0)
+            self.assertEqual(sim.svstate.mi1, 0)
+            self.assertEqual(sim.svstate.mi2, 0)
+            self.assertEqual(sim.svstate.mo0, 0)
+            self.assertEqual(sim.svstate.mo1, 0)
+            self.assertEqual(SVSHAPE0.svgpr, 16) # SVG is shifted up by 1
+            for i in range(1,4):
+                shape = sim.spr['SVSHAPE%d' % i]
+                self.assertEqual(shape.svgpr, 0) 
+            self._check_regs(sim, expected_regs)
+
+    def tst_2_sv_index_add(self):
+        """sets VL=6 (via SVSTATE) then does 2D remapped svindex, and an add.
+
+        dim=3,yx=1
+        only RA is re-mapped via Indexing, not RB or RT
+        """
+        isa = SVP64Asm(['svindex 8, 1, 3, 0, 1, 0, 0',
+                        'sv.add *8, *0, *0',
+                       ])
+        lst = list(isa)
+        print ("listing", lst)
+
+        # initial values in GPR regfile
+        initial_regs = [0] * 32
+        idxs = [1, 0, 5, 2, 4, 3] # random enough
+        for i in range(6):
+            initial_regs[16+i] = idxs[i]
+            initial_regs[i] = i
+
+        # SVSTATE vl=10
+        svstate = SVP64State()
+        svstate.vl = 6 # VL
+        svstate.maxvl = 6 # MAXVL
+        print ("SVSTATE", bin(svstate.asint()))
+
+        # copy before running
+        expected_regs = deepcopy(initial_regs)
+        for i in range(6):
+            xi = i % 3
+            yi = i // 3
+            remap = yi+xi*2
+            RA = initial_regs[0+idxs[remap]] # modulo 3 but still indexed
+            RB = initial_regs[0+i]
+            expected_regs[i+8] = RA+RB
+            print ("expected", i, expected_regs[i+8])
+
+        with Program(lst, bigendian=False) as program:
+            sim = self.run_tst_program(program, initial_regs, svstate=svstate)
+
+            print (sim.spr)
+            SVSHAPE0 = sim.spr['SVSHAPE0']
+            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 ("      RMpst", bin(sim.svstate.RMpst))
+            print ("       SVme", bin(sim.svstate.SVme))
+            print ("        mo0", bin(sim.svstate.mo0))
+            print ("        mo1", bin(sim.svstate.mo1))
+            print ("        mi0", bin(sim.svstate.mi0))
+            print ("        mi1", bin(sim.svstate.mi1))
+            print ("        mi2", bin(sim.svstate.mi2))
+            print ("STATE0svgpr", hex(SVSHAPE0.svgpr))
+            print ("STATE0 xdim", SVSHAPE0.xdimsz)
+            print ("STATE0 ydim", SVSHAPE0.ydimsz)
+            print ("STATE0 skip", bin(SVSHAPE0.skip))
+            print ("STATE0  inv", SVSHAPE0.invxyz)
+            print ("STATE0order", SVSHAPE0.order)
+            print (sim.gpr.dump())
+            self.assertEqual(sim.svstate.RMpst, 0) # mm=0 so persist=0
+            self.assertEqual(sim.svstate.SVme, 0b00001) # same as rmm
+            # rmm is 0b00001 which means mi0=0 and all others inactive (0)
+            self.assertEqual(sim.svstate.mi0, 0)
+            self.assertEqual(sim.svstate.mi1, 0)
+            self.assertEqual(sim.svstate.mi2, 0)
+            self.assertEqual(sim.svstate.mo0, 0)
+            self.assertEqual(sim.svstate.mo1, 0)
+            self.assertEqual(SVSHAPE0.svgpr, 16) # SVG is shifted up by 1
+            for i in range(1,4):
+                shape = sim.spr['SVSHAPE%d' % i]
+                self.assertEqual(shape.svgpr, 0) 
+            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 aa694b7f4703674a0bfd581c491944fd043101ce..e094392e5560774edd1e5a7969203a10ad5bccae 100644 (file)
@@ -215,7 +215,7 @@ def svshape2(fields):
 
     return instruction(
         (PO, 0, 5),
-        (offs, 6, 10), # offset (the whole point of adding svshape2)
+        (offs, 6, 9),  # offset (the whole point of adding svshape2)
         (yx, 10, 10),  # like svindex
         (rmm, 11, 15), # ditto svindex
         (SVd, 16, 20), # ditto svindex