swap complicated bits, simplify ISACaller, reduce indent level
[openpower-isa.git] / src / openpower / decoder / isa / test_caller_svp64_fp.py
index a6c28611196525f3017d85bf74125ff7782ffde1..610fb59fabf71e20efd0559c39cb5e5bed3c8787 100644 (file)
@@ -1,5 +1,5 @@
 from nmigen import Module, Signal
-from nmigen.back.pysim import Simulator, Delay, Settle
+from nmigen.sim import Simulator, Delay, Settle
 from nmutil.formaltest import FHDLTestCase
 import unittest
 from openpower.decoder.isa.caller import ISACaller
@@ -22,19 +22,19 @@ class DecoderTestCase(FHDLTestCase):
         for i in range(32):
             self.assertEqual(sim.gpr(i), SelectableInt(expected[i], 64))
 
-    def tst_sv_fpload(self):
-        """>>> lst = ["sv.lfsx 2.v, 0, 0.v"
+    def test_sv_fpload(self):
+        """>>> lst = ["sv.lfsx *2, 0, *0"
                         ]
         """
-        lst = SVP64Asm(["sv.lfsx 2.v, 0, 0.v"
+        lst = SVP64Asm(["sv.lfsx *2, 0, *0"
                         ])
         lst = list(lst)
 
         # 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()))
+        svstate.vl = 2 # VL
+        svstate.maxvl = 2 # MAXVL
+        print ("SVSTATE", bin(svstate.asint()))
 
         # memory addresses 0x0000 and 0x0008
         initial_mem = {0x0000: (0x42013333, 8), # 32.3
@@ -58,22 +58,50 @@ class DecoderTestCase(FHDLTestCase):
             self.assertEqual(sim.fpr(3), SelectableInt(0xC004000000000000, 64))
 
     def test_fp_single_ldst(self):
-        """>>> lst = ["sv.lfsx 0.v, 0, 2.v",   # load fp 1/2 from mem 0/8
-                      "sv.stfsu 0.v, 16(4.v)", # store fp 1/2, update RA *twice*
-                      "sv.lfs 3.v, 0(4.v)",   # re-load from UPDATED r4/r5
+        """>>> lst = ["sv.lfsx *0, 0, *4",   # load fp 1/2 from mem 0/8
+                      "sv.stfsu *0, 16(*4)", # store fp 1/2, update RA *twice*
+                      "sv.lfs *2, 0(*4)",   # re-load from UPDATED r4/r5
                      ]
+
+        This is quite an involved (deceptively simple looking) test.
+        The sv.stfsu is creating a *Vector* of Effective Addresses, and
+        consequently is updating (writing) a *Vector* of EAs into the GPR.
+
+        Walkthrough:
+
+        1) sv.lfsx *0, 0, *4    VL=2 so there are *two* lfsx operations
+                lfsx 0, 0, 4      loads from MEM[GPR(4)], stores in FPR(0)
+                lfsx 1, 0, 5      loads from MEM[GPR(5)], stores in FPR(1)
+
+        2) sv.stfsu *0, 16(*4)  again, VL=2 so there are two ST-FP-update ops
+                stfsu 0, 16(4)    EA=GPR(4)+16, FPR(0) to MEM[EA], EA to GPR(4)
+                stfsu 1, 16(5)    EA=GPR(5)+16, FPR(0) to MEM[EA], EA to GPR(5)
+
+           note that there are **TWO** FP writes to memory, and **TWO**
+           writes of the calculated Effective Address to GPR, in regs 4 and 5
+           GPRs 4 and 5 are *overwritten*.
+
+        3) sv.lfs *3, 0(*4)     VL=2, so two immediate-LDs
+                lfs 3, 0(4)       EA=GPR(4)+0, FPR(3) = MEM[EA]
+                lfs 4, 0(5)       EA=GPR(5)+0, FPR(4) = MEM[EA]
+
+           here we have loaded from the *overwritten* GPRs 4 and 5.
+
+        strictly speaking this unit test should also verify the contents
+        of the memory locations 0x10 and 0x18, which should contain the
+        single-precision FP numbers in the bottom 4 bytes.  TODO
         """
-        lst = SVP64Asm(["sv.lfsx 0.v, 0, 4.v",
-                        "sv.stfsu 0.v, 16(4.v)",
-                        "sv.lfs 3.v, 0(4.v)",
+        lst = SVP64Asm(["sv.lfsx *0, 0, *4",
+                        "sv.stfsu *0, 16(*4)",
+                        "sv.lfs *2, 0(*4)",
                      ])
         lst = list(lst)
 
         # 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()))
+        svstate.vl = 2 # VL
+        svstate.maxvl = 2 # MAXVL
+        print ("SVSTATE", bin(svstate.asint()))
 
         # memory addresses 0x0000 and 0x0008
         initial_mem = {0x0000: (0x42013333, 8), # 32.3
@@ -100,15 +128,14 @@ class DecoderTestCase(FHDLTestCase):
             self.assertEqual(sim.gpr(5), SelectableInt(0x18, 64))
             self.assertEqual(sim.fpr(0), SelectableInt(0x4040266660000000, 64))
             self.assertEqual(sim.fpr(1), SelectableInt(0xC004000000000000, 64))
-            self.assertEqual(sim.fpr(3), SelectableInt(0x4040266660000000, 64))
-            self.assertEqual(sim.fpr(4), SelectableInt(0xC004000000000000, 64))
-
+            self.assertEqual(sim.fpr(2), SelectableInt(0x4040266660000000, 64))
+            self.assertEqual(sim.fpr(3), SelectableInt(0xC004000000000000, 64))
 
-    def tst_sv_fpadd(self):
-        """>>> lst = ["sv.fadds 6.v, 2.v, 4.v"
+    def test_sv_fpadd(self):
+        """>>> lst = ["sv.fadds *6, *2, *4"
                         ]
         """
-        lst = SVP64Asm(["sv.fadds 6.v, 2.v, 4.v"
+        lst = SVP64Asm(["sv.fadds *6, *2, *4"
                         ])
         lst = list(lst)
 
@@ -120,9 +147,9 @@ class DecoderTestCase(FHDLTestCase):
 
         # 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()))
+        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,
@@ -130,6 +157,38 @@ class DecoderTestCase(FHDLTestCase):
             self.assertEqual(sim.fpr(6), SelectableInt(0x0, 64))
             self.assertEqual(sim.fpr(7), SelectableInt(0xc050266660000000, 64))
 
+    def test_sv_fpmadds(self):
+        """>>> lst = ["sv.fmadds *6, *2, *4, 8"
+                        ]
+            two vector mul-adds with a scalar in f8
+            * fp6 = fp2 * fp4 + f8 = 7.0 * 2.0 - 2.0 = 12.0
+            * fp7 = fp3 * fp5 + f8 = 7.0 * 2.0 - 2.0 = 12.0
+        """
+        lst = SVP64Asm(["sv.fmadds *6, *2, *4, 8"
+                        ])
+        lst = list(lst)
+
+        fprs = [0] * 32
+        fprs[2] = 0x401C000000000000  # 7.0
+        fprs[3] = 0xC02399999999999A  # -9.8
+        fprs[4] = 0x4000000000000000  # 2.0
+        fprs[5] = 0xC040266660000000 # -32.3
+        fprs[6] = 0x4000000000000000  # 2.0
+        fprs[7] = 0x4000000000000000  # 2.0
+        fprs[8] = 0xc000000000000000  # -2.0
+
+        # SVSTATE (in this case, VL=2)
+        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,
+                                       initial_fprs=fprs)
+            self.assertEqual(sim.fpr(6), SelectableInt(0x4028000000000000, 64))
+            self.assertEqual(sim.fpr(7), SelectableInt(0x4073a8a3c0000000, 64))
+
     def run_tst_program(self, prog, initial_regs=None,
                               svstate=None,
                               initial_mem=None,