Skip to content

Commit 62770f1

Browse files
committed
ARM: update call instructions for conversion to C expressions
1 parent aa1ad5f commit 62770f1

File tree

1 file changed

+56
-6
lines changed

1 file changed

+56
-6
lines changed

chb/arm/ARMCallOpcode.py

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ class ARMCallOpcodeXData(ARMOpcodeXData):
6868
"""
6969
xdata format: a:x[2n]xr[n]dh, call (n arguments)
7070
-------------------------------------------------
71-
xprs[0..2n-1]: (arg location expr, arg value expr) * n
71+
xprs_r[0..n-1]: arg values
72+
xprs_r[n..2n-1]: register arg values
73+
cxprs_r[0..n-1]: arg value (C representation)
7274
xprs[2n]: call target expression
7375
rdefs[0..n-1]: arg location reaching definitions
7476
uses[0]: lhs
@@ -110,11 +112,58 @@ def arguments(self) -> List["XXpr"]:
110112
arguments.append(x)
111113
return arguments
112114

115+
@property
116+
def c_arguments(self) -> List[Optional["XXpr"]]:
117+
argcount = self.argument_count
118+
c_args: List[Optional["XXpr"]] = []
119+
for i in range(argcount):
120+
x = self._xdata.cxprs_r[i]
121+
c_args.append(x)
122+
return c_args
123+
124+
@property
125+
def cx_arguments(self) -> List["XXpr"]:
126+
argcount = self.argument_count
127+
result: List["XXpr"] = []
128+
for i in range(argcount):
129+
x = self.c_arguments[i]
130+
if x is None:
131+
x = self.arguments[i]
132+
result.append(x)
133+
return result
134+
113135
@property
114136
def argumentxvars(self) -> List["XXpr"]:
115137
argcount = self.argument_count
116-
return [x for x in self._xdata.xprs_r[argcount:2 * argcount]
117-
if x is not None]
138+
argvars: List["XXpr"] = []
139+
for i in range(argcount):
140+
x = self._xdata.xprs_r[i + argcount]
141+
if x is None:
142+
raise UF.CHBError(
143+
"Unexpected None-value call argument at index "
144+
+ str(i))
145+
argvars.append(x)
146+
return argvars
147+
148+
def argument(self, index: int) -> Tuple[Optional["XXpr"], Optional[str]]:
149+
"""Returns argument for (1-based) index."""
150+
151+
if index > self.argument_count:
152+
msg = (
153+
"argument index " + str(index) + " exceeds argument count "
154+
+ str(self.argument_count))
155+
return (None, msg)
156+
if index <= 0:
157+
msg = (
158+
"argument index " + str(index) + " is invalid. A positive "
159+
+ "value is expected")
160+
return (None, msg)
161+
c_arg = self.c_arguments[index-1]
162+
if c_arg is None:
163+
x_arg = self.arguments[index-1]
164+
return (x_arg, "fall-back to x-expression")
165+
else:
166+
return (c_arg, None)
118167

119168
@property
120169
def calltarget(self) -> "CallTarget":
@@ -124,7 +173,8 @@ def calltarget(self) -> "CallTarget":
124173
def annotation(self) -> str:
125174
tgt = str(self.calltarget)
126175
args = ", ".join(str(x) for x in self.arguments)
127-
call = "call " + str(tgt) + "(" + args + ")"
176+
cargs = " (C: (" + ", ".join(str(x) for x in self.c_arguments) + "))"
177+
call = "call " + str(tgt) + "(" + args + ")" + cargs
128178
return self.add_instruction_condition(call)
129179

130180

@@ -310,15 +360,15 @@ def ast_call_prov(
310360
if len(astargtypes) < argcount:
311361
astargtypes += ([None] * (argcount - len(astargtypes)))
312362

313-
xargs = xd.arguments
363+
xargs = xd.cx_arguments
314364
xvarargs = xd.argumentxvars
315365
if len(rdefs) >= argcount:
316366
llrdefs = rdefs[:argcount]
317367
# x represents the (invariant-enhanced) argument value.
318368
# xv represents the location of the argument, which can be
319369
# either a register, or a stack location, where the stack
320370
# location is represented by an expression of the form
321-
# (sp + n), with n is the offset from the current stackpointer
371+
# (sp + n), where n is the offset from the current stackpointer
322372
# in bytes (note: not the stackpointer at function entry).
323373
# rdef represents the reaching definition for the argument
324374
# location.

0 commit comments

Comments
 (0)