diff options
| -rw-r--r-- | src/armv7/display.rs | 18 | ||||
| -rw-r--r-- | tests/armv7/thumb.rs | 10 |
2 files changed, 24 insertions, 4 deletions
diff --git a/src/armv7/display.rs b/src/armv7/display.rs index 4ed7b64..5a48362 100644 --- a/src/armv7/display.rs +++ b/src/armv7/display.rs @@ -531,8 +531,13 @@ pub(crate) fn visit_inst<T: DisplaySink>(instr: &Instruction, out: &mut T) -> fm out.write_char(' ')?; write_coproc(coproc, out)?; out.write_fixed_size(", ")?; - // opc1 is a 3-bit field - out.write_char((opc + 0x30) as char)?; + // mrc/mcr have 3-bit opc1, but mrrc/mcrr have 4-bit opc1 + if opc >= 10 { + out.write_char('1')?; + out.write_char((opc - 10 + 0x30) as char)?; + } else { + out.write_char((opc + 0x30) as char)?; + } let ops = instr.operands.iter(); for op in ops { @@ -586,8 +591,13 @@ pub(crate) fn visit_inst<T: DisplaySink>(instr: &Instruction, out: &mut T) -> fm out.write_char(' ')?; write_coproc(coproc, out)?; out.write_fixed_size(", ")?; - // opc1 is a 3-bit field - out.write_char((opc1 + 0x30) as char)?; + // opc1 is a 3-bit field for MCR and MRC, but is four bits for CDP + if opc1 >= 10 { + out.write_char('1')?; + out.write_char((opc1 - 10 + 0x30) as char)?; + } else { + out.write_char((opc1 + 0x30) as char)?; + } let ops = instr.operands.iter(); for op in ops { diff --git a/tests/armv7/thumb.rs b/tests/armv7/thumb.rs index c3935c1..660ca46 100644 --- a/tests/armv7/thumb.rs +++ b/tests/armv7/thumb.rs @@ -4650,6 +4650,16 @@ fn mrc_mcr_cdp() { &[0x80, 0xfe, 0x80, 0xc6], "cdp2 p6, 8, c12, c0, c0, 4" ); + + test_display( + &[0xa0, 0xee, 0x81, 0x13], + "cdp p3, 10, c1, c0, c1, 4", + ); + + test_display( + &[0x54, 0xec, 0xa0, 0x91], + "mrrc p1, 10, sb, r4, c0" + ); } #[test] |
