From 27f291bc07a2a66cbf8732bcda63db18157991b4 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sun, 14 May 2023 17:34:10 +0100 Subject: [PATCH] attempting to get LD/ST-Update SVP64 EXTRA3 working, getting some interesting behaviour in pysvp64dis https://bugs.libre-soc.org/show_bug.cgi?id=1084 --- .../decoder/isa/test_caller_svp64_ldst.py | 48 +++++++++++++++++++ src/openpower/decoder/power_insn.py | 7 +++ src/openpower/sv/trans/test_pysvp64dis.py | 6 +++ 3 files changed, 61 insertions(+) diff --git a/src/openpower/decoder/isa/test_caller_svp64_ldst.py b/src/openpower/decoder/isa/test_caller_svp64_ldst.py index 57402f65..b498d1d9 100644 --- a/src/openpower/decoder/isa/test_caller_svp64_ldst.py +++ b/src/openpower/decoder/isa/test_caller_svp64_ldst.py @@ -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): diff --git a/src/openpower/decoder/power_insn.py b/src/openpower/decoder/power_insn.py index b9d92508..0a2a13c1 100644 --- a/src/openpower/decoder/power_insn.py +++ b/src/openpower/decoder/power_insn.py @@ -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 diff --git a/src/openpower/sv/trans/test_pysvp64dis.py b/src/openpower/sv/trans/test_pysvp64dis.py index 7573ef8a..8330d7c8 100644 --- a/src/openpower/sv/trans/test_pysvp64dis.py +++ b/src/openpower/sv/trans/test_pysvp64dis.py @@ -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() -- 2.30.2