attempting to get LD/ST-Update SVP64 EXTRA3 working, getting some
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 14 May 2023 16:34:10 +0000 (17:34 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 14 May 2023 16:34:10 +0000 (17:34 +0100)
interesting behaviour in pysvp64dis
https://bugs.libre-soc.org/show_bug.cgi?id=1084

src/openpower/decoder/isa/test_caller_svp64_ldst.py
src/openpower/decoder/power_insn.py
src/openpower/sv/trans/test_pysvp64dis.py

index 57402f65b2295b1a0d1eb917ff1be276fdb203d8..b498d1d938d09a42fe88bb53998503f1c3e4b796 100644 (file)
@@ -809,6 +809,54 @@ 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):
+        """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
+            ]
+        )
+        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
+        initial_regs[17] = 20  # data starting point
+        for i in range(8): # set to garbage
+            initial_regs[16+i] = (0xbeef00) + i  # identifying garbage
+
+        # some memory with addresses to get from
+        initial_mem = {20: 40,
+                       40: 10,
+                       10: 0}
+
+        # calculate expected regs
+        expected_regs = deepcopy(initial_regs)
+        ptr_addr = 20
+        i = 0
+        while True: # VLI needs break at end
+            expected_regs[16+i] = ptr_addr
+            if ptr_addr == 0: break
+            ptr_addr = initial_mem[ptr_addr] # linked-list walk
+
+        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, 3)
+            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 run_tst_program(self, prog, initial_regs=None,
                         svstate=None, initial_fprs=None,
                         initial_mem=None):
index b9d92508a7654fd563e42c5b0392986b89002902..0a2a13c149ff4c88485123886b290525b91e292d 100644 (file)
@@ -1789,6 +1789,13 @@ class WordInstruction(Instruction):
             yield f"{blob}.long 0x{int(self):08x}"
             return
 
+        # awful temporary hack: workaround for ld-update
+        # https://bugs.libre-soc.org/show_bug.cgi?id=1056#c2
+        # XXX TODO must check that *EXTENDED* RA != extended-RT
+        if record.mode == _SVMode.LDST_IMM and 'u' in record.name:
+            yield f"{blob}.long 0x{int(self):08x}"
+            return
+
         paired = False
         if style is Style.LEGACY:
             paired = False
index 7573ef8af626a3fa6c70d8c0050ec126669fed55..8330d7c8d47e79997b7f4d7fee486bb8fa7d7840 100644 (file)
@@ -467,5 +467,11 @@ class SVSTATETestCase(unittest.TestCase):
                         ]
         self._do_tst(expected)
 
+    def test_34_ldst_update_imm_ffirst(self):
+        expected = [
+                    "sv.ldu/ff=~RC1/vli *16, 0(*17)",
+                        ]
+        self._do_tst(expected)
+
 if __name__ == "__main__":
     unittest.main()