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:
parent
6eab76d52f
commit
7e7d2c5208
|
@ -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),
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue