oppc: introduce C generator skeleton
authorDmitry Selyutin <ghostmansd@gmail.com>
Tue, 9 Jan 2024 21:26:03 +0000 (00:26 +0300)
committerDmitry Selyutin <ghostmansd@gmail.com>
Tue, 16 Jan 2024 19:10:07 +0000 (22:10 +0300)
src/openpower/oppc/__main__.py
src/openpower/oppc/pc_code.py [new file with mode: 0644]

index deb165a2722d70ec5f0c53a912ba3bcb83351662..2d415f2efcb82d4c296b18bcbc32bd991251b33a 100644 (file)
@@ -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 (file)
index 0000000..24f78d1
--- /dev/null
@@ -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)