oppc/code: emit only function body
[openpower-isa.git] / src / openpower / oppc / pc_code.py
index 04dcf23630605cfc00dabf232a76364a2564ff3a..d490a85dbc3019d921c7b6307e5b7a1f33e69c92 100644 (file)
@@ -32,9 +32,11 @@ class Instruction(pc_ast.Node):
 
 class CodeVisitor(pc_util.Visitor):
     def __init__(self, insn, root):
+        if not isinstance(root, pc_ast.Scope):
+            raise ValueError(root)
+
         self.__root = root
         self.__insn = insn
-        self.__attrs = {}
         self.__decls = set()
         self.__header = object()
         self.__footer = object()
@@ -45,11 +47,8 @@ class CodeVisitor(pc_util.Visitor):
 
         super().__init__(root=root)
 
-        self.__code[self.__header].emit(stmt="void")
-        self.__code[self.__header].emit(stmt=f"oppc_{insn.name}(struct oppc_value const *insn) {{")
-        with self.__code[self.__header]:
-            for decl in self.__decls:
-                self.__code[self.__header].emit(stmt=f"struct oppc_value {decl};")
+        for decl in self.__decls:
+            self.__code[self.__header].emit(stmt=f"struct oppc_value {decl};")
         decls = sorted(filter(lambda decl: decl in insn.fields, self.__decls))
         if decls:
             self.__code[self.__header].emit()
@@ -59,9 +58,8 @@ class CodeVisitor(pc_util.Visitor):
             symbol = pc_ast.Symbol(decl)
             assign = pc_ast.AssignExpr(lvalue=symbol, rvalue=transient)
             self.traverse(root=assign)
-            with self[self.__header]:
-                for (level, stmt) in self[assign]:
-                    self[self.__header].emit(stmt=stmt, level=level)
+            for (level, stmt) in self[assign]:
+                self[self.__header].emit(stmt=stmt, level=level)
             for (lbit, rbit) in enumerate(insn.fields[decl]):
                 lsymbol = pc_ast.Symbol(decl)
                 rsymbol = Instruction()
@@ -71,18 +69,17 @@ class CodeVisitor(pc_util.Visitor):
                 rvalue = pc_ast.SubscriptExpr(index=rindex, subject=rsymbol)
                 assign = pc_ast.AssignExpr(lvalue=lvalue, rvalue=rvalue)
                 self.traverse(root=assign)
-                with self[self.__header]:
-                    for (level, stmt) in self[assign]:
-                        self[self.__header].emit(stmt=stmt, level=level)
+                for (level, stmt) in self[assign]:
+                    self[self.__header].emit(stmt=stmt, level=level)
             self.__code[self.__header].emit()
         if decls:
             self.__code[self.__header].emit()
-        self.__code[self.__footer].emit(stmt=f"}}")
 
     def __iter__(self):
-        yield from self.__code[self.__header]
-        yield from self.__code[self.__root]
-        yield from self.__code[self.__footer]
+        yield from self[self.__header]
+        for (level, stmt) in self[self.__root]:
+            yield ((level - 1), stmt)
+        yield from self[self.__footer]
 
     def __getitem__(self, node):
         return self.__code[node]
@@ -116,7 +113,7 @@ class CodeVisitor(pc_util.Visitor):
 
     def fixup_ternary(self, node):
         self[node].clear()
