aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/armv7/display.rs18
-rw-r--r--tests/armv7/thumb.rs10
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]