2525# SOFTWARE.
2626# ------------------------------------------------------------------------------
2727
28- from typing import cast , List , TYPE_CHECKING , Tuple
28+ from typing import cast , Iterable , List , TYPE_CHECKING , Tuple
2929
3030from chb .app .InstrXData import InstrXData
3131
5252
5353
5454class ARMStoreMultipleIncrementAfterXData (ARMOpcodeXData ):
55+ """Data format:
56+ - variables:
57+ 0: baselhs
58+ 1..n: memlhss
59+
60+ - c variables:
61+ 1..n: cmemlhss
62+
63+ - expressions:
64+ 0: baserhs
65+ 1..n: rhss
66+ n+1..2n: rrhss
67+ 2n+1..3n: xaddrs
68+
69+ - c expressions:
70+ 0..n-1: crhss
71+ n..2n-1: cxaddrs
72+ """
5573
5674 def __init__ (self , xdata : InstrXData ) -> None :
5775 ARMOpcodeXData .__init__ (self , xdata )
@@ -71,32 +89,48 @@ def xdst(self) -> "XXpr":
7189 return self .ldmstm_xpr (0 , "xdst" )
7290
7391 @property
74- def is_xdst_unknown (self ) -> bool :
75- return self .xdata . xprs_r [ 0 ] is None
92+ def is_xdst_ok (self ) -> bool :
93+ return self .is_xpr_ok ( 0 )
7694
7795 @property
7896 def xsrc (self ) -> "XXpr" :
7997 return self .ldmstm_xpr (1 , "xsrc" )
8098
8199 @property
82- def is_xsrc_unknowns (self ) -> bool :
83- return self .xdata . xprs_r [ 1 ] is None
100+ def is_xsrc_ok (self ) -> bool :
101+ return self .is_xpr_ok ( 1 )
84102
85103 @property
86104 def xxdst (self ) -> "XXpr" :
87105 return self .ldmstm_xpr (2 , "xxdst" )
88106
89107 @property
90- def is_xxdst_unknown (self ) -> bool :
91- return self .xdata . xprs_r [ 2 ] is None
108+ def is_xxdst_ok (self ) -> bool :
109+ return self .is_xpr_ok ( 2 )
92110
93111 @property
94112 def xxsrc (self ) -> "XXpr" :
95113 return self .ldmstm_xpr (3 , "xxsrc" )
96114
97115 @property
98- def is_xxsrc_unknown (self ) -> bool :
99- return self .xdata .xprs_r [3 ] is None
116+ def is_xxsrc_ok (self ) -> bool :
117+ return self .is_xpr_ok (3 )
118+
119+ @property
120+ def cdst (self ) -> "XXpr" :
121+ return self .cxpr (0 , "cdst" )
122+
123+ @property
124+ def is_cdst_ok (self ) -> bool :
125+ return self .is_cxpr_ok (0 )
126+
127+ @property
128+ def csrc (self ) -> "XXpr" :
129+ return self .cxpr (1 , "csrc" )
130+
131+ @property
132+ def is_csrc_ok (self ) -> bool :
133+ return self .is_cxpr_ok (1 )
100134
101135 @property
102136 def copysize (self ) -> int :
@@ -114,16 +148,64 @@ def baselhs(self) -> "XVariable":
114148 return self .var (0 , "baselhs" )
115149
116150 @property
117- def is_baselhs_known (self ) -> bool :
118- return self .xdata . vars_r [ 0 ] is not None
151+ def memlhs_range (self ) -> Iterable [ int ] :
152+ return range ( 1 , self .regcount + 1 )
119153
120154 @property
121155 def memlhss (self ) -> List ["XVariable" ]:
122- return [self .var (i , "memlhs-" + str (i )) for i in range (1 , self .regcount + 1 )]
156+ return [self .var (i , "memlhs" ) for i in self .memlhs_range ]
157+
158+ @property
159+ def are_memlhss_ok (self ) -> bool :
160+ return all (self .is_var_ok (i ) for i in self .memlhs_range )
161+
162+ @property
163+ def cmemlhs_range (self ) -> Iterable [int ]:
164+ return range (0 , self .regcount )
165+
166+ @property
167+ def cmemlhss (self ) -> List ["XVariable" ]:
168+ return [self .cvar (i , "cmemlhs" ) for i in self .cmemlhs_range ]
169+
170+ @property
171+ def are_cmemlhss_ok (self ) -> bool :
172+ return all (self .is_cvar_ok (i ) for i in self .cmemlhs_range )
173+
174+ @property
175+ def rhs_range (self ) -> Iterable [int ]:
176+ return range (1 , self .regcount + 1 )
123177
124178 @property
125179 def rhss (self ) -> List ["XXpr" ]:
126- return [self .xpr (i , "rhs-" + str (i )) for i in range (3 , self .regcount + 3 )]
180+ return [self .xpr (i , "rhs" ) for i in self .rhs_range ]
181+
182+ @property
183+ def are_rhss_ok (self ) -> bool :
184+ return all (self .is_xpr_ok (i ) for i in self .rhs_range )
185+
186+ @property
187+ def rrhs_range (self ) -> Iterable [int ]:
188+ return range (self .regcount + 1 , (2 * self .regcount ) + 1 )
189+
190+ @property
191+ def rrhss (self ) -> List ["XXpr" ]:
192+ return [self .xpr (i , "rrhs" ) for i in self .rrhs_range ]
193+
194+ @property
195+ def are_rrhss_ok (self ) -> bool :
196+ return all (self .is_xpr_ok (i ) for i in self .rrhs_range )
197+
198+ @property
199+ def crhs_range (self ) -> Iterable [int ]:
200+ return range (0 , self .regcount )
201+
202+ @property
203+ def crhss (self ) -> List ["XXpr" ]:
204+ return [self .cxpr (i , "crhs" ) for i in self .crhs_range ]
205+
206+ @property
207+ def are_crhss_ok (self ) -> bool :
208+ return all (self .is_cxpr_ok (i ) for i in self .crhs_range )
127209
128210 @property
129211 def annotation (self ) -> str :
@@ -144,23 +226,26 @@ def annotation(self) -> str:
144226 return "; " .join (assigns )
145227 else :
146228 if self .is_ldmstm_aggregate :
147- if self .is_xxdst_unknown and self .is_xxsrc_unknown :
148- dst = str (self .xdst )
149- src = str (self .xsrc )
150- elif self .is_xxdst_unknown :
229+ if self .is_xxdst_ok :
230+ dst = str (self .xxdst )
231+ elif self .is_xdst_ok :
151232 dst = str (self .xdst )
152- src = str (self .xxsrc )
153233 else :
154- dst = str (self .xxdst )
234+ dst = "dst:error value"
235+ if self .is_xxsrc_ok :
236+ src = str (self .xxsrc )
237+ elif self .is_xsrc_ok :
155238 src = str (self .xsrc )
239+ else :
240+ src = "src:error value"
156241 return (
157- "memcpy("
158- + dst
159- + ", "
160- + src
161- + ", "
162- + str (self .copysize )
163- + ")" )
242+ "memcpy("
243+ + dst
244+ + ", "
245+ + src
246+ + ", "
247+ + str (self .copysize )
248+ + ")" )
164249 else :
165250 return "not yet supported"
166251
@@ -180,12 +265,6 @@ class ARMStoreMultipleIncrementAfter(ARMOpcode):
180265
181266 xdata:
182267 ----------------------------------------
183- vars[0]: base
184- vars[1..n]: lhs memory locations where values are stored
185- xprs[0]: base
186- xprs[1]: updated base (may be unchanged in case of no writeback)
187- xprs[2]: updated base (simplified)
188- xprs[3..n+2]: values of registers being stored (simplified)
189268 rdefs[0]: reaching definition base register
190269 rdefs[1..n]: reaching definitions of registers being stored
191270 uses[0]: use of base register
@@ -290,20 +369,9 @@ def ast_prov_ldmstmcopy(
290369 # high-level call
291370
292371 xd = ARMStoreMultipleIncrementAfterXData (xdata )
293- if not xd .is_ok :
294- if xd .is_xxsrc_unknown and xd .is_xxdst_unknown :
295- chklogger .logger .error (
296- "LDM-STM-memcpy: (%s): src and dst unknown" , iaddr )
297- elif xd .is_xxsrc_unknown :
298- chklogger .logger .error ("LDM-STM-memcpy: (%s): src unknown" , iaddr )
299- else :
300- chklogger .logger .error ("LDM-STM-memcpy: (%s): dst unknown" , iaddr )
301- return ([], [])
302372
303373 xdst = xd .xdst
304374 xsrc = xd .xsrc
305- xxdst = xd .xxdst
306- xxsrc = xd .xxsrc
307375 xsize = xd .copysize
308376
309377 # low-level arguments
@@ -322,6 +390,16 @@ def ast_prov_ldmstmcopy(
322390
323391 # high-level arguments
324392
393+ if xd .is_xxdst_ok :
394+ xxdst = xd .xxdst
395+ else :
396+ xxdst = xdst
397+
398+ if xd .is_xxsrc_ok :
399+ xxsrc = xd .xxsrc
400+ else :
401+ xxsrc = xsrc
402+
325403 if xxdst .is_stack_address :
326404 offset = xxdst .stack_address_offset ()
327405 stackvar = astree .mk_stack_variable_lval (offset )
0 commit comments