add /pi to sv/trans/svp64.py and power_insns.py
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 11 Oct 2022 12:31:58 +0000 (13:31 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 14 Oct 2022 08:53:19 +0000 (09:53 +0100)
src/openpower/decoder/power_insn.py
src/openpower/sv/trans/svp64.py
src/openpower/sv/trans/test_pysvp64dis.py

index c87e7e2a0494bd31ba7b23fb931166b712f48fde..e086a83254446ceae9ab0d731bbc9ba833f10739 100644 (file)
@@ -1615,9 +1615,16 @@ class LDSTImmSimpleRM(ElsBaseRM, ZZBaseRM, LDSTImmBaseRM):
     sz: BaseRM.mode[3]
 
 
-class LDSTImmRsvdRM(LDSTImmBaseRM):
-    """ld/st immediate: rsvd"""
-    pass
+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"
 
 
 class LDSTImmFFRc1RM(FFPRRc1BaseRM, LDSTImmBaseRM):
@@ -1669,7 +1676,7 @@ class LDSTImmPRRc0RM(FFPRRc0BaseRM, ElsBaseRM, LDSTImmBaseRM):
 
 class LDSTImmRM(LDSTImmBaseRM):
     simple: LDSTImmSimpleRM
-    rsvd: LDSTImmRsvdRM
+    post: LDSTImmPostRM
     ffrc1: LDSTImmFFRc1RM
     ffrc0: LDSTImmFFRc0RM
     sat: LDSTImmSatRM
@@ -1935,7 +1942,7 @@ class RM(BaseRM):
             # mode except reserved in place of mr
             table = (
                 (0b000000, 0b111000, "simple"), # simple     (no Rc)
-                (0b001000, 0b111000, "rsvd"),   # rsvd       (no Rc)
+                (0b001000, 0b111000, "post"),   # post       (no Rc)
                 (0b010001, 0b110001, "ffrc1"),  # ffirst,     Rc=1
                 (0b010000, 0b110001, "ffrc0"),  # ffirst,     Rc=0
                 (0b100000, 0b110000, "sat"),    # saturation (no Rc)
index 6c87f6d804504364ff1d3a4394cb1bd30dc31ead..a798085e57b7c2913e819560213c49c34a1493b9 100644 (file)
@@ -1056,6 +1056,7 @@ class SVP64Asm:
         # see https://libre-soc.org/openpower/sv/ldst/
         is_ldst = rm['mode'] in ['LDST_IDX', 'LDST_IMM']
         is_ldst_idx = rm['mode'] == 'LDST_IDX'
+        is_ldst_imm = rm['mode'] == 'LDST_IMM'
         is_ld = v30b_op.startswith("l") and is_ldst
         is_st = v30b_op.startswith("s") and is_ldst
 
@@ -1088,6 +1089,7 @@ class SVP64Asm:
         predresult = False
         failfirst = False
         ldst_elstride = 0
+        ldst_postinc = 0
         sea = False
 
         vli = False
@@ -1127,6 +1129,12 @@ class SVP64Asm:
             # just src width
             elif encmode.startswith("sw="):
                 srcwid = decode_elwidth(encmode[3:])
+            # post-increment
+            elif encmode == 'pi':
+                ldst_postinc = 1
+                # in indexed mode, set sv_mode=0b00
+                assert is_ldst_imm is True
+                sv_mode = 0b00
             # element-strided LD/ST
             elif encmode == 'els':
                 ldst_elstride = 1
@@ -1220,6 +1228,10 @@ class SVP64Asm:
             else:
                 raise AssertionError("unknown encmode %s" % encmode)
 
+        # post-inc only available on ld-with-update
+        if ldst_postinc:
+            assert "u" in opcode, "/pi only available on ld/st-update"
+
         # sanity check if dz/zz used in branch-mode
         if is_bc and dst_zero:
             raise AssertionError("dz/zz not supported in branch, use 'sz'")
@@ -1290,7 +1302,7 @@ class SVP64Asm:
             | 0-1 |  2  |  3   4  |  description               |
             | --- | --- |---------|--------------------------- |
             | 00  | 0   |  zz els | normal mode                |
-            | 00  | 1   |  /  /   | reserved                   |
+            | 00  | 1   | pi  lf  | post-inc, LD-fault-first   |
             | 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       |
@@ -1342,6 +1354,12 @@ class SVP64Asm:
                     pass
                 sv_mode = 0b00
 
+            ######################################
+            # ldst-immediate "post" (and "load-fault-first" modes)
+            elif sv_mode == 0b00 and ldst_postinc == 1: # (or ldst_ld_ffirst)
+                mode |= (0b1 << SVP64MODE.LDI_POST)         # sets bit 2
+                mode |= (ldst_postinc << SVP64MODE.LDI_PI)  # sets post-inc
+
             ######################################
             # "mapreduce" modes
             elif sv_mode == 0b00:
index 808b3b504a4a1192efce066ac4d16256a59b3896..54cbf6386ef14a2d1402c4ba2ff760c881302cb2 100644 (file)
@@ -384,6 +384,12 @@ class SVSTATETestCase(unittest.TestCase):
                         ]
         self._do_tst(expected)
 
+    def test_29_postinc(self):
+        expected = [
+                    "sv.ldu/pi 5,8(2)",
+                        ]
+        self._do_tst(expected)
+
 
 if __name__ == "__main__":
     unittest.main()