Skip to content

Commit f89f859

Browse files
committed
ARM: add ast provenance to UMLAL
1 parent c345482 commit f89f859

File tree

1 file changed

+89
-1
lines changed

1 file changed

+89
-1
lines changed

chb/arm/opcodes/ARMUnsignedMultiplyAccumulateLong.py

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,19 @@
2525
# SOFTWARE.
2626
# ------------------------------------------------------------------------------
2727

28-
from typing import List, TYPE_CHECKING
28+
from typing import List, Tuple, TYPE_CHECKING
2929

3030
from chb.app.InstrXData import InstrXData
3131

3232
from chb.arm.ARMDictionaryRecord import armregistry
3333
from chb.arm.ARMOpcode import ARMOpcode, ARMOpcodeXData, simplify_result
3434
from chb.arm.ARMOperand import ARMOperand
3535

36+
import chb.ast.ASTNode as AST
37+
from chb.astinterface.ASTInterface import ASTInterface
38+
39+
import chb.invariants.XXprUtil as XU
40+
3641
import chb.util.fileutil as UF
3742
from chb.util.IndexedTable import IndexedTableValue
3843
from chb.util.loggingutil import chklogger
@@ -110,6 +115,10 @@ def __init__(self, d: "ARMDictionary", ixval: IndexedTableValue) -> None:
110115
def operands(self) -> List[ARMOperand]:
111116
return [self.armd.arm_operand(self.args[i]) for i in [1, 2, 3, 4]]
112117

118+
@property
119+
def opargs(self) -> List[ARMOperand]:
120+
return [self.armd.arm_operand(self.args[i]) for i in [1, 2, 3, 4]]
121+
113122
def mnemonic_extension(self) -> str:
114123
cc = ARMOpcode.mnemonic_extension(self)
115124
wb = "S" if self.is_writeback else ""
@@ -125,3 +134,82 @@ def annotation(self, xdata: InstrXData) -> str:
125134
return xd.annotation
126135
else:
127136
return "Error value"
137+
138+
def ast_prov(
139+
self,
140+
astree: ASTInterface,
141+
iaddr: str,
142+
bytestring: str,
143+
xdata: InstrXData) -> Tuple[
144+
List[AST.ASTInstruction], List[AST.ASTInstruction]]:
145+
146+
annotations: List[str] = [iaddr, "UMLAL"]
147+
148+
# low-level assignment
149+
150+
(ll_lhslo, _, _) = self.opargs[0].ast_lvalue(astree)
151+
(ll_lhshi, _, _) = self.opargs[1].ast_lvalue(astree)
152+
(ll_lo, _, _) = self.opargs[0].ast_rvalue(astree)
153+
(ll_hi, _, _) = self.opargs[1].ast_rvalue(astree)
154+
(ll_rn, _, _) = self.opargs[2].ast_rvalue(astree)
155+
(ll_rm, _, _) = self.opargs[3].ast_rvalue(astree)
156+
157+
i32 = astree.mk_integer_constant(32)
158+
ll_rhs1 = astree.mk_doubleword_sum(ll_hi, ll_lo)
159+
ll_rhs2 = astree.mk_binary_op("mult", ll_rn, ll_rm)
160+
ll_rhs = astree.mk_binary_op("plus", ll_rhs2, ll_rhs1)
161+
ll_rhslo = astree.mk_binary_op("mod", ll_rhs, i32)
162+
ll_rhshi = astree.mk_binary_op("div", ll_rhs, i32)
163+
164+
ll_assign_lo = astree.mk_assign(
165+
ll_lhslo,
166+
ll_rhslo,
167+
iaddr=iaddr,
168+
bytestring=bytestring,
169+
annotations=annotations)
170+
171+
ll_assign_hi = astree.mk_assign(
172+
ll_lhshi,
173+
ll_rhshi,
174+
iaddr=iaddr,
175+
bytestring=bytestring,
176+
annotations=annotations)
177+
178+
rdefs = xdata.reachingdefs
179+
180+
astree.add_expr_reachingdefs(ll_rn, [rdefs[0]])
181+
astree.add_expr_reachingdefs(ll_rm, [rdefs[1]])
182+
astree.add_expr_reachingdefs(ll_lo, [rdefs[2]])
183+
astree.add_expr_reachingdefs(ll_hi, [rdefs[3]])
184+
185+
# high-level assignment
186+
187+
xd = ARMUnsignedMultiplyAccumulateLongXData(xdata)
188+
if not xd.is_ok:
189+
chklogger.logger.error(
190+
"Error value encountered for UMLAL at %s", iaddr)
191+
return ([], [])
192+
193+
hl_lhs = XU.xvariable_to_ast_lval(xd.vlo, xdata, iaddr, astree)
194+
hl_rhs = XU.xxpr_to_ast_def_expr(xd.rresult, xdata, iaddr, astree)
195+
196+
defuses = xdata.defuses
197+
defuseshigh = xdata.defuseshigh
198+
199+
hl_assign = astree.mk_assign(
200+
hl_lhs,
201+
hl_rhs,
202+
iaddr=iaddr,
203+
bytestring=bytestring,
204+
annotations=annotations)
205+
206+
astree.add_instr_mapping(hl_assign, ll_assign_lo)
207+
astree.add_instr_mapping(hl_assign, ll_assign_hi)
208+
astree.add_instr_address(hl_assign, [iaddr])
209+
astree.add_expr_mapping(hl_rhs, ll_rhslo)
210+
astree.add_lval_mapping(hl_lhs, ll_lhslo)
211+
astree.add_expr_reachingdefs(hl_rhs, rdefs[4:])
212+
astree.add_lval_defuses(hl_lhs, defuses[0])
213+
astree.add_lval_defuses_high(hl_lhs, defuseshigh[0])
214+
215+
return ([hl_assign], [ll_assign_lo, ll_assign_hi])

0 commit comments

Comments
 (0)