import argparse as _argparse
import enum as _enum
-import functools as _functools
import sys as _sys
+import os
from openpower.decoder.power_enums import (
- Function as _Function,
- SVP64BCCTRMode as _SVP64BCCTRMode,
- SVP64BCVLSETMode as _SVP64BCVLSETMode,
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.consts import SVP64MODE as _SVP64MODE
-from openpower.decoder.isa.caller import (
- SVP64PrefixFields as _SVP64PrefixFields,
- SVP64RMFields as _SVP64RMFields,
+from openpower.decoder.power_insn import (
+ Verbosity as _Verbosity,
+ Database as _Database,
+ WordInstruction as _WordInstruction,
+ PrefixedInstruction as _PrefixedInstruction,
+ SVP64Instruction as _SVP64Instruction,
)
return self.name.lower()
-DATABASE = _Database(_find_wiki_dir())
-
-
-class Instruction(_SelectableInt):
- def __init__(self, value, byteorder=ByteOrder.LITTLE, bits=32):
- if isinstance(value, _SelectableInt):
- value = value.value
- elif isinstance(value, bytes):
- value = int.from_bytes(value, byteorder=str(byteorder))
-
- if not isinstance(value, int):
- raise ValueError(value)
- if not isinstance(bits, int) or (bits not in {32, 64}):
- raise ValueError(bits)
-
- return super().__init__(value=value, bits=bits)
-
- def __repr__(self):
- return f"{self.__class__.__name__}({self.value:08x})"
-
- def disassemble(self):
- if self.dbrecord is None:
- yield f".long 0x{self.value:08x}"
- else:
- yield f".long 0x{self.value:08x} # {self.dbrecord.name}"
-
- @property
- def major(self):
- return self[0:6]
-
- @property
- def dbrecord(self):
- try:
- return DATABASE[int(self)]
- except KeyError:
- return None
-
-
-class PrefixedInstruction(Instruction):
- 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 disassemble(self):
- if self.dbrecord is None:
- yield f".llong 0x{self.value:08x}"
- else:
- yield f".llong 0x{self.value:08x} # {self.dbrecord.name}"
-
- @property
- def prefix(self):
- return Instruction(self[0:32])
-
- @property
- def suffix(self):
- return Instruction(self[32:64])
-
- @property
- def major(self):
- return self.suffix.major
-
- @property
- def dbrecord(self):
- return self.suffix.dbrecord
-
-
-class SVP64Instruction(PrefixedInstruction):
- class PrefixError(ValueError):
- pass
-
- class Prefix(_SVP64PrefixFields, Instruction):
- class RM(_SVP64RMFields):
- @property
- def sv_mode(self):
- return (self.mode & 0b11)
-
- @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 disassemble(self):
- if self.dbrecord is None:
- yield f".llong 0x{self.value:08x}"
- else:
- yield f".llong 0x{self.value:08x} # sv.{self.dbrecord.name}"
- rm = self.prefix.rm
- mode = self.prefix.rm.mode
- if self.dbrecord.function is _Function.BRANCH:
- bc_ctrtest = _SVP64BCCTRMode.NONE
- if mode[_SVP64MODE.BC_CTRTEST]:
- if rm.ewsrc[0]:
- bc_ctrtest = _SVP64BCCTRMode.TEST_INV
- else:
- bc_ctrtest = _SVP64BCCTRMode.TEST
- bc_vlset = _SVP64BCVLSETMode.NONE
- if mode[_SVP64MODE.BC_VLSET]:
- if mode[_SVP64MODE.BC_VLI]:
- bc_vlset = _SVP64BCVLSETMode.VL_INCL
- else:
- bc_vlset = _SVP64BCVLSETMode.VL_EXCL
- bc_gate = rm.elwidth[0]
- bc_lru = rm.elwidth[1]
- bc_vsb = rm.ewsrc[1]
-
-
- @property
- def prefix(self):
- return self.__class__.Prefix(super().prefix)
-
- @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)
+def load(ifile, byteorder=ByteOrder.LITTLE, **_):
+ byteorder = str(byteorder)
+ curpos = ifile.tell() # get file position
- 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)
- 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 = 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 from insn.disassemble()
+ 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()