project standard is to use c standard string specifiers NOT format
[openpower-isa.git] / src / openpower / decoder / power_svp64_rm.py
index 1f548830e28f6c90aa2b3efb5f3b3c4a870f71f1..c14ead3e6811835b4f7f21f02abd9a8011d377de 100644 (file)
@@ -3,7 +3,7 @@
 # Funded by NLnet http://nlnet.nl
 
 # sigh this entire module is a laborious mess. it really should be
-# auto-generated from the power_insn.py database but a technique
+# auto-generated from the insndb/types.py database but a technique
 # for doing so (similar to python HTML/XML-node-walking) is needed
 
 """SVP64 RM (Remap) Record.
@@ -48,60 +48,49 @@ sv_input_record_layout = [
     ]
 
 """RM Mode
-there are four Mode variants, two for LD/ST, one for Branch-Conditional,
+there are five Mode variants, two for LD/ST, one for Branch-Conditional,
 and one for everything else
 https://libre-soc.org/openpower/sv/svp64/
 https://libre-soc.org/openpower/sv/ldst/
 https://libre-soc.org/openpower/sv/branches/
+https://libre-soc.org/openpower/sv/crops/
 
 LD/ST immed:
+
 | 0 | 1 |  2  |  3   4  |  description               |
 |---|---| --- |---------|--------------------------- |
-| 0 | 0 | 0   |  zz els | simple mode                |
-| 0 | 0 | 1   | PI  LF  | post-increment and Fault-First  |
-| 1 | 0 |   N | zz  els |  sat mode: N=0/1 u/s       |
-|VLi| 1 | inv | CR-bit  | Rc=1: ffirst CR sel        |
-|VLi| 1 | inv | els RC1 |  Rc=0: ffirst z/nonz       |
-
-00     0       zz els  normal mode (with element-stride option)
-01     inv     CR-bit  Rc=1: ffirst CR sel
-01     inv     els RC1 Rc=0: ffirst z/nonz
-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
+|els| 0 | PI  |  zz LF | simple mode                |
+|VLi| 1 | inv | CR-bit  | ffirst CR sel             |
 
 LD/ST indexed:
 
 | 0 | 1 |  2  |  3   4  |  description               |
 |---|---| --- |---------|--------------------------- |
-|els| 0 | SEA |  dz  sz | simple mode        |
-|VLi| 1 | inv | CR-bit  | Rc=1: ffirst CR sel        |
-|VLi| 1 | inv | els RC1 |  Rc=0: ffirst z/nonz       |
-
-00     0       sz dz   normal mode
-00     1       rsvd    reserved
-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     zz RC1  Rc=0: pred-result z/nonz
+|els| 0 | PI  |  zz SEA | simple mode        |
+|VLi| 1 | inv | CR-bit  | ffirst CR sel        |
 
 Arithmetic:
-| 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 | /   1   | reserved |
-| 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 | /    1  |  reserved |
-| 11  | inv | CR-bit  |  Rc=1: pred-result CR sel |
-| 11  | inv | zz  RC1 |  Rc=0: pred-result z/nonz |
+
+| 0-1    |  2  |  3   4  |  description                     |
+| ------ | --- |---------|----------------------------------|
+| 0   0  |   0 |  dz  sz | simple mode                      |
+| 0   0  |   1 |  RG  0  | scalar reduce mode (mapreduce)   |
+| 0   0  |   1 |  /   1  | reserved                         |
+| 1   0  |   N | dz   sz |  sat mode: N=0/1 u/s             |
+| VLi 1  | inv | CR-bit  | Rc=1: ffirst CR sel              |
+| VLi 1  | inv | zz RC1  | Rc=0: ffirst z/nonz              |
+
+CROps:
+
+|6 | 7 |19:20|21 | 22:23   |  description     |
+|--|---|-----|---|---------|------------------|
+|/ | / |0  0 |RG | dz  sz  | simple mode                      |
+|/ | / |1  0 |RG | dz  sz  | scalar reduce mode (mapreduce) |
+|zz|SNZ|VLI 1|inv|  CR-bit | Ffirst 3-bit mode      |
+|/ |SNZ|VLI 1|inv|  dz sz  | Ffirst 5-bit mode (implies CR-bit from result) |
 
 Branch Conditional:
+
 note that additional BC modes are in *other bits*, specifically
 the element-width fields: SVP64Rec.ewsrc and SVP64Rec.elwidth
 
@@ -225,20 +214,12 @@ class SVP64RMModeDecode(Elaboratable):
         #####################
         with m.Elif(is_ldst):
             with m.Switch(mode2):
-                with m.Case(0): # needs further decoding (LDST no mapreduce)
-                    with m.If(is_ldstimm & mode[SVP64MODE.LDI_POST]):
-                        comb += self.mode.eq(SVP64RMMode.NORMAL)
-                        comb += self.ldst_postinc.eq(mode[SVP64MODE.LDI_PI])
-                        comb += self.ldst_ffirst.eq(mode[SVP64MODE.LDI_FF])
-                    with m.Elif(is_ldst):
-                        comb += self.mode.eq(SVP64RMMode.NORMAL)
+                with m.Case(0, 2): # needs further decoding (LDST no mapreduce)
+                    comb += self.mode.eq(SVP64RMMode.NORMAL)
+                    comb += self.ldst_postinc.eq(mode[SVP64MODE.LDI_PI])
+                    comb += self.ldst_ffirst.eq(mode[SVP64MODE.LDI_FF])
                 with m.Case(1, 3):
                     comb += self.mode.eq(SVP64RMMode.FFIRST) # ffirst
