power_insn: support verbosity levels
[openpower-isa.git] / src / openpower / sv / trans / pysvp64dis.py
index 6f8d4cf4a4002a150b168884480f05763077adf0..837041da1ac9edbfeab150a4f3a272911b10aa9e 100644 (file)
@@ -1,16 +1,18 @@
 import argparse as _argparse
 import enum as _enum
-import functools as _functools
 import sys as _sys
+import os
 
-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
+from openpower.decoder.power_enums import (
+    find_wiki_dir as _find_wiki_dir,
+)
+from openpower.decoder.power_insn import (
+    Verbosity as _Verbosity,
+    Database as _Database,
+    WordInstruction as _WordInstruction,
+    PrefixedInstruction as _PrefixedInstruction,
+    SVP64Instruction as _SVP64Instruction,
+)
 
 
 class ByteOrder(_enum.Enum):
@@ -21,88 +23,44 @@ class ByteOrder(_enum.Enum):
         return self.name.lower()
 
 
-class Instruction(_SelectableInt):
-    def __init__(self, value, byteorder=ByteOrder.LITTLE):
-        if isinstance(value, bytes):
-            value = int.from_bytes(value, byteorder=str(byteorder))
-        if not isinstance(value, int) or (value < 0) or (value > ((1 << 32) - 1)):
-            raise ValueError(value)
-        return super().__init__(value=value, bits=32)
-
-    def __repr__(self):
-        return f"{self.__class__.__name__}({self.value:08x})"
-
-    def __str__(self):
-        return f".long 0x{self.value:08x}"
-
-
-class PrefixedInstruction(_SelectableInt):
-    def __init__(self, prefix, suffix, byteorder=ByteOrder.LITTLE):
-        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}"
-
-    @property
-    def prefix(self):
-        return self[0:32]
-
-    @property
-    def suffix(self):
-        return self[32:64]
-
+def load(ifile, byteorder=ByteOrder.LITTLE, **_):
+    byteorder = str(byteorder)
+    curpos = ifile.tell() # get file position
 
-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)
-        length = len(prefix)
-        if length == 0:
-            return None
-        elif length < 4:
-            raise IOError(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)
+    while True:
+        insn = ifile.read(4)
+        length = len(insn)
         if length == 0:
-            return prefix
+            return
         elif length < 4:
-            raise IOError(suffix)
-        if sv_prefix.pid == 0b11:
-            return SVP64Instruction(prefix, suffix, byteorder)
-        else:
-            return PrefixedInstruction(prefix, suffix, byteorder)
-
-    while True:
-        insn = load(ifile)
-        if insn is None:
-            break
+            raise IOError(insn)
+        insn = _WordInstruction.integer(value=insn, byteorder=byteorder)
+        if insn.po == 0x1:
+            suffix = ifile.read(4)
+            length = len(suffix)
+            if length == 0:
+                yield insn
+                return
+            elif length < 4:
+                raise IOError(suffix)
+
+            prefix = insn
+            suffix = _WordInstruction.integer(value=suffix, byteorder=byteorder)
+            insn = _SVP64Instruction.pair(prefix=prefix, suffix=suffix)
+            if insn.prefix.id != 0b11:
+                insn = _PrefixedInstruction.pair(prefix=prefix, suffix=suffix)
         yield insn
 
+    ifile.seek(curpos) # restore position so that generator can be reused
 
-def dump(insns, ofile, **_):
+
+def dump(insns, verbosity, **_):
+    db = _Database(_find_wiki_dir())
     for insn in insns:
-        yield str(insn)
+        yield from insn.disassemble(db=db, verbosity=verbosity)
 
 
+# this is the entry-point for the console-script pysvp64dis
 def main():
     parser = _argparse.ArgumentParser()
     parser.add_argument("ifile", nargs="?",
@@ -111,12 +69,28 @@ def main():
         type=_argparse.FileType("w"), default=_sys.stdout)
     parser.add_argument("-b", "--byteorder",
         type=ByteOrder, default=ByteOrder.LITTLE)
+    parser.add_argument("-s", "--short",
+        dest="verbosity", default=_Verbosity.NORMAL,
+        action="store_const", const=_Verbosity.SHORT)
+    parser.add_argument("-v", "--verbose",
+        dest="verbosity", default=_Verbosity.NORMAL,
+        action="store_const", const=_Verbosity.VERBOSE)
+    parser.add_argument("-l", "--log",
+        action="store_true", default=False)
+
     args = dict(vars(parser.parse_args()))
 
+    # if logging requested do not disable it.
+    if not args['log']:
+        os.environ['SILENCELOG'] = '1'
+
+    # load instructions and dump them
     insns = load(**args)
     for line in dump(insns, **args):
-        print(line)
+        print(line, file=args["ofile"])
 
 
+# still here but use "python3 setup.py develop" then run the
+# command "pysvp64dis" instead of "python3 src/openpower/sv/trans/pysvp64dis.py"
 if __name__ == "__main__":
     main()