oppc/code: support basic fields initialization
authorDmitry Selyutin <ghostmansd@gmail.com>
Sun, 14 Jan 2024 20:00:49 +0000 (23:00 +0300)
committerDmitry Selyutin <ghostmansd@gmail.com>
Tue, 16 Jan 2024 19:10:07 +0000 (22:10 +0300)
src/openpower/oppc/pc_code.py

index d408648360b0b03cd594556d404ae42bd4573548..47aded9d974929fecb1ec71805c02684b7def067 100644 (file)
@@ -13,6 +13,9 @@ class Transient(pc_ast.Node):
 
         return super().__init__()
 
+    def __repr__(self):
+        return f"{hex(id(self))}@{self.__class__.__name__}({self.__value}, {self.__bits})"
+
     def __str__(self):
         return f"oppc_transient(&(struct oppc_value){{}}, {self.__value}, {self.__bits})"
 
@@ -23,15 +26,19 @@ class Call(pc_ast.Dataclass):
     stmt: bool
 
 
+class Instruction(pc_ast.Node):
+    pass
+
+
 class CodeVisitor(pc_util.Visitor):
     def __init__(self, insn, root):
         self.__root = root
         self.__insn = insn
         self.__attrs = {}
+        self.__decls = set()
         self.__header = object()
         self.__footer = object()
         self.__code = collections.defaultdict(lambda: pc_util.Code())
-        self.__decls = collections.defaultdict(list)
         self.__regfetch = collections.defaultdict(list)
         self.__regstore = collections.defaultdict(list)
         self.__pseudocode = pc_pseudocode.PseudocodeVisitor(root=root)
@@ -43,6 +50,30 @@ class CodeVisitor(pc_util.Visitor):
         with self.__code[self.__header]:
             for decl in self.__decls:
                 self.__code[self.__header].emit(stmt=f"struct oppc_value {decl};")
+        self.__code[self.__header].emit()
+        for decl in filter(lambda decl: decl in insn.fields, sorted(self.__decls)):
+            bits = f"{len(insn.fields[decl])}"
+            transient = Transient(bits=bits)
+            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 (lbit, rbit) in enumerate(insn.fields[decl]):
+                lsymbol = pc_ast.Symbol(decl)
+                rsymbol = Instruction()
+                lindex = Transient(value=str(lbit))
+                rindex = Transient(value=str(rbit))
+                lvalue = pc_ast.SubscriptExpr(index=lindex, subject=lsymbol)
+                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)
+            self.__code[self.__header].emit()
+        self.__code[self.__header].emit()
         self.__code[self.__footer].emit(stmt=f"}}")
 
     def __iter__(self):
@@ -587,9 +618,14 @@ class CodeVisitor(pc_util.Visitor):
         yield node
         with self.pseudocode(node=node):
             if str(node) not in ("fallthrough",):
-                self.__decls[str(node)].append(node)
+                self.__decls.add(str(node))
                 self[node].emit(stmt=f"&{str(node)}")
 
+    @pc_util.Hook(Instruction)
+    def Instruction(self, node):
+        yield node
+        self[node].emit("insn")
+
     @pc_util.Hook(pc_ast.Node)
     def Node(self, node):
         raise NotImplementedError(type(node))