use log function for warnings about .mdwn files in pagereader.py
[openpower-isa.git] / src / openpower / decoder / power_svp64_rm.py
index 9af4c1fda24ea993d17822762558499e140e51f5..85492ddbf215f2fc34ed56b84bbfe504bc4d739b 100644 (file)
@@ -20,7 +20,8 @@ from nmigen import Elaboratable, Module, Signal, Const
 from openpower.decoder.power_enums import (SVP64RMMode, Function, SVPtype,
                                     SVP64PredMode, SVP64sat, SVP64LDSTmode,
                                     SVP64BCPredMode, SVP64BCVLSETMode,
-                                    SVP64BCGate, SVP64BCStep,
+                                    SVP64BCGate, SVP64BCCTRMode,
+                                    SVP64width
                                     )
 from openpower.consts import EXTRA3, SVP64MODE
 from openpower.sv.svp64 import SVP64Rec
@@ -47,11 +48,11 @@ https://libre-soc.org/openpower/sv/ldst/
 https://libre-soc.org/openpower/sv/branches/
 
 LD/ST immed:
-00     0       dz els  normal mode (with element-stride)
-00     1       dz rsvd bit-reversed mode
+00     0       zz els  normal mode (with element-stride option)
+00     1       zz els  Pack/unpack (with element-stride option)
 01     inv     CR-bit  Rc=1: ffirst CR sel
 01     inv     els RC1 Rc=0: ffirst z/nonz
-10     N       dz els  sat mode: N=0/1 u/s
+10     N       zz els  sat mode: N=0/1 u/s
 11     inv     CR-bit  Rc=1: pred-result CR sel
 11     inv     els RC1 Rc=0: pred-result z/nonz
 
@@ -62,17 +63,22 @@ LD/ST indexed:
 01     inv     dz RC1  Rc=0: ffirst z/nonz
 10     N       sz dz   sat mode: N=0/1 u/s
 11     inv     CR-bit  Rc=1: pred-result CR sel
-11     inv     dz RC1  Rc=0: pred-result z/nonz
+11     inv     zz RC1  Rc=0: pred-result z/nonz
 
 Arithmetic:
-00     0       sz dz   normal mode
-00     1       dz CRM  reduce mode (mapreduce), SUBVL=1
-00     1       SVM CRM subvector reduce mode, SUBVL>1
-01     inv     CR-bit  Rc=1: ffirst CR sel
-01     inv     dz RC1  Rc=0: ffirst z/nonz
-10     N       sz dz   sat mode: N=0/1 u/s
-11     inv     CR-bit  Rc=1: pred-result CR sel
-11     inv     dz RC1  Rc=0: pred-result z/nonz
+| 0-1 |  2  |  3   4  |  description              |
+| --- | --- |---------|-------------------------- |
+| 00  |   0 |  dz  sz | simple mode                      |
+| 00  |   1 | 0  RG   | scalar reduce mode (mapreduce), SUBVL=1 |
+| 00  |   1 | SVM 0   | subvector reduce mode, SUBVL>1   |
+| 00  |   1 | SVM 1   | Pack/Unpack mode, SUBVL>1   |
+| 01  | inv | CR-bit  | Rc=1: ffirst CR sel              |
+| 01  | inv | VLi RC1 |  Rc=0: ffirst z/nonz |
+| 10  |   N | dz   sz |  sat mode: N=0/1 u/s, SUBVL=1 |
+| 10  |   N | zz   0  |  sat mode: N=0/1 u/s, SUBVL>1 |
+| 10  |   N | zz   1  |  Pack/Unpack sat mode: N=0/1 u/s, SUBVL>1 |
+| 11  | inv | CR-bit  |  Rc=1: pred-result CR sel |
+| 11  | inv | zz  RC1 |  Rc=0: pred-result z/nonz |
 
 Branch Conditional:
 note that additional BC modes are in *other bits*, specifically
@@ -105,7 +111,7 @@ class SVP64RMModeDecode(Elaboratable):
 
         # Branch Conditional Modes
         self.bc_vlset = Signal(SVP64BCVLSETMode) # Branch-Conditional VLSET
-        self.bc_step = Signal(SVP64BCStep)   # Branch-Conditional svstep mode
+        self.bc_ctrtest = Signal(SVP64BCCTRMode) # Branch-Conditional CTR-Test
         self.bc_pred = Signal(SVP64BCPredMode) # BC predicate mode
         self.bc_vsb = Signal()                 # BC VLSET-branch (like BO[1])
         self.bc_gate = Signal(SVP64BCGate)     # BC ALL or ANY gate
@@ -118,6 +124,11 @@ class SVP64RMModeDecode(Elaboratable):
         self.pred_sz = Signal(1) # predicate source zeroing
         self.pred_dz = Signal(1) # predicate dest zeroing
 
