insndb/db: simplify commands structure
[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 BaseVisitor(Visitor):
15 def __init__(self, **_):
16 pass
17
18
19 class ListVisitor(BaseVisitor):
20 @contextlib.contextmanager
21 def record(self, record):
22 print(record.name)
23 yield record
24
25
26 class ConcreteInstructionVisitor(BaseVisitor):
27 def __init__(self, insn, **_):
28 self.__insn = insn
29 return super().__init__()
30
31 def handler(self, record):
32 raise NotImplementedError
33
34 @contextlib.contextmanager
35 def record(self, record):
36 if record.name == self.__insn:
37 self.handler(record=record)
38 yield record
39
40
41 class OpcodesVisitor(ConcreteInstructionVisitor):
42 def handler(self, record):
43 for opcode in record.opcodes:
44 print(opcode)
45
46
47 class OperandsVisitor(ConcreteInstructionVisitor):
48 def handler(self, record):
49 for operand in record.dynamic_operands:
50 print(operand.name)
51 for operand in record.static_operands:
52 if operand.name not in ("PO", "XO"):
53 print(operand.name, operand.value, sep="=")
54
55
56 class PCodeVisitor(ConcreteInstructionVisitor):
57 def handler(self, record):
58 for line in record.pcode:
59 print(line)
60
61
62 def main():
63 commands = {
64 "list": (
65 ListVisitor,
66 "list available instructions",
67 ),
68 "opcodes": (
69 OpcodesVisitor,
70 "print instruction opcodes",
71 ),
72 "operands": (
73 OperandsVisitor,
74 "print instruction operands",
75 ),
76 "pcode": (
77 PCodeVisitor,
78 "print instruction pseudocode",
79 ),
80 }
81
82 main_parser = argparse.ArgumentParser()
83 main_parser.add_argument("-l", "--log",
84 help="activate logging",
85 action="store_true",
86 default=False)
87 main_subparser = main_parser.add_subparsers(dest="command", required=True)
88
89 for (command, (visitor, help)) in commands.items():
90 parser = main_subparser.add_parser(command, help=help)
91 if issubclass(visitor, ConcreteInstructionVisitor):
92 parser.add_argument("insn", metavar="INSN", help="instruction")
93
94 args = vars(main_parser.parse_args())
95 command = args.pop("command")
96 log = args.pop("log")
97 if not log:
98 os.environ["SILENCELOG"] = "true"
99 visitor = commands[command][0](**args)
100
101 db = Database(find_wiki_dir())
102 db.visit(visitor=visitor)