power_insn: fix Rc operand accessor
[openpower-isa.git] / src / openpower / decoder / power_insn.py
index 418d7c27232c220bfe1ed8eac99508300968f48c..1f216388bb574a20ed5e1828ca9d1c0b61bc1b04 100644 (file)
@@ -1399,6 +1399,13 @@ class NormalFailFirstRc0RM(NormalBaseRM):
     VLi: BaseRM.mode[3]
     RC1: BaseRM.mode[4]
 
+    def specifiers(self, record):
+        if self.RC1:
+            inv = "~" if self.inv else ""
+            yield f"ff={inv}RC1"
+
+        yield from super().specifiers(record=record)
+
 
 class NormalSaturationRM(NormalBaseRM):
     """normal: sat mode: N=0/1 u/s, SUBVL=1"""
@@ -1436,6 +1443,9 @@ class NormalPredResultRc0RM(NormalBaseRM):
     def specifiers(self, record):
         if self.zz:
             yield f"zz"
+        if self.RC1:
+            inv = "~" if self.inv else ""
+            yield f"pr={inv}RC1"
 
         yield from super().specifiers(record=record)
 
@@ -1486,6 +1496,12 @@ class LDSTImmFailFirstRc0RM(LDSTImmBaseRM):
     els: BaseRM.mode[3]
     RC1: BaseRM.mode[4]
 
+    def specifiers(self, record):
+        if self.RC1:
+            inv = "~" if self.inv else ""
+            yield f"ff={inv}RC1"
+
+        yield from super().specifiers(record=record)
 
 class LDSTImmSaturationRM(LDSTImmBaseRM):
     """ld/st immediate: sat mode: N=0/1 u/s"""
@@ -1518,6 +1534,12 @@ class LDSTImmPredResultRc0RM(LDSTImmBaseRM):
     els: BaseRM.mode[3]
     RC1: BaseRM.mode[4]
 
+    def specifiers(self, record):
+        if self.RC1:
+            inv = "~" if self.inv else ""
+            yield f"pr={inv}RC1"
+
+        yield from super().specifiers(record=record)
 
 class LDSTImmRM(LDSTImmBaseRM):
     simple: LDSTImmSimpleRM
@@ -1599,6 +1621,9 @@ class LDSTIdxPredResultRc0RM(LDSTIdxBaseRM):
     def specifiers(self, record):
         if self.zz:
             yield f"zz"
+        if self.RC1:
+            inv = "~" if self.inv else ""
+            yield f"pr={inv}RC1"
 
         yield from super().specifiers(record=record)
 
@@ -1751,6 +1776,12 @@ class RM(BaseRM):
     def select(self, record, Rc):
         rm = self
 
+        # the idea behind these tables is that they are now literally
+        # in identical format to insndb.csv and minor_xx.csv and can
+        # be done precisely as that.  the only thing to watch out for
+        # is the insertion of Rc=1 as a "mask/value" bit and likewise
+        # regtype detection (3-bit BF/BFA, 5-bit BA/BB/BT) also inserted
+        # as the LSB.
         table = None
         if record.svp64.mode is _SVMode.NORMAL:
             # concatenate mode 5-bit with Rc (LSB) then do a mask/map search
@@ -1798,7 +1829,7 @@ class RM(BaseRM):
             search = ((int(rm.mode) << 1) | Rc)
 
         elif record.svp64.mode is _SVMode.CROP:
-            # concatenate mode 5-bit with Rc (LSB) then do a mask/map search
+            # concatenate mode 5-bit with regtype (LSB) then do mask/map search
             #    mode  3b  mask  3b  member
             table = (
                 (0b000000, 0b111000, "simple"), # simple
@@ -1824,6 +1855,17 @@ class RM(BaseRM):
             rm = rm.cr_op
             search = ((int(rm.mode) << 1) | (regtype or 0))
 
+        elif record.svp64.mode is _SVMode.BRANCH:
+            # just mode 5-bit. could be reduced down to 2, oh well.
+            #         mode       mask   action(getattr)
+            table = [(0b00000, 0b11000, "simple"), # simple
+                     (0b01000, 0b11000, "vls"),    # VLset
+                     (0b10000, 0b11000, "ctr"),    # CTR mode
+                     (0b11000, 0b11000, "ctrvls"), # CTR+VLset mode
+                    ]
+            # slightly weird: doesn't have a 5-bit "mode" field like others
+            search = int(rm[19:23])
+
         # look up in table
         if table is not None:
             for (value, mask, member) in table:
@@ -1831,18 +1873,6 @@ class RM(BaseRM):
                     rm = getattr(rm, member)
                     break
 
-        elif record.svp64.mode is _SVMode.BRANCH:
-            if rm[19] == 0b0:
-                if rm[20] == 0b0:
-                    rm = rm.simple
-                else:
-                    rm = rm.vls
-            else:
-                if rm[20] == 0b0:
-                    rm = rm.ctr
-                else:
-                    rm = rm.ctrvls
-
         if rm.__class__ is self.__class__:
             raise ValueError(self)
 
@@ -1894,7 +1924,7 @@ class SVP64Instruction(PrefixedInstruction):
 
         Rc = False
         if record.mdwn.operands["Rc"] is not None:
-            Rc = bool(self.suffix[record.fields["Rc"]])
+            Rc = bool(record.mdwn.operands["Rc"].value)
         rm = self.prefix.rm.select(record=record, Rc=Rc)
 
         specifiers = tuple(rm.specifiers(record=record))