2525# SOFTWARE.
2626# ------------------------------------------------------------------------------
2727
28- from typing import List , TYPE_CHECKING
28+ from typing import List , Tuple , TYPE_CHECKING
2929
3030from chb .app .InstrXData import InstrXData
3131
3232from chb .arm .ARMDictionaryRecord import armregistry
3333from chb .arm .ARMOpcode import ARMOpcode , ARMOpcodeXData , simplify_result
3434from 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+
3641import chb .util .fileutil as UF
3742from chb .util .IndexedTable import IndexedTableValue
3843from 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