Skip to content

Commit

Permalink
Enhancement: more ARM32 rewriters.
Browse files Browse the repository at this point in the history
  • Loading branch information
uxmal committed Apr 7, 2022
1 parent db5d3c7 commit ac2e4d4
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 113 deletions.
32 changes: 16 additions & 16 deletions src/Arch/Arm/AArch32/A32Disassembler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1769,15 +1769,15 @@ static A32Disassembler()

// --
var LdrdRegister = Instr(Mnemonic.ldrd, Rp_12,M_(w8));
var LdrhRegister = Instr(Mnemonic.ldrh, r(3),M_(w2));
var LdrsbRegister = Instr(Mnemonic.ldrsb, r(3),M_(s1));
var LdrshRegister = Instr(Mnemonic.ldrsh, r(3),M_(s2));
var Ldrht = Instr(Mnemonic.ldrht, r(3),Mh(w2));
var Ldrsbt = Instr(Mnemonic.ldrsbt, r(3),Mh(s1));
var Ldrsht = Instr(Mnemonic.ldrsht, r(3),Mh(s2));
var LdrhRegister = Instr(Mnemonic.ldrh, Rnp12,M_(w2));
var LdrsbRegister = Instr(Mnemonic.ldrsb, Rnp12,M_(s1));
var LdrshRegister = Instr(Mnemonic.ldrsh, Rnp12,M_(s2));
var Ldrht = Instr(Mnemonic.ldrht, Rnp12,Mh(w2));
var Ldrsbt = Instr(Mnemonic.ldrsbt, Rnp12,Mh(s1));
var Ldrsht = Instr(Mnemonic.ldrsht, Rnp12,Mh(s2));
var StrdRegister = Instr(Mnemonic.strd, Rp_12,Mx(w8));
var StrhRegister = Instr(Mnemonic.strh, r(3),M_(w2));
var Strht = Instr(Mnemonic.strht, r(3),Mh(w2));
var StrhRegister = Instr(Mnemonic.strh, Rnp12,M_(w2));
var Strht = Instr(Mnemonic.strht, Rnp12,Mh(w2));

var LoadStoreDualHalfSbyteRegister = Mask(24, 1,
Mask(20, 2,
Expand Down Expand Up @@ -1813,16 +1813,16 @@ static A32Disassembler()
LdrsbRegister,
LdrshRegister)));

var LdrdLiteral = Instr(Mnemonic.ldrd, Rp_12, r(3), Mh(w8, false));
var LdrhLiteral = Instr(Mnemonic.ldrh, r(3), Mh(w2, false));
var LdrsbLiteral = Instr(Mnemonic.ldrsb, r(3),Mh(s1, false));
var LdrshLiteral = Instr(Mnemonic.ldrsh, r(3),Mh(s2, false));
var StrhImmediate = Instr(Mnemonic.strh, r(3),Mh(w2));
var LdrdLiteral = Instr(Mnemonic.ldrd, Rp_12, Rnp12, Mh(w8, false));
var LdrhLiteral = Instr(Mnemonic.ldrh, Rnp12, Mh(w2, false));
var LdrsbLiteral = Instr(Mnemonic.ldrsb, Rnp12, Mh(s1, false));
var LdrshLiteral = Instr(Mnemonic.ldrsh, Rnp12, Mh(s2, false));
var StrhImmediate = Instr(Mnemonic.strh, Rnp12, Mh(w2));
var LdrdImmediate = Instr(Mnemonic.ldrd, Rp_12,Mh(w8));
var StrdImmediate = Instr(Mnemonic.strd, Rp_12,Mh(w8));
var LdrhImmediate = Instr(Mnemonic.ldrh, r(3),Mh(w2));
var LdrsbImmediate = Instr(Mnemonic.ldrsb, r(3),Mh(s1));
var LdrshImmediate = Instr(Mnemonic.ldrsh, r(3),Mh(s2));
var LdrhImmediate = Instr(Mnemonic.ldrh, Rnp12, Mh(w2));
var LdrsbImmediate = Instr(Mnemonic.ldrsb, Rnp12, Mh(s1));
var LdrshImmediate = Instr(Mnemonic.ldrsh, Rnp12, Mh(s2));

