add mapreduce "reverse gear" unit tests
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 19 Jun 2021 12:52:42 +0000 (13:52 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 19 Jun 2021 12:52:42 +0000 (13:52 +0100)
add svp64 assembly mode "/mrr" - mapreduce reverse
add non-reverse mapreduce unit test as well (pascal triangle)

src/openpower/decoder/isa/caller.py
src/openpower/decoder/isa/test_caller_svp64_mapreduce.py
src/openpower/decoder/power_decoder2.py
src/openpower/decoder/power_svp64_rm.py
src/openpower/sv/trans/svp64.py

index b81aa99b8ae3d988d0bac7a29e4a7fecb5b1f82c..9ab9a67fa7c9313679a8900fc6d653cc017291ad 100644 (file)
@@ -1083,6 +1083,7 @@ class ISACaller:
         srcmask = dstmask = 0xffff_ffff_ffff_ffff
         if self.is_svp64_mode:
             pmode = yield self.dec2.rm_dec.predmode
+            reverse_gear = yield self.dec2.rm_dec.reverse_gear
             sv_ptype = yield self.dec2.dec.op.SV_Ptype
             srcpred = yield self.dec2.rm_dec.srcpred
             dstpred = yield self.dec2.rm_dec.dstpred
@@ -1097,6 +1098,7 @@ class ISACaller:
                 if sv_ptype == SVPtype.P2.value:
                     srcmask = get_predcr(self.crl, srcpred, vl)
             log ("    pmode", pmode)
+            log ("    reverse", reverse_gear)
             log ("    ptype", sv_ptype)
             log ("    srcpred", bin(srcpred))
             log ("    dstpred", bin(dstpred))
@@ -1344,6 +1346,7 @@ class ISACaller:
             srcstep = self.svstate.srcstep.asint(msb0=True)
             dststep = self.svstate.dststep.asint(msb0=True)
             rm_mode = yield self.dec2.rm_dec.mode
+            reverse_gear = yield self.dec2.rm_dec.reverse_gear
             sv_ptype = yield self.dec2.dec.op.SV_Ptype
             out_vec = not (yield self.dec2.no_out_vec)
             in_vec = not (yield self.dec2.no_in_vec)
@@ -1352,6 +1355,7 @@ class ISACaller:
             log ("    svstate.srcstep", srcstep)
             log ("    svstate.dststep", dststep)
             log ("    mode", rm_mode)
+            log ("    reverse", reverse_gear)
             log ("    out_vec", out_vec)
             log ("    in_vec", in_vec)
             log ("    sv_ptype", sv_ptype, sv_ptype == SVPtype.P2.value)
index d592091966ca0eb4ec47bcf2fc56b909bbfc63ce..c5b57877eb941160aeb21fd6491a528e5c6da563 100644 (file)
@@ -57,6 +57,83 @@ class DecoderTestCase(FHDLTestCase):
                                                 svstate=svstate)
             self._check_regs(sim, expected_regs)
 
