From d5175bb0d99f31117a14c9efdaa7a9fb01ee5610 Mon Sep 17 00:00:00 2001 From: iximeow Date: Sun, 2 Aug 2026 02:31:32 +0000 Subject: thumb mrs/msr first operand was wildly wrong --- src/armv7/thumb.rs | 30 +++++++----------------------- tests/armv7/thumb.rs | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/armv7/thumb.rs b/src/armv7/thumb.rs index 1e3ee28..16d671a 100644 --- a/src/armv7/thumb.rs +++ b/src/armv7/thumb.rs @@ -1594,13 +1594,7 @@ pub fn decode_into::Address, ::Word>>(d let R = instr2[4]; inst.opcode = Opcode::MSR; inst.operands = [ - // TODO: is this the appropriate banked reg? - if let Some(op) = Reg::from_sysm(R, sysm as u8) { - // TODO: from_sysm should succeed? - op - } else { - return Err(DecodeError::InvalidOperand); - }, + Operand::StatusRegMask(StatusRegMask::from_raw(sysm as u8)?), Operand::Reg(Reg::from_u8(rn)), Operand::Nothing, Operand::Nothing, @@ -1640,16 +1634,11 @@ pub fn decode_into::Address, ::Word>>(d } else { // `Move to Special register, System level` (`B9-1984`) let mask = lower2[8..12].load::(); - let R = instr2[4]; + let R = if instr2[4] { 1 } else { 0 }; + let sysm = (R << 4) | mask; inst.opcode = Opcode::MSR; inst.operands = [ - // TODO: is this the appropriate? - if let Some(op) = Reg::from_sysm(R, mask) { - // TODO: from_sysm should succeed? - op - } else { - return Err(DecodeError::InvalidOperand); - }, + Operand::StatusRegMask(StatusRegMask::from_raw(sysm as u8)?), Operand::Reg(Reg::from_u8(rn)), Operand::Nothing, Operand::Nothing, @@ -1658,16 +1647,11 @@ pub fn decode_into::Address, ::Word>>(d } else { // `Move to Special register, System level` (`B9-1984`) let mask = lower2[8..12].load::(); - let R = instr2[4]; + let R = if instr2[4] { 1 } else { 0 }; + let sysm = (R << 4) | mask; inst.opcode = Opcode::MSR; inst.operands = [ - // TODO: is this the appropriate? - if let Some(op) = Reg::from_sysm(R, mask) { - // TODO: from_sysm should succeed? - op - } else { - return Err(DecodeError::InvalidOperand); - }, + Operand::StatusRegMask(StatusRegMask::from_raw(sysm as u8)?), Operand::Reg(Reg::from_u8(rn)), Operand::Nothing, Operand::Nothing, diff --git a/tests/armv7/thumb.rs b/tests/armv7/thumb.rs index fe92e40..59dafaa 100644 --- a/tests/armv7/thumb.rs +++ b/tests/armv7/thumb.rs @@ -4553,6 +4553,26 @@ fn test_decode_tbb_tbh_cases() { } #[test] +fn msr_mrs() { + test_display( + &[0x8f, 0xf3, 0x00, 0x87], + "msr.w cpsr_sxc, pc" + ); + test_display( + &[0x9f, 0xf3, 0x00, 0x87], + "msr.w spsr_sxc, pc" + ); + test_display( + &[0x90, 0xf3, 0x00, 0x8b], + "msr.w spsr_fxc, r0" + ); + test_display( + &[0x9b, 0xf3, 0x00, 0x85], + "msr.w spsr_sc, fp" + ); +} + +#[test] fn test_decode_tbh_operand_shape() { use yaxpeax_arm::armv7::{Opcode, Operand, RegShiftStyle, ShiftStyle}; -- cgit v1.1