Fix exceptions and dataprocess mode change
Former-commit-id: 5892131496904b621398212b9dfc077242fa9557
This commit is contained in:
parent
7501adfd12
commit
c0d437b1a1
|
@ -180,10 +180,21 @@ impl Core {
|
||||||
let rd = insn.rd();
|
let rd = insn.rd();
|
||||||
|
|
||||||
if let Some(result) = self.alu(opcode, op1, op2, set_flags) {
|
if let Some(result) = self.alu(opcode, op1, op2, set_flags) {
|
||||||
self.set_reg(rd, result as u32);
|
|
||||||
if rd == REG_PC {
|
if rd == REG_PC {
|
||||||
|
// TODO move this code into a function
|
||||||
|
let old_mode = self.cpsr.mode();
|
||||||
|
if let Some(index) = old_mode.spsr_index() {
|
||||||
|
let new_psr = self.spsr[index];
|
||||||
|
if old_mode != new_psr.mode() {
|
||||||
|
self.change_mode(new_psr.mode());
|
||||||
|
}
|
||||||
|
self.cpsr = new_psr;
|
||||||
|
} else {
|
||||||
|
panic!("tried to change spsr from invalid mode {}", old_mode)
|
||||||
|
}
|
||||||
self.flush_pipeline();
|
self.flush_pipeline();
|
||||||
}
|
}
|
||||||
|
self.set_reg(rd, result as u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -121,11 +121,8 @@ impl Core {
|
||||||
self.spsr[index] = self.cpsr;
|
self.spsr[index] = self.cpsr;
|
||||||
}
|
}
|
||||||
self.map_banked_registers(curr_mode, new_mode);
|
self.map_banked_registers(curr_mode, new_mode);
|
||||||
let next_index = new_mode.bank_index();
|
// let next_index = new_mode.bank_index();
|
||||||
self.gpr_banked_r14[next_index] = self
|
// self.gpr_banked_r14[next_index] = self.get_next_pc();
|
||||||
.pc
|
|
||||||
.wrapping_sub(self.word_size() as u32)
|
|
||||||
.wrapping_add(4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resets the cpu
|
/// Resets the cpu
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
use super::REG_LR;
|
||||||
use super::{cpu::Core, CpuMode, CpuState};
|
use super::{cpu::Core, CpuMode, CpuState};
|
||||||
|
|
||||||
use colored::*;
|
use colored::*;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
|
@ -35,10 +35,18 @@ impl Core {
|
||||||
let vector = e as u32;
|
let vector = e as u32;
|
||||||
let new_mode = CpuMode::from(e);
|
let new_mode = CpuMode::from(e);
|
||||||
if self.verbose {
|
if self.verbose {
|
||||||
println!("{}: {:?}, new_mode: {:?}", "Exception".cyan(), e, new_mode);
|
println!(
|
||||||
|
"{}: {:?}, pc: {:#x}, new_mode: {:?}",
|
||||||
|
"Exception".cyan(),
|
||||||
|
e,
|
||||||
|
self.pc,
|
||||||
|
new_mode
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.change_mode(new_mode);
|
self.change_mode(new_mode);
|
||||||
|
self.gpr[REG_LR] = self.get_next_pc() + (self.word_size() as u32);
|
||||||
|
|
||||||
// Set appropriate CPSR bits
|
// Set appropriate CPSR bits
|
||||||
self.cpsr.set_state(CpuState::ARM);
|
self.cpsr.set_state(CpuState::ARM);
|
||||||
self.cpsr.set_mode(new_mode);
|
self.cpsr.set_mode(new_mode);
|
||||||
|
|
|
@ -262,11 +262,7 @@ impl ThumbInstruction {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fmt_thumb_swi(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt_thumb_swi(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(
|
write!(f, "swi\t{value:#x}", value = self.raw & 0xff,)
|
||||||
f,
|
|
||||||
"swi\t{value:#x}",
|
|
||||||
value = self.raw & 0xff,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fmt_thumb_branch(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt_thumb_branch(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
|
Reference in a new issue