Skip to content

Commit 31082f0

Browse files
committed
Assignments to pc => goto
1 parent 9ccdaf4 commit 31082f0

File tree

3 files changed

+37
-21
lines changed

3 files changed

+37
-21
lines changed

src/Arch/Arm/ThumbRewriter.Alu.cs

+11-11
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919
#endregion
2020

21+
using Gee.External.Capstone.Arm;
2122
using Reko.Core;
2223
using Reko.Core.Expressions;
2324
using Reko.Core.Rtl;
@@ -120,12 +121,9 @@ private void RewriteLdr(DataType dtDst, DataType dtSrc)
120121
var baseReg = GetReg(ops[1].MemoryValue.BaseRegister);
121122
Predicate(itStateCondition, tmp, src);
122123
Predicate(itStateCondition, baseReg, emitter.IAdd(baseReg, RewriteOp(ops[2])));
123-
Predicate(itStateCondition, dst, tmp);
124-
}
125-
else
126-
{
127-
Predicate(itStateCondition, dst, src);
124+
src = tmp;
128125
}
126+
Predicate(itStateCondition, dst, src);
129127
}
130128

131129
private void RewriteLdrex()
@@ -190,25 +188,27 @@ private void RewriteMvn()
190188
private void RewritePop()
191189
{
192190
var sp = frame.EnsureRegister(A32Registers.sp);
191+
emitter.Assign(sp, emitter.IAdd(sp, Constant.Int32(ops.Length * 4)));
193192
int offset = ops.Length * 4;
194193
foreach (var op in ops.OrderByDescending(o => o.RegisterValue.Value))
195194
{
196-
offset -= 4;
197-
emitter.Assign(
195+
Predicate(
196+
ArmCodeCondition.AL,
198197
GetReg(op.RegisterValue.Value),
199-
emitter.LoadDw(emitter.IAdd(sp, Constant.Int32(offset))));
198+
emitter.LoadDw(emitter.ISub(sp, Constant.Int32(offset))));
199+
offset -= 4;
200200
}
201-
emitter.Assign(sp, emitter.IAdd(sp, Constant.Int32( ops.Length * 4)));
202201
}
203202

204203
private void RewritePush()
205204
{
206205
var sp = frame.EnsureRegister(A32Registers.sp);
207206
emitter.Assign(sp, emitter.ISub(sp, Constant.Int32( ops.Length * 4)));
208207
int offset = 0;
209-
foreach (var op in ops.OrderBy(o => o.RegisterValue.Value))
208+
foreach (var op in ops.OrderByDescending(o => o.RegisterValue.Value))
210209
{
211-
emitter.Assign(
210+
Predicate(
211+
ArmCodeCondition.AL,
212212
emitter.LoadDw(emitter.IAdd(sp, Constant.Int32(offset))),
213213
GetReg(op.RegisterValue.Value));
214214
offset += 4;

src/Arch/Arm/ThumbRewriter.cs

+12-3
Original file line numberDiff line numberDiff line change
@@ -256,11 +256,20 @@ private void Predicate(ArmCodeCondition cond, RtlInstruction instr)
256256

257257
private void Predicate(ArmCodeCondition cond, Expression dst, Expression src)
258258
{
259-
var ass = new RtlAssignment(dst, src);
259+
RtlInstruction instr;
260+
Identifier id;
261+
if (dst.As<Identifier>(out id) && id.Storage == A32Registers.pc)
262+
{
263+
instr = new RtlGoto(src, RtlClass.Transfer);
264+
}
265+
else
266+
{
267+
instr = new RtlAssignment(dst, src);
268+
}
260269
if (cond == ArmCodeCondition.AL)
261-
emitter.Emit(ass);
270+
emitter.Emit(instr);
262271
else
263-
emitter.If(TestCond(cond), ass);
272+
emitter.If(TestCond(cond), instr);
264273
}
265274
}
266275
}

src/UnitTests/Arch/Arm/ThumbRewriterTests.cs

+14-7
Original file line numberDiff line numberDiff line change
@@ -5773,8 +5773,8 @@ public void ThumbRw_push()
57735773
AssertCode(
57745774
"0|00100000(4): 3 instructions",
57755775
"1|L--|sp = sp - 8",
5776-
"2|L--|Mem0[sp + 0:word32] = lr",
5777-
"3|L--|Mem0[sp + 4:word32] = fp");
5776+
"2|L--|Mem0[sp + 0:word32] = fp",
5777+
"3|L--|Mem0[sp + 4:word32] = lr");
57785778
}
57795779

57805780
[Test]
@@ -5783,9 +5783,9 @@ public void ThumbRw_pop()
57835783
BuildTest(0xE8BD, 0x8800); // pop.w\t{fp,pc}
57845784
AssertCode(
57855785
"0|00100000(4): 3 instructions",
5786-
"1|L--|fp = Mem0[sp + 4:word32]",
5787-
"2|L--|pc = Mem0[sp + 0:word32]",
5788-
"3|L--|sp = sp + 8");
5786+
"1|L--|sp = sp + 8",
5787+
"2|L--|fp = Mem0[sp - 8:word32]",
5788+
"3|T--|goto Mem0[sp - 4:word32]");
57895789
}
57905790

57915791
[Test]
@@ -6150,7 +6150,7 @@ public void ThumbRw_ldr_postIndex()
61506150
"0|00100000(4): 3 instructions",
61516151
"1|L--|v4 = Mem0[sp:word32]",
61526152
"2|L--|sp = sp + 12",
6153-
"3|L--|pc = v4");
6153+
"3|T--|goto v4");
61546154
}
61556155
[Test]
61566156
public void ThumbRw_strb_preIndex()
@@ -6172,6 +6172,13 @@ public void ThumbRw_strb_postIndex()
61726172
"2|L--|r2 = r2 + 1");
61736173
}
61746174

6175-
6175+
[Test]
6176+
public void ThumbRw_ldr_pc()
6177+
{
6178+
BuildTest(0xF8DC, 0xF000); // ldr pc,[r12]
6179+
AssertCode(
6180+
"0|00100000(4): 1 instructions",
6181+
"1|T--|goto Mem0[ip:word32]");
6182+
}
61766183
}
61776184
}

0 commit comments

Comments
 (0)