Skip to content

Commit c3e3d81

Browse files
committed
ARM:STRH: update for conversion to C expressions
1 parent c8e85d2 commit c3e3d81

File tree

1 file changed

+103
-33
lines changed

1 file changed

+103
-33
lines changed

chb/arm/opcodes/ARMStoreRegisterHalfword.py

Lines changed: 103 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,25 @@
5151

5252

5353
class ARMStoreRegisterHalfwordXData(ARMOpcodeXData):
54+
"""Data format:
55+
- variables:
56+
0: vmem_r (lhs)
57+
58+
- c variables:
59+
0: cvmem_r (lhs)
60+
61+
- expressions:
62+
0: xrn
63+
1: xrm
64+
2: xrt (rhs)
65+
3: xxrt (rhs, rewritten)
66+
4: xaddr (lhs address)
67+
5: xxaddr (lhs address, rewritten)
68+
69+
- c expressions:
70+
0: cxrt (rhs)
71+
1: cxaddr (lhs address)
72+
"""
5473

5574
def __init__(self, xdata: InstrXData) -> None:
5675
ARMOpcodeXData.__init__(self, xdata)
@@ -60,8 +79,16 @@ def vmem(self) -> "XVariable":
6079
return self.var(0, "vmem")
6180

6281
@property
63-
def is_vmem_unknown(self) -> bool:
64-
return self.xdata.vars_r[0] is None
82+
def is_vmem_ok(self) -> bool:
83+
return self.is_var_ok(0)
84+
85+
@property
86+
def cvmem(self) -> "XVariable":
87+
return self.cvar(0, "cvmem")
88+
89+
@property
90+
def is_cvmem_ok(self) -> bool:
91+
return self.is_cvar_ok(0)
6592

6693
@property
6794
def xrn(self) -> "XXpr":
@@ -80,31 +107,65 @@ def xxrt(self) -> "XXpr":
80107
return self.xpr(3, "xxrt")
81108

82109
@property
83-
def is_xxrt_known(self) -> bool:
84-
return self.xdata.xprs_r[3] is not None
110+
def is_xxrt_ok(self) -> bool:
111+
return self.is_xpr_ok(3)
112+
113+
@property
114+
def cxrt(self) -> "XXpr":
115+
return self.cxpr(0, "cxrt")
116+
117+
@property
118+
def is_cxrt_ok(self) -> bool:
119+
return self.is_cxpr_ok(0)
85120

86121
@property
87122
def xaddr(self) -> "XXpr":
88123
return self.xpr(4, "xaddr")
89124

90125
@property
91-
def is_address_known(self) -> bool:
92-
return self.xdata.xprs_r[4] is not None
126+
def is_xaddr_ok(self) -> "bool":
127+
return self.is_xpr_ok(4)
128+
129+
@property
130+
def xxaddr(self) -> "XXpr":
131+
return self.xpr(5, "xxaddr")
132+
133+
@property
134+
def is_xxaddr_ok(self) -> bool:
135+
return self.is_xpr_ok(5)
136+
137+
@property
138+
def cxaddr(self) -> "XXpr":
139+
return self.cxpr(1, "cxaddr")
140+
141+
@property
142+
def is_cxaddr_ok(self) -> bool:
143+
return self.is_cxpr_ok(1)
93144

94145
@property
95146
def annotation(self) -> str:
96147
wbu = self.writeback_update()
97-
if self.is_ok:
98-
assignment = str(self.vmem) + " := " + str(self.xxrt)
99-
elif not self.is_xxrt_known:
100-
assignment = "(*" + str(self.xaddr) + ") := " + str(self.xrt)
101-
elif self.is_vmem_unknown and self.is_address_known:
102-
assignment = "*(" + str(self.xaddr) + ") := " + str(self.xxrt)
148+
clhs = str(self.cvmem) if self.is_cvmem_ok else "None"
149+
crhs = str(self.cxrt) if self.is_cxrt_ok else "None"
150+
assignc = "(C: " + clhs + " := " + crhs + ")"
151+
if self.is_vmem_ok:
152+
lhs = str(self.vmem)
153+
elif self.is_xxaddr_ok:
154+
lhs = "*(" + str(self.xxaddr) + ")"
155+
elif self.is_xaddr_ok:
156+
lhs = "*(" + str(self.xaddr) + ")"
157+
else:
158+
lhs = "Error addr"
159+
if self.is_xxrt_ok:
160+
rhs = str(self.xxrt)
103161
else:
104-
assignment = "Error value"
162+
rhs = "Error value"
163+
assign = lhs + " := " + rhs
164+
assignment = assign + " " + assignc
105165
return self.add_instruction_condition(assignment + wbu)
106166

