1 import argparse
as _argparse
3 import functools
as _functools
6 from openpower
.decoder
.power_enums
import find_wiki_dir
as _find_wiki_dir
7 from openpower
.decoder
.power_insn
import Database
as _Database
8 from openpower
.decoder
.selectable_int
import SelectableInt
as _SelectableInt
9 from openpower
.decoder
.isa
.caller
import (
10 SVP64PrefixFields
as _SVP64PrefixFields
,
11 SVP64RMFields
as _SVP64RMFields
,
15 class ByteOrder(_enum
.Enum
):
20 return self
.name
.lower()
23 DATABASE
= _Database(_find_wiki_dir())
26 class Instruction(_SelectableInt
):
27 def __init__(self
, value
, byteorder
=ByteOrder
.LITTLE
, bits
=32):
28 if isinstance(value
, _SelectableInt
):
30 elif isinstance(value
, bytes
):
31 value
= int.from_bytes(value
, byteorder
=str(byteorder
))
33 if not isinstance(value
, int):
34 raise ValueError(value
)
35 if not isinstance(bits
, int) or (bits
not in {32, 64}):
36 raise ValueError(bits
)
38 return super().__init
__(value
=value
, bits
=bits
)
41 return f
"{self.__class__.__name__}({self.value:08x})"
43 def disassemble(self
):
44 if self
.dbrecord
is None:
45 yield f
".long 0x{self.value:08x}"
47 yield f
".long 0x{self.value:08x} # {self.dbrecord.name}"
56 return DATABASE
[int(self
)]
61 class PrefixedInstruction(Instruction
):
62 def __init__(self
, prefix
, suffix
, byteorder
=ByteOrder
.LITTLE
):
63 insn
= _functools
.partial(Instruction
, byteorder
=byteorder
)
64 (prefix
, suffix
) = map(insn
, (prefix
, suffix
))
65 value
= ((prefix
.value
<< 32) | suffix
.value
)
66 return super().__init
__(value
=value
, bits
=64)
69 return f
"{self.__class__.__name__}({self.value:016x})"
71 def disassemble(self
):
72 if self
.dbrecord
is None:
73 yield f
".llong 0x{self.value:08x}"
75 yield f
".llong 0x{self.value:08x} # {self.dbrecord.name}"
79 return Instruction(self
[0:32])
83 return Instruction(self
[32:64])
87 return self
.suffix
.major
91 return self
.suffix
.dbrecord
94 class SVP64Instruction(PrefixedInstruction
):
95 class PrefixError(ValueError):
98 class Prefix(_SVP64PrefixFields
, Instruction
):
99 class RM(_SVP64RMFields
):
102 return (self
.mode
& 0b11)
106 return self
.__class
__.RM(super().rm
)
108 class Suffix(Instruction
):
111 def __init__(self
, prefix
, suffix
, byteorder
=ByteOrder
.LITTLE
):
112 if SVP64Instruction
.Prefix(prefix
).pid
!= 0b11:
113 raise SVP64Instruction
.PrefixError(prefix
)
114 return super().__init
__(prefix
, suffix
, byteorder
)
116 def disassemble(self
):
117 if self
.dbrecord
is None:
118 yield f
".llong 0x{self.value:08x}"
120 yield f
".llong 0x{self.value:08x} # sv.{self.dbrecord.name}"
124 return self
.__class
__.Prefix(super().prefix
)
128 return self
.__class
__.Suffix(super().suffix
)
131 def load(ifile
, byteorder
, **_
):
133 prefix
= ifile
.read(4)
138 raise IOError(prefix
)
139 prefix
= Instruction(prefix
, byteorder
)
140 if prefix
.major
!= 0x1:
141 return Instruction(prefix
, byteorder
)
143 suffix
= ifile
.read(4)
148 raise IOError(suffix
)
150 return SVP64Instruction(prefix
, suffix
, byteorder
)
151 except SVP64Instruction
.PrefixError
:
152 return PrefixedInstruction(prefix
, suffix
, byteorder
)
161 def dump(insns
, ofile
, **_
):
163 yield from insn
.disassemble()
167 parser
= _argparse
.ArgumentParser()
168 parser
.add_argument("ifile", nargs
="?",
169 type=_argparse
.FileType("rb"), default
=_sys
.stdin
.buffer)
170 parser
.add_argument("ofile", nargs
="?",
171 type=_argparse
.FileType("w"), default
=_sys
.stdout
)
172 parser
.add_argument("-b", "--byteorder",
173 type=ByteOrder
, default
=ByteOrder
.LITTLE
)
175 args
= dict(vars(parser
.parse_args()))
176 ifile
= args
["ifile"]
177 ofile
= args
["ofile"]
178 byteorder
= args
["byteorder"]
180 insns
= load(ifile
, byteorder
)
181 for line
in dump(insns
, byteorder
):
182 print(line
, file=ofile
)
185 if __name__
== "__main__":