refactor(cpu): share instruction fetch samples with bus history

This commit is contained in:
0xrsydn 2026-10-06 14:12:03 +07:00
commit e630d7a0ea
18 changed files with 538 additions and 117 deletions

View file

@ -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),
});
}
}