import argparse as _argparse
import enum as _enum
-import functools as _functools
import sys as _sys
+import os
+from io import BytesIO
-from openpower.decoder.power_enums import find_wiki_dir as _find_wiki_dir
-from openpower.decoder.power_insn import Database as _Database
-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):
return self.name.lower()
-DATABASE = _Database(_find_wiki_dir())
-
-
-class Instruction(_SelectableInt):
- def __init__(self, value, byteorder=ByteOrder.LITTLE):
- if isinstance(value, Instruction):
- value = value.value
- elif 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}"
-
- @property
- def major(self):
- return self[0:6]
-
-
-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}"
-
- @cached_property
- def prefix(self):
- return Instruction(self[0:32])
-
- @cached_property
- def suffix(self):
- return Instruction(self[32:64])
-
+def load(ifile, byteorder=ByteOrder.LITTLE, **_):
+ byteorder = str(byteorder)
-class SVP64Instruction(PrefixedInstruction):
- class PrefixError(ValueError):
- pass
+ # copy over to persistent binfile (BytesIO)
+ cpfile = BytesIO()
+ cpfile.write(ifile.read())
+ cpfile.seek(0)
- class Prefix(_SVP64PrefixFields, Instruction):
- class RM(_SVP64RMFields):
- @cached_property
- def sv_mode(self):
- return (self.mode & 0b11)
-
- @cached_property
- def rm(self):
- return self.__class__.RM(super().rm)
-
- class Suffix(Instruction):
- pass
-
- def __init__(self, prefix, suffix, byteorder=ByteOrder.LITTLE):
- if SVP64Instruction.Prefix(prefix).pid != 0b11:
- raise SVP64Instruction.PrefixError(prefix)
- return super().__init__(prefix, suffix, byteorder)
-
- def __str__(self):
- return (super().__str__() + " # sv")
-
- @cached_property
- def prefix(self):
- return self.__class__.Prefix(super().prefix)
-
- @cached_property
- def suffix(self):
- return self.__class__.Suffix(super().suffix)
-
-
-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)
- prefix = Instruction(prefix, byteorder)
- if prefix.major != 0x1:
- return Instruction(prefix, byteorder)
-
- suffix = ifile.read(4)
- length = len(suffix)
+ while True:
+ insn = cpfile.read(4)
+ length = len(insn)
if length == 0:
- return prefix
+ return
elif length < 4:
- raise IOError(suffix)
- try:
- return SVP64Instruction(prefix, suffix, byteorder)
- except SVP64Instruction.PrefixError:
- 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 = cpfile.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
+ cpfile.seek(0) # 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="?",
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()))
- ifile = args["ifile"]
- ofile = args["ofile"]
- byteorder = args["byteorder"]
- insns = load(ifile, byteorder)
- for line in dump(insns, byteorder):
- print(line, file=ofile)
+ # 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, 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()