From ff779091c25eee099bf51e4a58b9c39bc7527fca Mon Sep 17 00:00:00 2001 From: Dmitry Selyutin Date: Wed, 10 Jan 2024 00:26:03 +0300 Subject: [PATCH] oppc: introduce C generator skeleton --- src/openpower/oppc/__main__.py | 4 ++ src/openpower/oppc/pc_code.py | 67 ++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 src/openpower/oppc/pc_code.py diff --git a/src/openpower/oppc/__main__.py b/src/openpower/oppc/__main__.py index deb165a2..2d415f2e 100644 --- a/src/openpower/oppc/__main__.py +++ b/src/openpower/oppc/__main__.py @@ -6,6 +6,7 @@ from openpower.decoder.power_enums import ( find_wiki_dir, ) +import openpower.oppc.pc_code as pc_code import openpower.oppc.pc_lexer as pc_lexer import openpower.oppc.pc_parser as pc_parser import openpower.oppc.pc_pseudocode as pc_pseudocode @@ -66,3 +67,6 @@ tree = parser.parse(code=code) print(tree) for (level, line) in pc_pseudocode.pseudocode(tree): print(f"{' ' * 4 * level}{line}") + +for (level, line) in pc_code.code(name="cdtbcd", root=tree): + print(f"{' ' * 4 * level}{line}") diff --git a/src/openpower/oppc/pc_code.py b/src/openpower/oppc/pc_code.py new file mode 100644 index 00000000..24f78d17 --- /dev/null +++ b/src/openpower/oppc/pc_code.py @@ -0,0 +1,67 @@ +import collections + +import openpower.oppc.pc_ast as pc_ast +import openpower.oppc.pc_util as pc_util + + +class CodeVisitor(pc_util.Visitor): + def __init__(self, name, root): + self.__name = name + self.__code = pc_util.Code() + self.__decls = collections.defaultdict(list) + self.__regfetch = collections.defaultdict(list) + self.__regstore = collections.defaultdict(list) + + super().__init__(root=root) + + self.__code.emit("void") + self.__code.emit(f"oppc_{name}(void) {{") + with self.__code: + for decl in self.__decls: + self.__code.emit(f"uint64_t {decl};") + self.__code.emit(f"}}") + + def __iter__(self): + yield from self.__code + + @pc_util.Hook(pc_ast.AssignExpr, pc_ast.AssignIEAExpr) + def AssignExpr(self, node): + yield node + if isinstance(node.lvalue, (pc_ast.GPR, pc_ast.FPR)): + self.__regstore[str(node.lvalue)].append(node.lvalue) + if isinstance(node.rvalue, (pc_ast.GPR, pc_ast.FPR)): + self.__regfetch[str(node.rvalue)].append(node.rvalue) + + @pc_util.Hook(pc_ast.BinaryExpr) + def BinaryExpr(self, node): + yield node + if isinstance(node.left, (pc_ast.GPR, pc_ast.FPR)): + self.__regfetch[str(node.left)].append(node.left) + if isinstance(node.right, (pc_ast.GPR, pc_ast.FPR)): + self.__regfetch[str(node.right)].append(node.left) + + @pc_util.Hook(pc_ast.UnaryExpr) + def UnaryExpr(self, node): + yield node + if isinstance(node.value, (pc_ast.GPR, pc_ast.FPR)): + self.__regfetch[str(node.value)].append(node.value) + + @pc_util.Hook(pc_ast.Call.Name) + def CallName(self, node): + yield node + + @pc_util.Hook(pc_ast.Call.Arguments) + def CallArguments(self, node): + yield node + for subnode in node: + if isinstance(subnode, (pc_ast.GPR, pc_ast.FPR)): + self.__regfetch[str(subnode)].append(subnode) + + @pc_util.Hook(pc_ast.Symbol) + def Symbol(self, node): + yield node + self.__decls[str(node)].append(node) + + +def code(name, root): + yield from CodeVisitor(name=name, root=root) -- 2.30.2