check RC1, add data-dependent fail-first LD/ST test
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 15 Apr 2023 16:32:29 +0000 (17:32 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 2 Jun 2023 18:51:17 +0000 (19:51 +0100)
src/openpower/decoder/isa/caller.py
src/openpower/decoder/isa/test_caller_svp64_ldst.py
src/openpower/decoder/power_decoder2.py

index 8829cb67a7681b6fb6a5bd2dc7eee1275d55e542..a8bb8487806515bbbe426ad7a018c6cdac10639a 100644 (file)
@@ -543,6 +543,15 @@ def get_cr_out(dec2, name):
     if name == 'CR1':  # these are not actually calculated correctly
         if out_sel == CROutSel.CR1.value:
             return out, o_isvec
+    # check RC1 set? if so return implicit vector, this is a REAL bad hack
+    RC1 = yield dec2.rm_dec.RC1
+    if RC1:
+        log("get_cr_out RC1 mode")
+        if name == 'CR0':
+            return 0, True # XXX TODO: offset CR0 from SVSTATE SPR
+        if name == 'CR1':
+            return 1, True # XXX TODO: offset CR1 from SVSTATE SPR
+    # nope - not found.
     log("get_cr_out not found", name)
     return None, False
 
index 647e7935d1aa9a77713c3a7af4838e16b5e4c028..a54ada320bce720a0de9cd566f9e023412df5909 100644 (file)
@@ -700,6 +700,49 @@ class DecoderTestCase(FHDLTestCase):
             for i in range(len(avi)):
                 self.assertEqual(sim.gpr(i+12), av[i])
 
+    def test_sv_load_dd_ffirst_excl(self):
+        """data-dependent fail-first on LD/ST
+        """
+        lst = SVP64Asm(
+            [
+                # load VL bytes but test if they are zero and truncate
+                "sv.lbz/ff=RC1 *16, 1(10)",
+            ]
+        )
+        lst = list(lst)
+
+        # SVSTATE (in this case, VL=8)
+        svstate = SVP64State()
+        svstate.vl = 8  # VL
+        svstate.maxvl = 8  # MAXVL
+        print("SVSTATE", bin(svstate.asint()))
+
+        tst_string = "hel\x00e\x00"
+        initial_regs = [0] * 32
+        initial_regs[3] = len(tst_string)  # including the zero
+        initial_regs[10] = 16  # load address
+        initial_regs[12] = 40  # store address
+        for i in range(8): # set to garbage
+            initial_regs[16+i] = (0xbeef00) + i  # identifying garbage
+
+        # some memory with identifying garbage in it
+        initial_mem = {16: 0xf0f1_f2f3_f4f5_f6f7,
+                       24: 0x4041_4243_4445_4647,
+                       40: 0x8081_8283_8485_8687,
+                       48: 0x9091_9293_9495_9697,
+                       }
+
+        for i, c in enumerate(tst_string):
+            write_byte(initial_mem, 16+i, ord(c))
+
+        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, 1)
+
     def run_tst_program(self, prog, initial_regs=None,
                         svstate=None, initial_fprs=None,
                         initial_mem=None):
index aecda3b6849e04c1e34f48467d265e2e6ec04864..88b2023859061d7601a9dc94e052c75ec59fd8b1 100644 (file)
@@ -1487,7 +1487,7 @@ class PowerDecode2(PowerDecodeSubset):
                 (e.read_cr1, self.dec_cr_in, "cr_bitfield", crin_svdec, 0),
                 (e.read_cr2, self.dec_cr_in, "cr_bitfield_b", crin_svdec_b, 0),
                 (e.read_cr3, self.dec_cr_in, "cr_bitfield_o", crin_svdec_o, 0),
-                    (e.write_cr, self.dec_cr_out, "cr_bitfield", crout_svdec, 1)):
+                (e.write_cr, self.dec_cr_out, "cr_bitfield", crout_svdec, 1)):
                 fromreg = getattr(cr, name)
                 comb += svdec.extra.eq(extra)     # EXTRA field of SVP64 RM
                 comb += svdec.etype.eq(sv_etype)  # EXTRA2/3 for this insn