add CR0 setting and unit test on svstep
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 8 Jul 2021 22:04:51 +0000 (23:04 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 8 Jul 2021 22:04:51 +0000 (23:04 +0100)
src/openpower/decoder/isa/caller.py
src/openpower/decoder/isa/test_caller_setvl.py

index d57a8fc12387dfa63e231ec952ad6a59d169f823..d8f4d3fcab27f53b70bb58953a383579cffd8b7b 100644 (file)
@@ -1442,9 +1442,11 @@ class ISACaller:
             yield from self.svstate_pre_inc()
             pre = yield from self.update_new_svstate_steps()
             if pre:
-                log ("SVSTATE_NEXT: end of loop, reset (TODO, update CR0)")
+                log ("SVSTATE_NEXT: end of loop, reset")
                 self.svp64_reset_loop()
                 self.update_nia()
+                results = [SelectableInt(0, 64)]
+                self.handle_comparison(results) # CR0
             else:
                 log ("SVSTATE_NEXT: post-inc")
                 srcstep, dststep = self.new_srcstep, self.new_dststep
@@ -1456,9 +1458,16 @@ class ISACaller:
                 if not end_dst:
                     self.svstate.dststep += SelectableInt(1, 7)
                 self.namespace['SVSTATE'] = self.svstate.spr
+                # set CR0 (if Rc=1) based on end
+                if rc_en:
+                    srcstep = self.svstate.srcstep.asint(msb0=True)
+                    dststep = self.svstate.srcstep.asint(msb0=True)
+                    endtest = 0 if (end_src or end_dst) else 1
+                    results = [SelectableInt(endtest, 64)]
+                    self.handle_comparison(results) # CR0
                 if end_src or end_dst:
                     self.svp64_reset_loop()
-                    # TODO: set CR0 (if Rc=1) based on end
+
         elif self.is_svp64_mode:
             yield from self.svstate_post_inc()
         else:
index f9729138c04c998005635bdfe26dd4121f36acf5..f4c17058fd16bcca45c7346c441139486c9b174a 100644 (file)
@@ -6,7 +6,7 @@ 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.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
@@ -28,6 +28,37 @@ class DecoderTestCase(FHDLTestCase):
                         ])
         lst = list(lst)
 
+        # SVSTATE (in this case, VL=4) which is going to get erased by setvl
+        svstate = SVP64State()
+        svstate.vl[0:7] = 4 # VL
+        svstate.maxvl[0:7] = 4 # MAXVL
+        print ("SVSTATE", bin(svstate.spr.asint()))
+
+        with Program(lst, bigendian=False) as program:
+            sim = self.run_tst_program(program, svstate=svstate)
+            print ("SVSTATE after", bin(sim.svstate.spr.asint()))
+            print ("        vl", bin(sim.svstate.vl.asint(True)))
+            print ("        mvl", bin(sim.svstate.maxvl.asint(True)))
+            print ("    srcstep", bin(sim.svstate.srcstep.asint(True)))
+            print ("    dststep", bin(sim.svstate.dststep.asint(True)))
+            self.assertEqual(sim.svstate.vl.asint(True), 10)
+            self.assertEqual(sim.svstate.maxvl.asint(True), 10)
+            self.assertEqual(sim.svstate.srcstep.asint(True), 2)
+            self.assertEqual(sim.svstate.dststep.asint(True), 2)
+            print("      gpr1", sim.gpr(0))
+            self.assertEqual(sim.gpr(0), SelectableInt(0, 64))
+            print("      msr", bin(sim.msr.value))
+            self.assertEqual(sim.msr, SelectableInt(1<<(63-6), 64))
+
+    def test_svstep_2(self):
+        """tests svstep when it reaches VL
+        """
+        lst = SVP64Asm(["setvl 0, 0, 1, 1, 1, 1",
+                        "setvl. 0, 0, 0, 1, 0, 0",
+                        "setvl. 0, 0, 0, 1, 0, 0"
+                        ])
+        lst = list(lst)
+
         # SVSTATE (in this case, VL=2)
         svstate = SVP64State()
         svstate.vl[0:7] = 2 # VL
@@ -41,14 +72,59 @@ class DecoderTestCase(FHDLTestCase):
             print ("        mvl", bin(sim.svstate.maxvl.asint(True)))
             print ("    srcstep", bin(sim.svstate.srcstep.asint(True)))
             print ("    dststep", bin(sim.svstate.dststep.asint(True)))
-            self.assertEqual(sim.svstate.vl.asint(True), 10)
-            self.assertEqual(sim.svstate.maxvl.asint(True), 10)
+            self.assertEqual(sim.svstate.vl.asint(True), 2)
+            self.assertEqual(sim.svstate.maxvl.asint(True), 2)
+            self.assertEqual(sim.svstate.srcstep.asint(True), 0)
+            self.assertEqual(sim.svstate.dststep.asint(True), 0)
+            print("      gpr1", sim.gpr(0))
+            self.assertEqual(sim.gpr(0), SelectableInt(0, 64))
+            print("      msr", bin(sim.msr.value))
+            self.assertEqual(sim.msr, SelectableInt(1<<(63-6), 64))
+            CR0 = sim.crl[0]
+            print("      CR0", bin(CR0.get_range().value))
+            self.assertEqual(CR0[CRFields.EQ], 1)
+            self.assertEqual(CR0[CRFields.LT], 0)
+            self.assertEqual(CR0[CRFields.GT], 0)
+            self.assertEqual(CR0[CRFields.SO], 0)
+
+    def test_svstep_3(self):
+        """tests svstep when it *doesn't* reach VL
+        """
+        lst = SVP64Asm(["setvl 0, 0, 2, 1, 1, 1",
+                        "setvl. 0, 0, 0, 1, 0, 0",
+                        "setvl. 0, 0, 0, 1, 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()))
+
+        with Program(lst, bigendian=False) as program:
+            sim = self.run_tst_program(program, svstate=svstate)
+            print ("SVSTATE after", bin(sim.svstate.spr.asint()))
+            print ("        vl", bin(sim.svstate.vl.asint(True)))
+            print ("        mvl", bin(sim.svstate.maxvl.asint(True)))
+            print ("    srcstep", bin(sim.svstate.srcstep.asint(True)))
+            print ("    dststep", bin(sim.svstate.dststep.asint(True)))
+            self.assertEqual(sim.svstate.vl.asint(True), 3)
+            self.assertEqual(sim.svstate.maxvl.asint(True), 3)
+            # svstep called twice, didn't reach VL, so srcstep/dststep both 2
             self.assertEqual(sim.svstate.srcstep.asint(True), 2)
             self.assertEqual(sim.svstate.dststep.asint(True), 2)
             print("      gpr1", sim.gpr(0))
             self.assertEqual(sim.gpr(0), SelectableInt(0, 64))
             print("      msr", bin(sim.msr.value))
             self.assertEqual(sim.msr, SelectableInt(1<<(63-6), 64))
+            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], 1)
+            self.assertEqual(CR0[CRFields.SO], 0)
+
 
     def test_setvl_1(self):
         lst = SVP64Asm(["setvl 1, 0, 9, 0, 1, 1",