From 7e70f851a481d36669e64edcd61ce7df9d578468 Mon Sep 17 00:00:00 2001 From: iximeow Date: Fri, 11 Sep 2026 15:53:27 +0000 Subject: fix mrc/mrc2 use of CRd=15 --- CHANGELOG | 2 ++ src/armv7.rs | 2 ++ src/armv7/display.rs | 1 + src/armv7/thumb.rs | 7 ++++++- tests/armv7/thumb.rs | 5 +++++ 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index b0265a1..7b35eaa 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -23,6 +23,8 @@ * thumb2: unknown wide hints are decoded as `hint` like other cases in ARM, rather than rejected as invalid * thumb2: support ARMv8 hints PACBTI, BTI, ESB, PAC, and AUT +* thumb2: fix `mrc`, `mrc2` use of register number "15", which means apsr_nzcv, + rather than pc * ARMv8: support thumb2 encoding of `Test Target` instruction, `Opcode::TT` (formatted as any of `tt`, `ttt`, `tta`, `ttat`) * ARMv8: formerly-coprocessor instructions have been defined into SIMD extensions, diff --git a/src/armv7.rs b/src/armv7.rs index 6edb6c9..87b44f5 100644 --- a/src/armv7.rs +++ b/src/armv7.rs @@ -660,6 +660,8 @@ pub enum StatusRegMask { SPSR_FSC = 0b11101, SPSR_FSX = 0b11110, SPSR_FSXC = 0b11111, + // not part of the above bitpacking, this is encoded by reg number 0b1111 in some instructions. + APSR_NZCV = 0b100000, } impl StatusRegMask { diff --git a/src/armv7/display.rs b/src/armv7/display.rs index 5a48362..1398ce6 100644 --- a/src/armv7/display.rs +++ b/src/armv7/display.rs @@ -1330,6 +1330,7 @@ impl StatusRegMask { StatusRegMask::CPSR_SC => "cpsr_sc", StatusRegMask::CPSR_SX => "cpsr_sx", StatusRegMask::CPSR_SXC => "cpsr_sxc", + StatusRegMask::APSR_NZCV => "apsr_nzcv", StatusRegMask::APSR_NZCVQ => "apsr_nzcvq", StatusRegMask::CPSR_FC => "cpsr_fc", StatusRegMask::CPSR_FX => "cpsr_fx", diff --git a/src/armv7/thumb.rs b/src/armv7/thumb.rs index d029221..4340e95 100644 --- a/src/armv7/thumb.rs +++ b/src/armv7/thumb.rs @@ -4418,8 +4418,13 @@ fn decode_table_a6_30(decoder: &InstDecoder, inst: &mut Instruction, instr2: Bit } else { // MRC, MRC2 (A8-493) inst.opcode = Opcode::MRC(coproc, opc1, opc2, is_2); + let dest = if CRd == 0b1111 { + Operand::StatusRegMask(StatusRegMask::APSR_NZCV) + } else { + Operand::Reg(Reg::from_u8(CRd)) + }; inst.operands = [ - Operand::Reg(Reg::from_u8(CRd)), + dest, Operand::CReg(CReg::from_u8(CRn)), Operand::CReg(CReg::from_u8(CRm)), Operand::Nothing, diff --git a/tests/armv7/thumb.rs b/tests/armv7/thumb.rs index 0c017e9..1278bd6 100644 --- a/tests/armv7/thumb.rs +++ b/tests/armv7/thumb.rs @@ -4664,6 +4664,11 @@ fn mrc_mcr_cdp() { &[0x54, 0xec, 0xa0, 0x91], "mrrc p1, 10, sb, r4, c0" ); + + test_display( + &[0x1a, 0xee, 0xff, 0xf4], + "mrc p4, 0, apsr_nzcv, c10, c15, 7", + ); } #[test] -- cgit v1.1