107167

168+
108169
@armregistry.register_tag("STRH", ARMOpcode)
109170
class ARMStoreRegisterHalfword(ARMOpcode):
110171
"""Stores the least significant halfword from a register into memory.
@@ -118,15 +179,8 @@ class ARMStoreRegisterHalfword(ARMOpcode):
118179
args[3]: index of memory location in armdictionary
119180
args[4]: is-wide (thumb)
120181
121-
xdata format: a:vxxxxrrrdh
122-
--------------------------
123-
vars[0]: lhs
124-
xprs[0]: xrn (base register)
125-
xprs[1]: xrm (index)
126-
xprs[2]: xrt (rhs, source register)
127-
xprs[3]: xrt (rhs, simplified)
128-
xprs[4]: address of memory location
129-
xprs[5]: condition (if TC is set)
182+
xdata format:
183+
-------------
130184
rdefs[0]: rn
131185
rdefs[1]: rm
132186
rdefs[2]: rt
@@ -193,24 +247,40 @@ def ast_prov(
193247

194248
xd = ARMStoreRegisterHalfwordXData(xdata)
195249

196-
if xd.is_ok:
250+
if xd.is_cvmem_ok:
251+
lhs = xd.cvmem
252+
hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree)
253+
254+
elif xd.is_vmem_ok:
197255
lhs = xd.vmem
198-
memaddr = xd.xaddr
199-
hl_lhs = XU.xvariable_to_ast_lval(
200-
lhs, xdata, iaddr, astree, memaddr=memaddr)
256+
hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree)
201257

202-
elif xd.is_vmem_unknown and xd.is_address_known:
258+
elif xd.is_cxaddr_ok:
259+
memaddr = xd.cxaddr
260+
hl_lhs = XU.xmemory_dereference_lval(memaddr, xdata, iaddr, astree)
261+
262+
elif xd.is_xxaddr_ok:
263+
memaddr = xd.xxaddr
264+
hl_lhs = XU.xmemory_dereference_lval(memaddr, xdata, iaddr, astree)
265+
266+
elif xd.is_xaddr_ok:
203267
memaddr = xd.xaddr
204268
hl_lhs = XU.xmemory_dereference_lval(memaddr, xdata, iaddr, astree)
205269

206270
else:
207271
chklogger.logger.error(
208272
"STRH: Lhs lval and address both have error values: skipping "
209-
+ "store instruction at address %s",
210-
iaddr)
211-
return ([], [])
273+
"store instruction at address %s", iaddr)
274+
return ([], (ll_preinstrs + [ll_assign] + ll_postinstrs))
275+
276+
if xd.is_cxrt_ok:
277+
rhs = xd.cxrt
278+
elif xd.is_xxrt_ok:
279+
rhs = xd.xxrt
280+
else:
281+
rhs = xd.xrt
282+
hl_rhs = XU.xxpr_to_ast_def_expr(rhs, xdata, iaddr, astree)
212283

213-
rhs = xd.xxrt
214284
rdefs = xdata.reachingdefs
215285
defuses = xdata.defuses
216286
defuseshigh = xdata.defuseshigh
@@ -228,7 +298,7 @@ def ast_prov(
228298
# to variables that are part of a struct or array variable, so these
229299
# assignments must be explicitly forced to appear in the lifting
230300
if (
231-
xd.is_vmem_unknown
301+
(not xd.is_vmem_ok)
232302
or lhs.is_memory_variable and cast("VMemoryVariable",
233303
lhs.denotation).base.is_basevar
234304
or hl_lhs.offset.is_index_offset
@@ -282,4 +352,4 @@ def ast_prov(
282352
ll_assigns = [ll_assign]
283353
hl_assigns = [hl_assign]
284354

285-
return (hl_assigns, ll_assigns)
355+
return (hl_assigns, (ll_preinstrs + ll_assigns + ll_postinstrs))

0 commit comments

Comments
 (0)