attempting to add src/dest-zeroing to ISACaller
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 20 Mar 2021 00:12:06 +0000 (00:12 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 20 Mar 2021 00:12:06 +0000 (00:12 +0000)
src/soc/decoder/isa/caller.py
src/soc/decoder/isa/test_caller_svp64_predication.py
src/soc/sv/trans/svp64.py

index 4d6b54bf1efdeda0f2f09aad017e80e7dab04d55..d4908c3062633f96df13d30809bb271a63ae6433 100644 (file)
@@ -927,6 +927,8 @@ class ISACaller:
             sv_ptype = yield self.dec2.dec.op.SV_Ptype
             srcpred = yield self.dec2.rm_dec.srcpred
             dstpred = yield self.dec2.rm_dec.dstpred
+            pred_src_zero = yield self.dec2.rm_dec.pred_sz
+            pred_dst_zero = yield self.dec2.rm_dec.pred_dz
             if pmode == SVP64PredMode.INT.value:
                 srcmask = dstmask = get_predint(self.gpr, dstpred)
                 if sv_ptype == SVPtype.P2.value:
@@ -939,17 +941,21 @@ class ISACaller:
             print ("    ptype", sv_ptype)
             print ("    srcmask", bin(srcmask))
             print ("    dstmask", bin(dstmask))
+            print ("    pred_sz", bin(pred_src_zero))
+            print ("    pred_dz", bin(pred_dst_zero))
 
             # okaaay, so here we simply advance srcstep (TODO dststep)
             # until the predicate mask has a "1" bit... or we run out of VL
             # let srcstep==VL be the indicator to move to next instruction
-            while (((1<<srcstep) & srcmask) == 0) and (srcstep != vl):
-                print ("      skip", bin(1<<srcstep))
-                srcstep += 1
+            if not pred_src_zero:
+                while (((1<<srcstep) & srcmask) == 0) and (srcstep != vl):
+                    print ("      skip", bin(1<<srcstep))
+                    srcstep += 1
             # same for dststep
-            while (((1<<dststep) & dstmask) == 0) and (dststep != vl):
-                print ("      skip", bin(1<<dststep))
-                dststep += 1
+            if not pred_dst_zero:
+                while (((1<<dststep) & dstmask) == 0) and (dststep != vl):
+                    print ("      skip", bin(1<<dststep))
+                    dststep += 1
 
             # update SVSTATE with new srcstep
             self.svstate.srcstep[0:7] = srcstep
@@ -990,8 +996,12 @@ class ISACaller:
             # in case getting the register number is needed, _RA, _RB
             regname = "_" + name
             self.namespace[regname] = regnum
-            print('reading reg %s %s' % (name, str(regnum)), is_vec)
-            reg_val = self.gpr(regnum)
+            if not self.is_svp64_mode or not pred_src_zero:
+                print('reading reg %s %s' % (name, str(regnum)), is_vec)
+                reg_val = self.gpr(regnum)
+            else:
+                print('zero input reg %s %s' % (name, str(regnum)), is_vec)
+                reg_val = 0
             inputs.append(reg_val)
 
         # "special" registers
@@ -1034,27 +1044,29 @@ class ISACaller:
         if carry_en:
             yield from self.handle_carry_(inputs, results, already_done)
 
-        # detect if overflow was in return result
-        overflow = None
-        if info.write_regs:
-            for name, output in zip(output_names, results):
-                if name == 'overflow':
-                    overflow = output
-
-        if hasattr(self.dec2.e.do, "oe"):
-            ov_en = yield self.dec2.e.do.oe.oe
-            ov_ok = yield self.dec2.e.do.oe.ok
-        else:
-            ov_en = False
-            ov_ok = False
-        print("internal overflow", overflow, ov_en, ov_ok)
-        if ov_en & ov_ok:
-            yield from self.handle_overflow(inputs, results, overflow)
-
-        if hasattr(self.dec2.e.do, "rc"):
-            rc_en = yield self.dec2.e.do.rc.rc
-        else:
-            rc_en = False
+        if not self.is_svp64_mode: # yeah just no. not in parallel processing
+            # detect if overflow was in return result
+            overflow = None
+            if info.write_regs:
+                for name, output in zip(output_names, results):
+                    if name == 'overflow':
+                        overflow = output
+
+            if hasattr(self.dec2.e.do, "oe"):
+                ov_en = yield self.dec2.e.do.oe.oe
+                ov_ok = yield self.dec2.e.do.oe.ok
+            else:
+                ov_en = False
+                ov_ok = False
+            print("internal overflow", overflow, ov_en, ov_ok)
+            if ov_en & ov_ok:
+                yield from self.handle_overflow(inputs, results, overflow)
+
+        # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
+        rc_en = False
+        if not self.is_svp64_mode or not pred_dst_zero:
+            if hasattr(self.dec2.e.do, "rc"):
+                rc_en = yield self.dec2.e.do.rc.rc
         if rc_en:
             regnum, is_vec = yield from get_pdecode_cr_out(self.dec2, "CR0")
             self.handle_comparison(results, regnum)
@@ -1087,7 +1099,13 @@ class ISACaller:
                         # temporary hack for not having 2nd output
                         regnum = yield getattr(self.decoder, name)
                         is_vec = False
-                    print('writing reg %d %s' % (regnum, str(output)), is_vec)
+                    if self.is_svp64_mode and pred_dst_zero:
+                        print('zeroing reg %d %s' % (regnum, str(output)),
+                                                     is_vec)
+                        output = SelectableInt(0, 256)
+                    else:
+                        print('writing reg %d %s' % (regnum, str(output)),
+                                                     is_vec)
                     if output.bits > 64:
                         output = SelectableInt(output.value, 64)
                     self.gpr[regnum] = output
index d962c0db1a708d88a43225b29aced25e8b47ba0b..96eadaac4def9d359fbae024f0f0102a2fbb16c1 100644 (file)
@@ -42,7 +42,7 @@ class DecoderTestCase(FHDLTestCase):
             self.assertEqual(sim.gpr(9), SelectableInt(0x1234, 64))
             self.assertEqual(sim.gpr(10), SelectableInt(0x1235, 64))
 
-    def test_sv_extsw_intpred(self):
+    def tst_sv_extsw_intpred(self):
         # extsb, integer twin-pred mask: source is ~r3 (0b01), dest r3 (0b10)
         # works as follows, where any zeros indicate "skip element"
         #       - sources are 9 and 10
@@ -88,7 +88,35 @@ class DecoderTestCase(FHDLTestCase):
             sim = self.run_tst_program(program, initial_regs, svstate)
             self._check_regs(sim, expected_regs)
 
-    def test_sv_add_intpred(self):
+    def test_sv_extsw_intpred_dz(self):
+        # extsb, integer twin-pred mask: dest is r3 (0b01), zeroing on dest
+        isa = SVP64Asm(['svextsb/m=r3/dz 5.v, 9.v'
+                       ])
+        lst = list(isa)
+        print ("listing", lst)
+
+        # initial values in GPR regfile
+        initial_regs = [0] * 32
+        initial_regs[3] = 0b01   # predicate mask (dest)
+        initial_regs[5] = 0xfeed # going to be overwritten
+        initial_regs[6] = 0xbeef # going to be overwritten (with zero)
+        initial_regs[9] = 0x91   # dest r3 is 0b01 so this will be used
+        initial_regs[10] = 0x90  # this gets read but the output gets zero'd
+        # 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()))
+        # copy before running
+        expected_regs = deepcopy(initial_regs)
+        expected_regs[5] = 0xffff_ffff_ffff_ff91 # dest r3 is 0b01: store
+        expected_regs[6] = 0                     # 2nd bit of r3 is 1: zero
+
+        with Program(lst, bigendian=False) as program:
+            sim = self.run_tst_program(program, initial_regs, svstate)
+            self._check_regs(sim, expected_regs)
+
+    def tst_sv_add_intpred(self):
         # adds, integer predicated mask r3=0b10
         #       1 = 5 + 9   => not to be touched (skipped)
         #       2 = 6 + 10  => 0x3334 = 0x2223+0x1111
@@ -119,7 +147,7 @@ class DecoderTestCase(FHDLTestCase):
             sim = self.run_tst_program(program, initial_regs, svstate)
             self._check_regs(sim, expected_regs)
 
-    def test_sv_add_cr_pred(self):
+    def tst_sv_add_cr_pred(self):
         # adds, CR predicated mask CR4.eq = 1, CR5.eq = 0, invert (ne)
         #       1 = 5 + 9   => not to be touched (skipped)
         #       2 = 6 + 10  => 0x3334 = 0x2223+0x1111
index 77745001dd44b6d292ff2c1b393009fb8de244f1..56c1a1fd856a3dc102841df9b9d66c2a84dba33a 100644 (file)
@@ -498,7 +498,7 @@ class SVP64Asm:
 
             # "normal" mode
             if sv_mode is None:
-                mode |= (src_zero << 3) | (dst_zero << 4) # predicate zeroing
+                mode |= (src_zero << 4) | (dst_zero << 3) # predicate zeroing
                 sv_mode = 0b00
 
             # "mapreduce" modes
@@ -511,46 +511,46 @@ class SVP64Asm:
                 # bit of weird encoding to jam zero-pred or SVM mode in.
                 # SVM mode can be enabled only when SUBVL=2/3/4 (vec2/3/4)
                 if subvl == 0:
-                    mode |= (src_zero << 3) # predicate src-zeroing
+                    mode |= (dst_zero << 3) # predicate src-zeroing
                 elif mapreduce_svm:
                     mode |= (1 << 3) # SVM mode
 
             # "failfirst" modes
             elif sv_mode == 0b01:
-                assert dst_zero == 0, "dest-zero not allowed in failfirst mode"
+                assert src_zero == 0, "dest-zero not allowed in failfirst mode"
                 if failfirst == 'RC1':
                     mode |= (0b1<<4) # sets RC1 mode
-                    mode |= (src_zero << 3) # predicate src-zeroing
+                    mode |= (dst_zero << 3) # predicate src-zeroing
                     assert rc_mode==False, "ffirst RC1 only possible when Rc=0"
                 elif failfirst == '~RC1':
                     mode |= (0b1<<4) # sets RC1 mode...
-                    mode |= (src_zero << 3) # predicate src-zeroing
+                    mode |= (dst_zero << 3) # predicate src-zeroing
                     mode |= (0b1<<2) # ... with inversion
                     assert rc_mode==False, "ffirst RC1 only possible when Rc=0"
                 else:
-                    assert src_zero == 0, "src-zero not allowed in ffirst BO"
+                    assert dst_zero == 0, "dst-zero not allowed in ffirst BO"
                     assert rc_mode, "ffirst BO only possible when Rc=1"
                     mode |= (failfirst << 2) # set BO
 
             # "saturation" modes
             elif sv_mode == 0b10:
-                mode |= (src_zero << 3) | (dst_zero << 4) # predicate zeroing
+                mode |= (src_zero << 4) | (dst_zero << 3) # predicate zeroing
                 mode |= (saturation<<2) # sets signed/unsigned saturation
 
             # "predicate-result" modes.  err... code-duplication from ffirst
             elif sv_mode == 0b11:
-                assert dst_zero == 0, "dest-zero not allowed in predresult mode"
+                assert src_zero == 0, "dest-zero not allowed in predresult mode"
                 if predresult == 'RC1':
                     mode |= (0b1<<4) # sets RC1 mode
-                    mode |= (src_zero << 3) # predicate src-zeroing
+                    mode |= (dst_zero << 3) # predicate src-zeroing
                     assert rc_mode==False, "pr-mode RC1 only possible when Rc=0"
                 elif predresult == '~RC1':
                     mode |= (0b1<<4) # sets RC1 mode...
-                    mode |= (src_zero << 3) # predicate src-zeroing
+                    mode |= (dst_zero << 3) # predicate src-zeroing
                     mode |= (0b1<<2) # ... with inversion
                     assert rc_mode==False, "pr-mode RC1 only possible when Rc=0"
                 else:
-                    assert src_zero == 0, "src-zero not allowed in pr-mode BO"
+                    assert dst_zero == 0, "dst-zero not allowed in pr-mode BO"
                     assert rc_mode, "pr-mode BO only possible when Rc=1"
                     mode |= (predresult << 2) # set BO