3 import openpower
.oppc
.pc_ast
as pc_ast
4 import openpower
.oppc
.pc_util
as pc_util
7 class CodeVisitor(pc_util
.Visitor
):
8 def __init__(self
, name
, root
):
10 self
.__header
= object()
11 self
.__footer
= object()
12 self
.__code
= collections
.defaultdict(lambda: pc_util
.Code())
13 self
.__decls
= collections
.defaultdict(list)
14 self
.__regfetch
= collections
.defaultdict(list)
15 self
.__regstore
= collections
.defaultdict(list)
17 super().__init
__(root
=root
)
19 self
.__code
[self
.__header
].emit("void")
20 self
.__code
[self
.__header
].emit(f
"oppc_{name}(void) {{")
21 with self
.__code
[self
.__header
]:
22 for decl
in self
.__decls
:
23 self
.__code
[self
.__header
].emit(f
"uint64_t {decl};")
24 self
.__code
[self
.__footer
].emit(f
"}}")
27 yield from self
.__code
[self
.__header
]
28 yield from self
.__code
[self
.__root
]
29 yield from self
.__code
[self
.__footer
]
31 def __getitem__(self
, node
):
32 return self
.__code
[node
]
34 @pc_util.Hook(pc_ast
.Scope
)
35 def Scope(self
, node
):
39 for (level
, stmt
) in self
[subnode
]:
40 self
[node
].emit(stmt
=stmt
, level
=level
)
42 @pc_util.Hook(pc_ast
.AssignExpr
, pc_ast
.AssignIEAExpr
)
43 def AssignExpr(self
, node
):
45 if isinstance(node
.lvalue
, (pc_ast
.GPR
, pc_ast
.FPR
)):
46 self
.__regstore
[str(node
.lvalue
)].append(node
.lvalue
)
47 if isinstance(node
.rvalue
, (pc_ast
.GPR
, pc_ast
.FPR
)):
48 self
.__regfetch
[str(node
.rvalue
)].append(node
.rvalue
)
51 str(self
[node
.lvalue
]),
53 str(self
[node
.rvalue
]),
55 self
[node
].emit(stmt
=f
"{stmt};")
57 @pc_util.Hook(pc_ast
.BinaryExpr
)
58 def BinaryExpr(self
, node
):
60 if isinstance(node
.left
, (pc_ast
.GPR
, pc_ast
.FPR
)):
61 self
.__regfetch
[str(node
.left
)].append(node
.left
)
62 if isinstance(node
.right
, (pc_ast
.GPR
, pc_ast
.FPR
)):
63 self
.__regfetch
[str(node
.right
)].append(node
.left
)
71 if isinstance(node
.op
, special
):
72 raise NotImplementedError(node
)
76 str(self
[node
.right
]),
78 self
[node
].emit(stmt
=f
"({stmt})")
80 @pc_util.Hook(pc_ast
.UnaryExpr
)
81 def UnaryExpr(self
, node
):
85 f
"({str(self[node.value])})",
87 self
[node
].emit(stmt
=stmt
)
90 pc_ast
.Not
, pc_ast
.Add
, pc_ast
.Sub
,
91 pc_ast
.Mul
, pc_ast
.Div
, pc_ast
.Mod
,
93 pc_ast
.Eq
, pc_ast
.NotEq
,
95 pc_ast
.LShift
, pc_ast
.RShift
,
96 pc_ast
.BitAnd
, pc_ast
.BitOr
, pc_ast
.BitXor
,
119 self
[node
].emit(stmt
=op
)
121 @pc_util.Hook(pc_ast
.BinLiteral
, pc_ast
.DecLiteral
, pc_ast
.HexLiteral
)
122 def Integer(self
, node
):
124 if isinstance(node
, pc_ast
.BinLiteral
):
126 elif isinstance(node
, pc_ast
.DecLiteral
):
128 elif isinstance(node
, pc_ast
.HexLiteral
):
131 raise ValueError(node
)
132 self
[node
].emit(stmt
=f
"UINT64_C({hex(int(node, base))})")
134 @pc_util.Hook(pc_ast
.GPR
)
137 self
[node
].emit(stmt
=f
"ctx->gpr[OPPC_GPR_{str(node)}]")
139 @pc_util.Hook(pc_ast
.FPR
)
142 self
[node
].emit(stmt
=f
"ctx->fpr[OPPC_FPR_{str(node)}]")
144 @pc_util.Hook(pc_ast
.RepeatExpr
)
145 def RepeatExpr(self
, node
):
147 subject
= str(self
[node
.subject
])
148 times
= str(self
[node
.times
])
149 self
[node
].emit(f
"oppc_repeat({subject}, {times})")
151 @pc_util.Hook(pc_ast
.XLEN
)
152 def XLEN(self
, node
):
154 self
[node
].emit(f
"ctx->XLEN")
156 @pc_util.Hook(pc_ast
.SubscriptExpr
)
157 def SubscriptExpr(self
, node
):
159 index
= str(self
[node
.index
])
160 subject
= str(self
[node
.subject
])
161 self
[node
].emit(f
"oppc_subscript({subject}, {index})")
163 @pc_util.Hook(pc_ast
.RangeSubscriptExpr
)
164 def RangeSubscriptExpr(self
, node
):
166 start
= str(self
[node
.start
])
167 end
= str(self
[node
.end
])
168 subject
= str(self
[node
.subject
])
169 self
[node
].emit(f
"oppc_range_subscript({subject}, {start}, {end})")
171 @pc_util.Hook(pc_ast
.Call
.Name
)
172 def CallName(self
, node
):
175 @pc_util.Hook(pc_ast
.Call
.Arguments
)
176 def CallArguments(self
, node
):
179 if isinstance(subnode
, (pc_ast
.GPR
, pc_ast
.FPR
)):
180 self
.__regfetch
[str(subnode
)].append(subnode
)
182 @pc_util.Hook(pc_ast
.Symbol
)
183 def Symbol(self
, node
):
185 self
.__decls
[str(node
)].append(node
)
186 self
[node
].emit(stmt
=str(node
))
188 @pc_util.Hook(pc_ast
.Node
)
189 def Node(self
, node
):
190 raise NotImplementedError(type(node
))
193 def code(name
, root
):
194 yield from CodeVisitor(name
=name
, root
=root
)