-                with m.Case(2):
-                    with m.If(is_ldstimm):
-                        comb += self.mode.eq(SVP64RMMode.SATURATE) # saturate
-                    with m.Else():
-                        comb += self.mode.eq(SVP64RMMode.NORMAL) # els-bit
 
             # extract zeroing
             with m.If(is_ldst & ~is_ldstimm): # LDST-Indexed
@@ -250,15 +231,10 @@ class SVP64RMModeDecode(Elaboratable):
 
             with m.Elif(is_ldstimm): # LDST-Immediate
                 with m.Switch(mode2):
-                    with m.Case(0):  # simple mode
-                        with m.If(~mode[2]): # (but not PI/LF)
-                            # [MSB0-numbered] bits 0,1,2 of mode zero, use zz
-                            comb += self.pred_sz.eq(mode[SVP64MODE.ZZ])
-                            comb += self.pred_dz.eq(mode[SVP64MODE.ZZ])
-                    with m.Case(2): # saturated mode
-                            # saturated-mode also uses zz
-                            comb += self.pred_sz.eq(mode[SVP64MODE.ZZ])
-                            comb += self.pred_dz.eq(mode[SVP64MODE.ZZ])
+                    with m.Case(0,2):  # simple mode
+                        # use zz
+                        comb += self.pred_sz.eq(mode[SVP64MODE.ZZ])
+                        comb += self.pred_dz.eq(mode[SVP64MODE.ZZ])
 
             # extract failfirst
             with m.If(self.mode == SVP64RMMode.FFIRST): # fail-first
@@ -292,23 +268,12 @@ class SVP64RMModeDecode(Elaboratable):
             # extract els (element strided mode bit)
             # see https://libre-soc.org/openpower/sv/ldst/
             els = Signal()
-            with m.If(is_ldstimm):    # LD/ST-immediate
-                with m.Switch(mode2):
-                    with m.Case(0):
-                        with m.If(~mode[2]): # (but not PI/LF)
-                            comb += els.eq(mode[SVP64MODE.ELS_NORMAL])
-                    with m.Case(2):
-                        comb += els.eq(mode[SVP64MODE.ELS_SAT])
-                    with m.Case(1, 3):
-                        with m.If(self.rc_in):
-                            comb += els.eq(mode[SVP64MODE.ELS_FFIRST_PRED])
-            with m.Else():           # LD/ST-Indexed
-                with m.Switch(mode2):
-                    with m.Case(0, 2):
-                        comb += els.eq(mode[SVP64MODE.LDIDX_ELS])
-                    with m.Case(1, 3):
-                        with m.If(self.rc_in):
-                            comb += els.eq(mode[SVP64MODE.ELS_FFIRST_PRED])
+            with m.Switch(mode2):
+                with m.Case(0, 2):
+                    comb += els.eq(mode[SVP64MODE.LDST_ELS])
+                with m.Case(1, 3):
+                    with m.If(self.rc_in):
+                        comb += els.eq(mode[SVP64MODE.ELS_FFIRST_PRED])
 
             # RA is vectorised
             with m.If(self.ldst_ra_vec):
@@ -387,38 +352,6 @@ class SVP64RMModeDecode(Elaboratable):
             comb += self.ew_dst.eq(self.rm_in.elwidth)
             comb += self.subvl.eq(self.rm_in.subvl)
 
-            # extract els (element strided mode bit)
-            # see https://libre-soc.org/openpower/sv/ldst/
-            els = Signal()
-            with m.If(is_ldst):
-                with m.If(is_ldstimm):
-                    with m.Switch(mode2):
-                        with m.Case(0):
-                            comb += els.eq(mode[SVP64MODE.ELS_NORMAL])
-                        with m.Case(2):
-                            comb += els.eq(mode[SVP64MODE.ELS_SAT])
-                        with m.Case(1, 3):
-                            with m.If(self.rc_in):
-                                comb += els.eq(mode[SVP64MODE.ELS_FFIRST_PRED])
-                with m.Else():
-                    with m.Switch(mode2):
-                        with m.Case(0, 2):
-                            comb += els.eq(mode[SVP64MODE.LDIDX_ELS])
-                        with m.Case(1, 3):
-                            with m.If(self.rc_in):
-                                comb += els.eq(mode[SVP64MODE.ELS_FFIRST_PRED])
-
-                # RA is vectorised
-                with m.If(self.ldst_ra_vec):
-                    comb += self.ldstmode.eq(SVP64LDSTmode.INDEXED)
-                # not element-strided, therefore unit...
-                with m.Elif(~els):
-                    comb += self.ldstmode.eq(SVP64LDSTmode.UNITSTRIDE)
-                # but if the LD/ST immediate is zero, allow cache-inhibited
-                # loads from same location, therefore don't do element-striding
-                with m.Elif(~self.ldst_imz_in):
-                    comb += self.ldstmode.eq(SVP64LDSTmode.ELSTRIDE)
-
         ######################
         # Common fields (not many, sigh)
         ######################