c7788f8a08c58545c215eadb95a4fa37771b1626
6 from openpower
.decoder
.power_enums
import (
9 from openpower
.insndb
.core
import (
22 class Instruction(str):
23 def __new__(cls
, string
):
25 if string
.startswith("sv."):
26 string
= string
[len("sv."):]
28 self
= super().__new
__(cls
, string
)
37 class SVP64Instruction(Instruction
):
38 def __new__(cls
, string
):
39 self
= super().__new
__(cls
, string
)
41 raise ValueError("illegal SVP64 instruction")
45 class TreeVisitor(Visitor
):
49 return super().__init
__()
51 @contextlib.contextmanager
52 def __call__(self
, path
, node
):
53 with
super().__call
__(path
=path
, node
=node
):
54 self
.__path
.append(path
)
55 print("/".join(self
.__path
))
56 if not isinstance(node
, (Dataclass
, Tuple
, Dict
)):
57 print(" ", repr(node
), sep
="")
64 class ListVisitor(Visitor
):
65 @visitormethod(Record
)
66 def Record(self
, path
, node
):
71 # No use other than checking issubclass and adding an argument.
72 class InstructionVisitor(Visitor
):
75 class SVP64InstructionVisitor(InstructionVisitor
):
79 class OpcodesVisitor(InstructionVisitor
):
80 @visitormethod(Record
)
81 def Record(self
, path
, node
):
82 for opcode
in node
.opcodes
:
87 class OperandsVisitor(InstructionVisitor
):
88 @visitormethod(Record
)
89 def Record(self
, path
, node
):
90 if isinstance(node
, Record
):
91 for operand
in node
.dynamic_operands
:
92 print(operand
.name
, ",".join(map(str, operand
.span
)))
93 for operand
in node
.static_operands
:
94 if operand
.name
not in ("PO", "XO"):
95 desc
= f
"{operand.name}={operand.value}"
96 print(desc
, ",".join(map(str, operand
.span
)))
100 class PCodeVisitor(InstructionVisitor
):
101 @visitormethod(Record
)
102 def Record(self
, path
, node
):
103 if isinstance(node
, Record
):
104 for line
in node
.pcode
:
109 class ExtrasVisitor(SVP64InstructionVisitor
):
110 @visitormethod(Record
)
111 def Record(self
, path
, node
):
112 for (name
, extra
) in node
.extras
.items():
114 print(" sel", extra
["sel"])
115 print(" reg", extra
["reg"])
116 print(" seltype", extra
["seltype"])
117 print(" idx", extra
["idx"])
129 "list available instructions",
133 "print instruction opcodes",
137 "print instruction operands",
141 "print instruction pseudocode",
145 "print instruction extras (SVP64)",
149 main_parser
= argparse
.ArgumentParser()
150 main_parser
.add_argument("-l", "--log",
151 help="activate logging",
154 main_subparser
= main_parser
.add_subparsers(dest
="command", required
=True)
156 for (command
, (visitor
, helper
)) in commands
.items():
157 parser
= main_subparser
.add_parser(command
, help=helper
)
158 if issubclass(visitor
, InstructionVisitor
):
159 if command
in ("extras",):
160 arg_cls
= SVP64Instruction
162 arg_cls
= Instruction
163 parser
.add_argument("insn", type=arg_cls
,
164 metavar
="INSN", help="instruction")
166 args
= vars(main_parser
.parse_args())
167 command
= args
.pop("command")
168 log
= args
.pop("log")
170 os
.environ
["SILENCELOG"] = "true"
171 visitor
= commands
[command
][0]()
173 db
= Database(find_wiki_dir())
174 (path
, records
) = next(db
.walk(match
=lambda pair
: isinstance(pair
, Records
)))
175 if not isinstance(visitor
, InstructionVisitor
):
178 insn
= args
.pop("insn")
180 return (isinstance(record
, Record
) and (record
.name
== insn
))
182 for (subpath
, node
) in records
.walk(match
=match
):
183 visit(visitor
=visitor
, node
=node
, path
=subpath
)
186 if __name__
== "__main__":