var LoadStoreDualHalfSbyteImmediate = Mask(Bf((24, 1), (20, 2)), // LoadStoreDualHalfSbyteImmediate Rn != pc P:W:op1"LoadStoreDualHalfSbyteImmediate",
Mask(5, 2, // LoadStoreDualHalfSbyteImmediate Rn != pc P:W:op1=000 op2
Expand Down
32 changes: 20 additions & 12 deletions src/Arch/Arm/AArch32/ArmRewriter.Alu.cs
Original file line number Diff line number Diff line change
Expand Up @@ -280,15 +280,15 @@ private void RewriteTst()
m.Cond(m.And(opDst, opSrc)));
}

private void RewriteLoadAcquire(IntrinsicProcedure intrinsic)
private void RewriteLoadAcquire(IntrinsicProcedure intrinsic, DataType dt)
{
var mem = (MemoryOperand) instr.Operands[1];
var ea = binder.EnsureRegister(mem.BaseRegister!);
var dst = binder.EnsureRegister((RegisterStorage) instr.Operands[0]);
intrinsic = intrinsic.MakeInstance(32, dt);
Expression src = m.Fn(intrinsic, ea);
if (src.DataType.BitSize != dst.DataType.BitSize)
{
var dt = intrinsic.ReturnType;
var tmp = binder.CreateTemporary(dt);
m.Assign(tmp, src);
src = m.Convert(tmp, dt, dst.DataType);
Expand All @@ -304,7 +304,7 @@ private void RewriteLoadAcquireDouble(IntrinsicProcedure intrinsic)
var regHi = (RegisterStorage) instr.Operands[0];
var regLo = (RegisterStorage) instr.Operands[1];
var dst = binder.EnsureSequence(PrimitiveType.Word64, regHi, regLo);
var src = m.Fn(intrinsic, ea);
var src = m.Fn(intrinsic.MakeInstance(32, dst.DataType), ea);
m.Assign(dst, src);
}

Expand Down Expand Up @@ -380,7 +380,7 @@ private void RewriteLdrd()
MaybePostOperand(2);
}

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

private void RewriteStoreExclusive(string intrinsicName, PrimitiveType dt)
private void RewriteStoreExclusive(IntrinsicProcedure intrinsic, PrimitiveType dt)
{
var src = binder.EnsureRegister((RegisterStorage) instr.Operands[1]);
if (src.DataType.BitSize != dt.BitSize)
Expand All @@ -408,20 +408,20 @@ private void RewriteStoreExclusive(string intrinsicName, PrimitiveType dt)
var mem = (MemoryOperand) instr.Operands[2];
var ea = binder.EnsureRegister(mem.BaseRegister!);
ea.DataType = new Pointer(dt, 32);
var store = host.Intrinsic(intrinsicName, true, dt, ea, src);
var store = m.Fn(intrinsic.MakeInstance(32, dt), ea, src);
var dst = Operand(0);
m.Assign(dst, store);
}

private void RewriteStoreReleaseDoubleExclusive(string intrinsicName)
private void RewriteStoreReleaseDoubleExclusive(IntrinsicProcedure intrinsic)
{
var mem = (MemoryOperand) instr.Operands[3];
var ea = binder.EnsureRegister(mem.BaseRegister!);
ea.DataType = new Pointer(PrimitiveType.Word64, 32);
var regHi = (RegisterStorage) instr.Operands[1];
var regLo = (RegisterStorage) instr.Operands[2];
var src = binder.EnsureSequence(PrimitiveType.Word64, regHi, regLo);
var store = host.Intrinsic(intrinsicName, true, src.DataType, ea, src);
var store = m.Fn(intrinsic.MakeInstance(32, src.DataType), ea, src);
var dst = Operand(0);
m.Assign(dst, store);
}
Expand Down Expand Up @@ -471,7 +471,7 @@ private void RewriteMultiplyAccumulate(Func<Expression, Expression, Expression>

private void RewriteHint()
{
var ldrex = m.Fn(ldrex_intrinsic, m.AddrOf(PrimitiveType.Ptr32, Operand(0)));
var ldrex = m.Fn(ldrex_intrinsic.MakeInstance(32, PrimitiveType.Word32), m.AddrOf(PrimitiveType.Ptr32, Operand(0)));
m.SideEffect(m.Fn(ldrex));
}

Expand Down Expand Up @@ -514,9 +514,17 @@ private void RewriteLdm(Expression dst, int skip, int offset, Func<Expression, E
}
}

