diff --git a/arch/armv7/test_lift.py b/arch/armv7/test_lift.py index 983ff092df..b61a7cda4f 100755 --- a/arch/armv7/test_lift.py +++ b/arch/armv7/test_lift.py @@ -128,6 +128,9 @@ ('T', b'\x41\xf3\x1d\x50', 'LLIL_SET_REG.d(r0,LLIL_ASR.d(LLIL_REG.d(r1),LLIL_CONST.b(0x14)))'), # rev r1, r1 ('T', b'\x09\xba', 'LLIL_SET_REG.d(r1,LLIL_OR.d(LLIL_LSR.d(LLIL_REG.d(r1),LLIL_CONST.d(0x18)),LLIL_OR.d(LLIL_LSL.d(LLIL_AND.d(LLIL_LSR.d(LLIL_REG.d(r1),LLIL_CONST.d(0x10)),LLIL_CONST.d(0xFF)),LLIL_CONST.b(0x8)),LLIL_OR.d(LLIL_LSL.d(LLIL_AND.d(LLIL_LSR.d(LLIL_REG.d(r1),LLIL_CONST.d(0x8)),LLIL_CONST.d(0xFF)),LLIL_CONST.b(0x10)),LLIL_LSL.d(LLIL_AND.d(LLIL_REG.d(r1),LLIL_CONST.d(0xFF)),LLIL_CONST.b(0x18))))))'), + ('T', b'\x09\xba', 'LLIL_SET_REG.d(r1,LLIL_OR.d(LLIL_LSR.d(LLIL_REG.d(r1),LLIL_CONST.d(0x18)),LLIL_OR.d(LLIL_LSL.d(LLIL_AND.d(LLIL_LSR.d(LLIL_REG.d(r1),LLIL_CONST.d(0x10)),LLIL_CONST.d(0xFF)),LLIL_CONST.b(0x8)),LLIL_OR.d(LLIL_LSL.d(LLIL_AND.d(LLIL_LSR.d(LLIL_REG.d(r1),LLIL_CONST.d(0x8)),LLIL_CONST.d(0xFF)),LLIL_CONST.b(0x10)),LLIL_LSL.d(LLIL_AND.d(LLIL_REG.d(r1),LLIL_CONST.d(0xFF)),LLIL_CONST.b(0x18))))))'), + # smlabb r0, r0, r5, r4 + ('T', b'\x10\xfb\x05\x40', 'LLIL_SET_REG(r0,LLIL_ADD.d(LLIL_MULS_DP.w(LLIL_LOW_PART.w(LLIL_REG.d(r0)),LLIL_LOW_PART.w(LLIL_REG.d(r5))),LLIL_REG.d(r4)))'), ] import re diff --git a/arch/armv7/thumb2_disasm/il_thumb2.cpp b/arch/armv7/thumb2_disasm/il_thumb2.cpp index cc3856c985..e5ecdd2a3d 100644 --- a/arch/armv7/thumb2_disasm/il_thumb2.cpp +++ b/arch/armv7/thumb2_disasm/il_thumb2.cpp @@ -1641,6 +1641,38 @@ bool GetLowLevelILForThumbInstruction(Architecture* arch, LowLevelILFunction& il case armv7::ARMV7_SMULL: il.AddInstruction(WriteSplitOperands(il, instr, 1, 0, il.MultDoublePrecSigned(4, ReadILOperand(il, instr, 2), ReadILOperand(il, instr, 3)))); break; + case armv7::ARMV7_SMLABB: + case armv7::ARMV7_SMLABT: + case armv7::ARMV7_SMLATB: + case armv7::ARMV7_SMLATT: + { + ExprId op1 = ReadILOperand(il, instr, 1); + ExprId op2 = ReadILOperand(il, instr, 2); + + switch (instr->mnem) { + case armv7::ARMV7_SMLABB: + op1 = il.LowPart(2, op1); + op2 = il.LowPart(2, op2); + break; + case armv7::ARMV7_SMLABT: + op1 = il.LowPart(2, op1); + op2 = il.LowPart(2, il.ArithShiftRight(4, op2, il.Const(1, 16))); + break; + case armv7::ARMV7_SMLATB: + op1 = il.LowPart(2, il.ArithShiftRight(4, op1, il.Const(1, 16))); + op2 = il.LowPart(2, op2); + break; + case armv7::ARMV7_SMLATT: + op1 = il.LowPart(2, il.ArithShiftRight(4, op1, il.Const(1, 16))); + op2 = il.LowPart(2, il.ArithShiftRight(4, op2, il.Const(1, 16))); + break; + } + + il.AddInstruction(WriteArithOperand(il, instr, il.Add(4, il.MultDoublePrecSigned(2, op1, + op2), ReadILOperand(il, instr, 3)), IL_FLAGWRITE_NONE)); + + break; + } case armv7::ARMV7_SMULBB: il.AddInstruction(WriteArithOperand(il, instr, il.Mult(4, il.LowPart(2, ReadILOperand(il, instr, 1)), il.LowPart(2, ReadILOperand(il, instr, 2)), IL_FLAGWRITE_NONE)));