thumb: Fix misimplementation of THUMB 12 :(

And this kids, is why you don't ever assume what an instruction does
without reading the manual.
Also, I called the ThumbFormat enum variant "LdrAddress", so I went
ahead and implemented as an ldr_str :/


Former-commit-id: f13833d16fba07565a0aba9d247d9754dbfc3d39
This commit is contained in:
Michel Heily 2019-07-08 00:49:03 +03:00
parent 6eab76d52f
commit 7e7d2c5208
3 changed files with 11 additions and 9 deletions

View file

@ -163,7 +163,7 @@ impl ThumbInstruction {
) )
} }
fn fmt_thumb_ldr_address(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt_thumb_load_address(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!( write!(
f, f,
"add\t{Rd}, {r}, #{Imm:#x}", "add\t{Rd}, {r}, #{Imm:#x}",
@ -291,7 +291,7 @@ impl fmt::Display for ThumbInstruction {
ThumbFormat::LdrStrImmOffset => self.fmt_thumb_ldr_str_imm_offset(f), ThumbFormat::LdrStrImmOffset => self.fmt_thumb_ldr_str_imm_offset(f),
ThumbFormat::LdrStrHalfWord => self.fmt_thumb_ldr_str_halfword(f), ThumbFormat::LdrStrHalfWord => self.fmt_thumb_ldr_str_halfword(f),
ThumbFormat::LdrStrSp => self.fmt_thumb_ldr_str_sp(f), ThumbFormat::LdrStrSp => self.fmt_thumb_ldr_str_sp(f),
ThumbFormat::LdrAddress => self.fmt_thumb_ldr_address(f), ThumbFormat::LoadAddress => self.fmt_thumb_load_address(f),
ThumbFormat::AddSp => self.fmt_thumb_add_sp(f), ThumbFormat::AddSp => self.fmt_thumb_add_sp(f),
ThumbFormat::PushPop => self.fmt_thumb_push_pop(f), ThumbFormat::PushPop => self.fmt_thumb_push_pop(f),
ThumbFormat::LdmStm => self.fmt_thumb_ldm_stm(f), ThumbFormat::LdmStm => self.fmt_thumb_ldm_stm(f),

View file

@ -266,13 +266,15 @@ impl Core {
self.do_exec_thumb_ldr_str_with_addr(bus, insn, addr) self.do_exec_thumb_ldr_str_with_addr(bus, insn, addr)
} }
fn exec_thumb_ldr_address(&mut self, bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult { fn exec_thumb_load_address(&mut self, bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult {
let addr = if insn.flag(ThumbInstruction::FLAG_SP) { let result = if insn.flag(ThumbInstruction::FLAG_SP) {
self.gpr[REG_SP] + (insn.word8() as Addr) self.gpr[REG_SP] + (insn.word8() as Addr)
} else { } else {
(insn.pc & !0b10) + 4 + (insn.word8() as Addr) (insn.pc & !0b10) + 4 + (insn.word8() as Addr)
}; };
self.do_exec_thumb_ldr_str_with_addr(bus, insn, addr) self.gpr[insn.rd()] = result;
Ok(CpuPipelineAction::IncPC)
} }
fn do_exec_thumb_ldr_str_with_addr( fn do_exec_thumb_ldr_str_with_addr(
@ -415,7 +417,7 @@ impl Core {
ThumbFormat::LdrStrImmOffset => self.exec_thumb_ldr_str_imm_offset(bus, insn), ThumbFormat::LdrStrImmOffset => self.exec_thumb_ldr_str_imm_offset(bus, insn),
ThumbFormat::LdrStrHalfWord => self.exec_thumb_ldr_str_halfword(bus, insn), ThumbFormat::LdrStrHalfWord => self.exec_thumb_ldr_str_halfword(bus, insn),
ThumbFormat::LdrStrSp => self.exec_thumb_ldr_str_sp(bus, insn), ThumbFormat::LdrStrSp => self.exec_thumb_ldr_str_sp(bus, insn),
ThumbFormat::LdrAddress => self.exec_thumb_ldr_address(bus, insn), ThumbFormat::LoadAddress => self.exec_thumb_load_address(bus, insn),
ThumbFormat::AddSp => self.exec_thumb_add_sp(bus, insn), ThumbFormat::AddSp => self.exec_thumb_add_sp(bus, insn),
ThumbFormat::PushPop => self.exec_thumb_push_pop(bus, insn), ThumbFormat::PushPop => self.exec_thumb_push_pop(bus, insn),
ThumbFormat::LdmStm => self.exec_thumb_ldm_stm(bus, insn), ThumbFormat::LdmStm => self.exec_thumb_ldm_stm(bus, insn),

View file

@ -61,7 +61,7 @@ pub enum ThumbFormat {
/// Format 11 /// Format 11
LdrStrSp, LdrStrSp,
/// Format 12 /// Format 12
LdrAddress, LoadAddress,
/// Format 13 /// Format 13
AddSp, AddSp,
/// Format 14 /// Format 14
@ -116,7 +116,7 @@ impl InstructionDecoder for ThumbInstruction {
} else if raw & 0xf000 == 0x9000 { } else if raw & 0xf000 == 0x9000 {
Ok(LdrStrSp) Ok(LdrStrSp)
} else if raw & 0xf000 == 0xa000 { } else if raw & 0xf000 == 0xa000 {
Ok(LdrAddress) Ok(LoadAddress)
} else if raw & 0xff00 == 0xb000 { } else if raw & 0xff00 == 0xb000 {
Ok(AddSp) Ok(AddSp)
} else if raw & 0xf600 == 0xb400 { } else if raw & 0xf600 == 0xb400 {
@ -208,7 +208,7 @@ impl ThumbInstruction {
ThumbFormat::DataProcessImm ThumbFormat::DataProcessImm
| ThumbFormat::LdrPc | ThumbFormat::LdrPc
| ThumbFormat::LdrStrSp | ThumbFormat::LdrStrSp
| ThumbFormat::LdrAddress => self.raw.bit_range(8..11) as usize, | ThumbFormat::LoadAddress => self.raw.bit_range(8..11) as usize,
_ => (self.raw & 0b111) as usize, _ => (self.raw & 0b111) as usize,
} }
} }