Fix word alignment for arm BX
Former-commit-id: 9223259793cd8ecccb02b40c428d32315c632bff
This commit is contained in:
parent
2864f83681
commit
50086a8715
|
@ -44,20 +44,25 @@ impl Core {
|
||||||
Ok(CpuPipelineAction::Flush)
|
Ok(CpuPipelineAction::Flush)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cycles 2S+1N
|
pub fn branch_exchange(&mut self, mut addr: Addr) -> CpuResult<CpuPipelineAction> {
|
||||||
fn exec_bx(&mut self, _bus: &mut Bus, insn: ArmInstruction) -> CpuResult<CpuPipelineAction> {
|
if addr.bit(0) {
|
||||||
let rn = self.get_reg(insn.rn());
|
addr = addr & !0x1;
|
||||||
if rn.bit(0) {
|
|
||||||
self.cpsr.set_state(CpuState::THUMB);
|
self.cpsr.set_state(CpuState::THUMB);
|
||||||
} else {
|
} else {
|
||||||
|
addr = addr & !0x3;
|
||||||
self.cpsr.set_state(CpuState::ARM);
|
self.cpsr.set_state(CpuState::ARM);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.pc = rn & !1;
|
self.pc = addr;
|
||||||
|
|
||||||
Ok(CpuPipelineAction::Flush)
|
Ok(CpuPipelineAction::Flush)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Cycles 2S+1N
|
||||||
|
fn exec_bx(&mut self, _bus: &mut Bus, insn: ArmInstruction) -> CpuResult<CpuPipelineAction> {
|
||||||
|
self.branch_exchange(self.get_reg(insn.rn()))
|
||||||
|
}
|
||||||
|
|
||||||
fn exec_swi(&mut self, _bus: &mut Bus, _insn: ArmInstruction) -> CpuResult<CpuPipelineAction> {
|
fn exec_swi(&mut self, _bus: &mut Bus, _insn: ArmInstruction) -> CpuResult<CpuPipelineAction> {
|
||||||
self.exception(Exception::SoftwareInterrupt);
|
self.exception(Exception::SoftwareInterrupt);
|
||||||
Ok(CpuPipelineAction::Flush)
|
Ok(CpuPipelineAction::Flush)
|
||||||
|
|
|
@ -112,19 +112,7 @@ impl Core {
|
||||||
} else {
|
} else {
|
||||||
insn.rs()
|
insn.rs()
|
||||||
};
|
};
|
||||||
|
self.branch_exchange(self.get_reg(src_reg))
|
||||||
let mut addr = self.get_reg(src_reg);
|
|
||||||
if addr.bit(0) {
|
|
||||||
self.cpsr.set_state(CpuState::THUMB);
|
|
||||||
} else {
|
|
||||||
// word align when switching to arm state
|
|
||||||
addr = addr & !0x3;
|
|
||||||
self.cpsr.set_state(CpuState::ARM);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.pc = addr & !1;
|
|
||||||
|
|
||||||
Ok(CpuPipelineAction::Flush)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exec_thumb_hi_reg_op_or_bx(
|
fn exec_thumb_hi_reg_op_or_bx(
|
||||||
|
|
Reference in a new issue