More fixes

Former-commit-id: 897cbc0fb9c12469606c48ee8a02d35bf82c2ae5
This commit is contained in:
Michel Heily 2019-07-06 18:48:22 +03:00
parent 8dc169d25d
commit 36dba78c55
3 changed files with 93 additions and 11 deletions

View file

@ -446,16 +446,30 @@ mod tests {
use crate::sysbus::BoxedMemory; use crate::sysbus::BoxedMemory;
#[test] #[test]
fn test_decode_swi() { fn swi() {
let mut core = Core::new();
let bytes = vec![];
let mut mem = BoxedMemory::new(bytes.into_boxed_slice());
// swi #0x1337 // swi #0x1337
let decoded = ArmInstruction::decode(0xef001337, 0).unwrap(); let decoded = ArmInstruction::decode(0xef001337, 0).unwrap();
assert_eq!(decoded.fmt, ArmFormat::SWI); assert_eq!(decoded.fmt, ArmFormat::SWI);
assert_eq!(decoded.swi_comment(), 0x1337); assert_eq!(decoded.swi_comment(), 0x1337);
assert_eq!(format!("{}", decoded), "swi\t#0x1337"); assert_eq!(format!("{}", decoded), "swi\t#0x1337");
assert_eq!(
core.exec_arm(&mut mem, decoded),
Ok(CpuPipelineAction::Flush)
);
assert_eq!(core.cpsr.mode() , CpuMode::Supervisor);
assert_eq!(core.pc, Exception::SoftwareInterrupt as u32);
} }
#[test] #[test]
fn test_decode_branch_forwards() { fn branch_forwards() {
// 0x20: b 0x30 // 0x20: b 0x30
let decoded = ArmInstruction::decode(0xea_00_00_02, 0x20).unwrap(); let decoded = ArmInstruction::decode(0xea_00_00_02, 0x20).unwrap();
assert_eq!(decoded.fmt, ArmFormat::B_BL); assert_eq!(decoded.fmt, ArmFormat::B_BL);
@ -465,10 +479,22 @@ mod tests {
0x30 0x30
); );
assert_eq!(format!("{}", decoded), "b\t0x30"); assert_eq!(format!("{}", decoded), "b\t0x30");
let mut core = Core::new();
core.pc = 0x20 + 8;
let bytes = vec![];
let mut mem = BoxedMemory::new(bytes.into_boxed_slice());
assert_eq!(
core.exec_arm(&mut mem, decoded),
Ok(CpuPipelineAction::Flush)
);
assert_eq!(core.pc, 0x30);
} }
#[test] #[test]
fn test_decode_branch_link_backwards() { fn branch_link_backwards() {
// 0x20: bl 0x10 // 0x20: bl 0x10
let decoded = ArmInstruction::decode(0xeb_ff_ff_fa, 0x20).unwrap(); let decoded = ArmInstruction::decode(0xeb_ff_ff_fa, 0x20).unwrap();
assert_eq!(decoded.fmt, ArmFormat::B_BL); assert_eq!(decoded.fmt, ArmFormat::B_BL);
@ -478,10 +504,22 @@ mod tests {
0x10 0x10
); );
assert_eq!(format!("{}", decoded), "bl\t0x10"); assert_eq!(format!("{}", decoded), "bl\t0x10");
let mut core = Core::new();
core.pc = 0x20 + 8;
let bytes = vec![];
let mut mem = BoxedMemory::new(bytes.into_boxed_slice());
assert_eq!(
core.exec_arm(&mut mem, decoded),
Ok(CpuPipelineAction::Flush)
);
assert_eq!(core.pc, 0x10);
} }
#[test] #[test]
fn test_decode_ldr_pre_index() { fn ldr_pre_index() {
// ldreq r2, [r5, -r6, lsl #5] // ldreq r2, [r5, -r6, lsl #5]
let decoded = ArmInstruction::decode(0x07_15_22_86, 0).unwrap(); let decoded = ArmInstruction::decode(0x07_15_22_86, 0).unwrap();
assert_eq!(decoded.fmt, ArmFormat::LDR_STR); assert_eq!(decoded.fmt, ArmFormat::LDR_STR);
@ -501,11 +539,31 @@ mod tests {
); );
assert_eq!(format!("{}", decoded), "ldreq\tr2, [r5, -r6, lsl #5]"); assert_eq!(format!("{}", decoded), "ldreq\tr2, [r5, -r6, lsl #5]");
let mut core = Core::new();
core.cpsr.set_Z(true);
core.gpr[5] = 0x34;
core.gpr[6] = 1;
core.gpr[2] = 0;
let bytes = vec![
/* 00h: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 10h: */ 0x00, 0x00, 0x00, 0x00, 0x37, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 20h: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 30h: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
];
let mut mem = BoxedMemory::new(bytes.into_boxed_slice());
assert_eq!(
core.exec_arm(&mut mem, decoded),
Ok(CpuPipelineAction::IncPC)
);
assert_eq!(core.gpr[2], 0x1337);
} }
#[test] #[test]
fn test_decode_str_post_index() { fn str_post_index() {
// strteq r2, [r4], -r7, lsl #8 // strteq r2, [r4], -r7, asr #8
let decoded = ArmInstruction::decode(0x06_24_24_47, 0).unwrap(); let decoded = ArmInstruction::decode(0x06_24_24_47, 0).unwrap();
assert_eq!(decoded.fmt, ArmFormat::LDR_STR); assert_eq!(decoded.fmt, ArmFormat::LDR_STR);
assert_eq!(decoded.cond, ArmCond::Equal); assert_eq!(decoded.cond, ArmCond::Equal);
@ -524,6 +582,26 @@ mod tests {
); );
assert_eq!(format!("{}", decoded), "strteq\tr2, [r4], -r7, asr #8"); assert_eq!(format!("{}", decoded), "strteq\tr2, [r4], -r7, asr #8");
let mut core = Core::new();
core.cpsr.set_Z(true);
core.gpr[4] = 0x0;
core.gpr[7] = 1;
core.gpr[2] = 0xabababab;
let bytes = vec![
/* 00h: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 10h: */ 0x00, 0x00, 0x00, 0x00, 0x37, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 20h: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 30h: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
];
let mut mem = BoxedMemory::new(bytes.into_boxed_slice());
assert_eq!(
core.exec_arm(&mut mem, decoded),
Ok(CpuPipelineAction::IncPC)
);
assert_eq!(mem.read_32(0), 0xabababab);
} }
#[test] #[test]

