Skip to content

Commit ac2e4d4

Browse files
committed
Enhancement: more ARM32 rewriters.
1 parent db5d3c7 commit ac2e4d4

4 files changed

Lines changed: 163 additions & 113 deletions

File tree

src/Arch/Arm/AArch32/A32Disassembler.cs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1769,15 +1769,15 @@ static A32Disassembler()
17691769

17701770
// --
17711771
var LdrdRegister = Instr(Mnemonic.ldrd, Rp_12,M_(w8));
1772-
var LdrhRegister = Instr(Mnemonic.ldrh, r(3),M_(w2));
1773-
var LdrsbRegister = Instr(Mnemonic.ldrsb, r(3),M_(s1));
1774-
var LdrshRegister = Instr(Mnemonic.ldrsh, r(3),M_(s2));
1775-
var Ldrht = Instr(Mnemonic.ldrht, r(3),Mh(w2));
1776-
var Ldrsbt = Instr(Mnemonic.ldrsbt, r(3),Mh(s1));
1777-
var Ldrsht = Instr(Mnemonic.ldrsht, r(3),Mh(s2));
1772+
var LdrhRegister = Instr(Mnemonic.ldrh, Rnp12,M_(w2));
1773+
var LdrsbRegister = Instr(Mnemonic.ldrsb, Rnp12,M_(s1));
1774+
var LdrshRegister = Instr(Mnemonic.ldrsh, Rnp12,M_(s2));
1775+
var Ldrht = Instr(Mnemonic.ldrht, Rnp12,Mh(w2));
1776+
var Ldrsbt = Instr(Mnemonic.ldrsbt, Rnp12,Mh(s1));
1777+
var Ldrsht = Instr(Mnemonic.ldrsht, Rnp12,Mh(s2));
17781778
var StrdRegister = Instr(Mnemonic.strd, Rp_12,Mx(w8));
1779-
var StrhRegister = Instr(Mnemonic.strh, r(3),M_(w2));
1780-
var Strht = Instr(Mnemonic.strht, r(3),Mh(w2));
1779+
var StrhRegister = Instr(Mnemonic.strh, Rnp12,M_(w2));
1780+
var Strht = Instr(Mnemonic.strht, Rnp12,Mh(w2));
17811781

17821782
var LoadStoreDualHalfSbyteRegister = Mask(24, 1,
17831783
Mask(20, 2,
@@ -1813,16 +1813,16 @@ static A32Disassembler()
18131813
LdrsbRegister,
18141814
LdrshRegister)));
18151815

1816-
var LdrdLiteral = Instr(Mnemonic.ldrd, Rp_12, r(3), Mh(w8, false));
1817-
var LdrhLiteral = Instr(Mnemonic.ldrh, r(3), Mh(w2, false));
1818-
var LdrsbLiteral = Instr(Mnemonic.ldrsb, r(3),Mh(s1, false));
1819-
var LdrshLiteral = Instr(Mnemonic.ldrsh, r(3),Mh(s2, false));
1820-
var StrhImmediate = Instr(Mnemonic.strh, r(3),Mh(w2));
1816+
var LdrdLiteral = Instr(Mnemonic.ldrd, Rp_12, Rnp12, Mh(w8, false));
1817+
var LdrhLiteral = Instr(Mnemonic.ldrh, Rnp12, Mh(w2, false));
1818+
var LdrsbLiteral = Instr(Mnemonic.ldrsb, Rnp12, Mh(s1, false));
1819+
var LdrshLiteral = Instr(Mnemonic.ldrsh, Rnp12, Mh(s2, false));
1820+
var StrhImmediate = Instr(Mnemonic.strh, Rnp12, Mh(w2));
18211821
var LdrdImmediate = Instr(Mnemonic.ldrd, Rp_12,Mh(w8));
18221822
var StrdImmediate = Instr(Mnemonic.strd, Rp_12,Mh(w8));
1823-
var LdrhImmediate = Instr(Mnemonic.ldrh, r(3),Mh(w2));
1824-
var LdrsbImmediate = Instr(Mnemonic.ldrsb, r(3),Mh(s1));
1825-
var LdrshImmediate = Instr(Mnemonic.ldrsh, r(3),Mh(s2));
1823+
var LdrhImmediate = Instr(Mnemonic.ldrh, Rnp12, Mh(w2));
1824+
var LdrsbImmediate = Instr(Mnemonic.ldrsb, Rnp12, Mh(s1));
1825+
var LdrshImmediate = Instr(Mnemonic.ldrsh, Rnp12, Mh(s2));
18261826

