b8311f31780262e767601374b5332484db26a57f
[openpower-isa.git] / src / openpower / insndb / db.py
1 import argparse
2 import contextlib
3 import os
4
5 from openpower.decoder.power_enums import (
6 find_wiki_dir,
7 )
8 from openpower.insndb.core import (
9 Database,
10 Visitor,
11 )
12
13
14 class Instruction(str):
15 def __new__(cls, string):
16 svp64 = False
17 if string.startswith("sv."):
18 string = string[len("sv."):]
19 svp64 = True
20 self = super().__new__(cls, string)
21 self.__svp64 = svp64
22 return self
23
24 @property
25 def svp64(self):
26 return self.__svp64
27
28
29 class BaseVisitor(Visitor):
30 def __init__(self, **_):
31 pass
32
33
34 class ListVisitor(BaseVisitor):
35 @contextlib.contextmanager
36 def record(self, record):
37 print(record.name)
38 yield record
39
40
41 class ConcreteInstructionVisitor(BaseVisitor):
42 def __init__(self, insn, **_):
43 self.__insn = insn
44 return super().__init__()
45
46 def handler(self, record):
47 raise NotImplementedError
48
49 @contextlib.contextmanager
50 def record(self, record):
51 if record.name == self.__insn:
52 self.handler(record=record)
53 yield record
54
55
56 class OpcodesVisitor(ConcreteInstructionVisitor):
57 def handler(self, record):
58 for opcode in record.opcodes:
59 print(opcode)
60
61
62 class OperandsVisitor(ConcreteInstructionVisitor):
63 def handler(self, record):
64 for operand in record.dynamic_operands:
65 print(operand.name)
66 for operand in record.static_operands:
67 if operand.name not in ("PO", "XO"):
68 print(operand.name, operand.value, sep="=")
69
70
71 class PCodeVisitor(ConcreteInstructionVisitor):
72 def handler(self, record):
73 for line in record.pcode:
74 print(line)
75
76
77 def main():
78 commands = {
79 "list": (
80 ListVisitor,
81 "list available instructions",
82 ),
83 "opcodes": (
84 OpcodesVisitor,
85 "print instruction opcodes",
86 ),
87 "operands": (
88 OperandsVisitor,
89 "print instruction operands",
90 ),
91 "pcode": (
92 PCodeVisitor,
93 "print instruction pseudocode",
94 ),
95 }
96
97 main_parser = argparse.ArgumentParser()
98 main_parser.add_argument("-l", "--log",
99 help="activate logging",
100 action="store_true",
101 default=False)
102 main_subparser = main_parser.add_subparsers(dest="command", required=True)
103
104 for (command, (visitor, help)) in commands.items():
105 parser = main_subparser.add_parser(command, help=help)
106 if issubclass(visitor, ConcreteInstructionVisitor):
107 parser.add_argument("insn", type=Instruction,
108 metavar="INSN", help="instruction")
109
110 args = vars(main_parser.parse_args())
111 command = args.pop("command")
112 log = args.pop("log")
113 if not log:
114 os.environ["SILENCELOG"] = "true"
115 visitor = commands[command][0](**args)
116
117 db = Database(find_wiki_dir())
118 db.visit(visitor=visitor)
119
120
121 if __name__ == "__main__":
122 main()