power_insn: refactor extandable operands assembly
authorDmitry Selyutin <ghostmansd@gmail.com>
Mon, 7 Nov 2022 18:22:05 +0000 (21:22 +0300)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 2 Jun 2023 18:51:16 +0000 (19:51 +0100)
src/openpower/decoder/power_insn.py

index eabdca80eb6db75ccfb75e95461656faf81929dc..117997b1ae11bd64ea18a76169108ebbccce8718 100644 (file)
@@ -1113,6 +1113,43 @@ class ExtendableOperand(DynamicOperand):
 
         return _SVExtra.NONE
 
+    def remap(self, value, vector):
+        raise NotImplementedError
+
+    def assemble(self, value, insn, prefix):
+        vector = False
+
+        if isinstance(value, str):
+            value = value.lower()
+            if value.startswith("%"):
+                value = value[1:]
+            if value.startswith("*"):
+                if not isinstance(insn, SVP64Instruction):
+                    raise ValueError(value)
+                value = value[1:]
+                vector = True
+            if value.startswith(prefix):
+                value = value[len(prefix):]
+            value = int(value, 0)
+
+        if isinstance(insn, SVP64Instruction):
+            (value, extra) = self.remap(value=value, vector=vector)
+
+            extra_idx = self.extra_idx
+            if extra_idx is _SVExtra.NONE:
+                raise ValueError(self.record)
+
+            if self.record.etype is _SVEtype.EXTRA3:
+                insn.prefix.rm.extra3[extra_idx] = extra
+            elif self.record.etype is _SVEtype.EXTRA2:
+                insn.prefix.rm.extra2[extra_idx] = extra
+            else:
+                raise ValueError(self.record.etype)
+
+            return super().assemble(value=value, insn=insn)
+
+        return super().assemble(value=value, insn=insn)
+
     def disassemble(self, insn,
             verbosity=Verbosity.NORMAL, prefix="", indent=""):
         (vector, value, span) = self.spec(insn=insn)
@@ -1136,67 +1173,35 @@ class ExtendableOperand(DynamicOperand):
 
 @_dataclasses.dataclass(eq=True, frozen=True)
 class SimpleRegisterOperand(ExtendableOperand):
-    def assemble_svp64(self, value, insn, vector):
+    def remap(self, value, vector):
         if vector:
-            sv_extra = (value & 0b11)
-            field = (value >> 2)
+            extra = (value & 0b11)
+            value = (value >> 2)
         else:
-            sv_extra = (value >> 5)
-            field = (value & 0b11111)
+            extra = (value >> 5)
+            value = (value & 0b11111)
 
         # now sanity-check. EXTRA3 is ok, EXTRA2 has limits
         # (and shrink to a single bit if ok)
         if self.record.etype is _SVEtype.EXTRA2:
             if vector:
                 # range is r0-r127 in increments of 2 (r0 r2 ... r126)
-                assert (sv_extra & 0b01) == 0, \
+                assert (extra & 0b01) == 0, \
                     ("vector field %s cannot fit into EXTRA2" % value)
-                sv_extra = (0b10 | (sv_extra >> 1))
+                extra = (0b10 | (extra >> 1))
             else:
                 # range is r0-r63 in increments of 1
-                assert (sv_extra >> 1) == 0, \
+                assert (extra >> 1) == 0, \
                     ("scalar GPR %d cannot fit into EXTRA2" % value)
-                sv_extra &= 0b01
+                extra &= 0b01
         elif self.record.etype is _SVEtype.EXTRA3:
             if vector:
                 # EXTRA3 vector bit needs marking
-                sv_extra |= 0b100
-        else:
-            raise ValueError(self.record.etype)
-
-        extra_idx = self.extra_idx
-        if extra_idx is _SVExtra.NONE:
-            raise ValueError(self.record)
-
-        if self.record.etype is _SVEtype.EXTRA3:
-            insn.prefix.rm.extra3[extra_idx] = sv_extra
-        elif self.record.etype is _SVEtype.EXTRA2:
-            insn.prefix.rm.extra2[extra_idx] = sv_extra
+                extra |= 0b100
         else:
             raise ValueError(self.record.etype)
 
-        return super().assemble(value=field, insn=insn)
-
-    def assemble(self, value, insn, prefix):
-        vector = False
-
-        if isinstance(value, str):
-            value = value.lower()
-            if value.startswith("%"):
-                value = value[1:]
-            if value.startswith("*"):
-                if not isinstance(insn, SVP64Instruction):
-                    raise ValueError(value)
-                value = value[1:]
-                vector = True
-            if value.startswith(prefix):
-                value = value[len(prefix):]
-            value = int(value, 0)
-
-        if isinstance(insn, SVP64Instruction):
-            return self.assemble_svp64(value=value, insn=insn, vector=vector)
-
-        return super().assemble(value=value, insn=insn)
+        return (value, extra)
 
 
 @_dataclasses.dataclass(eq=True, frozen=True)