got linked-list-pointer-chasing working
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 15 May 2023 11:55:20 +0000 (12:55 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 15 May 2023 11:55:20 +0000 (12:55 +0100)
including with LD/ST-with-update
https://bugs.libre-soc.org/show_bug.cgi?id=1047

src/openpower/decoder/isa/caller.py
src/openpower/decoder/isa/test_caller_svp64_ldst.py

index 5d8498857e7ee95b1f621f25cbc8f05d14694236..a038a3af83602de5ea6b948f950702799af24c6c 100644 (file)
@@ -45,7 +45,9 @@ from openpower.xer import XERState
 from openpower.util import LogKind, log
 
 LDST_UPDATE_INSNS = ['ldu', 'lwzu', 'lbzu', 'lhzu', 'lhau', 'lfsu', 'lfdu',
-                    ]
+                     'stwu', 'stbu', 'sthu', 'stfsu', 'stfdu', 'stdu', 
+                     ]
+
 
 instruction_info = namedtuple('instruction_info',
                               'func read_regs uninit_regs write_regs ' +
index b498d1d938d09a42fe88bb53998503f1c3e4b796..8e37fce1853d5a928a2692f832929edb65f9d9be 100644 (file)
@@ -809,14 +809,14 @@ class DecoderTestCase(FHDLTestCase):
                 print ("%i %x %x" % (i, sim.gpr(i).value, expected_regs[i]))
                 self.assertEqual(sim.gpr(i), expected_regs[i])
 
-    def tst_sv_load_update_dd_ffirst_incl(self):
+    def test_sv_load_dd_ffirst_incl(self):
         """data-dependent fail-first on LD/ST, inclusive (/vli)
         performs linked-list walking
         """
         lst = SVP64Asm(
             [
                 # load VL bytes but test if they are zero and truncate
-                "sv.ldu/ff=~RC1/vli *16, 0(*17)", # offset zero to next addr
+                "sv.ld/ff=RC1/vli *17, 8(*16)", # offset 8 to next addr
             ]
         )
         lst = list(lst)
@@ -828,23 +828,28 @@ class DecoderTestCase(FHDLTestCase):
         print("SVSTATE", bin(svstate.asint()))
 
         initial_regs = [0] * 32
-        initial_regs[17] = 20  # data starting point
         for i in range(8): # set to garbage
             initial_regs[16+i] = (0xbeef00) + i  # identifying garbage
+        initial_regs[16] = 24  # data starting point
 
-        # some memory with addresses to get from
-        initial_mem = {20: 40,
-                       40: 10,
-                       10: 0}
+        # some memory with addresses to get from.  all locations are offset 8
+        initial_mem = { 24: 0xfeed0001, 32: 48, # data @ 24, ptr @ 32+8 -> 48
+                        48: 0xfeed0002, 56: 16, # data @ 48, ptr @ 48+8 -> 16
+                        16: 0xfeed0003, 24: 80, # data @ 16, ptr @ 16+8 -> 80
+                        80: 0xfeed0004, 88: 0,  # data @ 80, ptr @ 80+8 -> 0
+                      }
 
         # calculate expected regs
         expected_regs = deepcopy(initial_regs)
-        ptr_addr = 20
+        ptr_addr = 24
         i = 0
         while True: # VLI needs break at end
             expected_regs[16+i] = ptr_addr
+            print ("expected regs", 16+i, hex(expected_regs[16+i]))
+            i += 1
             if ptr_addr == 0: break
-            ptr_addr = initial_mem[ptr_addr] # linked-list walk
+            print ("ptr_addr", ptr_addr)
+            ptr_addr = initial_mem[ptr_addr+8] # linked-list walk, offset 8
 
         with Program(lst, bigendian=False) as program:
             sim = self.run_tst_program(program, svstate=svstate,
@@ -852,7 +857,62 @@ class DecoderTestCase(FHDLTestCase):
                                        initial_regs=initial_regs)
             mem = sim.mem.dump(printout=True, asciidump=True)
             print (mem)
-            self.assertEqual(sim.svstate.vl, 3)
+            self.assertEqual(sim.svstate.vl, 4)
+            for i in range(len(expected_regs)):
+                print ("%i %x %x" % (i, sim.gpr(i).value, expected_regs[i]))
+                self.assertEqual(sim.gpr(i), expected_regs[i])
+
+    def test_sv_load_update_dd_ffirst_incl(self):
+        """data-dependent fail-first on LD/ST-with-update, inclusive (/vli)
+        performs linked-list walking, and stores the Effective Address
+        *behind* where it is picked up (on the next element-iteration).
+        """
+        lst = SVP64Asm(
+            [
+                # load VL bytes but test if they are zero and truncate
+                "sv.ldu/ff=RC1/vli *17, 8(*16)", # offset 8 to next addr
+            ]
+        )
+        lst = list(lst)
+
+        # SVSTATE (in this case, VL=8)
+        svstate = SVP64State()
+        svstate.vl = 8  # VL
+        svstate.maxvl = 8  # MAXVL
+        print("SVSTATE", bin(svstate.asint()))
+
+        initial_regs = [0] * 32
+        for i in range(8): # set to garbage
+            initial_regs[16+i] = (0xbeef00) + i  # identifying garbage
+        initial_regs[16] = 24  # data starting point
+
+        # some memory with addresses to get from.  all locations are offset 8
+        initial_mem = { 24: 0xfeed0001, 32: 48, # data @ 24, ptr @ 32+8 -> 48
+                        48: 0xfeed0002, 56: 16, # data @ 48, ptr @ 48+8 -> 16
+                        16: 0xfeed0003, 24: 80, # data @ 16, ptr @ 16+8 -> 80
+                        80: 0xfeed0004, 88: 0,  # data @ 80, ptr @ 80+8 -> 0
+                      }
+
+        # calculate expected regs
+        expected_regs = deepcopy(initial_regs)
+        i = 0
+        while True: # VLI needs break at end
+            ptr_addr = expected_regs[16+i]
+            newptr_addr = initial_mem[ptr_addr+8] # linked-list walk, offset 8
+            expected_regs[17+i] = newptr_addr
+            expected_regs[16+i] = ptr_addr+8
+            print ("expected regs", 16+i, hex(expected_regs[16+i]))
+            i += 1
+            print ("ptr_addr", ptr_addr)
+            if newptr_addr == 0: break # VLI stop at end
+
+        with Program(lst, bigendian=False) as program:
+            sim = self.run_tst_program(program, svstate=svstate,
+                                       initial_mem=initial_mem,
+                                       initial_regs=initial_regs)
+            mem = sim.mem.dump(printout=True, asciidump=True)
+            print (mem)
+            self.assertEqual(sim.svstate.vl, 4)
             for i in range(len(expected_regs)):
                 print ("%i %x %x" % (i, sim.gpr(i).value, expected_regs[i]))
                 self.assertEqual(sim.gpr(i), expected_regs[i])