|
From: <sv...@va...> - 2013-04-23 08:53:25
|
sewardj 2013-04-23 09:56:43 +0100 (Tue, 23 Apr 2013)
New Revision: 2713
Log:
Implement SMMLA{r}, both ARM and Thumb. n-i-bz.
(Ben Cheng <bc...@go...>)
Also, move ARM encoding of SMMUL{R} to a more sensible place.
Modified files:
trunk/priv/guest_arm_toIR.c
Modified: trunk/priv/guest_arm_toIR.c (+71 -22)
===================================================================
--- trunk/priv/guest_arm_toIR.c 2013-04-21 01:45:18 +01:00 (rev 2712)
+++ trunk/priv/guest_arm_toIR.c 2013-04-23 09:56:43 +01:00 (rev 2713)
@@ -15320,6 +15320,30 @@
}
}
+ /* ------------------- smmla ------------------ */
+ if (INSN(27,20) == BITS8(0,1,1,1,0,1,0,1)
+ && INSN(15,12) != BITS4(1,1,1,1)
+ && (INSN(7,4) & BITS4(1,1,0,1)) == BITS4(0,0,0,1)) {
+ UInt bitR = INSN(5,5);
+ UInt rD = INSN(19,16);
+ UInt rA = INSN(15,12);
+ UInt rM = INSN(11,8);
+ UInt rN = INSN(3,0);
+ if (rD != 15 && rM != 15 && rN != 15) {
+ IRExpr* res
+ = unop(Iop_64HIto32,
+ binop(Iop_Add64,
+ binop(Iop_Add64,
+ binop(Iop_32HLto64, getIRegA(rA), mkU32(0)),
+ binop(Iop_MullS32, getIRegA(rN), getIRegA(rM))),
+ mkU64(bitR ? 0x80000000ULL : 0ULL)));
+ putIRegA(rD, res, condT, Ijk_Boring);
+ DIP("smmla%s%s r%u, r%u, r%u, r%u\n",
+ nCC(INSN_COND), bitR ? "r" : "", rD, rN, rM, rA);
+ goto decode_success;
+ }
+ }
+
/* ------------------- NOP ------------------ */
if (0x0320F000 == (insn & 0x0FFFFFFF)) {
DIP("nop%s\n", nCC(INSN_COND));
@@ -19121,6 +19145,52 @@
}
}
+ /* ------------------- (T1) SMMUL{R} ------------------ */
+ if (INSN0(15,7) == BITS9(1,1,1,1,1,0,1,1,0)
+ && INSN0(6,4) == BITS3(1,0,1)
+ && INSN1(15,12) == BITS4(1,1,1,1)
+ && INSN1(7,5) == BITS3(0,0,0)) {
+ UInt bitR = INSN1(4,4);
+ UInt rD = INSN1(11,8);
+ UInt rM = INSN1(3,0);
+ UInt rN = INSN0(3,0);
+ if (!isBadRegT(rD) && !isBadRegT(rN) && !isBadRegT(rM)) {
+ IRExpr* res
+ = unop(Iop_64HIto32,
+ binop(Iop_Add64,
+ binop(Iop_MullS32, getIRegT(rN), getIRegT(rM)),
+ mkU64(bitR ? 0x80000000ULL : 0ULL)));
+ putIRegT(rD, res, condT);
+ DIP("smmul%s r%u, r%u, r%u\n",
+ bitR ? "r" : "", rD, rN, rM);
+ goto decode_success;
+ }
+ }
+
+ /* ------------------- (T1) SMMLA{R} ------------------ */
+ if (INSN0(15,7) == BITS9(1,1,1,1,1,0,1,1,0)
+ && INSN0(6,4) == BITS3(1,0,1)
+ && INSN1(7,5) == BITS3(0,0,0)) {
+ UInt bitR = INSN1(4,4);
+ UInt rA = INSN1(15,12);
+ UInt rD = INSN1(11,8);
+ UInt rM = INSN1(3,0);
+ UInt rN = INSN0(3,0);
+ if (!isBadRegT(rD) && !isBadRegT(rN) && !isBadRegT(rM) && (rA != 13)) {
+ IRExpr* res
+ = unop(Iop_64HIto32,
+ binop(Iop_Add64,
+ binop(Iop_Add64,
+ binop(Iop_32HLto64, getIRegT(rA), mkU32(0)),
+ binop(Iop_MullS32, getIRegT(rN), getIRegT(rM))),
+ mkU64(bitR ? 0x80000000ULL : 0ULL)));
+ putIRegT(rD, res, condT);
+ DIP("smmla%s r%u, r%u, r%u, r%u\n",
+ bitR ? "r" : "", rD, rN, rM, rA);
+ goto decode_success;
+ }
+ }
+
/* ------------------ (T2) ADR ------------------ */
if ((INSN0(15,0) == 0xF2AF || INSN0(15,0) == 0xF6AF)
&& INSN1(15,15) == 0) {
@@ -19477,6 +19547,7 @@
goto decode_success;
}
}
+
/* -------------- v7 barrier insns -------------- */
if (INSN0(15,0) == 0xF3BF && (INSN1(15,0) & 0xFF00) == 0x8F00) {
/* FIXME: should this be unconditional? */
@@ -19586,28 +19657,6 @@
goto decode_success;
}
- /* ------------------- (T1) SMMUL{R} ------------------ */
- if (INSN0(15,7) == BITS9(1,1,1,1,1,0,1,1,0)
- && INSN0(6,4) == BITS3(1,0,1)
- && INSN1(15,12) == BITS4(1,1,1,1)
- && INSN1(7,5) == BITS3(0,0,0)) {
- UInt bitR = INSN1(4,4);
- UInt rD = INSN1(11,8);
- UInt rM = INSN1(3,0);
- UInt rN = INSN0(3,0);
- if (!isBadRegT(rD) && !isBadRegT(rN) && !isBadRegT(rM)) {
- IRExpr* res
- = unop(Iop_64HIto32,
- binop(Iop_Add64,
- binop(Iop_MullS32, getIRegT(rN), getIRegT(rM)),
- mkU64(bitR ? 0x80000000ULL : 0ULL)));
- putIRegT(rD, res, condT);
- DIP("smmul%s r%u, r%u, r%u\n",
- bitR ? "r" : "", rD, rN, rM);
- goto decode_success;
- }
- }
-
/* -------------- (T1) LDRT reg+#imm8 -------------- */
/* Load Register Unprivileged:
ldrt Rt, [Rn, #imm8]
|