aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/armv7/thumb.rs30
-rw-r--r--tests/armv7/thumb.rs20
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<T: Reader<<ARMv7 as Arch>::Address, <ARMv7 as Arch>::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<T: Reader<<ARMv7 as Arch>::Address, <ARMv7 as Arch>::Word>>(d
} else {
// `Move to Special register, System level` (`B9-1984`)
let mask = lower2[8..12].load::<u8>();
- 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<T: Reader<<ARMv7 as Arch>::Address, <ARMv7 as Arch>::Word>>(d
} else {
// `Move to Special register, System level` (`B9-1984`)
let mask = lower2[8..12].load::<u8>();
- 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};