@@ -17706,6 +17769,76 @@
}
}
+ /* ----------------- (T1) LDREXD ---------------- */
+ if (INSN0(15,4) == 0xe8d) {
+ /* ldrexb, ldrexh, ldrexd (also TBB and tbh but they're done elsewhere */
+ if (INSN1(7,0) == 0x7f) {
+ /* ldrexd */
+ UInt rN = INSN0(3,0);
+ UInt rT = INSN1(15,12);
+ UInt rT2 = INSN1(11,8);
+
+ if (isBadRegT(rT) || isBadRegT(rT2) || rT == rT2 || rN == 15) {
+ /* undecodable; fall through */
+ } else {
+ IRTemp res;
+
+ // go uncond
+ mk_skip_over_T32_if_cond_is_false( condT );
+
+ /* Ok, now we're unconditional. Do the load. */
+ res = newTemp(Ity_I64);
+ stmt( IRStmt_LLSC(Iend_LE, res, getIRegT(rN),
+ NULL/*this is a load*/) );
+ putIRegT(rT, unop(Iop_64HIto32, mkexpr(res)), IRTemp_INVALID);
+ putIRegT(rT2, unop(Iop_64to32, mkexpr(res)), IRTemp_INVALID);
+
+ DIP("ldrexd r%u, r%u, [r%u]\n", rT, rT2, rN);
+ goto decode_success;
+ }
+ }
+ }
+ /* ----------------- (T1) STREXD ---------------- */
+ if (INSN0(15,4) == 0xe8c) {
+ /* strexb, strexh, strexd */
+ if (INSN1(7,4) == 0x7) {
+ /* strexd */
+ UInt rN = INSN0(3,0);
+ UInt rT = INSN1(15,12);
+ UInt rT2 = INSN1(11,8);
+ UInt rD = INSN1(3,0);
+
+ if (rD == 15 || rN == 15
+ || isBadRegT(rD) || isBadRegT(rT) || isBadRegT(rT2)
+ || rD == rN || rD == rT || rD == rT2) {
+ /* undecodable; fall through */
+ } else {
+ IRTemp data;
+ IRTemp resSC1, resSC32;
+
+ // go uncond
+ mk_skip_over_T32_if_cond_is_false( condT );
+
+ data = newTemp(Ity_I64);
+ assign( data, binop(Iop_32HLto64, getIRegT(rT), getIRegT(rT2)) );
+ resSC1 = newTemp(Ity_I1);
+ stmt( IRStmt_LLSC(Iend_LE, resSC1, getIRegT(rN), mkexpr(data)) );
+
+ /* Set rD to 1 on failure, 0 on success. Currently we have
+ resSC1 == 0 on failure, 1 on success. */
+ resSC32 = newTemp(Ity_I32);
+ assign(resSC32,
+ unop(Iop_1Uto32, unop(Iop_Not1, mkexpr(resSC1))));
+
+ putIRegT(rD, mkexpr(resSC32),
+ IRTemp_INVALID);
+ DIP("strexd r%u, r%u, r%u, [r%u]\n", rD, rT, rT2, rN);
+ goto decode_success;
+ }
+ /* fall through */
+ }
+ }
+
/* ----------------- (T1) STREX ----------------- */
if (INSN0(15,4) == 0xE84) {
UInt rN = INSN0(3,0);