-        test = self.call(name="oppc_bool", code=[
+        test = self.call(name="oppc_cast_bool", code=[
             self[node.test],
         ])
         self[node].emit(stmt="(")
@@ -172,8 +169,9 @@ class CodeVisitor(pc_util.Visitor):
 
     @contextlib.contextmanager
     def pseudocode(self, node):
-        for (level, stmt) in self.__pseudocode[node]:
-            self[node].emit(stmt=f"/* {stmt} */", level=level)
+        if node in self.__pseudocode:
+            for (level, stmt) in self.__pseudocode[node]:
+                self[node].emit(stmt=f"/* {stmt} */", level=level)
         yield
 
     @pc_util.Hook(pc_ast.Scope)
@@ -260,7 +258,7 @@ class CodeVisitor(pc_util.Visitor):
 
         comparison = (
             pc_ast.Lt, pc_ast.Le,
-            pc_ast.Eq, pc_ast.NotEq,
+            pc_ast.Eq, pc_ast.Ne,
             pc_ast.Ge, pc_ast.Gt,
             pc_ast.LtU, pc_ast.GtU,
         )
@@ -282,7 +280,9 @@ class CodeVisitor(pc_util.Visitor):
         yield node
         if isinstance(node.value, pc_ast.IfExpr):
             self.fixup_ternary(node=node.value)
+        transient = self.transient()
         call = self.call(name=str(self[node.op]), code=[
+            self[transient],
             self[node.value],
         ])
         with self.pseudocode(node=node):
@@ -293,7 +293,7 @@ class CodeVisitor(pc_util.Visitor):
             pc_ast.Not, pc_ast.Add, pc_ast.Sub,
             pc_ast.Mul, pc_ast.Div, pc_ast.Mod,
             pc_ast.Lt, pc_ast.Le,
-            pc_ast.Eq, pc_ast.NotEq,
+            pc_ast.Eq, pc_ast.Ne,
             pc_ast.Ge, pc_ast.Gt,
             pc_ast.LtU, pc_ast.GtU,
             pc_ast.LShift, pc_ast.RShift,
@@ -312,9 +312,9 @@ class CodeVisitor(pc_util.Visitor):
             pc_ast.Lt: "oppc_lt",
             pc_ast.Le: "oppc_le",
             pc_ast.Eq: "oppc_eq",
+            pc_ast.Ne: "oppc_ne",
             pc_ast.LtU: "oppc_ltu",
             pc_ast.GtU: "oppc_gtu",
-            pc_ast.NotEq: "oppc_noteq",
             pc_ast.Ge: "oppc_ge",
             pc_ast.Gt: "oppc_gt",
             pc_ast.LShift: "oppc_lshift",
@@ -527,7 +527,7 @@ class CodeVisitor(pc_util.Visitor):
     @pc_util.Hook(pc_ast.IfExpr)
     def IfExpr(self, node):
         yield node
-        test = self.call(name="oppc_bool", code=[
+        test = self.call(name="oppc_cast_bool", code=[
             self[node.test],
         ])
         self[node].emit(stmt="if (")
@@ -546,7 +546,7 @@ class CodeVisitor(pc_util.Visitor):
     @pc_util.Hook(pc_ast.SwitchExpr)
     def SwitchExpr(self, node):
         yield node
-        subject = self.call(name="oppc_int64", code=[
+        subject = self.call(name="oppc_cast_int64", code=[
             self[node.subject],
         ])
         self[node].emit(stmt="switch (")
@@ -608,10 +608,17 @@ class CodeVisitor(pc_util.Visitor):
     @pc_util.Hook(pc_ast.Call)
     def Call(self, node):
         yield node
-        code = tuple(map(lambda arg: self[arg], node.args))
-        call = self.call(name=str(node.name), code=code)
-        for (level, stmt) in self[call]:
-            self[node].emit(stmt=stmt, level=level)
+        if node.args:
+            transient = self.transient()
+            code = [self[transient]]
+        else:
+            code = []
+        code.extend(map(lambda arg: self[arg], node.args))
+        name = f"OPPC_CALL_{str(node.name)}"
+        with self.pseudocode(node=node):
+            call = self.call(name=name, code=code)
+            for (level, stmt) in self[call]:
+                self[node].emit(stmt=stmt, level=level)
 
     @pc_util.Hook(pc_ast.Attribute.Name)
     def AttributeName(self, node):
@@ -628,7 +635,6 @@ class CodeVisitor(pc_util.Visitor):
         symbol = f"OPPC_ATTR_{attr.replace('.', '_')}"
         self[node].emit(f"/* {attr} */")
         self[node].emit(stmt=symbol)
-        self.__attrs[node] = symbol
 
     @pc_util.Hook(pc_ast.Symbol)
     def Symbol(self, node):
@@ -637,9 +643,10 @@ class CodeVisitor(pc_util.Visitor):
             decl = str(node)
             if decl not in ("fallthrough",):
                 if decl in ("TRAP",):
-                    self[node].emit(stmt=f"{decl}();")
+                    self[node].emit(stmt=f"OPPC_CALL_{decl}();")
                 else:
-                    self.__decls.add(decl)
+                    if node in self.__pseudocode:
+                        self.__decls.add(decl)
                     self[node].emit(stmt=f"&{decl}")
 
     @pc_util.Hook(Instruction)