+        # Modes n stuff
+        self.ew_src = Signal(SVP64width) # source elwidth
+        self.ew_dst = Signal(SVP64width) # dest elwidth
+        self.pack = Signal() # pack mode
+        self.unpack = Signal() # unpack mode
         self.saturate = Signal(SVP64sat)
         self.RC1 = Signal()
         self.cr_sel = Signal(2)  # bit of CR to test (index 0-3)
@@ -135,20 +146,21 @@ class SVP64RMModeDecode(Elaboratable):
         # decode pieces of mode
         is_ldst = Signal()
         is_bc = Signal()
+        do_pu = Signal() # whether to decode pack/unpack
         comb += is_ldst.eq(self.fn_in == Function.LDST)
         comb += is_bc.eq(self.fn_in == Function.BRANCH)
         mode2 = sel(m, mode, SVP64MODE.MOD2)
 
         with m.If(is_bc):
             # Branch-Conditional is completely different
-            # svstep mode
-            with m.If(mode2[0]):
+            # Counter-Test Mode.
+            with m.If(mode[SVP64MODE.BC_CTRTEST]):
                 with m.If(self.rm_in.ewsrc[0]):
-                    comb += self.bc_step.eq(SVP64BCStep.STEP_RC)
+                    comb += self.bc_ctrtest.eq(SVP64BCCTRMode.TEST_INV)
                 with m.Else():
-                    comb += self.bc_step.eq(SVP64BCStep.STEP)
+                    comb += self.bc_ctrtest.eq(SVP64BCCTRMode.TEST)
             # VLSET mode
-            with m.If(mode2[1]):
+            with m.If(mode[SVP64MODE.BC_VLSET]):
                 with m.If(mode[SVP64MODE.BC_VLI]):
                     comb += self.bc_vlset.eq(SVP64BCVLSETMode.VL_INCL)
                 with m.Else():
@@ -165,8 +177,12 @@ class SVP64RMModeDecode(Elaboratable):
                 with m.Case(0): # needs further decoding (LDST no mapreduce)
                     with m.If(is_ldst):
                         comb += self.mode.eq(SVP64RMMode.NORMAL)
+                        comb += do_pu.eq(mode[SVP64MODE.LDST_PACK]) # Pack mode
                     with m.Elif(mode[SVP64MODE.REDUCE]):
                         comb += self.mode.eq(SVP64RMMode.MAPREDUCE)
+                        # Pack only active if SVM=1 & SUBVL>1 & Mode[4]=1
+                        with m.If(self.rm_in.subvl != Const(0, 2)): # active
+                            comb += do_pu.eq(mode[SVP64MODE.ARITH_PACK])
                     with m.Else():
                         comb += self.mode.eq(SVP64RMMode.NORMAL)
                 with m.Case(1):
@@ -180,7 +196,7 @@ class SVP64RMModeDecode(Elaboratable):
             with m.If((~is_ldst) &                     # not for LD/ST
                         (mode2 == 0) &                 # first 2 bits == 0
                         mode[SVP64MODE.REDUCE] &       # bit 2 == 1
-                       (~mode[SVP64MODE.PARALLEL])):   # not parallel mapreduce
+                       (~mode[SVP64MODE.MOD3])):       # bit 3 == 0
                 comb += self.reverse_gear.eq(mode[SVP64MODE.RG]) # finally whew
 
             # extract zeroing
@@ -221,6 +237,16 @@ class SVP64RMModeDecode(Elaboratable):
                 with m.Default():
                     comb += self.saturate.eq(SVP64sat.NONE)
 
+            # extract pack/unpack, actually just ELWIDTH_SRC, so
+            # do elwidth/elwidth_src at same time
+            with m.If(do_pu):
+                comb += self.pack.eq(self.rm_in.ewsrc[0])
+                comb += self.unpack.eq(self.rm_in.ewsrc[1])
+                comb += self.ew_src.eq(self.rm_in.elwidth) # make same as elwid
+            with m.Else():
+                comb += self.ew_src.eq(self.rm_in.ewsrc)
+            comb += self.ew_dst.eq(self.rm_in.elwidth)
+
             # extract els (element strided mode bit)
             # see https://libre-soc.org/openpower/sv/ldst/
             els = Signal()
@@ -234,11 +260,8 @@ class SVP64RMModeDecode(Elaboratable):
                         with m.If(self.rc_in):
                             comb += els.eq(mode[SVP64MODE.ELS_FFIRST_PRED])
 
-                # Shifted Mode
-                with m.If(mode[SVP64MODE.LDST_SHIFT]):
-                    comb += self.ldstmode.eq(SVP64LDSTmode.SHIFT)
                 # RA is vectorised
-                with m.Elif(self.ldst_ra_vec):
+                with m.If(self.ldst_ra_vec):
                     comb += self.ldstmode.eq(SVP64LDSTmode.INDEXED)
                 # not element-strided, therefore unit...
                 with m.Elif(~els):