18271827
var LoadStoreDualHalfSbyteImmediate = Mask(Bf((24, 1), (20, 2)), // LoadStoreDualHalfSbyteImmediate Rn != pc P:W:op1"LoadStoreDualHalfSbyteImmediate",
18281828
Mask(5, 2, // LoadStoreDualHalfSbyteImmediate Rn != pc P:W:op1=000 op2

src/Arch/Arm/AArch32/ArmRewriter.Alu.cs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -280,15 +280,15 @@ private void RewriteTst()
280280
m.Cond(m.And(opDst, opSrc)));
281281
}
282282

283-
private void RewriteLoadAcquire(IntrinsicProcedure intrinsic)
283+
private void RewriteLoadAcquire(IntrinsicProcedure intrinsic, DataType dt)
284284
{
285285
var mem = (MemoryOperand) instr.Operands[1];
286286
var ea = binder.EnsureRegister(mem.BaseRegister!);
287287
var dst = binder.EnsureRegister((RegisterStorage) instr.Operands[0]);
288+
intrinsic = intrinsic.MakeInstance(32, dt);
288289
Expression src = m.Fn(intrinsic, ea);
289290
if (src.DataType.BitSize != dst.DataType.BitSize)
290291
{
291-
var dt = intrinsic.ReturnType;
292292
var tmp = binder.CreateTemporary(dt);
293293
m.Assign(tmp, src);
294294
src = m.Convert(tmp, dt, dst.DataType);
@@ -304,7 +304,7 @@ private void RewriteLoadAcquireDouble(IntrinsicProcedure intrinsic)
304304
var regHi = (RegisterStorage) instr.Operands[0];
305305
var regLo = (RegisterStorage) instr.Operands[1];
306306
var dst = binder.EnsureSequence(PrimitiveType.Word64, regHi, regLo);
307-
var src = m.Fn(intrinsic, ea);
307+
var src = m.Fn(intrinsic.MakeInstance(32, dst.DataType), ea);
308308
m.Assign(dst, src);
309309
}
310310

@@ -380,7 +380,7 @@ private void RewriteLdrd()
380380
MaybePostOperand(2);
381381
}
382382

383-
private void RewriteStoreRelease(string intrinsicName, PrimitiveType dt)
383+
private void RewriteStoreRelease(IntrinsicProcedure intrinsic, PrimitiveType dt)
384384
{
385385
var src = binder.EnsureRegister((RegisterStorage) instr.Operands[0]);
386386
if (src.DataType.BitSize != dt.BitSize)
@@ -392,11 +392,11 @@ private void RewriteStoreRelease(string intrinsicName, PrimitiveType dt)
392392
var mem = (MemoryOperand) instr.Operands[1];
393393
var ea = binder.EnsureRegister(mem.BaseRegister!);
394394
ea.DataType = new Pointer(dt, 32);
395-
var store = host.Intrinsic(intrinsicName, true, dt, ea, src);
395+
var store = m.Fn(intrinsic.MakeInstance(32, dt), ea, src);
396396
m.SideEffect(store);
397397
}
398398

399-
private void RewriteStoreExclusive(string intrinsicName, PrimitiveType dt)
399+
private void RewriteStoreExclusive(IntrinsicProcedure intrinsic, PrimitiveType dt)
400400
{
401401
var src = binder.EnsureRegister((RegisterStorage) instr.Operands[1]);
402402
if (src.DataType.BitSize != dt.BitSize)
@@ -408,20 +408,20 @@ private void RewriteStoreExclusive(string intrinsicName, PrimitiveType dt)
408408
var mem = (MemoryOperand) instr.Operands[2];
409409
var ea = binder.EnsureRegister(mem.BaseRegister!);
410410
ea.DataType = new Pointer(dt, 32);
411-
var store = host.Intrinsic(intrinsicName, true, dt, ea, src);
411+
var store = m.Fn(intrinsic.MakeInstance(32, dt), ea, src);
412412
var dst = Operand(0);
413413
m.Assign(dst, store);
414414
}
415415

