arm: Add tests for ldr/str
And also test disassembling while at it..
This commit is contained in:
parent
7898bf61f3
commit
bd7fd472cf
|
@ -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()
|
||||||
)
|
)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue