1 import argparse
as _argparse
3 import functools
as _functools
6 from openpower
.decoder
.power_enums
import (
8 SVP64BCCTRMode
as _SVP64BCCTRMode
,
9 SVP64BCVLSETMode
as _SVP64BCVLSETMode
,
10 find_wiki_dir
as _find_wiki_dir
,
12 from openpower
.decoder
.power_insn
import Database
as _Database
13 from openpower
.decoder
.selectable_int
import (
14 SelectableInt
as _SelectableInt
,
16 from openpower
.consts
import SVP64MODE
as _SVP64MODE
17 from openpower
.decoder
.isa
.caller
import (
18 SVP64PrefixFields
as _SVP64PrefixFields
,
19 SVP64RMFields
as _SVP64RMFields
,
23 class ByteOrder(_enum
.Enum
):
28 return self
.name
.lower()
31 DATABASE
= _Database(_find_wiki_dir())
34 class Instruction(_SelectableInt
):
35 def __init__(self
, value
, byteorder
=ByteOrder
.LITTLE
, bits
=32):
36 if isinstance(value
, _SelectableInt
):
38 elif isinstance(value
, bytes
):
39 value
= int.from_bytes(value
, byteorder
=str(byteorder
))
41 if not isinstance(value
, int):
42 raise ValueError(value
)
43 if not isinstance(bits
, int) or (bits
not in {32, 64}):
44 raise ValueError(bits
)
46 return super().__init
__(value
=value
, bits
=bits
)
49 return f
"{self.__class__.__name__}({self.value:08x})"
51 def disassemble(self
):
52 if self
.dbrecord
is None:
53 yield f
".long 0x{self.value:08x}"
55 yield f
".long 0x{self.value:08x} # {self.dbrecord.name}"
64 return DATABASE
[int(self
)]
69 class PrefixedInstruction(Instruction
):
70 def __init__(self
, prefix
, suffix
, byteorder
=ByteOrder
.LITTLE
):
71 insn
= _functools
.partial(Instruction
, byteorder
=byteorder
)
72 (prefix
, suffix
) = map(insn
, (prefix
, suffix
))
73 value
= ((prefix
.value
<< 32) | suffix
.value
)
74 return super().__init
__(value
=value
, bits
=64)
77 return f
"{self.__class__.__name__}({self.value:016x})"
79 def disassemble(self
):
80 if self
.dbrecord
is None:
81 yield f
".llong 0x{self.value:08x}"
83 yield f
".llong 0x{self.value:08x} # {self.dbrecord.name}"
87 return Instruction(self
[0:32])
91 return Instruction(self
[32:64])
95 return self
.suffix
.major
99 return self
.suffix
.dbrecord
102 class SVP64Instruction(PrefixedInstruction
):
103 class PrefixError(ValueError):
106 class Prefix(_SVP64PrefixFields
, Instruction
):
107 class RM(_SVP64RMFields
):
110 return (self
.mode
& 0b11)
114 return self
.__class
__.RM(super().rm
)
116 class Suffix(Instruction
):
119 def __init__(self
, prefix
, suffix
, byteorder
=ByteOrder
.LITTLE
):
120 if SVP64Instruction
.Prefix(prefix
).pid
!= 0b11:
121 raise SVP64Instruction
.PrefixError(prefix
)
122 return super().__init
__(prefix
, suffix
, byteorder
)
124 def disassemble(self
):
125 if self
.dbrecord
is None:
126 yield f
".llong 0x{self.value:08x}"
128 yield f
".llong 0x{self.value:08x} # sv.{self.dbrecord.name}"
130 mode
= self
.prefix
.rm
.mode
131 if self
.dbrecord
.function
is _Function
.BRANCH
:
132 bc_ctrtest
= _SVP64BCCTRMode
.NONE
133 if mode
[_SVP64MODE
.BC_CTRTEST
]:
135 bc_ctrtest
= _SVP64BCCTRMode
.TEST_INV
137 bc_ctrtest
= _SVP64BCCTRMode
.TEST
138 bc_vlset
= _SVP64BCVLSETMode
.NONE
139 if mode
[_SVP64MODE
.BC_VLSET
]:
140 if mode
[_SVP64MODE
.BC_VLI
]:
141 bc_vlset
= _SVP64BCVLSETMode
.VL_INCL
143 bc_vlset
= _SVP64BCVLSETMode
.VL_EXCL
144 bc_gate
= rm
.elwidth
[0]
145 bc_lru
= rm
.elwidth
[1]
151 return self
.__class
__.Prefix(super().prefix
)
155 return self
.__class
__.Suffix(super().suffix
)
158 def load(ifile
, byteorder
, **_
):
160 prefix
= ifile
.read(4)
165 raise IOError(prefix
)
166 prefix
= Instruction(prefix
, byteorder
)
167 if prefix
.major
!= 0x1:
168 return Instruction(prefix
, byteorder
)
170 suffix
= ifile
.read(4)
175 raise IOError(suffix
)
177 return SVP64Instruction(prefix
, suffix
, byteorder
)
178 except SVP64Instruction
.PrefixError
:
179 return PrefixedInstruction(prefix
, suffix
, byteorder
)
188 def dump(insns
, ofile
, **_
):
190 yield from insn
.disassemble()
194 parser
= _argparse
.ArgumentParser()
195 parser
.add_argument("ifile", nargs
="?",
196 type=_argparse
.FileType("rb"), default
=_sys
.stdin
.buffer)
197 parser
.add_argument("ofile", nargs
="?",
198 type=_argparse
.FileType("w"), default
=_sys
.stdout
)
199 parser
.add_argument("-b", "--byteorder",
200 type=ByteOrder
, default
=ByteOrder
.LITTLE
)
202 args
= dict(vars(parser
.parse_args()))
203 ifile
= args
["ifile"]
204 ofile
= args
["ofile"]
205 byteorder
= args
["byteorder"]
207 insns
= load(ifile
, byteorder
)
208 for line
in dump(insns
, byteorder
):
209 print(line
, file=ofile
)
212 if __name__
== "__main__":