Skip to content

Commit a96275b

Browse files
committed
[armv7] Emit bswap, clz, and rbit instructions during lifting
1 parent aad1f44 commit a96275b

1 file changed

Lines changed: 13 additions & 61 deletions

File tree

arch/armv7/il.cpp

Lines changed: 13 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,7 @@ bool GetLowLevelILForArmInstruction(Architecture* arch, uint64_t addr, LowLevelI
722722
InstructionOperand& op4 = instr.operands[3];
723723
InstructionOperand& op5 = instr.operands[4];
724724
InstructionOperand& op6 = instr.operands[5];
725-
LowLevelILLabel trueLabel, falseLabel, endLabel, loopBody, loopStart, loopExit;
725+
LowLevelILLabel trueLabel, falseLabel, endLabel;
726726
uint32_t flagOperation[2] = {IL_FLAGWRITE_NONE, IL_FLAGWRITE_ALL};
727727
LowLevelILLabel trueCode, falseCode, endCode;
728728
switch (instr.operation)
@@ -816,25 +816,8 @@ bool GetLowLevelILForArmInstruction(Architecture* arch, uint64_t addr, LowLevelI
816816
break;
817817
case ARMV7_CLZ:
818818
ConditionExecute(addr, instr.cond, instr, il, [&](size_t, Instruction&, LowLevelILFunction& il){
819-
//Count leading zeros
820-
//
821-
// TEMP0 = 0
822-
// TEMP1 = op2.reg
823-
// while (TEMP1 != 0)
824-
// TEMP1 = TEMP1 >> 1
825-
// TEMP0 = TEMP0 + 1
826-
// op1.reg = 32 - TEMP0
827-
il.AddInstruction(il.SetRegister(4, LLIL_TEMP(0), il.Const(4, 0)));
828-
il.AddInstruction(il.SetRegister(4, LLIL_TEMP(1), ReadRegisterOrPointer(il, op2, addr)));
829-
il.AddInstruction(il.Goto(loopStart));
830-
il.MarkLabel(loopStart);
831-
il.AddInstruction(il.If(il.CompareNotEqual(4, il.Register(4, LLIL_TEMP(1)), il.Const(4, 0)), loopBody, loopExit));
832-
il.MarkLabel(loopBody);
833-
il.AddInstruction(il.SetRegister(4, LLIL_TEMP(1), il.LogicalShiftRight(4, il.Register(4, LLIL_TEMP(1)), il.Const(4,1))));
834-
il.AddInstruction(il.SetRegister(4, LLIL_TEMP(0), il.Add(4, il.Register(4, LLIL_TEMP(0)), il.Const(4,1))));
835-
il.AddInstruction(il.Goto(loopStart));
836-
il.MarkLabel(loopExit);
837-
il.AddInstruction(SetRegisterOrBranch(il, op1.reg, il.Sub(4, il.Const(4, 32), il.Register(4, LLIL_TEMP(0)))));
819+
il.AddInstruction(SetRegisterOrBranch(il, op1.reg,
820+
il.CountLeadingZeros(4, ReadRegisterOrPointer(il, op2, addr))));
838821
});
839822
break;
840823
case ARMV7_CMN:
@@ -1833,59 +1816,28 @@ bool GetLowLevelILForArmInstruction(Architecture* arch, uint64_t addr, LowLevelI
18331816
break;
18341817
case ARMV7_RBIT:
18351818
ConditionExecute(addr, instr.cond, instr, il, [&](size_t, Instruction&, LowLevelILFunction& il){
1836-
//Reverse bits
1837-
//
1838-
// TEMP0 = 0
1839-
// TEMP1 = op2.reg
1840-
// TEMP2 = 0
1841-
// while (TEMP0 != 31)
1842-
// TEMP2 = TEMP2 | (TEMP1 & 1)
1843-
// TEMP2 = TEMP2 << 1
1844-
// TEMP1 = TEMP1 >> 1
1845-
// TEMP0 = TEMP0 + 1
1846-
// op1.reg = 32 - TEMP0
1847-
il.AddInstruction(il.SetRegister(4, LLIL_TEMP(0), il.Const(4, 0)));
1848-
il.AddInstruction(il.SetRegister(4, LLIL_TEMP(1), ReadRegisterOrPointer(il, op2, addr)));
1849-
il.AddInstruction(il.SetRegister(4, LLIL_TEMP(2), il.Const(4, 0)));
1850-
il.AddInstruction(il.Goto(loopStart));
1851-
il.MarkLabel(loopStart);
1852-
il.AddInstruction(il.If(il.CompareNotEqual(4, il.Register(4, LLIL_TEMP(0)), il.Const(4, 31)), loopBody, loopExit));
1853-
il.MarkLabel(loopBody);
1854-
il.AddInstruction(il.SetRegister(4, LLIL_TEMP(2), il.Or(4, il.Register(4, LLIL_TEMP(2)), il.And(4, il.Register(4, LLIL_TEMP(1)), il.Const(4,1)))));
1855-
il.AddInstruction(il.SetRegister(4, LLIL_TEMP(2), il.ShiftLeft(4, il.Register(4, LLIL_TEMP(2)), il.Const(4,1))));
1856-
il.AddInstruction(il.SetRegister(4, LLIL_TEMP(1), il.LogicalShiftRight(4, il.Register(4, LLIL_TEMP(1)), il.Const(4,1))));
1857-
il.AddInstruction(il.SetRegister(4, LLIL_TEMP(0), il.Add(4, il.Register(4, LLIL_TEMP(0)), il.Const(4,1))));
1858-
il.AddInstruction(il.Goto(loopStart));
1859-
il.MarkLabel(loopExit);
1860-
il.AddInstruction(SetRegisterOrBranch(il, op1.reg, il.Register(4, LLIL_TEMP(2))));
1819+
il.AddInstruction(SetRegisterOrBranch(il, op1.reg,
1820+
il.ReverseBits(4, ReadRegisterOrPointer(il, op2, addr))));
18611821
});
18621822
break;
18631823
case ARMV7_REV:
18641824
ConditionExecute(il, instr.cond, il.SetRegister(4, op1.reg,
1865-
il.Or(4,
1866-
il.LogicalShiftRight(4, il.Register(4, op2.reg), il.Const(1, 24)),
1867-
il.Or(4,
1868-
il.ShiftLeft(4, il.And(4, il.LogicalShiftRight(4, il.Register(4, op2.reg), il.Const(1, 16)), il.Const(4, 0xff)), il.Const(1, 8)),
1869-
il.Or(4,
1870-
il.ShiftLeft(4, il.And(4, il.LogicalShiftRight(4, il.Register(4, op2.reg), il.Const(1, 8)), il.Const(4, 0xff)), il.Const(1, 16)),
1871-
il.ShiftLeft(4, il.And(4, il.Register(4, op2.reg), il.Const(4, 0xff)), il.Const(1, 24))
1872-
)
1873-
)
1874-
),
1825+
il.ByteSwap(4, il.Register(4, op2.reg)),
18751826
flagOperation[instr.setsFlags]));
18761827
break;
18771828
case ARMV7_REV16:
1829+
// A 32-bit register holds two 16-bit lanes, so reversing the bytes within each lane is a
1830+
// full byte reversal rotated by one halfword
18781831
ConditionExecute(addr, instr.cond, instr, il, [&](size_t, Instruction&, LowLevelILFunction& il){
1879-
il.AddInstruction(il.SetRegister(2, LLIL_TEMP(0), il.RotateRight(2, il.LowPart(2, ReadILOperand(il, op2, addr)), il.Const(1, 16))));
1880-
il.AddInstruction(il.SetRegister(2, LLIL_TEMP(1), il.RotateRight(2, il.LogicalShiftRight(2, ReadILOperand(il, op2, addr), il.Const(1, 16)), il.Const(1, 16))));
1881-
il.AddInstruction(il.SetRegister(4, op1.reg, il.Or(4, il.ShiftLeft(4, il.Register(2, LLIL_TEMP(1)), il.Const(1, 16)), il.Register(2, LLIL_TEMP(0)))));
1832+
il.AddInstruction(il.SetRegister(4, op1.reg,
1833+
il.RotateRight(4, il.ByteSwap(4, ReadILOperand(il, op2, addr)), il.Const(1, 16))));
18821834
});
18831835
break;
18841836
case ARMV7_REVSH:
1837+
// Reverse the bytes of the low 16-bit halfword and sign-extend the result to 32 bits
18851838
ConditionExecute(addr, instr.cond, instr, il, [&](size_t, Instruction&, LowLevelILFunction& il){
1886-
il.AddInstruction(il.SetRegister(2, LLIL_TEMP(0), il.RotateRight(2, il.LowPart(2, ReadILOperand(il, op2, addr)), il.Const(1, 16))));
1887-
il.AddInstruction(il.SetRegister(2, LLIL_TEMP(1), il.RotateRight(2, il.LogicalShiftRight(2, ReadILOperand(il, op2, addr), il.Const(1, 16)), il.Const(1, 16))));
1888-
il.AddInstruction(il.SetRegister(4, op1.reg, il.SignExtend(4, il.Or(4, il.ShiftLeft(4, il.Register(2, LLIL_TEMP(1)), il.Const(1, 16)), il.Register(2, LLIL_TEMP(0))))));
1839+
il.AddInstruction(il.SetRegister(4, op1.reg,
1840+
il.SignExtend(4, il.ByteSwap(2, il.LowPart(2, ReadILOperand(il, op2, addr))))));
18891841
});
18901842
break;
18911843

0 commit comments

Comments
 (0)