416-
private void RewriteStoreReleaseDoubleExclusive(string intrinsicName)
416+
private void RewriteStoreReleaseDoubleExclusive(IntrinsicProcedure intrinsic)
417417
{
418418
var mem = (MemoryOperand) instr.Operands[3];
419419
var ea = binder.EnsureRegister(mem.BaseRegister!);
420420
ea.DataType = new Pointer(PrimitiveType.Word64, 32);
421421
var regHi = (RegisterStorage) instr.Operands[1];
422422
var regLo = (RegisterStorage) instr.Operands[2];
423423
var src = binder.EnsureSequence(PrimitiveType.Word64, regHi, regLo);
424-
var store = host.Intrinsic(intrinsicName, true, src.DataType, ea, src);
424+
var store = m.Fn(intrinsic.MakeInstance(32, src.DataType), ea, src);
425425
var dst = Operand(0);
426426
m.Assign(dst, store);
427427
}
@@ -471,7 +471,7 @@ private void RewriteMultiplyAccumulate(Func<Expression, Expression, Expression>
471471

472472
private void RewriteHint()
473473
{
474-
var ldrex = m.Fn(ldrex_intrinsic, m.AddrOf(PrimitiveType.Ptr32, Operand(0)));
474+
var ldrex = m.Fn(ldrex_intrinsic.MakeInstance(32, PrimitiveType.Word32), m.AddrOf(PrimitiveType.Ptr32, Operand(0)));
475475
m.SideEffect(m.Fn(ldrex));
476476
}
477477

@@ -514,9 +514,17 @@ private void RewriteLdm(Expression dst, int skip, int offset, Func<Expression, E
514514
}
515515
}
516516

517-
private void RewriteLdrex()
517+
private void RewriteLdrex(PrimitiveType dt)
518518
{
519-
m.Assign(Operand(0), m.Fn(ldrex_intrinsic, Operand(1)));
519+
m.Assign(Operand(0), m.Fn(ldrex_intrinsic.MakeInstance(32, dt), Operand(1)));
520+
}
521+
522+
private void RewriteLdrexd()
523+
{
524+
var regLo = (RegisterStorage) instr.Operands[0];
525+
var regHi = (RegisterStorage) instr.Operands[1];
526+
var opDst = binder.EnsureSequence(PrimitiveType.Word64, regHi, regLo);
527+
m.Assign(opDst, m.Fn(ldrex_intrinsic.MakeInstance(32, PrimitiveType.Word64), this.Operand(2)));
520528
}
521529

522530
private void RewriteShift(Func<Expression, Expression, Expression> ctor)

src/Arch/Arm/AArch32/ArmRewriter.cs