+    def test_sv_add_prefix_sum(self):
+        """>>> lst = ['sv.add/mr 2.v, 2.v, 1.v'
+                       ]
+            adds performed - not in reverse
+            * 2 = 2 + 1  => 1 + 2  =>  3
+            * 3 = 3 + 2  => 3 + 3  =>  6
+            * 4 = 4 + 3  => 4 + 6  =>  10
+
+            pascal's triangle!
+        """
+        isa = SVP64Asm(['sv.add/mr 2.v, 2.v, 1.v'
+                       ])
+        lst = list(isa)
+        print ("listing", lst)
+
+        # initial values in GPR regfile
+        initial_regs = [0] * 32
+        initial_regs[1] = 0x1
+        initial_regs[2] = 0x2
+        initial_regs[3] = 0x3
+        initial_regs[4] = 0x4
+        # SVSTATE (in this case, VL=2)
+        svstate = SVP64State()
+        svstate.vl[0:7] = 3 # VL
+        svstate.maxvl[0:7] = 3 # MAXVL
+        print ("SVSTATE", bin(svstate.spr.asint()))
+        # copy before running, then compute answers
+        expected_regs = deepcopy(initial_regs)
+        for i in range(3):
+            print ("%d += %d" % (2+i, 1+i))
+            expected_regs[2+i] += expected_regs[1+i]
+        for i in range(5):
+            print ("expected", i, expected_regs[i])
+
+        with Program(lst, bigendian=False) as program:
+            sim = self.run_tst_program(program, initial_regs,
+                                                svstate=svstate)
+            self._check_regs(sim, expected_regs)
+
+    def test_sv_add_prefix_sum_reverse(self):
+        """>>> lst = ['sv.add/mrr 2.v, 2.v, 1.v'
+                       ]
+            adds performed - *in reverse order*
+            * 4 = 4 + 3  => 1 + 2  =>  3
+            * 3 = 3 + 2  => 3 + 2  =>  5
+            * 2 = 2 + 1  => 3 + 4  =>  7
+        """
+        isa = SVP64Asm(['sv.add/mrr 2.v, 2.v, 1.v'
+                       ])
+        lst = list(isa)
+        print ("listing", lst)
+
+        # initial values in GPR regfile
+        initial_regs = [0] * 32
+        initial_regs[1] = 0x4
+        initial_regs[2] = 0x3
+        initial_regs[3] = 0x2
+        initial_regs[4] = 0x1
+        # SVSTATE (in this case, VL=2)
+        svstate = SVP64State()
+        svstate.vl[0:7] = 3 # VL
+        svstate.maxvl[0:7] = 3 # MAXVL
+        print ("SVSTATE", bin(svstate.spr.asint()))
+        # copy before running, then compute answers
+        expected_regs = deepcopy(initial_regs)
+        for i in range(3):
+            j = 2-i
+            print ("%d += %d" % (2+j, 1+j))
+            expected_regs[2+j] += expected_regs[1+j]
+        for i in range(5):
+            print ("expected", i, expected_regs[i])
+
+        with Program(lst, bigendian=False) as program:
+            sim = self.run_tst_program(program, initial_regs,
+                                                svstate=svstate)
+            self._check_regs(sim, expected_regs)
+
     def test_fp_muls_reduce(self):
         """>>> lst = ["sv.fmuls/mr 1, 2.v, 1",
                      ]
index 054de6505992215dfb077a536b355fd8eccde761..2cb25a24b89a0eae26970d30dd37eb4324ab5956 100644 (file)
@@ -1177,9 +1177,9 @@ class PowerDecode2(PowerDecodeSubset):
                     step = dststep if out else srcstep
                     # reverse gear goes the opposite way
                     with m.If(self.rm_dec.reverse_gear):
-                        comb += to_reg.data.eq(step+svdec.reg_out)
-                    with m.Else():
                         comb += to_reg.data.eq(svdec.reg_out+(vl-1-step))
+                    with m.Else():
+                        comb += to_reg.data.eq(step+svdec.reg_out)
                 with m.Else():
                     comb += to_reg.data.eq(svdec.reg_out)
 
index a91487e1a9ad950616002916f9fa619a34480217..6082a8fbfbc792f03f4586392e2feb355d7626ad 100644 (file)
@@ -129,7 +129,7 @@ class SVP64RMModeDecode(Elaboratable):
                     (mode2 == 0) &                 # first 2 bits == 0
                     mode[SVP64MODE.REDUCE] &       # bit 2 == 1
                    (~mode[SVP64MODE.PARALLEL])):   # not parallel mapreduce
-            comb += self.reverse_gear.eq(1)        # theeeen finally, whew
+            comb += self.reverse_gear.eq(mode[SVP64MODE.RG]) # finally, whew
 
         # extract zeroing
         with m.Switch(mode2):
index 7d66b3e56203d037235711eb8c6d530473aaa043..2bfe4c2b05a151e834575575a5b27ebfd327bd1e 100644 (file)
@@ -480,6 +480,7 @@ class SVP64Asm:
         sv_mode = None
 
         mapreduce = False
+        reverse_gear = False
         mapreduce_crm = False
         mapreduce_svm = False
 
@@ -543,6 +544,12 @@ class SVP64Asm:
                 assert sv_mode is None
                 sv_mode = 0b11
                 predresult = decode_ffirst(encmode[3:])
+            # map-reduce mode, reverse-gear
+            elif encmode == 'mrr':
+                assert sv_mode is None
+                sv_mode = 0b00
+                mapreduce = True
+                reverse_gear = True
             # map-reduce mode
             elif encmode == 'mr':
                 assert sv_mode is None
@@ -619,6 +626,8 @@ class SVP64Asm:
         elif sv_mode == 0b00:
             mode |= (0b1<<SVP64MODE.REDUCE) # sets mapreduce
             assert dst_zero == 0, "dest-zero not allowed in mapreduce mode"
+            if reverse_gear:
+                mode |= (0b1<<SVP64MODE.RG) # sets Reverse-gear mode
             if mapreduce_crm:
                 mode |= (0b1<<SVP64MODE.CRM) # sets CRM mode
                 assert rc_mode, "CRM only allowed when Rc=1"
@@ -874,6 +883,7 @@ if __name__ == '__main__':
     macros = {'win2': '50', 'win': '60'}
     lst = [
              'sv.addi win2.v, win.v, -1',
+             'sv.add./mrr 5.v, 2.v, 1.v',
     ]
     isa = SVP64Asm(lst, macros=macros)
     print ("list", list(isa))