arm: Add tests for ldr/str

And also test disassembling while at it..
This commit is contained in:
Michel Heily 2019-06-28 12:36:19 +03:00
parent 7898bf61f3
commit bd7fd472cf
3 changed files with 62 additions and 7 deletions

View file

@ -220,7 +220,7 @@ impl ArmInstruction {
fn fmt_ldr_str(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt_ldr_str(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!( write!(
f, f,
"{mnem}{B}{cond}{T}\t{Rd}, ", "{mnem}{B}{T}{cond}\t{Rd}, ",
mnem = if self.load_flag() { "ldr" } else { "str" }, mnem = if self.load_flag() { "ldr" } else { "str" },
B = if self.transfer_size() == 1 { "b" } else { "" }, B = if self.transfer_size() == 1 { "b" } else { "" },
cond = self.cond, cond = self.cond,
@ -358,7 +358,7 @@ impl ArmInstruction {
fn fmt_swi(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt_swi(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!( write!(
f, f,
"swi{cond}\t#0x{comm:08x}", "swi{cond}\t#{comm:#x}",
cond = self.cond, cond = self.cond,
comm = self.swi_comment() comm = self.swi_comment()
) )

View file

@ -2,7 +2,8 @@ use crate::bit::BitIndex;
use crate::arm7tdmi; use crate::arm7tdmi;
use arm7tdmi::cpu::{ use arm7tdmi::cpu::{
Core, CpuError, CpuExecResult, CpuInstruction, CpuPipelineAction, CpuResult, CpuState, Exception Core, CpuError, CpuExecResult, CpuInstruction, CpuPipelineAction, CpuResult, CpuState,
Exception,
}; };
use super::super::sysbus::SysBus; use super::super::sysbus::SysBus;

View file

@ -430,9 +430,8 @@ impl ArmInstruction {
} }
} }
#[cfg(test)] #[cfg(test)]
/// All instructions constants were generated using an ARM assembler.
mod tests { mod tests {
use super::*; use super::*;
@ -442,6 +441,7 @@ mod tests {
let decoded = ArmInstruction::try_from(0xef001337).unwrap(); let decoded = ArmInstruction::try_from(0xef001337).unwrap();
assert_eq!(decoded.fmt, ArmInstructionFormat::SWI); assert_eq!(decoded.fmt, ArmInstructionFormat::SWI);
assert_eq!(decoded.swi_comment(), 0x1337); assert_eq!(decoded.swi_comment(), 0x1337);
assert_eq!(format!("{}", decoded), "swi\t#0x1337");
} }
#[test] #[test]
@ -450,7 +450,11 @@ mod tests {
let decoded = ArmInstruction::try_from((0xea_00_00_02, 0x20)).unwrap(); let decoded = ArmInstruction::try_from((0xea_00_00_02, 0x20)).unwrap();
assert_eq!(decoded.fmt, ArmInstructionFormat::B_BL); assert_eq!(decoded.fmt, ArmInstructionFormat::B_BL);
assert_eq!(decoded.link_flag(), false); assert_eq!(decoded.link_flag(), false);
assert_eq!((decoded.pc as i32).wrapping_add(decoded.branch_offset()), 0x30); assert_eq!(
(decoded.pc as i32).wrapping_add(decoded.branch_offset()),
0x30
);
assert_eq!(format!("{}", decoded), "b\t0x30");
} }
#[test] #[test]
@ -459,6 +463,56 @@ mod tests {
let decoded = ArmInstruction::try_from((0xeb_ff_ff_fa, 0x20)).unwrap(); let decoded = ArmInstruction::try_from((0xeb_ff_ff_fa, 0x20)).unwrap();
assert_eq!(decoded.fmt, ArmInstructionFormat::B_BL); assert_eq!(decoded.fmt, ArmInstructionFormat::B_BL);
assert_eq!(decoded.link_flag(), true); assert_eq!(decoded.link_flag(), true);
assert_eq!((decoded.pc as i32).wrapping_add(decoded.branch_offset()), 0x10); assert_eq!(
(decoded.pc as i32).wrapping_add(decoded.branch_offset()),
0x10
);
assert_eq!(format!("{}", decoded), "b\t0x10");
}
#[test]
fn test_decode_ldr_preindex() {
// ldreq r2, [r5, -r6, lsl #5]
let decoded = ArmInstruction::try_from(0x07_15_22_86).unwrap();
assert_eq!(decoded.fmt, ArmInstructionFormat::LDR_STR);
assert_eq!(decoded.cond, ArmCond::Equal);
assert_eq!(decoded.load_flag(), true);
assert_eq!(decoded.pre_index_flag(), true);
assert_eq!(decoded.write_back_flag(), false);
assert_eq!(decoded.rd(), 2);
assert_eq!(decoded.rn(), 5);
assert_eq!(
decoded.ldr_str_offset(),
Ok(ArmShiftedValue::ShiftedRegister {
reg: 6,
shift: ArmRegisterShift::ShiftAmount(5, ArmShiftType::LSL),
added: Some(false)
})
);
assert_eq!(format!("{}", decoded), "ldreq\tr2, [r5, -r6, lsl #5]");
}
#[test]
fn test_decode_str_postindex() {
// strteq r2, [r4], -r7, lsl #8
let decoded = ArmInstruction::try_from(0x06_24_24_47).unwrap();
assert_eq!(decoded.fmt, ArmInstructionFormat::LDR_STR);
assert_eq!(decoded.cond, ArmCond::Equal);
assert_eq!(decoded.load_flag(), false);
assert_eq!(decoded.pre_index_flag(), false);
assert_eq!(decoded.write_back_flag(), true);
assert_eq!(decoded.rd(), 2);
assert_eq!(decoded.rn(), 4);
assert_eq!(
decoded.ldr_str_offset(),
Ok(ArmShiftedValue::ShiftedRegister {
reg: 7,
shift: ArmRegisterShift::ShiftAmount(8, ArmShiftType::ASR),
added: Some(false)
})
);
assert_eq!(format!("{}", decoded), "strteq\tr2, [r4], -r7, asr #8");
} }
} }