sort out predicate zeroing in ISACaller
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 20 Mar 2021 11:22:23 +0000 (11:22 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 20 Mar 2021 11:22:23 +0000 (11:22 +0000)
src/soc/consts.py
src/soc/decoder/isa/caller.py
src/soc/decoder/isa/test_caller_svp64_predication.py
src/soc/decoder/power_svp64_rm.py
src/soc/sv/trans/svp64.py

index 2af98d913bc903325fa7e254b717ecab9580743d..9b43a4b0898d4684f0f1eaab46e39cea99bca35e 100644 (file)
@@ -237,6 +237,9 @@ class SVP64MODEb:
     ELS_NORMAL = 2
     ELS_FFIRST_PRED = 3
     ELS_SAT = 4
+    # BO bits
+    BO_MSB = 2
+    BO_LSB = 4
 
 
 SVP64MODE_SIZE = 5
index d4908c3062633f96df13d30809bb271a63ae6433..b52f88c5db016b57ca2aaf070c31e48d58d135e2 100644 (file)
@@ -270,6 +270,7 @@ SV64P_RM_SIZE = len(SVP64PrefixFields().rm.br)
 def get_predint(gpr, mask):
     r10 = gpr(10)
     r30 = gpr(30)
+    print ("get_predint", mask, SVP64PredInt.ALWAYS.value)
     if mask == SVP64PredInt.ALWAYS.value:
         return 0xffff_ffff_ffff_ffff
     if mask == SVP64PredInt.R3_UNARY.value:
@@ -939,6 +940,8 @@ class ISACaller:
                     srcmask = get_predcr(self.crl, srcpred, vl)
             print ("    pmode", pmode)
             print ("    ptype", sv_ptype)
+            print ("    srcpred", bin(srcpred))
+            print ("    dstpred", bin(dstpred))
             print ("    srcmask", bin(srcmask))
             print ("    dstmask", bin(dstmask))
             print ("    pred_sz", bin(pred_src_zero))
@@ -957,6 +960,12 @@ class ISACaller:
                     print ("      skip", bin(1<<dststep))
                     dststep += 1
 
+            # now work out if the relevant mask bits require zeroing
+            if pred_dst_zero:
+                pred_dst_zero = ((1<<dststep) & dstmask) == 0
+            if pred_src_zero:
+                pred_src_zero = ((1<<srcstep) & srcmask) == 0
+
             # update SVSTATE with new srcstep
             self.svstate.srcstep[0:7] = srcstep
             self.svstate.dststep[0:7] = dststep
index 96eadaac4def9d359fbae024f0f0102a2fbb16c1..999ee7029ca56ddc0022c52775eef994e476b198 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 tst_sv_extsw_intpred(self):
+    def test_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
@@ -116,7 +116,7 @@ class DecoderTestCase(FHDLTestCase):
             sim = self.run_tst_program(program, initial_regs, svstate)
             self._check_regs(sim, expected_regs)
 
-    def tst_sv_add_intpred(self):
+    def test_sv_add_intpred(self):
         # adds, integer predicated mask r3=0b10
         #       1 = 5 + 9   => not to be touched (skipped)
         #       2 = 6 + 10  => 0x3334 = 0x2223+0x1111
@@ -147,7 +147,7 @@ class DecoderTestCase(FHDLTestCase):
             sim = self.run_tst_program(program, initial_regs, svstate)
             self._check_regs(sim, expected_regs)
 
-    def tst_sv_add_cr_pred(self):
+    def test_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 da6db621bbc0bd025efd8e8ea3a4d889150c9c9a..ac29159a914a5c121ce7d8100a2b33b468e173f0 100644 (file)
@@ -144,7 +144,7 @@ class SVP64RMModeDecode(Elaboratable):
         # identify predicate mode
         with m.If(self.rm_in.mmode == 1):
             comb += self.predmode.eq(SVP64PredMode.CR) # CR Predicate
-        with m.Elif(self.srcpred == 0):
+        with m.Elif((self.srcpred == 0) & (self.dstpred == 0)):
             comb += self.predmode.eq(SVP64PredMode.ALWAYS) # No predicate
         with m.Else():
             comb += self.predmode.eq(SVP64PredMode.INT) # non-zero src: INT
index 56c1a1fd856a3dc102841df9b9d66c2a84dba33a..18987e866ffb61b27bb721ca5f3e7f27d2c32a22 100644 (file)
@@ -28,6 +28,7 @@ from soc.decoder.isa.caller import (SVP64PrefixFields, SV64P_MAJOR_SIZE,
 from soc.decoder.pseudo.pagereader import ISA
 from soc.decoder.power_svp64 import SVP64RM, get_regtype, decode_extra
 from soc.decoder.selectable_int import SelectableInt
+from soc.consts import SVP64MODE
 
 
 # decode GPR into sv extra
@@ -498,61 +499,63 @@ class SVP64Asm:
 
             # "normal" mode
             if sv_mode is None:
-                mode |= (src_zero << 4) | (dst_zero << 3) # predicate zeroing
+                mode |= src_zero << SVP64MODE.SZ # predicate zeroing
+                mode |= dst_zero << SVP64MODE.DZ # predicate zeroing
                 sv_mode = 0b00
 
             # "mapreduce" modes
             elif sv_mode == 0b00:
-                mode |= (0b1<<2) # sets mapreduce
+                mode |= (0b1<<SVP64MODE.REDUCE) # sets mapreduce
                 assert dst_zero == 0, "dest-zero not allowed in mapreduce mode"
                 if mapreduce_crm:
-                    mode |= (0b1<<4) # sets CRM mode
+                    mode |= (0b1<<SVP64MODE.CRM) # sets CRM mode
                     assert rc_mode, "CRM only allowed when Rc=1"
                 # 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 |= (dst_zero << 3) # predicate src-zeroing
+                    mode |= dst_zero << SVP64MODE.DZ # predicate zeroing
                 elif mapreduce_svm:
-                    mode |= (1 << 3) # SVM mode
+                    mode |= (0b1<<SVP64MODE.SVM) # sets SVM mode
 
             # "failfirst" modes
             elif sv_mode == 0b01:
                 assert src_zero == 0, "dest-zero not allowed in failfirst mode"
                 if failfirst == 'RC1':
-                    mode |= (0b1<<4) # sets RC1 mode
-                    mode |= (dst_zero << 3) # predicate src-zeroing
+                    mode |= (0b1<<SVP64MODE.RC1) # sets RC1 mode
+                    mode |= (dst_zero << SVP64MODE.DZ) # predicate dst-zeroing
                     assert rc_mode==False, "ffirst RC1 only possible when Rc=0"
                 elif failfirst == '~RC1':
-                    mode |= (0b1<<4) # sets RC1 mode...
-                    mode |= (dst_zero << 3) # predicate src-zeroing
-                    mode |= (0b1<<2) # ... with inversion
+                    mode |= (0b1<<SVP64MODE.RC1) # sets RC1 mode
+                    mode |= (dst_zero << SVP64MODE.DZ) # predicate dst-zeroing
+                    mode |= (0b1<<SVP64MODE.INV) # ... with inversion
                     assert rc_mode==False, "ffirst RC1 only possible when Rc=0"
                 else:
                     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
+                    mode |= (failfirst << SVP64MODE.BO_LSB) # set BO
 
             # "saturation" modes
             elif sv_mode == 0b10:
-                mode |= (src_zero << 4) | (dst_zero << 3) # predicate zeroing
-                mode |= (saturation<<2) # sets signed/unsigned saturation
+                mode |= src_zero << SVP64MODE.SZ # predicate zeroing
+                mode |= dst_zero << SVP64MODE.DZ # predicate zeroing
+                mode |= (saturation << SVP64MODE.N) # signed/unsigned saturation
 
             # "predicate-result" modes.  err... code-duplication from ffirst
             elif sv_mode == 0b11:
                 assert src_zero == 0, "dest-zero not allowed in predresult mode"
                 if predresult == 'RC1':
-                    mode |= (0b1<<4) # sets RC1 mode
-                    mode |= (dst_zero << 3) # predicate src-zeroing
+                    mode |= (0b1<<SVP64MODE.RC1) # sets RC1 mode
+                    mode |= (dst_zero << SVP64MODE.DZ) # predicate dst-zeroing
                     assert rc_mode==False, "pr-mode RC1 only possible when Rc=0"
                 elif predresult == '~RC1':
-                    mode |= (0b1<<4) # sets RC1 mode...
-                    mode |= (dst_zero << 3) # predicate src-zeroing
-                    mode |= (0b1<<2) # ... with inversion
+                    mode |= (0b1<<SVP64MODE.RC1) # sets RC1 mode
+                    mode |= (dst_zero << SVP64MODE.DZ) # predicate dst-zeroing
+                    mode |= (0b1<<SVP64MODE.INV) # ... with inversion
                     assert rc_mode==False, "pr-mode RC1 only possible when Rc=0"
                 else:
                     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
+                    mode |= (predresult << SVP64MODE.BO_LSB) # set BO
 
             # whewww.... modes all done :)
             # now put into svp64_rm