add shift-left and shift-right scalar-to-vector tests
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 29 Sep 2022 10:56:20 +0000 (11:56 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 29 Sep 2022 10:56:20 +0000 (11:56 +0100)
src/openpower/decoder/isa/test_caller_svp64_bigint.py [new file with mode: 0644]

diff --git a/src/openpower/decoder/isa/test_caller_svp64_bigint.py b/src/openpower/decoder/isa/test_caller_svp64_bigint.py
new file mode 100644 (file)
index 0000000..e271966
--- /dev/null
@@ -0,0 +1,139 @@
+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):
+        for i in range(32):
+            self.assertEqual(sim.gpr(i), SelectableInt(expected[i], 64),
+                             "reg %d expected %x got %x" % \
+                            (i, sim.gpr(i).value, expected[i]))
+
+    def test_sv_bigint_add(self):
+        """performs a carry-rollover-vector-add aka "big integer vector add"
+        this is remarkably simple, each sv.addeo uses and produces a CA which
+        goes into the next sv.addeo.  arbitrary size is possible (1024+) as
+        is looping using the CA bit from one sv.addeo on another batch to do
+        unlimited-size biginteger add.
+
+        r3/r2: 0x0000_0000_0000_0001 0xffff_ffff_ffff_ffff +
+        r5/r4: 0x8000_0000_0000_0000 0x0000_0000_0000_0001 =
+        r1/r0: 0x8000_0000_0000_0002 0x0000_0000_0000_0000
+        """
+        isa = SVP64Asm(['sv.addeo *0, *2, *4'
+                       ])
+        lst = list(isa)
+        print ("listing", lst)
+
+        # initial values in GPR regfile
+        initial_regs = [0] * 32
+        initial_regs[2] = 0xffff_ffff_ffff_ffff   # lo dword A
+        initial_regs[3] = 0x0000_0000_0000_0001   # hi dword A
+        initial_regs[4] = 0x0000_0000_0000_0001   # lo dword B
+        initial_regs[5] = 0x8000_0000_0000_0000   # hi dword B
+        # SVSTATE (in this case, VL=2)
+        svstate = SVP64State()
+        svstate.vl = 2 # VL
+        svstate.maxvl = 2 # MAXVL
+        print ("SVSTATE", bin(svstate.asint()))
+        # copy before running
+        expected_regs = deepcopy(initial_regs)
+        expected_regs[0] = 0x0                   # rollover to zero, carry
+        expected_regs[1] = 0x8000_0000_0000_0002 # carry rolled-over
+
+        with Program(lst, bigendian=False) as program:
+            sim = self.run_tst_program(program, initial_regs, svstate)
+            self._check_regs(sim, expected_regs)
+
+    def test_sv_bigint_scalar_shiftright(self):
+        """performs a scalar-to-vector right-shift.
+
+        r3                    r2                    r1                       r4
+        0x0000_0000_0000_0002 0x8000_8000_8000_8001 0xffff_ffff_ffff_ffff >> 4
+        0x0000_0000_0000_0002 0x2800_0800_0800_0800 0x1fff_ffff_ffff_ffff >> 4
+        """
+        isa = SVP64Asm(['sv.dsrd *0,*1,4,1'
+                       ])
+        lst = list(isa)
+        print ("listing", lst)
+
+        # initial values in GPR regfile
+        initial_regs = [0] * 32
+        initial_regs[0] = 0xffff_ffff_ffff_ffff   # lo dword A
+        initial_regs[1] = 0x8000_8000_8000_8001   # mid dword A
+        initial_regs[2] = 0x0000_0000_0000_0002   # hi dword A
+        initial_regs[4] = 0x0000_0000_0000_0004   # shift amount (a nibble)
+        # SVSTATE (in this case, VL=2)
+        svstate = SVP64State()
+        svstate.vl = 2 # VL
+        svstate.maxvl = 2 # MAXVL
+        print ("SVSTATE", bin(svstate.asint()))
+        # copy before running
+        expected_regs = deepcopy(initial_regs)
+        expected_regs[0] = 0x1fff_ffff_ffff_ffff   # MSB nibble gets LSB
+        expected_regs[1] = 0x2800_0800_0800_0800   # hi dword A
+
+        with Program(lst, bigendian=False) as program:
+            sim = self.run_tst_program(program, initial_regs, svstate)
+            self._check_regs(sim, expected_regs)
+
+    def test_sv_bigint_scalar_shiftleft(self):
+        """performs a scalar-to-vector left-shift: because the result is moved
+        down by one scalar (RT=0 not 1) there is no need for reverse-gear.
+        r2 is *not* modified (contains its original value).
+        r2                    r1                    r0                       r4
+        0x0000_0000_0001_0002 0x3fff_ffff_ffff_ffff 0x4000_0000_0000_0001 << 4
+        0x0000_0000_0001_0002 0x0000_0000_0010_0023 0xffff_ffff_ffff_fff4
+        """
+        isa = SVP64Asm(['sv.dsld *0,*1,4,1'
+                       ])
+        lst = list(isa)
+        print ("listing", lst)
+
+        # initial values in GPR regfile
+        initial_regs = [0] * 32
+        initial_regs[0] = 0x4000_0000_0000_0001   # lo dword A
+        initial_regs[1] = 0x3fff_ffff_ffff_ffff   # mid dword A
+        initial_regs[2] = 0x0000_0000_0001_0002   # hi dword A
+        initial_regs[4] = 0x0000_0000_0000_0004   # shift amount (a nibble)
+        # SVSTATE (in this case, VL=2)
+        svstate = SVP64State()
+        svstate.vl = 2 # VL
+        svstate.maxvl = 2 # MAXVL
+        print ("SVSTATE", bin(svstate.asint()))
+        # copy before running
+        expected_regs = deepcopy(initial_regs)
+        expected_regs[0] = 0xffff_ffff_ffff_fff4   # MSB nibble gets LSB
+        expected_regs[1] = 0x0000_0000_0010_0023   # hi dword A
+
+        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,
+                              initial_cr=0):
+        if initial_regs is None:
+            initial_regs = [0] * 32
+        simulator = run_tst(prog, initial_regs, svstate=svstate,
+                            initial_cr=initial_cr)
+        simulator.gpr.dump()
+        return simulator
+
+
+if __name__ == "__main__":
+    unittest.main()