2525# SOFTWARE.
2626# ------------------------------------------------------------------------------
2727
28- from typing import List , Tuple , TYPE_CHECKING
28+ from typing import Iterable , List , Tuple , TYPE_CHECKING
2929
3030from chb .app .InstrXData import InstrXData
3131
4949
5050
5151class ARMLoadMultipleIncrementAfterXData (ARMOpcodeXData ):
52+ """Data format:
53+ - variables:
54+ 0: baselhs
55+ 1..n: lhsvars
56+
57+ - expressions:
58+ 0: baserhs
59+ 1..n: memrhss
60+ n+1..2n: rmemrhss (memrhss, rewritten)
61+ 2n+1..3n: xaddrs
62+
63+ - c expressions:
64+ 0..n-1: cmemrhss
65+ """
5266
5367 def __init__ (self , xdata : InstrXData ) -> None :
5468 ARMOpcodeXData .__init__ (self , xdata )
@@ -57,6 +71,23 @@ def __init__(self, xdata: InstrXData) -> None:
5771 def regcount (self ) -> int :
5872 return len (self .xdata .vars_r ) - 1
5973
74+ def has_index (self , index : int ) -> bool :
75+ """returns true if index is between 1 and regcount (inclusive)."""
76+
77+ return index > 0 and index <= self .regcount
78+
79+ @property
80+ def memrhs_range (self ) -> Iterable [int ]:
81+ return range (1 , self .regcount + 1 )
82+
83+ @property
84+ def rmemrhs_range (self ) -> Iterable [int ]:
85+ return range (self .regcount + 1 , (2 * self .regcount ) + 1 )
86+
87+ @property
88+ def xaddr_range (self ) -> Iterable [int ]:
89+ return range ((2 * self .regcount ) + 1 , (3 * self .regcount ) + 1 )
90+
6091 @property
6192 def baselhs (self ) -> "XVariable" :
6293 return self .var (0 , "baselhs" )
@@ -65,23 +96,106 @@ def baselhs(self) -> "XVariable":
6596 def lhsvars (self ) -> List ["XVariable" ]:
6697 return [self .var (i , "lhsvar" ) for i in range (1 , self .regcount + 1 )]
6798
99+ def lhsvar (self , index : int ) -> "XVariable" :
100+ """returns the lhsvar at (1-based) position index"""
101+
102+ if self .has_index (index ):
103+ return self .lhsvars [index ]
104+ else :
105+ raise UF .CHBError ("LDM: index out of bounds: " + str (index ))
106+
68107 @property
69108 def baserhs (self ) -> "XXpr" :
70109 return self .xpr (0 , "baserhs" )
71110
72111 @property
73- def rhsexprs (self ) -> List ["XXpr" ]:
74- return [self .xpr (i , "rhsexpr" ) for i in range (1 , self .regcount + 1 )]
112+ def memrhss (self ) -> List ["XXpr" ]:
113+ return [self .xpr (i , "memrhs" ) for i in self .memrhs_range ]
114+
115+ @property
116+ def are_memrhss_ok (self ) -> bool :
117+ return all (self .is_xpr_ok (i ) for i in self .memrhs_range )
118+
119+ def memrhs (self , index ) -> "XXpr" :
120+ """returns the rhs expression at (1-based) position index"""
121+
122+ if self .has_index (index ):
123+ if self .are_memrhss_ok :
124+ return self .memrhss [index - 1 ]
125+ else :
126+ raise UF .CHBError ("LDM: memrhss have error values" )
127+ else :
128+ raise UF .CHBError ("LDM: index out of bounds for memrhs" )
129+
130+ @property
131+ def rmemrhss (self ) -> List ["XXpr" ]:
132+ return [self .xpr (i , "rmemrhs" ) for i in self .rmemrhs_range ]
133+
134+ @property
135+ def are_rmemrhss_ok (self ) -> bool :
136+ return all (self .is_xpr_ok (i ) for i in self .rmemrhs_range )
137+
138+ def rmemrhs (self , index ) -> "XXpr" :
139+ """returns the rewritten rhs expr at (1-based) position index"""
140+
141+ if self .has_index (index ):
142+ if self .are_rmemrhss_ok :
143+ return self .rmemrhss [index - 1 ]
144+ else :
145+ raise UF .CHBError ("LDM: rmemrhss have error values" )
146+ else :
147+ raise UF .CHBError ("LDM: index out of bounds for rmemrhs" )
75148
76149 @property
77150 def xaddrs (self ) -> List ["XXpr" ]:
78- return [self .xpr (i , "xaddr" )
79- for i in range (self .regcount + 1 , (2 * self .regcount ) + 3 )]
151+ return [self .xpr (i , "xaddr" ) for i in self .xaddr_range ]
152+
153+ @property
154+ def are_xaddrs_ok (self ) -> bool :
155+ return all (self .is_xpr_ok (i ) for i in self .xaddr_range )
156+
157+ def xaddr (self , index ) -> "XXpr" :
158+ """returns the rhs addr at (1-based) position index"""
159+
160+ if self .has_index (index ):
161+ if self .are_xaddrs_ok :
162+ return self .xaddrs [index - 1 ]
163+ else :
164+ raise UF .CHBError ("LDM: xaddrs have error values" )
165+ else :
166+ raise UF .CHBError ("LDM: index out of bounds for xaddr" )
167+
168+ @property
169+ def cmemrhss (self ) -> List ["XXpr" ]:
170+ return [self .cxpr (i , "cmemrhs" ) for i in range (0 , self .regcount )]
171+
172+ @property
173+ def are_cmemrhss_ok (self ) -> bool :
174+ return all (self .is_cxpr_ok (i ) for i in range (0 , self .regcount ))
175+
176+ def cmemrhs (self , index ) -> "XXpr" :
177+ """returns the rhs addr at (1-based) position index"""
178+
179+ if self .has_index (index ):
180+ if self .are_cmemrhss_ok :
181+ return self .cmemrhss [index - 1 ]
182+ else :
183+ raise UF .CHBError ("LDM: cmemrhss have error values" )
184+ else :
185+ raise UF .CHBError ("LDM: index out of bounds cmemrhs" )
80186
81187 @property
82188 def annotation (self ) -> str :
83- pairs = zip (self .lhsvars , self .rhsexprs )
84- assigns = "; " .join (str (v ) + " := " + str (x ) for (x , v ) in pairs )
189+ if self .are_rmemrhss_ok :
190+ pairs = list (zip (self .lhsvars , self .rmemrhss ))
191+ elif self .are_memrhss_ok :
192+ pairs = list (zip (self .lhsvars , self .memrhss ))
193+ else :
194+ pairs = []
195+ if len (pairs ) > 0 :
196+ assigns = "; " .join (str (v ) + " := " + str (x ) for (x , v ) in pairs )
197+ else :
198+ assigns = "unknown rhs memory"
85199 wbu = self .writeback_update ()
86200 return self .add_instruction_condition (assigns + wbu )
87201
@@ -98,14 +212,8 @@ class ARMLoadMultipleIncrementAfter(ARMOpcode):
98212 args[2]: index of registers in arm dictionary
99213 args[3]: index of base memory address
100214
101- xdata format: vv[n]xxxx[n]rr[n]dd[n]hh[n]
102- ----------------------------------------
103- vars[0]: base lhs
104- vars[1..n]: register lhss
105- xprs[0]: base rhs
106- xprs[1]: updated base (may be unchanged in case of no writeback)
107- xprs[2]: updated base (simplified)
108- xprs[3..n+2]: values of memory locations read
215+ xdata format:
216+ -------------
109217 rdefs[0]: reaching definition base register
110218 rdefs[1..n]: reaching definition memory locations
111219 uses[0]: base lhs
@@ -143,10 +251,7 @@ def is_load_instruction(self, xdata: InstrXData) -> bool:
143251
144252 def annotation (self , xdata : InstrXData ) -> str :
145253 xd = ARMLoadMultipleIncrementAfterXData (xdata )
146- if xd .is_ok :
147- return xd .annotation
148- else :
149- return "Error value"
254+ return xd .annotation
150255
151256 # -------------------------------------------------------------------------
152257 # address = R[n];
@@ -168,15 +273,22 @@ def ast_prov(
168273 List [AST .ASTInstruction ], List [AST .ASTInstruction ]]:
169274
170275 xd = ARMLoadMultipleIncrementAfterXData (xdata )
171- if not xd .is_ok :
276+
277+ if xd .are_cmemrhss_ok :
278+ rhsexprs = xd .cmemrhss
279+ elif xd .are_rmemrhss_ok :
280+ rhsexprs = xd .rmemrhss
281+ elif xd .are_memrhss_ok :
282+ rhsexprs = xd .memrhss
283+
284+ else :
172285 chklogger .logger .error (
173- "Error value encountered at address %s" , iaddr )
286+ "LDM: Error value encountered at address %s" , iaddr )
174287 return ([], [])
175288
176289 baselhs = xd .baselhs
177290 lhsvars = xd .lhsvars
178291 baserhs = xd .baserhs
179- rhsexprs = xd .rhsexprs
180292
181293 baserdef = xdata .reachingdefs [0 ]
182294 memrdefs = xdata .reachingdefs [1 :]
0 commit comments