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!(
|
||||
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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue