refactor(cpu): share instruction fetch samples with bus history
This commit is contained in:
parent
ea055270f4
commit
e630d7a0ea
18 changed files with 538 additions and 117 deletions
|
|
@ -1,6 +1,6 @@
|
|||
//! ARM/Thumb instruction buffering. Timing and bus ownership remain separate.
|
||||
use super::{Cpu, CpuError, InstructionSet};
|
||||
use crate::memory::{Memory, MemoryError};
|
||||
use crate::memory::{InstructionFetch, Memory, MemoryError};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub(super) struct Pipeline {
|
||||
|
|
@ -14,6 +14,7 @@ pub(super) struct Pipeline {
|
|||
pub(super) struct Fetched {
|
||||
pub instruction: u32,
|
||||
pub continuation: Pipeline,
|
||||
pub lookahead: InstructionFetch,
|
||||
}
|
||||
|
||||
impl Cpu {
|
||||
|
|
@ -34,11 +35,15 @@ impl Cpu {
|
|||
.filter(|pipe| pipe.pc == pc && pipe.instruction_set == instruction_set);
|
||||
let instruction = match retained {
|
||||
Some(pipe) => pipe.instructions[0].clone(),
|
||||
None => memory.fetch_instruction(pc, instruction_set),
|
||||
None => memory.fetch_instruction(pc, instruction_set).instruction,
|
||||
}?;
|
||||
let decode = match retained {
|
||||
Some(pipe) => pipe.instructions[1].clone(),
|
||||
None => memory.fetch_instruction(pc.wrapping_add(width), instruction_set),
|
||||
None => {
|
||||
memory
|
||||
.fetch_instruction(pc.wrapping_add(width), instruction_set)
|
||||
.instruction
|
||||
}
|
||||
};
|
||||
let fetched = memory.fetch_instruction(pc.wrapping_add(2 * width), instruction_set);
|
||||
Ok(Fetched {
|
||||
|
|
@ -46,23 +51,26 @@ impl Cpu {
|
|||
continuation: Pipeline {
|
||||
pc: pc.wrapping_add(width),
|
||||
instruction_set,
|
||||
instructions: [decode, fetched],
|
||||
instructions: [decode, fetched.instruction.clone()],
|
||||
},
|
||||
lookahead: fetched,
|
||||
})
|
||||
}
|
||||
|
||||
/// Capture the target pair using the resulting state, without early errors.
|
||||
/// Explicit exception entry without Memory leaves a cold buffer instead.
|
||||
pub(crate) fn refill_pipeline(&mut self, memory: &Memory) {
|
||||
pub(crate) fn refill_pipeline(&mut self, memory: &mut Memory) {
|
||||
let pc = self.pc();
|
||||
let instruction_set = self.instruction_set;
|
||||
let fetches = [
|
||||
memory.fetch_instruction(pc, instruction_set),
|
||||
memory.fetch_instruction(pc.wrapping_add(instruction_set.width()), instruction_set),
|
||||
];
|
||||
memory.refill_cpu_bus_history(&fetches);
|
||||
self.pipeline = Some(Pipeline {
|
||||
pc,
|
||||
instruction_set,
|
||||
instructions: [
|
||||
memory.fetch_instruction(pc, instruction_set),
|
||||
memory.fetch_instruction(pc.wrapping_add(instruction_set.width()), instruction_set),
|
||||
],
|
||||
instructions: fetches.map(|fetch| fetch.instruction),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue