Skip to content

Commit 4293a7e

Browse files
committed
ARM: update instruction liftings
1 parent aa06704 commit 4293a7e

11 files changed

+282
-232
lines changed

chb/arm/opcodes/ARMArithmeticShiftRight.py

Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# ------------------------------------------------------------------------------
55
# The MIT License (MIT)
66
#
7-
# Copyright (c) 2021-2023 Aarno Labs LLC
7+
# Copyright (c) 2021-2024 Aarno Labs LLC
88
#
99
# Permission is hereby granted, free of charge, to any person obtaining a copy
1010
# of this software and associated documentation files (the "Software"), to deal
@@ -123,6 +123,22 @@ def ast_prov(
123123

124124
annotations: List[str] = [iaddr, "ASR"]
125125

126+
# low-level assignment
127+
128+
(ll_lhs, _, _) = self.opargs[0].ast_lvalue(astree)
129+
(ll_rhs1, _, _) = self.opargs[1].ast_rvalue(astree)
130+
(ll_rhs2, _, _) = self.opargs[2].ast_rvalue(astree)
131+
ll_asr = astree.mk_binary_op("asr", ll_rhs1, ll_rhs2)
132+
133+
ll_assign = astree.mk_assign(
134+
ll_lhs,
135+
ll_asr,
136+
iaddr=iaddr,
137+
bytestring=bytestring,
138+
annotations=annotations)
139+
140+
# high-level assignment
141+
126142
lhs = xdata.vars[0]
127143
rhs1 = xdata.xprs[0]
128144
rhs2 = xdata.xprs[1]
@@ -131,43 +147,25 @@ def ast_prov(
131147
defuses = xdata.defuses
132148
defuseshigh = xdata.defuseshigh
133149

134-
(ll_lhs, _, _) = self.opargs[0].ast_lvalue(astree)
135-
(ll_rhs1, _, _) = self.opargs[1].ast_rvalue(astree)
136-
(ll_rhs2, _, _) = self.opargs[2].ast_rvalue(astree)
137-
ll_asr_expr = astree.mk_binary_op("asr", ll_rhs1, ll_rhs2)
150+
hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree)
151+
hl_rhs = XU.xxpr_to_ast_def_expr(rhs3, xdata, iaddr, astree)
138152

139-
ll_assign = astree.mk_assign(
140-
ll_lhs,
141-
ll_asr_expr,
153+
hl_assign = astree.mk_assign(
154+
hl_lhs,
155+
hl_rhs,
142156
iaddr=iaddr,
143157
bytestring=bytestring,
144158
annotations=annotations)
145159

146-
hl_lhss = XU.xvariable_to_ast_lvals(lhs, xdata, astree)
147-
hl_rhss = XU.xxpr_to_ast_exprs(rhs3, xdata, iaddr, astree)
148-
if len(hl_lhss) == 1 and len(hl_rhss) == 1:
149-
hl_lhs = hl_lhss[0]
150-
hl_rhs = hl_rhss[0]
151-
hl_assign = astree.mk_assign(
152-
hl_lhs,
153-
hl_rhs,
154-
iaddr=iaddr,
155-
bytestring=bytestring,
156-
annotations=annotations)
157-
158-
astree.add_instr_mapping(hl_assign, ll_assign)
159-
astree.add_instr_address(hl_assign, [iaddr])
160-
astree.add_expr_mapping(hl_rhs, ll_asr_expr)
161-
astree.add_lval_mapping(hl_lhs, ll_lhs)
162-
astree.add_expr_reachingdefs(ll_asr_expr, [rdefs[0], rdefs[1]])
163-
astree.add_expr_reachingdefs(ll_rhs1, [rdefs[0]])
164-
astree.add_expr_reachingdefs(ll_rhs2, [rdefs[1]])
165-
astree.add_expr_reachingdefs(hl_rhs, rdefs[2:])
166-
astree.add_lval_defuses(hl_lhs, defuses[0])
167-
astree.add_lval_defuses_high(hl_lhs, defuseshigh[0])
168-
169-
return ([hl_assign], [ll_assign])
170-
171-
else:
172-
raise UF.CHBError(
173-
"ARMArithmeticShiftRight: multiple lval/expressions in ast")
160+
astree.add_instr_mapping(hl_assign, ll_assign)
161+
astree.add_instr_address(hl_assign, [iaddr])
162+
astree.add_expr_mapping(hl_rhs, ll_asr)
163+
astree.add_lval_mapping(hl_lhs, ll_lhs)
164+
astree.add_expr_reachingdefs(ll_asr, [rdefs[0], rdefs[1]])
165+
astree.add_expr_reachingdefs(ll_rhs1, [rdefs[0]])
166+
astree.add_expr_reachingdefs(ll_rhs2, [rdefs[1]])
167+
astree.add_expr_reachingdefs(hl_rhs, rdefs[2:])
168+
astree.add_lval_defuses(hl_lhs, defuses[0])
169+
astree.add_lval_defuses_high(hl_lhs, defuseshigh[0])
170+
171+
return ([hl_assign], [ll_assign])

chb/arm/opcodes/ARMBitFieldInsert.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# ------------------------------------------------------------------------------
55
# The MIT License (MIT)
66
#
7-
# Copyright (c) 2021-2023 Aarno Labs LLC
7+
# Copyright (c) 2021-2024 Aarno Labs LLC
88
#
99
# Permission is hereby granted, free of charge, to any person obtaining a copy
1010
# of this software and associated documentation files (the "Software"), to deal
@@ -133,6 +133,16 @@ def ast_prov(
133133

134134
annotations: List[str] = [iaddr, "BFI"]
135135

136+
if self.width == 0:
137+
nopinstr = astree.mk_nop_instruction(
138+
"BFI (width = 0)",
139+
iaddr=iaddr,
140+
bytestring=bytestring,
141+
annotations=annotations)
142+
astree.add_instr_address(nopinstr, [iaddr])
143+
144+
return ([], [nopinstr])
145+
136146
lhs = xdata.vars[0]
137147
rhs1 = xdata.xprs[0]
138148
rhs2 = xdata.xprs[1]
@@ -143,6 +153,7 @@ def ast_prov(
143153
(ll_lhs, _, _) = self.operands[0].ast_lvalue(astree)
144154
(ll_op1, _, _) = self.operands[0].ast_rvalue(astree)
145155
(ll_op2, _, _) = self.operands[0].ast_rvalue(astree)
156+
146157
mask1 = int("1" * self.width, 2)
147158
mask1const = astree.mk_integer_constant(mask1)
148159
ll_rhs2 = astree.mk_binary_op("band", ll_op2, mask1const)

chb/arm/opcodes/ARMBitwiseBitClear.py

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# ------------------------------------------------------------------------------
55
# The MIT License (MIT)
66
#
7-
# Copyright (c) 2021-2022 Aarno Labs LLC
7+
# Copyright (c) 2021-2024 Aarno Labs LLC
88
#
99
# Permission is hereby granted, free of charge, to any person obtaining a copy
1010
# of this software and associated documentation files (the "Software"), to deal
@@ -112,11 +112,7 @@ def ast_prov(
112112

113113
annotations: List[str] = [iaddr, "BIC"]
114114

115-
lhs = xdata.vars[0]
116-
rhs = xdata.xprs[3]
117-
rdefs = xdata.reachingdefs
118-
defuses = xdata.defuses
119-
defuseshigh = xdata.defuseshigh
115+
# low-level assignment
120116

121117
(ll_lhs, _, _) = self.operands[0].ast_lvalue(astree)
122118
(ll_op1, _, _) = self.operands[0].ast_rvalue(astree)
@@ -131,27 +127,20 @@ def ast_prov(
131127
bytestring=bytestring,
132128
annotations=annotations)
133129

134-
lhsasts = XU.xvariable_to_ast_lvals(lhs, xdata, astree)
135-
if len(lhsasts) == 0:
136-
raise UF.CHBError("BitFieldInsert (BFI): no lval found")
137-
138-
if len(lhsasts) > 1:
139-
raise UF.CHBError(
140-
"BitFieldInsert (BFI): multiple lvals found: "
141-
+ ", ".join(str(v) for v in lhsasts))
130+
rdefs = xdata.reachingdefs
142131

143-
hl_lhs = lhsasts[0]
132+
astree.add_expr_reachingdefs(ll_op1, [rdefs[0]])
133+
astree.add_expr_reachingdefs(ll_op2, [rdefs[1]])
144134

145-
rhsasts = XU.xxpr_to_ast_def_exprs(rhs, xdata, iaddr, astree)
146-
if len(rhsasts) == 0:
147-
raise UF.CHBError("BitwiseBitClear (BIC): no lval found")
135+
# high-level assignment
148136

149-
if len(rhsasts) > 1:
150-
raise UF.CHBError(
151-
"BitwiseBitClear (BIC): multiple rhs values found: "
152-
+ ", ".join(str(v) for v in rhsasts))
137+
lhs = xdata.vars[0]
138+
rhs = xdata.xprs[3]
139+
defuses = xdata.defuses
140+
defuseshigh = xdata.defuseshigh
153141

154-
hl_rhs = rhsasts[0]
142+
hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree)
143+
hl_rhs = XU.xxpr_to_ast_def_expr(rhs, xdata, iaddr, astree)
155144

156145
hl_assign = astree.mk_assign(
157146
hl_lhs,
@@ -165,8 +154,6 @@ def ast_prov(
165154
astree.add_instr_address(hl_assign, [iaddr])
166155
astree.add_expr_mapping(hl_rhs, ll_rhs)
167156
astree.add_lval_mapping(hl_lhs, ll_lhs)
168-
astree.add_expr_reachingdefs(ll_op1, [rdefs[0]])
169-
astree.add_expr_reachingdefs(ll_op2, [rdefs[1]])
170157
astree.add_lval_defuses(hl_lhs, defuses[0])
171158
astree.add_lval_defuses_high(hl_lhs, defuseshigh[0])
172159

chb/arm/opcodes/ARMBitwiseOr.py

Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# ------------------------------------------------------------------------------
55
# The MIT License (MIT)
66
#
7-
# Copyright (c) 2021-2023 Aarno Labs LLC
7+
# Copyright (c) 2021-2024 Aarno Labs LLC
88
#
99
# Permission is hereby granted, free of charge, to any person obtaining a copy
1010
# of this software and associated documentation files (the "Software"), to deal
@@ -123,50 +123,47 @@ def ast_prov(
123123

124124
annotations: List[str] = [iaddr, "ORR"]
125125

126-
lhs = xdata.vars[0]
127-
rhs1 = xdata.xprs[0]
128-
rhs2 = xdata.xprs[1]
129-
rhs3 = xdata.xprs[3]
130-
rdefs = xdata.reachingdefs
131-
defuses = xdata.defuses
132-
defuseshigh = xdata.defuseshigh
126+
# low-level assignment
133127

134128
(ll_lhs, _, _) = self.opargs[0].ast_lvalue(astree)
135129
(ll_op1, _, _) = self.opargs[1].ast_rvalue(astree)
136130
(ll_op2, _, _) = self.opargs[2].ast_rvalue(astree)
137131
ll_rhs = astree.mk_binary_op("bor", ll_op1, ll_op2)
138132

139-
astree.add_expr_reachingdefs(ll_op1, [rdefs[0]])
140-
astree.add_expr_reachingdefs(ll_op2, [rdefs[1]])
141-
142133
ll_assign = astree.mk_assign(
143134
ll_lhs,
144135
ll_rhs,
145136
iaddr=iaddr,
146137
bytestring=bytestring,
147138
annotations=annotations)
148139

149-
lhsasts = XU.xvariable_to_ast_lvals(lhs, xdata, astree)
150-
if len(lhsasts) == 0:
151-
raise UF.CHBError("BitwiseOr (ORR): no lval found")
140+
rdefs = xdata.reachingdefs
152141

153-
if len(lhsasts) > 1:
154-
raise UF.CHBError(
155-
"BitwiseOr (ORR): multiple lvals found: "
156-
+ ", ".join(str(v) for v in lhsasts))
142+
astree.add_expr_reachingdefs(ll_op1, [rdefs[0]])
143+
astree.add_expr_reachingdefs(ll_op2, [rdefs[1]])
157144

158-
hl_lhs = lhsasts[0]
145+
# high-level assignment
159146

160-
rhsasts = XU.xxpr_to_ast_def_exprs(rhs3, xdata, iaddr, astree)
161-
if len(rhsasts) == 0:
162-
raise UF.CHBError("BitwiseOr (ORR): no lval found")
147+
lhs = xdata.vars[0]
148+
rhs1 = xdata.xprs[0]
149+
rhs2 = xdata.xprs[1]
150+
rhs3 = xdata.xprs[3]
163151

164-
if len(rhsasts) > 1:
165-
raise UF.CHBError(
166-
"BitwiseOr (ORR): multiple rhs values found: "
167-
+ ", ".join(str(v) for v in rhsasts))
152+
defuses = xdata.defuses
153+
defuseshigh = xdata.defuseshigh
168154

169-
hl_rhs = rhsasts[0]
155+
astree.add_expr_reachingdefs(ll_op1, [rdefs[0]])
156+
astree.add_expr_reachingdefs(ll_op2, [rdefs[1]])
157+
158+
ll_assign = astree.mk_assign(
159+
ll_lhs,
160+
ll_rhs,
161+
iaddr=iaddr,
162+
bytestring=bytestring,
163+
annotations=annotations)
164+
165+
hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree)
166+
hl_rhs = XU.xxpr_to_ast_def_expr(rhs3, xdata, iaddr, astree)
170167

171168
hl_assign = astree.mk_assign(
172169
hl_lhs,
@@ -175,14 +172,11 @@ def ast_prov(
175172
bytestring=bytestring,
176173
annotations=annotations)
177174

178-
astree.add_reg_definition(iaddr, hl_lhs, hl_rhs)
179175
astree.add_instr_mapping(hl_assign, ll_assign)
180176
astree.add_instr_address(hl_assign, [iaddr])
181177
astree.add_expr_mapping(hl_rhs, ll_rhs)
182178
astree.add_lval_mapping(hl_lhs, ll_lhs)
183-
astree.add_expr_reachingdefs(ll_rhs, [rdefs[0], rdefs[1]])
184-
astree.add_expr_reachingdefs(ll_op1, [rdefs[0]])
185-
astree.add_expr_reachingdefs(ll_op2, [rdefs[1]])
179+
astree.add_expr_reachingdefs(ll_rhs, rdefs[:2])
186180
astree.add_expr_reachingdefs(hl_rhs, rdefs[2:])
187181
astree.add_lval_defuses(hl_lhs, defuses[0])
188182
astree.add_lval_defuses_high(hl_lhs, defuseshigh[0])

chb/arm/opcodes/ARMBranchExchange.py

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# ------------------------------------------------------------------------------
55
# The MIT License (MIT)
66
#
7-
# Copyright (c) 2021-2023 Aarno Labs LLC
7+
# Copyright (c) 2021-2024 Aarno Labs LLC
88
#
99
# Permission is hereby granted, free of charge, to any person obtaining a copy
1010
# of this software and associated documentation files (the "Software"), to deal
@@ -29,6 +29,7 @@
2929

3030
from chb.app.InstrXData import InstrXData
3131

32+
from chb.arm.ARMCallOpcode import ARMCallOpcode
3233
from chb.arm.ARMDictionaryRecord import armregistry
3334
from chb.arm.ARMOpcode import ARMOpcode, simplify_result
3435
from chb.arm.ARMOperand import ARMOperand
@@ -43,11 +44,12 @@
4344
from chb.util.IndexedTable import IndexedTableValue
4445

4546
if TYPE_CHECKING:
47+
from chb.api.CallTarget import CallTarget, AppTarget, StaticStubTarget
4648
import chb.arm.ARMDictionary
4749

4850

4951
@armregistry.register_tag("BX", ARMOpcode)
50-
class ARMBranchExchange(ARMOpcode):
52+
class ARMBranchExchange(ARMCallOpcode):
5153
"""Branch to an address and instruction set specified by a register.
5254
5355
tags[1]: <c>
@@ -84,17 +86,36 @@ def return_value(self, xdata: InstrXData) -> Optional[XXpr]:
8486
else:
8587
return None
8688

89+
def is_call(self, xdata: InstrXData) -> bool:
90+
return len(xdata.tags) >= 2 and xdata.tags[1] == "call"
91+
92+
def is_call_instruction(self, xdata: InstrXData) -> bool:
93+
return xdata.has_call_target()
94+
95+
def call_target(self, xdata: InstrXData) -> "CallTarget":
96+
if self.is_call_instruction(xdata):
97+
return xdata.call_target(self.ixd)
98+
else:
99+
raise UF.CHBError("Instruction is not a call: " + str(self))
100+
101+
def arguments(self, xdata: InstrXData) -> Sequence[XXpr]:
102+
return xdata.xprs
103+
87104
def annotation(self, xdata: InstrXData) -> str:
88105
"""xdata format: a:x .
89106
90107
xprs[0]: target operand
91108
"""
109+
if self.is_call_instruction(xdata):
110+
tgt = xdata.call_target(self.ixd)
111+
args = ", ".join(str(x) for x in self.arguments(xdata))
112+
return "call " + str(tgt) + "(" + args + ")"
92113

93-
tgt = str(xdata.xprs[0])
94-
if tgt == "LR":
114+
tgtop = str(xdata.xprs[0])
115+
if tgtop == "LR":
95116
return "return"
96117
else:
97-
return "goto " + tgt
118+
return "goto " + tgtop
98119

99120
def assembly_ast(
100121
self,
@@ -115,8 +136,24 @@ def ast_prov(
115136

116137
annotations: List[str] = [iaddr, "BX"]
117138

118-
nopinstr = astree.mk_nop_instruction(
119-
"BX", iaddr=iaddr, bytestring=bytestring, annotations=annotations)
120-
astree.add_instr_address(nopinstr, [iaddr])
139+
if self.is_call_instruction(xdata) and xdata.has_call_target():
140+
return self.ast_call_prov(
141+
astree, iaddr, bytestring, "BranchExchange", xdata)
142+
else:
143+
nopinstr = astree.mk_nop_instruction(
144+
"BX", iaddr=iaddr, bytestring=bytestring, annotations=annotations)
145+
astree.add_instr_address(nopinstr, [iaddr])
146+
147+
return ([], [nopinstr])
148+
149+
def ast_call_prov(
150+
self,
151+
astree: ASTInterface,
152+
iaddr: str,
153+
bytestring: str,
154+
name: str,
155+
xdata: InstrXData) -> Tuple[
156+
List[AST.ASTInstruction], List[AST.ASTInstruction]]:
121157

122-
return ([], [nopinstr])
158+
return ARMCallOpcode.ast_call_prov(
159+
self, astree, iaddr, bytestring, "BranchExchange (BX)", xdata)

0 commit comments

Comments
 (0)