diff options
| author | Josh Ferrell <josh@vector35.com> | 2025-03-05 18:14:46 -0500 |
|---|---|---|
| committer | Josh Ferrell <josh@vector35.com> | 2025-03-06 16:38:58 -0500 |
| commit | d59ee7f42ceb379dc107c6bca723b012b0c0e24a (patch) | |
| tree | 734687510a85b964dd2e054832410cf953f204fe /arch/armv7 | |
| parent | f8ca56c3aa836b281e56290c6e51274c573ac142 (diff) | |
ARMv7: Add support for register-shifted registers
Diffstat (limited to 'arch/armv7')
| -rw-r--r-- | arch/armv7/il.cpp | 62 |
1 files changed, 61 insertions, 1 deletions
diff --git a/arch/armv7/il.cpp b/arch/armv7/il.cpp index 0b314f20..58eee5c7 100644 --- a/arch/armv7/il.cpp +++ b/arch/armv7/il.cpp @@ -167,13 +167,73 @@ static ExprId GetShiftedOffset(LowLevelILFunction& il, InstructionOperand& op) } +static ExprId GetRegisterShiftedRegister(LowLevelILFunction& il, Register reg, Register shiftReg, Shift shiftType) +{ + if (shiftType == SHIFT_NONE) + return il.Register(get_register_size(reg), reg); + + uint32_t regSize = get_register_size(reg); + uint32_t shiftRegSize = get_register_size(shiftReg); + switch (shiftType) + { + case SHIFT_ASR: + return il.ArithShiftRight( + regSize, + il.Register(regSize, reg), + il.And( + shiftRegSize, + il.Register(shiftRegSize, shiftReg), + il.Const(shiftRegSize, 0xff) + )); + case SHIFT_LSL: + return il.ShiftLeft( + regSize, + il.Register(regSize, reg), + il.And( + shiftRegSize, + il.Register(shiftRegSize, shiftReg), + il.Const(shiftRegSize, 0xff) + )); + case SHIFT_LSR: + return il.LogicalShiftRight( + regSize, + il.Register(regSize, reg), + il.And( + shiftRegSize, + il.Register(shiftRegSize, shiftReg), + il.Const(shiftRegSize, 0xff) + )); + case SHIFT_ROR: + return il.RotateRight( + regSize, + il.Register(regSize, reg), + il.And( + shiftRegSize, + il.Register(shiftRegSize, shiftReg), + il.Const(shiftRegSize, 0xff) + )); + case SHIFT_RRX: + //RRX can only shift 1 at a time + return il.RotateRightCarry( + regSize, + il.Register(regSize, reg), + il.Const(1, 1), + il.Flag(IL_FLAG_C) + ); + default: + return 0; + } +} + + static ExprId GetShiftedRegister(LowLevelILFunction& il, InstructionOperand& op) { + if (op.flags.offsetRegUsed == 1) + return GetRegisterShiftedRegister(il, op.reg, op.offset, op.shift); return GetShifted(il, op.reg, op.imm, op.shift); } - static ExprId ReadAddress(LowLevelILFunction& il, InstructionOperand& op, size_t addr) { //This should only be called by with cls or MEM_* or label |
