summaryrefslogtreecommitdiff
path: root/arch/armv7
diff options
context:
space:
mode:
authorJosh Ferrell <josh@vector35.com>2025-03-05 18:14:46 -0500
committerJosh Ferrell <josh@vector35.com>2025-03-06 16:38:58 -0500
commitd59ee7f42ceb379dc107c6bca723b012b0c0e24a (patch)
tree734687510a85b964dd2e054832410cf953f204fe /arch/armv7
parentf8ca56c3aa836b281e56290c6e51274c573ac142 (diff)
ARMv7: Add support for register-shifted registers
Diffstat (limited to 'arch/armv7')
-rw-r--r--arch/armv7/il.cpp62
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