diff options
| -rw-r--r-- | src/armv7/display.rs | 23 | ||||
| -rw-r--r-- | tests/armv7/mod.rs | 15 |
2 files changed, 30 insertions, 8 deletions
diff --git a/src/armv7/display.rs b/src/armv7/display.rs index 3ee0daa..f81e2cc 100644 --- a/src/armv7/display.rs +++ b/src/armv7/display.rs @@ -368,6 +368,19 @@ impl<T: DisplaySink> crate::armv7::OperandVisitor for DisplayingOperandVisitor<' } } +fn write_coproc<T: DisplaySink>(coproc: u8, out: &mut T) -> fmt::Result { + // coproc is a 4-bit field + debug_assert!(coproc < 16); + + out.write_char('p')?; + if coproc < 10 { + out.write_char((coproc + 0x30) as char) + } else { + out.write_char('1')?; + out.write_char((coproc - 10 + 0x30) as char) + } +} + #[allow(non_snake_case)] pub(crate) fn visit_inst<T: DisplaySink>(instr: &Instruction, out: &mut T) -> fmt::Result { // handle a few instruction aliasing cases first... @@ -491,10 +504,9 @@ pub(crate) fn visit_inst<T: DisplaySink>(instr: &Instruction, out: &mut T) -> fm out.write_lt_8(instr.opcode.name())?; } out.span_end_opcode(); - out.write_fixed_size(" p")?; - // coproc is a 3-bit field - out.write_char((coproc + 0x30) as char)?; + out.write_char(' ')?; + write_coproc(coproc, out)?; out.write_fixed_size(", ")?; // opc1 is a 3-bit field out.write_char((opc + 0x30) as char)?; @@ -521,10 +533,9 @@ pub(crate) fn visit_inst<T: DisplaySink>(instr: &Instruction, out: &mut T) -> fm out.write_lt_8(instr.opcode.name())?; } out.span_end_opcode(); - out.write_fixed_size(" p")?; - // coproc is a 3-bit field - out.write_char((coproc + 0x30) as char)?; + out.write_char(' ')?; + write_coproc(coproc, out)?; out.write_fixed_size(", ")?; // opc1 is a 3-bit field out.write_char((opc1 + 0x30) as char)?; diff --git a/tests/armv7/mod.rs b/tests/armv7/mod.rs index 59dea7c..b878dd1 100644 --- a/tests/armv7/mod.rs +++ b/tests/armv7/mod.rs @@ -554,26 +554,37 @@ fn test_unconditional() { test_armv6([0x0f, 0x05, 0xed, 0xf8], "srsia sp!, 0xf"); test_armv5([0x01, 0x02, 0x03, 0xfb], "blx $+0xc0806"); test_armv5([0x01, 0x02, 0x03, 0xfa], "blx $+0xc0804"); +} + +#[test] +fn test_coproc() { test_armv5([0x12, 0x34, 0xcf, 0xfc], "stc2l p4, c3, [pc], {0x12}"); + test_armv5([0x12, 0x3d, 0xcf, 0xfc], "stc2l p13, c3, [pc], {0x12}"); test_armv5([0x12, 0x34, 0xdf, 0xfc], "ldc2l p4, c3, [pc], {0x12}"); test_armv5([0x34, 0x78, 0xff, 0xfc], "ldc2l p8, c7, [pc], 0xd0"); + test_armv5([0x34, 0x7d, 0xff, 0xfc], "ldc2l p13, c7, [pc], 0xd0"); test_invalid([0x34, 0x78, 0x1f, 0xfc]); test_armv5([0x34, 0x78, 0x9f, 0xfc], "ldc2 p8, c7, [pc], {0x34}"); + test_armv5([0x34, 0x7d, 0x9f, 0xfc], "ldc2 p13, c7, [pc], {0x34}"); test_armv5([0x34, 0x78, 0xbf, 0xfc], "ldc2 p8, c7, [pc], 0xd0"); test_armv5([0x34, 0x78, 0xbf, 0xfd], "ldc2 p8, c7, [pc, 0xd0]!"); test_armv5([0x34, 0x78, 0x9f, 0xfd], "ldc2 p8, c7, [pc, 0xd0]"); - test_armv5([0x34, 0x78, 0x1f, 0xfd], "ldc2 p8, c7, [pc, -0xd0]"); - test_armv5([0x34, 0x78, 0xdf, 0xfc], "ldc2l p8, c7, [pc], {0x34}"); test_armv6([0x34, 0x78, 0x5a, 0xfc], "mrrc2 p8, 3, r7, r10, c4"); + test_armv6([0x34, 0x7d, 0x5a, 0xfc], "mrrc2 p13, 3, r7, r10, c4"); // Rt/Rt2 may not be r15 test_invalid([0x34, 0x78, 0x5f, 0xfc]); test_armv6([0x34, 0x78, 0x4a, 0xfc], "mcrr2 p8, 3, r7, r10, c4"); + test_armv6([0x34, 0x7d, 0x4a, 0xfc], "mcrr2 p13, 3, r7, r10, c4"); // Rt/Rt2 may not be r15 test_invalid([0x34, 0x78, 0x4f, 0xfc]); test_armv5([0x34, 0x78, 0x4f, 0xfe], "mcr2 p8, 2, r7, c15, c4, 1"); + test_armv5([0x34, 0x7d, 0x4f, 0xfe], "mcr2 p13, 2, r7, c15, c4, 1"); test_armv5([0x34, 0x78, 0x5f, 0xfe], "mrc2 p8, 2, r7, c15, c4, 1"); + test_armv5([0x34, 0x7d, 0x5f, 0xfe], "mrc2 p13, 2, r7, c15, c4, 1"); test_armv5([0x24, 0x78, 0x5f, 0xfe], "cdp2 p8, 5, c7, c15, c4, 1"); + test_armv5([0x24, 0x7d, 0x5f, 0xfe], "cdp2 p13, 5, c7, c15, c4, 1"); test_armv5([0x24, 0x78, 0x4f, 0xfe], "cdp2 p8, 4, c7, c15, c4, 1"); + test_armv5([0x24, 0x7d, 0x4f, 0xfe], "cdp2 p13, 4, c7, c15, c4, 1"); } #[test] |
