2525# SOFTWARE.
2626# ------------------------------------------------------------------------------
2727
28- from typing import List , Tuple , TYPE_CHECKING
28+ from typing import List , Optional , Tuple , TYPE_CHECKING
2929
3030from chb .app .InstrXData import InstrXData
3131
4545
4646if TYPE_CHECKING :
4747 from chb .arm .ARMDictionary import ARMDictionary
48+ from chb .invariants .VarInvariantFact import ReachingDefFact
4849 from chb .invariants .XVariable import XVariable
4950 from chb .invariants .XXpr import XXpr
5051
5152
5253class ARMAddCarryXData (ARMOpcodeXData ):
54+ """Adc <rd> <rn> <rm> ==> result
55+
56+ Data format (regular)
57+ - variables:
58+ 0: vrd
59+
60+ - expressions:
61+ 0: xrn
62+ 1: xrm
63+ 2: result
64+ 3: rresult (result, rewritten)
65+ 4: xxrn (xrn, rewritten)
66+ 5: xxrm (xrm, rewritten)
67+
68+ - c expressions:
69+ 0: cresult
70+
71+ rdefs[0]: xrn
72+ rdefs[1]: xrm
73+ rdefs[2:..]: reaching definitions for simplified result expression
74+ uses[0]: vrd
75+ useshigh[0]: vrd
76+
77+ Data format (as part of jump table)
78+ - expressions:
79+ 0: xrn
80+ 1: xxrn (xrn, rewritten)
81+
82+ rdefs[0]: xrn
83+ rdefs[1:]: reaching definitions for xxrn
84+ """
5385
5486 def __init__ (self , xdata : InstrXData ) -> None :
5587 ARMOpcodeXData .__init__ (self , xdata )
@@ -70,14 +102,57 @@ def xrm(self) -> "XXpr":
70102 def result (self ) -> "XXpr" :
71103 return self .xpr (2 , "result" )
72104
105+ @property
106+ def is_result_ok (self ) -> bool :
107+ return self .is_xpr_ok (2 )
108+
73109 @property
74110 def rresult (self ) -> "XXpr" :
75111 return self .xpr (3 , "rresult" )
76112
113+ @property
114+ def is_rresult_ok (self ) -> bool :
115+ return self .is_xpr_ok (3 )
116+
117+ @property
118+ def cresult (self ) -> "XXpr" :
119+ return self .cxpr (0 , "cresult" )
120+
121+ @property
122+ def is_cresult_ok (self ) -> bool :
123+ return self .is_cxpr_ok (0 )
124+
77125 @property
78126 def result_simplified (self ) -> str :
79- return simplify_result (
80- self .xdata .args [3 ], self .xdata .args [4 ], self .result , self .rresult )
127+ if self .is_result_ok and self .is_rresult_ok :
128+ return simplify_result (
129+ self .xdata .args [3 ], self .xdata .args [4 ], self .result , self .rresult )
130+ else :
131+ return str (self .xrn ) + " + " + str (self .xrm )
132+
133+ @property
134+ def xxrn (self ) -> "XXpr" :
135+ return self .xpr (4 , "xxrn" )
136+
137+ @property
138+ def is_xxrn_ok (self ) -> bool :
139+ return self .is_xpr_ok (4 )
140+
141+ @property
142+ def xxrm (self ) -> "XXpr" :
143+ return self .xpr (5 , "xxrm" )
144+
145+ @property
146+ def is_xxrm_ok (self ) -> bool :
147+ return self .is_xpr_ok (5 )
148+
149+ @property
150+ def rn_rdef (self ) -> Optional ["ReachingDefFact" ]:
151+ return self ._xdata .reachingdefs [0 ]
152+
153+ @property
154+ def rm_rdef (self ) -> Optional ["ReachingDefFact" ]:
155+ return self ._xdata .reachingdefs [1 ]
81156
82157 @property
83158 def annotation (self ) -> str :
@@ -135,10 +210,7 @@ def mnemonic_extension(self) -> str:
135210
136211 def annotation (self , xdata : InstrXData ) -> str :
137212 xd = ARMAddCarryXData (xdata )
138- if xd .is_ok :
139- return xd .annotation
140- else :
141- return "Error value"
213+ return xd .annotation
142214
143215 def ast_prov (
144216 self ,
@@ -150,15 +222,6 @@ def ast_prov(
150222
151223 annotations : List [str ] = [iaddr , "ADC" ]
152224
153- lhs = xdata .vars [0 ]
154- rhs1 = xdata .xprs [0 ]
155- rhs2 = xdata .xprs [1 ]
156- rhssum = xdata .xprs [2 ]
157- rhs3 = xdata .xprs [3 ]
158- rdefs = xdata .reachingdefs
159- defuses = xdata .defuses
160- defuseshigh = xdata .defuseshigh
161-
162225 # low-level assignment
163226
164227 (ll_lhs , _ , _ ) = self .operands [0 ].ast_lvalue (astree )
@@ -180,22 +243,41 @@ def ast_prov(
180243
181244 # high-level assignment
182245
246+ def has_cast () -> bool :
247+ return (
248+ astree .has_register_variable_intro (iaddr )
249+ and astree .get_register_variable_intro (iaddr ).has_cast ())
250+
183251 xd = ARMAddCarryXData (xdata )
184- if not xdata .is_ok :
252+
253+ if xd .is_cresult_ok and xd .is_rresult_ok :
254+ rhs = xd .cresult
255+ xrhs = xd .rresult
256+
257+ elif xd .is_rresult_ok :
258+ rhs = xd .rresult
259+ xrhs = xd .rresult
260+
261+ elif xd .is_result_ok :
262+ rhs = xd .result
263+ xrhs = xd .result
264+
265+ else :
185266 chklogger .logger .error (
186- "Encountered error value at address %s" , iaddr )
187- return ([], [])
267+ "ADC: Encountered error value for rhs at address %s" , iaddr )
268+ return ([], [ll_assign ])
188269
189270 lhs = xd .vrd
190271 rhs1 = xd .xrn
191272 rhs2 = xd .xrm
192- rhs3 = xd .rresult
273+ rrhs1 = xd .xxrn if xd .is_xxrn_ok else xd .xrn
274+ rrhs2 = xd .xxrm if xd .is_xxrm_ok else xd .xrm
193275
194276 defuses = xdata .defuses
195277 defuseshigh = xdata .defuseshigh
196278
197279 hl_lhs = XU .xvariable_to_ast_lval (lhs , xdata , iaddr , astree )
198- hl_rhs = XU .xxpr_to_ast_def_expr (rhs3 , xdata , iaddr , astree )
280+ hl_rhs = XU .xxpr_to_ast_def_expr (rhs , xdata , iaddr , astree )
199281
200282 hl_assign = astree .mk_assign (
201283 hl_lhs ,
@@ -213,4 +295,9 @@ def ast_prov(
213295 astree .add_lval_defuses (hl_lhs , defuses [0 ])
214296 astree .add_lval_defuses_high (hl_lhs , defuseshigh [0 ])
215297
298+ if astree .has_register_variable_intro (iaddr ):
299+ rvintro = astree .get_register_variable_intro (iaddr )
300+ if rvintro .has_cast ():
301+ astree .add_expose_instruction (hl_assign .instrid )
302+
216303 return ([hl_assign ], [ll_assign ])
0 commit comments