aboutsummaryrefslogtreecommitdiff
path: root/src/armv7
diff options
context:
space:
mode:
authorBrandon Ros <brandonros1@gmail.com>2026-07-03 00:14:45 -0400
committeriximeow <me@iximeow.net>2026-07-28 02:53:24 +0000
commit9e9c7b2663fa52881bf6883e74f4cd8610c38570 (patch)
tree9646b1250f2f2bea921a582192932eda40ed3ab0 /src/armv7
parenteea7a08447871114c86ad3c42945847336960d2c (diff)
fix more thumb2 register data-processing decode bugs
- register-controlled shifts (lsl/lsr/asr/ror by register) all decoded as lsl: the shift type was read from hw1[6:5] (always 0 for this form) instead of hw0[6:5] - 32-bit uxt*/sxt* extends read the ror amount from the wrong field (hw1[2:1] scaled by 4 instead of hw1[5:4] scaled by 8), so a no-rotation extend came back as ror #4; rotation of 0 is now omitted - sxtab was decoded as sxtah (wrong opcode table entry) all cases verified against binutils objdump
Diffstat (limited to 'src/armv7')
-rw-r--r--src/armv7/thumb.rs20
1 files changed, 14 insertions, 6 deletions
diff --git a/src/armv7/thumb.rs b/src/armv7/thumb.rs
index 4424d44..e9427d1 100644
--- a/src/armv7/thumb.rs
+++ b/src/armv7/thumb.rs
@@ -2695,7 +2695,7 @@ pub fn decode_into<T: Reader<<ARMv7 as Arch>::Address, <ARMv7 as Arch>::Word>>(d
Opcode::LSR,
Opcode::ASR,
Opcode::ROR,
- ][op2[1..3].load::<usize>()];
+ ][op1[1..3].load::<usize>()];
let rd = lower2[8..12].load::<u8>();
let rm = lower2[0..4].load::<u8>();
inst.opcode = op;
@@ -2723,14 +2723,18 @@ pub fn decode_into<T: Reader<<ARMv7 as Arch>::Address, <ARMv7 as Arch>::Word>>(d
][op1];
let rm = lower2[..4].load::<u8>();
- let rotate = lower2[1..3].load::<u8>() << 2;
+ let rotate = lower2[4..6].load::<u8>() << 3;
let rd = lower2[8..12].load::<u8>();
inst.opcode = op;
inst.operands = [
Operand::Reg(Reg::from_u8(rd)),
Operand::Reg(Reg::from_u8(rm)),
- Operand::Imm32(rotate as u32),
+ if rotate != 0 {
+ Operand::Imm32(rotate as u32)
+ } else {
+ Operand::Nothing
+ },
Operand::Nothing,
];
} else {
@@ -2739,12 +2743,12 @@ pub fn decode_into<T: Reader<<ARMv7 as Arch>::Address, <ARMv7 as Arch>::Word>>(d
Opcode::UXTAH,
Opcode::SXTAB16,
Opcode::UXTAB16,
- Opcode::SXTAH,
+ Opcode::SXTAB,
Opcode::UXTAB,
][op1];
let rm = lower2[..4].load::<u8>();
- let rotate = lower2[1..3].load::<u8>() << 2;
+ let rotate = lower2[4..6].load::<u8>() << 3;
let rd = lower2[8..12].load::<u8>();
inst.opcode = op;
@@ -2752,7 +2756,11 @@ pub fn decode_into<T: Reader<<ARMv7 as Arch>::Address, <ARMv7 as Arch>::Word>>(d
Operand::Reg(Reg::from_u8(rd)),
Operand::Reg(Reg::from_u8(rn)),
Operand::Reg(Reg::from_u8(rm)),
- Operand::Imm32(rotate as u32),
+ if rotate != 0 {
+ Operand::Imm32(rotate as u32)
+ } else {
+ Operand::Nothing
+ },
];
};
}