From: Dmitry Selyutin Date: Sun, 14 Jan 2024 18:12:03 +0000 (+0300) Subject: oppc: support attributes X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=59be6c8d6a5b29cf94346d8748fec74e09663b78;p=openpower-isa.git oppc: support attributes --- diff --git a/src/openpower/oppc/pc_code.py b/src/openpower/oppc/pc_code.py index d7cdeef5..107099fa 100644 --- a/src/openpower/oppc/pc_code.py +++ b/src/openpower/oppc/pc_code.py @@ -26,6 +26,7 @@ class Call(pc_ast.Dataclass): class CodeVisitor(pc_util.Visitor): def __init__(self, name, root): self.__root = root + self.__attrs = {} self.__header = object() self.__footer = object() self.__code = collections.defaultdict(lambda: pc_util.Code()) @@ -51,6 +52,9 @@ class CodeVisitor(pc_util.Visitor): def __getitem__(self, node): return self.__code[node] + def __setitem__(self, node, code): + self.__code[node] = code + def transient(self, node, value="UINT64_C(0)", bits="(uint8_t)OPPC_XLEN"): @@ -75,7 +79,7 @@ class CodeVisitor(pc_util.Visitor): self.traverse(root=call) return call - def ternary(self, node): + def fixup_ternary(self, node): self[node].clear() test = self.call(name="oppc_bool", node=node, code=[ self[node.test], @@ -92,6 +96,45 @@ class CodeVisitor(pc_util.Visitor): self[node].emit(stmt=stmt, level=level) self[node].emit(stmt=")") + def fixup_attr(self, node, assign=False): + root = node + code = tuple(self[root]) + attribute_or_subscript = ( + pc_ast.Attribute, + pc_ast.SubscriptExpr, + pc_ast.RangeSubscriptExpr, + ) + while isinstance(node.subject, attribute_or_subscript): + node = node.subject + + def wrap(code): + def wrap(item): + (level, stmt) = item + if not (not stmt or + stmt.startswith("/*") or + stmt.endswith((",", "(", "{", "*/"))): + stmt = (stmt + ",") + return (level, stmt) + + return tuple(map(wrap, code)) + + code = pc_util.Code() + for (level, stmt) in wrap(self[node.subject]): + code.emit(stmt=stmt, level=level) + for (level, stmt) in wrap(self[root]): + code.emit(stmt=stmt, level=level) + + # discard the last comma + (level, stmt) = code[-1] + code[-1] = (level, stmt[:-1]) + + if not assign: + call = self.call(name="oppc_attr", node=root, code=[ + code, + ]) + code = self[call] + self[root] = code + @contextlib.contextmanager def pseudocode(self, node): for (level, stmt) in self.__pseudocode[node]: @@ -115,7 +158,11 @@ class CodeVisitor(pc_util.Visitor): self.__regfetch[str(node.rvalue)].append(node.rvalue) if isinstance(node.rvalue, pc_ast.IfExpr): - self.ternary(node=node.rvalue) + self.fixup_ternary(node=node.rvalue) + if isinstance(node.lvalue, pc_ast.Attribute): + self.fixup_attr(node=node.lvalue, assign=True) + if isinstance(node.rvalue, pc_ast.Attribute): + self.fixup_attr(node=node.rvalue) if isinstance(node.lvalue, pc_ast.SubscriptExpr): call = self.call(name="oppc_subscript_assign", node=node, stmt=True, code=[ @@ -130,6 +177,11 @@ class CodeVisitor(pc_util.Visitor): self[node.lvalue.end], self[node.rvalue], ]) + elif isinstance(node.lvalue, pc_ast.Attribute): + call = self.call(name="oppc_attr_assign", stmt=True, node=node, code=[ + self[node.lvalue], + self[node.rvalue], + ]) else: call = self.call(name="oppc_assign", stmt=True, node=node, code=[ self[node.lvalue], @@ -154,9 +206,13 @@ class CodeVisitor(pc_util.Visitor): pc_ast.LtU, pc_ast.GtU, ) if isinstance(node.left, pc_ast.IfExpr): - self.ternary(node=node.left) + self.fixup_ternary(node=node.left) if isinstance(node.right, pc_ast.IfExpr): - self.ternary(node=node.right) + self.fixup_ternary(node=node.right) + if isinstance(node.left, pc_ast.Attribute): + self.fixup_attr(node=node.left) + if isinstance(node.right, pc_ast.Attribute): + self.fixup_attr(node=node.right) if isinstance(node.op, comparison): call = self.call(name=str(self[node.op]), node=node, code=[ @@ -178,7 +234,7 @@ class CodeVisitor(pc_util.Visitor): def UnaryExpr(self, node): yield node if isinstance(node.value, pc_ast.IfExpr): - self.ternary(node=node.value) + self.fixup_ternary(node=node.value) call = self.call(name=str(self[node.op]), node=node, code=[ self[node.value], ]) @@ -487,6 +543,19 @@ class CodeVisitor(pc_util.Visitor): for (level, stmt) in self[call]: self[node].emit(stmt=stmt, level=level) + @pc_util.Hook(pc_ast.Attribute.Name) + def AttributeName(self, node): + yield node + + @pc_util.Hook(pc_ast.Attribute) + def Attribute(self, node): + yield node + attr = str(self.__pseudocode[node]) + 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): yield node