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!(
f,
"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::LdrStrHalfWord => self.fmt_thumb_ldr_str_halfword(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::PushPop => self.fmt_thumb_push_pop(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)
}
fn exec_thumb_ldr_address(&mut self, bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult {
let addr = if insn.flag(ThumbInstruction::FLAG_SP) {
fn exec_thumb_load_address(&mut self, bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult {
let result = if insn.flag(ThumbInstruction::FLAG_SP) {
self.gpr[REG_SP] + (insn.word8() as Addr)
} else {
(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(
@ -415,7 +417,7 @@ impl Core {
ThumbFormat::LdrStrImmOffset => self.exec_thumb_ldr_str_imm_offset(bus, insn),
ThumbFormat::LdrStrHalfWord => self.exec_thumb_ldr_str_halfword(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::PushPop => self.exec_thumb_push_pop(bus, insn),
ThumbFormat::LdmStm => self.exec_thumb_ldm_stm(bus, insn),

View file

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