private void RewriteLdrex()
private void RewriteLdrex(PrimitiveType dt)
{
m.Assign(Operand(0), m.Fn(ldrex_intrinsic, Operand(1)));
m.Assign(Operand(0), m.Fn(ldrex_intrinsic.MakeInstance(32, dt), Operand(1)));
}

private void RewriteLdrexd()
{
var regLo = (RegisterStorage) instr.Operands[0];
var regHi = (RegisterStorage) instr.Operands[1];
var opDst = binder.EnsureSequence(PrimitiveType.Word64, regHi, regLo);
m.Assign(opDst, m.Fn(ldrex_intrinsic.MakeInstance(32, PrimitiveType.Word64), this.Operand(2)));
}

private void RewriteShift(Func<Expression, Expression, Expression> ctor)
Expand Down
100 changes: 55 additions & 45 deletions src/Arch/Arm/AArch32/ArmRewriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,6 @@ public IEnumerator<RtlInstructionCluster> GetEnumerator()
case Mnemonic.fldmiax:
case Mnemonic.fstmdbx:
case Mnemonic.fstmiax:
case Mnemonic.ldrexb:
case Mnemonic.ldrexd:
case Mnemonic.ldrexh:
case Mnemonic.mcr2:
case Mnemonic.mcrr2:
case Mnemonic.mrc2:
Expand Down Expand Up @@ -132,7 +129,6 @@ public IEnumerator<RtlInstructionCluster> GetEnumerator()
case Mnemonic.srsia:
case Mnemonic.srsib:
case Mnemonic.ssax:
case Mnemonic.strexd:
case Mnemonic.sxtab16:
case Mnemonic.sxtb16:
case Mnemonic.uhadd16:
Expand Down Expand Up @@ -270,12 +266,13 @@ public IEnumerator<RtlInstructionCluster> GetEnumerator()
case Mnemonic.hvc: RewriteHvc(); break;
case Mnemonic.isb: RewriteIsb(); break;
case Mnemonic.it: RewriteIt(); break;
case Mnemonic.lda: RewriteLoadAcquire(lda_sig); break;
case Mnemonic.ldab: RewriteLoadAcquire(ldab_sig); break;
case Mnemonic.ldaex: RewriteLoadAcquire(ldaex_sig); break;
case Mnemonic.ldaexb: RewriteLoadAcquire(ldaexb_sig); break;
case Mnemonic.ldaexd: RewriteLoadAcquireDouble(ldaexd_sig); break;
case Mnemonic.ldah: RewriteLoadAcquire(ldah_sig); break;
case Mnemonic.lda: RewriteLoadAcquire(lda_sig, PrimitiveType.Word32); break;
case Mnemonic.ldab: RewriteLoadAcquire(lda_sig, PrimitiveType.Byte); break;
case Mnemonic.ldaex: RewriteLoadAcquire(ldaex_sig, PrimitiveType.Word32); break;
case Mnemonic.ldaexb: RewriteLoadAcquire(ldaex_sig, PrimitiveType.Byte); break;
case Mnemonic.ldaexd: RewriteLoadAcquireDouble(ldaex_sig); break;
case Mnemonic.ldaexh: RewriteLoadAcquire(ldaex_sig, PrimitiveType.Word16); break;
case Mnemonic.ldah: RewriteLoadAcquire(lda_sig, PrimitiveType.Word16); break;
case Mnemonic.ldc2l: RewriteLdc("__ldc2l"); break;
case Mnemonic.ldc2: RewriteLdc("__ldc2"); break;
case Mnemonic.ldcl: RewriteLdc("__ldcl"); break;
Expand All @@ -295,7 +292,10 @@ public IEnumerator<RtlInstructionCluster> GetEnumerator()
case Mnemonic.ldrsh: RewriteLdr(PrimitiveType.Word32, PrimitiveType.Int16); break;
case Mnemonic.ldrsht: RewriteLdr(PrimitiveType.Word32, PrimitiveType.Int16); break;
case Mnemonic.ldrd: RewriteLdrd(); break;
case Mnemonic.ldrex: RewriteLdrex(); break;
case Mnemonic.ldrex: RewriteLdrex(PrimitiveType.Word32); break;
case Mnemonic.ldrexb: RewriteLdrex(PrimitiveType.Byte); break;
case Mnemonic.ldrexd: RewriteLdrexd(); break;
case Mnemonic.ldrexh: RewriteLdrex(PrimitiveType.Word16); break;
case Mnemonic.lsl: case Mnemonic.lsls: RewriteShift(m.Shl); break;
case Mnemonic.lsr: RewriteShift(m.Shr); break;
case Mnemonic.nop: m.Nop(); break;
Expand Down Expand Up @@ -386,13 +386,13 @@ public IEnumerator<RtlInstructionCluster> GetEnumerator()
case Mnemonic.stc2l: RewriteStc(stc2l_intrinsic); break;
case Mnemonic.stc2: RewriteStc(stc2_intrinsic); break;
case Mnemonic.stcl: RewriteStc(stcl_intrinsic); break;
case Mnemonic.stl: RewriteStoreRelease("__store_release_32", PrimitiveType.Word32); break;
case Mnemonic.stlb: RewriteStoreRelease("__store_release_8", PrimitiveType.Byte); break;
case Mnemonic.stlh: RewriteStoreRelease("__store_release_16", PrimitiveType.Word16); break;
case Mnemonic.stlex: RewriteStoreExclusive("__store_release_exclusive_32", PrimitiveType.Word32); break;
case Mnemonic.stlexb: RewriteStoreExclusive("__store_release_exclusive_8", PrimitiveType.Byte); break;
case Mnemonic.stlexh: RewriteStoreExclusive("__store_release_exclusive_16", PrimitiveType.Word16); break;
case Mnemonic.stlexd: RewriteStoreReleaseDoubleExclusive("__store_release_exclusive_64"); break;
case Mnemonic.stl: RewriteStoreRelease(stl_intrinsic, PrimitiveType.Word32); break;
case Mnemonic.stlb: RewriteStoreRelease(stl_intrinsic, PrimitiveType.Byte); break;
case Mnemonic.stlh: RewriteStoreRelease(stl_intrinsic, PrimitiveType.Word16); break;
case Mnemonic.stlex: RewriteStoreExclusive(stlex_intrinsic, PrimitiveType.Word32); break;
case Mnemonic.stlexb: RewriteStoreExclusive(stlex_intrinsic, PrimitiveType.Byte); break;
case Mnemonic.stlexh: RewriteStoreExclusive(stlex_intrinsic, PrimitiveType.Word16); break;
case Mnemonic.stlexd: RewriteStoreReleaseDoubleExclusive(stlex_intrinsic); break;
case Mnemonic.stm: RewriteStm(true, true); break;
case Mnemonic.stmdb: RewriteStm(false, false); break;
case Mnemonic.stmda: RewriteStm(false, true); break;
Expand All @@ -401,9 +401,10 @@ public IEnumerator<RtlInstructionCluster> GetEnumerator()
case Mnemonic.strb: RewriteStr(PrimitiveType.Byte); break;
case Mnemonic.strbt: RewriteStr(PrimitiveType.Byte); break;
case Mnemonic.strd: RewriteStrd(); break;
case Mnemonic.strex: RewriteStoreExclusive("__store_exclusive_32", PrimitiveType.Word32); break;
case Mnemonic.strexb: RewriteStoreExclusive("__store_exclusive_8", PrimitiveType.Byte); break;
case Mnemonic.strexh: RewriteStoreExclusive("__store_exclusive_16", PrimitiveType.Word16); break;
case Mnemonic.strex: RewriteStoreExclusive(strex_intrinsic, PrimitiveType.Word32); break;
case Mnemonic.strexb: RewriteStoreExclusive(strex_intrinsic, PrimitiveType.Byte); break;
case Mnemonic.strexd: RewriteStoreReleaseDoubleExclusive(strex_intrinsic); break;
case Mnemonic.strexh: RewriteStoreExclusive(strex_intrinsic, PrimitiveType.Word16); break;
case Mnemonic.strh: RewriteStr(PrimitiveType.UInt16); break;
case Mnemonic.strht: RewriteStr(PrimitiveType.UInt16); break;
case Mnemonic.strt: RewriteStr(PrimitiveType.Word32); break;
Expand Down Expand Up @@ -646,7 +647,17 @@ void RewriteB(bool link)
else
{
ConditionalSkip(true);
m.Goto(dst);
if (instr.Operands[0] is RegisterStorage rop && rop == Registers.lr)
{
//$TODO: cheating a little since
// one could consider lr being set explitly.
// however, this is very uncommon.
m.Return(0, 0);
}
else
{
m.Goto(dst);
}
}
}
}
Expand Down Expand Up @@ -1068,16 +1079,14 @@ private void EmitUnitTest(AArch32Instruction instr)
.Void();
private static readonly IntrinsicProcedure cps_id_intrinsic = new IntrinsicBuilder("__cps_id", true)
.Void();
private static readonly IntrinsicProcedure lda_sig;
private static readonly IntrinsicProcedure ldab_sig;
private static readonly IntrinsicProcedure ldah_sig;
private static readonly IntrinsicProcedure ldaex_sig;
private static readonly IntrinsicProcedure ldaexb_sig;
private static readonly IntrinsicProcedure ldaexd_sig;
private static readonly IntrinsicProcedure ldaexh_sig;
private static readonly IntrinsicProcedure lda_sig = new IntrinsicBuilder("__load_acquire", true)
.GenericTypes("T").PtrParam("T").Returns("T");
private static readonly IntrinsicProcedure ldaex_sig = new IntrinsicBuilder("__load_acquire_exclusive", true)
.GenericTypes("T").PtrParam("T").Returns("T");
private static readonly IntrinsicProcedure ldrex_intrinsic = new IntrinsicBuilder("__ldrex", true)
.PtrParam(PrimitiveType.Word32)
.Returns(PrimitiveType.Word32);
.GenericTypes("T")
.PtrParam("T")
.Returns("T");
private static readonly IntrinsicProcedure rev_intrinsic = new IntrinsicBuilder("__rev", false)
.GenericTypes("T")
.Param(PrimitiveType.Word32)
Expand All @@ -1104,6 +1113,21 @@ private void EmitUnitTest(AArch32Instruction instr)
.Param(PrimitiveType.Word32)
.Param(PrimitiveType.Word32)
.Void();
private static readonly IntrinsicProcedure stl_intrinsic = new IntrinsicBuilder("__store_release", true)
.GenericTypes("T")
.PtrParam("T")
.Param("T")
.Void();
private static readonly IntrinsicProcedure stlex_intrinsic = new IntrinsicBuilder("__store_release_exclusive", true)
.GenericTypes("T")
.PtrParam("T")
.Param("T")
.Returns("T");
private static readonly IntrinsicProcedure strex_intrinsic = new IntrinsicBuilder("__store_exclusive", true)
.GenericTypes("T")
.PtrParam("T")
.Param("T")
.Returns("T");
private static readonly IntrinsicProcedure usat_intrinsic = new IntrinsicBuilder("__usat", false)
.Param(PrimitiveType.Int32)
.Param(PrimitiveType.Int32)
Expand All @@ -1118,20 +1142,6 @@ static ArmRewriter()
var p16 = new Pointer(PrimitiveType.Word16, 32);
var p32 = new Pointer(PrimitiveType.Word32, 32);
var p64 = new Pointer(PrimitiveType.Word64, 64);
lda_sig = new IntrinsicBuilder("__load_acquire_32", true)
.Param(p32).Returns(PrimitiveType.Word32);
ldab_sig = new IntrinsicBuilder("__load_acquire_8", true)
.Param(pb).Returns(PrimitiveType.Byte);
ldah_sig = new IntrinsicBuilder("__load_acquire_16", true)
.Param(p16).Returns(PrimitiveType.Byte);
ldaex_sig = new IntrinsicBuilder("__load_acquire_exclusive_32", true)
.Param(p32).Returns(PrimitiveType.Word32);
ldaexb_sig = new IntrinsicBuilder("__load_acquire_exclusive_8", true)
.Param(pb).Returns(PrimitiveType.Byte);
ldaexd_sig = new IntrinsicBuilder("__load_acquire_exclusive_64", true)
.Param(p64).Returns(PrimitiveType.Word64);
ldaexh_sig = new IntrinsicBuilder("__load_acquire_exclusive_16", true)
.Param(p16).Returns(PrimitiveType.Word16);

ssat16_intrinsic = new IntrinsicBuilder("__ssat16", false)
.Param(PrimitiveType.Int32)
Expand Down
Loading

0 comments on commit ac2e4d4

Please sign in to comment.