44# ------------------------------------------------------------------------------
55# The MIT License (MIT)
66#
7- # Copyright (c) 2021-2023 Aarno Labs LLC
7+ # Copyright (c) 2021-2025 Aarno Labs LLC
88#
99# Permission is hereby granted, free of charge, to any person obtaining a copy
1010# of this software and associated documentation files (the "Software"), to deal
3030from chb .app .InstrXData import InstrXData
3131
3232from chb .arm .ARMDictionaryRecord import armregistry
33- from chb .arm .ARMOpcode import ARMOpcode , simplify_result
33+ from chb .arm .ARMOpcode import ARMOpcode , ARMOpcodeXData , simplify_result
3434from chb .arm .ARMOperand import ARMOperand
3535
3636import chb .ast .ASTNode as AST
4040import chb .invariants .XXprUtil as XU
4141
4242import chb .util .fileutil as UF
43-
4443from chb .util .IndexedTable import IndexedTableValue
44+ from chb .util .loggingutil import chklogger
4545
4646if TYPE_CHECKING :
47- import chb .arm .ARMDictionary
47+ from chb .arm .ARMDictionary import ARMDictionary
48+ from chb .invariants .XVariable import XVariable
49+ from chb .invariants .XXpr import XXpr
50+
51+
52+ class ARMAddCarryXData (ARMOpcodeXData ):
53+
54+ def __init__ (self , xdata : InstrXData ) -> None :
55+ ARMOpcodeXData .__init__ (self , xdata )
56+
57+ @property
58+ def vrd (self ) -> "XVariable" :
59+ return self .var (0 , "vrd" )
60+
61+ @property
62+ def xrn (self ) -> "XXpr" :
63+ return self .xpr (0 , "xrn" )
64+
65+ @property
66+ def xrm (self ) -> "XXpr" :
67+ return self .xpr (1 , "xrm" )
68+
69+ @property
70+ def result (self ) -> "XXpr" :
71+ return self .xpr (2 , "result" )
72+
73+ @property
74+ def rresult (self ) -> "XXpr" :
75+ return self .xpr (3 , "rresult" )
76+
77+ @property
78+ def result_simplified (self ) -> str :
79+ return simplify_result (
80+ self .xdata .args [3 ], self .xdata .args [4 ], self .result , self .rresult )
81+
82+ @property
83+ def annotation (self ) -> str :
84+ assignment = str (self .vrd ) + " := " + self .result_simplified
85+ return self .add_instruction_condition (assignment )
4886
4987
5088@armregistry .register_tag ("ADC" , ARMOpcode )
@@ -73,10 +111,7 @@ class ARMAddCarry(ARMOpcode):
73111 useshigh[0]: lhs
74112 """
75113
76- def __init__ (
77- self ,
78- d : "chb.arm.ARMDictionary.ARMDictionary" ,
79- ixval : IndexedTableValue ) -> None :
114+ def __init__ (self , d : "ARMDictionary" , ixval : IndexedTableValue ) -> None :
80115 ARMOpcode .__init__ (self , d , ixval )
81116 self .check_key (2 , 5 , "AddCarry" )
82117
@@ -99,18 +134,11 @@ def mnemonic_extension(self) -> str:
99134 return wb + cc + wide
100135
101136 def annotation (self , xdata : InstrXData ) -> str :
102- lhs = str (xdata .vars [0 ])
103- result = xdata .xprs [2 ]
104- rresult = xdata .xprs [3 ]
105- xresult = simplify_result (xdata .args [3 ], xdata .args [4 ], result , rresult )
106- assignment = lhs + " := " + xresult
107- if xdata .has_unknown_instruction_condition ():
108- return "if ? then " + assignment
109- elif xdata .has_instruction_condition ():
110- c = str (xdata .xprs [1 ])
111- return "if " + c + " then " + assignment
137+ xd = ARMAddCarryXData (xdata )
138+ if xd .is_ok :
139+ return xd .annotation
112140 else :
113- return assignment
141+ return "Error value"
114142
115143 def ast_prov (
116144 self ,
@@ -131,6 +159,8 @@ def ast_prov(
131159 defuses = xdata .defuses
132160 defuseshigh = xdata .defuseshigh
133161
162+ # low-level assignment
163+
134164 (ll_lhs , _ , _ ) = self .operands [0 ].ast_lvalue (astree )
135165 (ll_op1 , _ , _ ) = self .operands [1 ].ast_rvalue (astree )
136166 (ll_op2 , _ , _ ) = self .operands [2 ].ast_rvalue (astree )
@@ -143,27 +173,29 @@ def ast_prov(
143173 bytestring = bytestring ,
144174 annotations = annotations )
145175
146- lhsasts = XU .xvariable_to_ast_lvals (lhs , xdata , astree )
147- if len (lhsasts ) == 0 :
148- raise UF .CHBError ("Adc: no lval found" )
176+ rdefs = xdata .reachingdefs
177+
178+ astree .add_expr_reachingdefs (ll_op1 , [rdefs [0 ]])
179+ astree .add_expr_reachingdefs (ll_op2 , [rdefs [1 ]])
149180
150- if len (lhsasts ) > 1 :
151- raise UF .CHBError (
152- "Adc: multiple lvals in ast: "
153- + ", " .join (str (v ) for v in lhsasts ))
181+ # high-level assignment
154182
155- hl_lhs = lhsasts [0 ]
183+ xd = ARMAddCarryXData (xdata )
184+ if not xdata .is_ok :
185+ chklogger .logger .error (
186+ "Encountered error value at address %s" , iaddr )
187+ return ([], [])
156188
157- rhsasts = XU .xxpr_to_ast_def_exprs (rhs3 , xdata , iaddr , astree )
158- if len (rhsasts ) == 0 :
159- raise UF .CHBError ("Adc: no rhs value found" )
189+ lhs = xd .vrd
190+ rhs1 = xd .xrn
191+ rhs2 = xd .xrm
192+ rhs3 = xd .rresult
160193
161- if len (rhsasts ) > 1 :
162- raise UF .CHBError (
163- "Multiple rhs values found for Adc: "
164- + ", " .join (str (v ) for v in rhsasts ))
194+ defuses = xdata .defuses
195+ defuseshigh = xdata .defuseshigh
165196
166- hl_rhs = rhsasts [0 ]
197+ hl_lhs = XU .xvariable_to_ast_lval (lhs , xdata , iaddr , astree )
198+ hl_rhs = XU .xxpr_to_ast_def_expr (rhs3 , xdata , iaddr , astree )
167199
168200 hl_assign = astree .mk_assign (
169201 hl_lhs ,
@@ -172,14 +204,12 @@ def ast_prov(
172204 bytestring = bytestring ,
173205 annotations = annotations )
174206
175- astree .add_reg_definition (iaddr , hl_lhs , hl_rhs )
176207 astree .add_instr_mapping (hl_assign , ll_assign )
177208 astree .add_instr_address (hl_assign , [iaddr ])
178209 astree .add_expr_mapping (hl_rhs , ll_rhs )
179210 astree .add_lval_mapping (hl_lhs , ll_lhs )
180- astree .add_expr_reachingdefs (ll_rhs , [rdefs [0 ], rdefs [1 ]])
181- astree .add_expr_reachingdefs (ll_op1 , [rdefs [0 ]])
182- astree .add_expr_reachingdefs (ll_op2 , [rdefs [1 ]])
211+ astree .add_expr_reachingdefs (hl_rhs , rdefs [2 :])
212+ astree .add_expr_reachingdefs (ll_rhs , rdefs [:2 ])
183213 astree .add_lval_defuses (hl_lhs , defuses [0 ])
184214 astree .add_lval_defuses_high (hl_lhs , defuseshigh [0 ])
185215
0 commit comments