big set of updates to LD/ST in line with new spec changes
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 21 May 2023 14:23:19 +0000 (15:23 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 2 Jun 2023 18:51:18 +0000 (19:51 +0100)
https://bugs.libre-soc.org/show_bug.cgi?id=1083
LD/ST-imm and LD/ST-idx are now pretty similar

src/openpower/consts.py
src/openpower/decoder/power_insn.py
src/openpower/decoder/power_svp64_rm.py

index 9774eda3958bd15831585b20f33e2b6a91872358..dd09c8b866f0a9fc3b5957b95a2f484eaebbdfa5 100644 (file)
@@ -268,12 +268,10 @@ class SVP64MODEb(_Const):
     # LD immediate els (element-stride) locations, depending on mode
     ELS_NORMAL = 4
     ELS_FFIRST_PRED = 3
-    ELS_SAT = 4
-    LDI_POST = 2 # LD-Immediate Post/FF Mode
-    LDI_PI = 3 # LD-Immediate Post-Increment
+    LDI_PI = 2 # LD-Immediate Post-Increment
     LDI_FF = 4 # LD-Immediate Fault-First
-    # LDST Indexed
-    LDIDX_ELS = 0 # Indexed element-strided
+    # LDST element-strided
+    LDST_ELS = 0 # Indexed element-strided
     # LDST VLI for ffirst is in bit 0
     LDST_VLI = 0
     # BO bits
index c6ea0ca5d9398ea4079c7b00aafc5f3012827468..54a4ead03664d10a539639fd88d68094c24c687d 100644 (file)
@@ -2214,23 +2214,21 @@ class LDSTImmBaseRM(PredicateWidthBaseRM):
 
 class LDSTImmSimpleRM(ElsBaseRM, ZZBaseRM, LDSTImmBaseRM):
     """ld/st immediate: simple mode"""
+    pi: BaseRM.mode[2]  # Post-Increment Mode
+    lf: BaseRM.mode[4]  # Fault-First Mode (not *Data-Dependent* Fail-First)
     zz: BaseRM.mode[3]
-    els: BaseRM.mode[4]
+    els: BaseRM.mode[0]
     dz: BaseRM.mode[3]
     sz: BaseRM.mode[3]
 
-
-class LDSTImmPostRM(LDSTImmBaseRM):
-    """ld/st immediate: postinc mode (and load-fault)"""
-    pi: BaseRM.mode[3]  # Post-Increment Mode
-    lf: BaseRM.mode[4]  # Fault-First Mode (not *Data-Dependent* Fail-First)
-
     def specifiers(self, record):
         if self.pi:
             yield "pi"
         if self.lf:
             yield "lf"
 
+        yield from super().specifiers(record=record)
+
 
 class LDSTFFRc1RM(FFRc1BaseRM, VLiBaseRM, LDSTImmBaseRM):
     """ld/st immediate&indexed: Rc=1: ffirst CR sel"""
@@ -2242,32 +2240,20 @@ class LDSTFFRc1RM(FFRc1BaseRM, VLiBaseRM, LDSTImmBaseRM):
         yield from super().specifiers(record=record, mode="ff")
 
 
-class LDSTFFRc0RM(FFRc0BaseRM, VLiBaseRM, ElsBaseRM, LDSTImmBaseRM):
+class LDSTFFRc0RM(FFRc0BaseRM, VLiBaseRM, LDSTImmBaseRM):
     """ld/st immediate&indexed: Rc=0: ffirst z/nonz"""
     VLi: BaseRM.mode[0]
     inv: BaseRM.mode[2]
-    els: BaseRM.mode[3]
     RC1: BaseRM.mode[4]
 
     def specifiers(self, record):
         yield from super().specifiers(record=record, mode="ff")
 
 
-class LDSTImmSatRM(ElsBaseRM, SatBaseRM, ZZBaseRM, LDSTImmBaseRM):
-    """ld/st immediate: sat mode: N=0/1 u/s"""
-    N: BaseRM.mode[2]
-    zz: BaseRM.mode[3]
-    els: BaseRM.mode[4]
-    dz: BaseRM.mode[3]
-    sz: BaseRM.mode[3]
-
-
 class LDSTImmRM(LDSTImmBaseRM):
     simple: LDSTImmSimpleRM
-    post: LDSTImmPostRM
     ffrc1: LDSTFFRc1RM
     ffrc0: LDSTFFRc0RM
-    sat: LDSTImmSatRM
 
 
 class LDSTIdxBaseRM(PredicateWidthBaseRM):
@@ -2292,16 +2278,8 @@ class LDSTIdxSimpleRM(SEABaseRM, ZZCombinedBaseRM, LDSTIdxBaseRM):
         yield from super().specifiers(record=record)
 
 
-class LDSTIdxSatRM(SatBaseRM, ZZCombinedBaseRM, LDSTIdxBaseRM):
-    """ld/st index: sat mode: N=0/1 u/s"""
-    N: BaseRM.mode[2]
-    dz: BaseRM.mode[3]
-    sz: BaseRM.mode[4]
-
-
 class LDSTIdxRM(LDSTIdxBaseRM):
     simple: LDSTIdxSimpleRM
-    sat: LDSTIdxSatRM
     ffrc1: LDSTFFRc1RM
     ffrc0: LDSTFFRc0RM
 
@@ -3100,7 +3078,6 @@ class SpecifierPI(Specifier):
 
     def assemble(self, insn):
         selector = insn.select(record=self.record)
-        selector.mode[0] = 0b0
         selector.mode[1] = 0b0
         selector.mode[2] = 0b1
         selector.pi = 0b1
@@ -3120,7 +3097,7 @@ class SpecifierLF(Specifier):
 
     def assemble(self, insn):
         selector = insn.select(record=self.record)
-        selector.mode[2] = 1
+        selector.mode[1] = 0
         selector.lf = 0b1
 
 
@@ -3295,11 +3272,9 @@ class RMSelector:
             # ironically/coincidentally this table is identical to NORMAL
             # mode except reserved in place of mr
             table = (
-                (0b000000, 0b111000, "simple"), # simple     (no Rc involved)
-                (0b001000, 0b111000, "post"),   # post       (no Rc involved)
+                (0b000000, 0b010000, "simple"), # simple     (no Rc involved)
                 (0b010001, 0b010001, "ffrc1"),  # ffirst,     Rc=1
                 (0b010000, 0b010001, "ffrc0"),  # ffirst,     Rc=0
-                (0b100000, 0b110000, "sat"),    # saturation (no Rc)
             )
             search = ((int(self.insn.prefix.rm.ldst_imm.mode) << 1) |
                       self.record.Rc)
index fa02b652954d266a2f25da78069974a298a938a4..f92a4edd7c0c412a4604edbce2f214e27f4933d9 100644 (file)
@@ -216,20 +216,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
@@ -241,15 +233,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
@@ -283,23 +270,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):
@@ -378,38 +354,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)
         ######################