pysvp64dis: refactor classes; use fields helpers
authorDmitry Selyutin <ghostmansd@gmail.com>
Tue, 16 Aug 2022 14:55:56 +0000 (17:55 +0300)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 29 Aug 2022 19:38:10 +0000 (20:38 +0100)
src/openpower/sv/trans/pysvp64dis.py

index 44adf3329bf7d58ecf13389c0f666ef93af675ba..6f8d4cf4a4002a150b168884480f05763077adf0 100644 (file)
@@ -4,6 +4,13 @@ import functools as _functools
 import sys as _sys
 
 from openpower.decoder.selectable_int import SelectableInt as _SelectableInt
+from openpower.decoder.isa.caller import SVP64PrefixFields as _SVP64PrefixFields
+from openpower.decoder.isa.caller import SVP64RMFields as _SVP64RMFields
+
+try:
+    from functools import cached_property
+except ImportError:
+    from cached_property import cached_property
 
 
 class ByteOrder(_enum.Enum):
@@ -15,31 +22,30 @@ class ByteOrder(_enum.Enum):
 
 
 class Instruction(_SelectableInt):
-    def __init__(self, value, bits=32, byteorder=ByteOrder.LITTLE):
+    def __init__(self, value, byteorder=ByteOrder.LITTLE):
         if isinstance(value, bytes):
             value = int.from_bytes(value, byteorder=str(byteorder))
-        if not isinstance(value, (int, _SelectableInt)) or (value < 0):
+        if not isinstance(value, int) or (value < 0) or (value > ((1 << 32) - 1)):
             raise ValueError(value)
-        return super().__init__(value=value, bits=bits)
+        return super().__init__(value=value, bits=32)
 
     def __repr__(self):
-        return f"{self.__class__.__name__}({str(self)})"
+        return f"{self.__class__.__name__}({self.value:08x})"
 
     def __str__(self):
         return f".long 0x{self.value:08x}"
 
-    @property
-    def major(self):
-        return self[0:6]
-
 
-class PrefixedInstruction(Instruction):
+class PrefixedInstruction(_SelectableInt):
     def __init__(self, prefix, suffix, byteorder=ByteOrder.LITTLE):
-        insn = _functools.partial(Instruction, bits=64)
+        insn = _functools.partial(Instruction, byteorder=byteorder)
         (prefix, suffix) = map(insn, (prefix, suffix))
         value = ((prefix.value << 32) | suffix.value)
         return super().__init__(value=value, bits=64)
 
+    def __repr__(self):
+        return f"{self.__class__.__name__}({self.value:016x})"
+
     def __str__(self):
         return f".llong 0x{self.value:016x}"
 
@@ -52,6 +58,16 @@ class PrefixedInstruction(Instruction):
         return self[32:64]
 
 
+class SVP64Instruction(PrefixedInstruction):
+    @cached_property
+    def prefix(self):
+        return _SVP64PrefixFields(super().prefix)
+
+    @cached_property
+    def rm(self):
+        return _SVP64RMFields(self.prefix.rm)
+
+
 def load(ifile, byteorder, **_):
     def load(ifile):
         prefix = ifile.read(4)
@@ -60,9 +76,9 @@ def load(ifile, byteorder, **_):
             return None
         elif length < 4:
             raise IOError(prefix)
-        prefix = Instruction(prefix, byteorder=byteorder)
-        if prefix.major != 0x1:
-            return prefix
+        sv_prefix = _SVP64PrefixFields(int.from_bytes(prefix, byteorder=str(byteorder)))
+        if sv_prefix.major != 0x1:
+            return Instruction(prefix, byteorder)
 
         suffix = ifile.read(4)
         length = len(suffix)
@@ -70,8 +86,10 @@ def load(ifile, byteorder, **_):
             return prefix
         elif length < 4:
             raise IOError(suffix)
-
-        return PrefixedInstruction(prefix, suffix, byteorder=byteorder)
+        if sv_prefix.pid == 0b11:
+            return SVP64Instruction(prefix, suffix, byteorder)
+        else:
+            return PrefixedInstruction(prefix, suffix, byteorder)
 
     while True:
         insn = load(ifile)