Lines changed: 55 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,6 @@ public IEnumerator<RtlInstructionCluster> GetEnumerator()
9494
case Mnemonic.fldmiax:
9595
case Mnemonic.fstmdbx:
9696
case Mnemonic.fstmiax:
97-
case Mnemonic.ldrexb:
98-
case Mnemonic.ldrexd:
99-
case Mnemonic.ldrexh:
10097
case Mnemonic.mcr2:
10198
case Mnemonic.mcrr2:
10299
case Mnemonic.mrc2:
@@ -132,7 +129,6 @@ public IEnumerator<RtlInstructionCluster> GetEnumerator()
132129
case Mnemonic.srsia:
133130
case Mnemonic.srsib:
134131
case Mnemonic.ssax:
135-
case Mnemonic.strexd:
136132
case Mnemonic.sxtab16:
137133
case Mnemonic.sxtb16:
138134
case Mnemonic.uhadd16:
@@ -270,12 +266,13 @@ public IEnumerator<RtlInstructionCluster> GetEnumerator()
270266
case Mnemonic.hvc: RewriteHvc(); break;
271267
case Mnemonic.isb: RewriteIsb(); break;
272268
case Mnemonic.it: RewriteIt(); break;
273-
case Mnemonic.lda: RewriteLoadAcquire(lda_sig); break;
274-
case Mnemonic.ldab: RewriteLoadAcquire(ldab_sig); break;
275-
case Mnemonic.ldaex: RewriteLoadAcquire(ldaex_sig); break;
276-
case Mnemonic.ldaexb: RewriteLoadAcquire(ldaexb_sig); break;
277-
case Mnemonic.ldaexd: RewriteLoadAcquireDouble(ldaexd_sig); break;
278-
case Mnemonic.ldah: RewriteLoadAcquire(ldah_sig); break;
269+
case Mnemonic.lda: RewriteLoadAcquire(lda_sig, PrimitiveType.Word32); break;
270+
case Mnemonic.ldab: RewriteLoadAcquire(lda_sig, PrimitiveType.Byte); break;
271+
case Mnemonic.ldaex: RewriteLoadAcquire(ldaex_sig, PrimitiveType.Word32); break;
272+
case Mnemonic.ldaexb: RewriteLoadAcquire(ldaex_sig, PrimitiveType.Byte); break;
273+
case Mnemonic.ldaexd: RewriteLoadAcquireDouble(ldaex_sig); break;
274+
case Mnemonic.ldaexh: RewriteLoadAcquire(ldaex_sig, PrimitiveType.Word16); break;
275+
case Mnemonic.ldah: RewriteLoadAcquire(lda_sig, PrimitiveType.Word16); break;
279276
case Mnemonic.ldc2l: RewriteLdc("__ldc2l"); break;
280277
case Mnemonic.ldc2: RewriteLdc("__ldc2"); break;
281278
case Mnemonic.ldcl: RewriteLdc("__ldcl"); break;
@@ -295,7 +292,10 @@ public IEnumerator<RtlInstructionCluster> GetEnumerator()
295292
case Mnemonic.ldrsh: RewriteLdr(PrimitiveType.Word32, PrimitiveType.Int16); break;
296293
case Mnemonic.ldrsht: RewriteLdr(PrimitiveType.Word32, PrimitiveType.Int16); break;
297294
case Mnemonic.ldrd: RewriteLdrd(); break;
298-
case Mnemonic.ldrex: RewriteLdrex(); break;
295+
case Mnemonic.ldrex: RewriteLdrex(PrimitiveType.Word32); break;
296+
case Mnemonic.ldrexb: RewriteLdrex(PrimitiveType.Byte); break;
297+
case Mnemonic.ldrexd: RewriteLdrexd(); break;
298+
case Mnemonic.ldrexh: RewriteLdrex(PrimitiveType.Word16); break;
299299
case Mnemonic.lsl: case Mnemonic.lsls: RewriteShift(m.Shl); break;
300300
case Mnemonic.lsr: RewriteShift(m.Shr); break;
301301
case Mnemonic.nop: m.Nop(); break;
@@ -386,13 +386,13 @@ public IEnumerator<RtlInstructionCluster> GetEnumerator()
386386
case Mnemonic.stc2l: RewriteStc(stc2l_intrinsic); break;
387387
case Mnemonic.stc2: RewriteStc(stc2_intrinsic); break;
388388
case Mnemonic.stcl: RewriteStc(stcl_intrinsic); break;
389-
case Mnemonic.stl: RewriteStoreRelease("__store_release_32", PrimitiveType.Word32); break;
390-
case Mnemonic.stlb: RewriteStoreRelease("__store_release_8", PrimitiveType.Byte); break;
391-
case Mnemonic.stlh: RewriteStoreRelease("__store_release_16", PrimitiveType.Word16); break;
392-
case Mnemonic.stlex: RewriteStoreExclusive("__store_release_exclusive_32", PrimitiveType.Word32); break;
393-
case Mnemonic.stlexb: RewriteStoreExclusive("__store_release_exclusive_8", PrimitiveType.Byte); break;
394-
case Mnemonic.stlexh: RewriteStoreExclusive("__store_release_exclusive_16", PrimitiveType.Word16); break;
395-
case Mnemonic.stlexd: RewriteStoreReleaseDoubleExclusive("__store_release_exclusive_64"); break;
389+
case Mnemonic.stl: RewriteStoreRelease(stl_intrinsic, PrimitiveType.Word32); break;
390+
case Mnemonic.stlb: RewriteStoreRelease(stl_intrinsic, PrimitiveType.Byte); break;
391+
case Mnemonic.stlh: RewriteStoreRelease(stl_intrinsic, PrimitiveType.Word16); break;
392+
case Mnemonic.stlex: RewriteStoreExclusive(stlex_intrinsic, PrimitiveType.Word32); break;
393+
case Mnemonic.stlexb: RewriteStoreExclusive(stlex_intrinsic, PrimitiveType.Byte); break;
394+
case Mnemonic.stlexh: RewriteStoreExclusive(stlex_intrinsic, PrimitiveType.Word16); break;
395+
case Mnemonic.stlexd: RewriteStoreReleaseDoubleExclusive(stlex_intrinsic); break;
396396
case Mnemonic.stm: RewriteStm(true, true); break;
397397
case Mnemonic.stmdb: RewriteStm(false, false); break;
398398
case Mnemonic.stmda: RewriteStm(false, true); break;
@@ -401,9 +401,10 @@ public IEnumerator<RtlInstructionCluster> GetEnumerator()
401401
case Mnemonic.strb: RewriteStr(PrimitiveType.Byte); break;
402402
case Mnemonic.strbt: RewriteStr(PrimitiveType.Byte); break;
403403
case Mnemonic.strd: RewriteStrd(); break;
404-
case Mnemonic.strex: RewriteStoreExclusive("__store_exclusive_32", PrimitiveType.Word32); break;
405-
case Mnemonic.strexb: RewriteStoreExclusive("__store_exclusive_8", PrimitiveType.Byte); break;
406-
case Mnemonic.strexh: RewriteStoreExclusive("__store_exclusive_16", PrimitiveType.Word16); break;
404+
case Mnemonic.strex: RewriteStoreExclusive(strex_intrinsic, PrimitiveType.Word32); break;
405+
case Mnemonic.strexb: RewriteStoreExclusive(strex_intrinsic, PrimitiveType.Byte); break;
406+
case Mnemonic.strexd: RewriteStoreReleaseDoubleExclusive(strex_intrinsic); break;
407+
case Mnemonic.strexh: RewriteStoreExclusive(strex_intrinsic, PrimitiveType.Word16); break;
407408
case Mnemonic.strh: RewriteStr(PrimitiveType.UInt16); break;
408409
case Mnemonic.strht: RewriteStr(PrimitiveType.UInt16); break;
409410
case Mnemonic.strt: RewriteStr(PrimitiveType.Word32); break;
@@ -646,7 +647,17 @@ void RewriteB(bool link)
646647
else
647648
{
648649
ConditionalSkip(true);
649-
m.Goto(dst);
650+
if (instr.Operands[0] is RegisterStorage rop && rop == Registers.lr)
651+
{
652+
//$TODO: cheating a little since
653+
// one could consider lr being set explitly.
654+
// however, this is very uncommon.
655+
m.Return(0, 0);
656+
}
657+
else
658+
{
659+
m.Goto(dst);
660+
}
650661
}
651662
}
652663
}
@@ -1068,16 +1079,14 @@ private void EmitUnitTest(AArch32Instruction instr)
10681079
.Void();
10691080
private static readonly IntrinsicProcedure cps_id_intrinsic = new IntrinsicBuilder("__cps_id", true)
10701081
.Void();
1071-
private static readonly IntrinsicProcedure lda_sig;
1072-
private static readonly IntrinsicProcedure ldab_sig;
1073-
private static readonly IntrinsicProcedure ldah_sig;
1074-
private static readonly IntrinsicProcedure ldaex_sig;
1075-
private static readonly IntrinsicProcedure ldaexb_sig;
1076-
private static readonly IntrinsicProcedure ldaexd_sig;
1077-
private static readonly IntrinsicProcedure ldaexh_sig;
1082+
private static readonly IntrinsicProcedure lda_sig = new IntrinsicBuilder("__load_acquire", true)
1083+
.GenericTypes("T").PtrParam("T").Returns("T");
1084+
private static readonly IntrinsicProcedure ldaex_sig = new IntrinsicBuilder("__load_acquire_exclusive", true)
1085+
.GenericTypes("T").PtrParam("T").Returns("T");
10781086
private static readonly IntrinsicProcedure ldrex_intrinsic = new IntrinsicBuilder("__ldrex", true)
1079-
.PtrParam(PrimitiveType.Word32)
1080-
.Returns(PrimitiveType.Word32);
1087+
.GenericTypes("T")
1088+
.PtrParam("T")
1089+
.Returns("T");
10811090
private static readonly IntrinsicProcedure rev_intrinsic = new IntrinsicBuilder("__rev", false)
10821091
.GenericTypes("T")
10831092
.Param(PrimitiveType.Word32)
@@ -1104,6 +1113,21 @@ private void EmitUnitTest(AArch32Instruction instr)
11041113
.Param(PrimitiveType.Word32)
11051114
.Param(PrimitiveType.Word32)
11061115
.Void();
1116+
private static readonly IntrinsicProcedure stl_intrinsic = new IntrinsicBuilder("__store_release", true)
1117+
.GenericTypes("T")
1118+
.PtrParam("T")
1119+
.Param("T")
1120+
.Void();
1121+
private static readonly IntrinsicProcedure stlex_intrinsic = new IntrinsicBuilder("__store_release_exclusive", true)
1122+
.GenericTypes("T")
1123+
.PtrParam("T")
1124+
.Param("T")
1125+
.Returns("T");
1126+
private static readonly IntrinsicProcedure strex_intrinsic = new IntrinsicBuilder("__store_exclusive", true)
1127+
.GenericTypes("T")
1128+
.PtrParam("T")
1129+
.Param("T")
1130+
.Returns("T");
11071131
private static readonly IntrinsicProcedure usat_intrinsic = new IntrinsicBuilder("__usat", false)
11081132
.Param(PrimitiveType.Int32)
11091133
.Param(PrimitiveType.Int32)
@@ -1118,20 +1142,6 @@ static ArmRewriter()
11181142
var p16 = new Pointer(PrimitiveType.Word16, 32);
11191143
var p32 = new Pointer(PrimitiveType.Word32, 32);
11201144
var p64 = new Pointer(PrimitiveType.Word64, 64);
1121-
lda_sig = new IntrinsicBuilder("__load_acquire_32", true)
1122-
.Param(p32).Returns(PrimitiveType.Word32);
1123-
ldab_sig = new IntrinsicBuilder("__load_acquire_8", true)
1124-
.Param(pb).Returns(PrimitiveType.Byte);
1125-
ldah_sig = new IntrinsicBuilder("__load_acquire_16", true)
1126-
.Param(p16).Returns(PrimitiveType.Byte);
1127-
ldaex_sig = new IntrinsicBuilder("__load_acquire_exclusive_32", true)
1128-
.Param(p32).Returns(PrimitiveType.Word32);
1129-
ldaexb_sig = new IntrinsicBuilder("__load_acquire_exclusive_8", true)
1130-
.Param(pb).Returns(PrimitiveType.Byte);
1131-
ldaexd_sig = new IntrinsicBuilder("__load_acquire_exclusive_64", true)
1132-
.Param(p64).Returns(PrimitiveType.Word64);
1133-
ldaexh_sig = new IntrinsicBuilder("__load_acquire_exclusive_16", true)
1134-
.Param(p16).Returns(PrimitiveType.Word16);
11351145

11361146
ssat16_intrinsic = new IntrinsicBuilder("__ssat16", false)
11371147
.Param(PrimitiveType.Int32)

0 commit comments

Comments
 (0)