Skip to content

Commit 080c833

Browse files
committed
ARM:LDM: update for conversion to C expressions
1 parent e0a51bc commit 080c833

File tree

1 file changed

+134
-22
lines changed

1 file changed

+134
-22
lines changed

chb/arm/opcodes/ARMLoadMultipleIncrementAfter.py

Lines changed: 134 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
# SOFTWARE.
2626
# ------------------------------------------------------------------------------
2727

28-
from typing import List, Tuple, TYPE_CHECKING
28+
from typing import Iterable, List, Tuple, TYPE_CHECKING
2929

3030
from chb.app.InstrXData import InstrXData
3131

@@ -49,6 +49,20 @@
4949

5050

5151
class 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

Comments
 (0)