View file

@ -41,20 +41,20 @@ where
D: InstructionDecoder, D: InstructionDecoder,
N: Num, N: Num,
{ {
fn flush(&mut self) { pub fn flush(&mut self) {
self.fetched = None; self.fetched = None;
self.decoded = None; self.decoded = None;
} }
fn is_flushed(&self) -> bool { pub fn is_flushed(&self) -> bool {
self.fetched.is_none() && self.decoded.is_none() self.fetched.is_none() && self.decoded.is_none()
} }
fn is_only_fetched(&self) -> bool { pub fn is_only_fetched(&self) -> bool {
self.fetched.is_some() && self.decoded.is_none() self.fetched.is_some() && self.decoded.is_none()
} }
fn is_ready_to_execute(&self) -> bool { pub fn is_ready_to_execute(&self) -> bool {
self.fetched.is_some() && self.decoded.is_some() self.fetched.is_some() && self.decoded.is_some()
} }
} }

View file

@ -262,7 +262,11 @@ impl ThumbInstruction {
} }
pub fn is_transferring_bytes(&self) -> bool { pub fn is_transferring_bytes(&self) -> bool {
self.raw.bit(10) match self.fmt {
ThumbFormat::LdrStrRegOffset => self.raw.bit(10),
ThumbFormat::LdrStrImmOffset => self.raw.bit(12),
_ => unreachable!()
}
} }
pub fn is_load(&self) -> bool { pub fn is_load(&self) -> bool {