pub struct BasicEagerInstructionFetcher<'a, I>where
I: Instruction,{ /* private fields */ }Expand description
Eager instruction fetcher walks instructions that BasicEagerInstructions decoded upfront.
This is a plain Copy cursor without a destructor, see BasicEagerInstructions for why.
The fallback instruction after the decoded stream has no address of its own, so
ProgramCounter::set_pc() refuses the address right after the decoded stream as out of
bounds, unless the return trap is there. Execution that starts again at that address therefore
fails with ExecutionError::OutOfBoundsRead or stops at the trap, instead of running the
fallback instruction.
Trait Implementations§
Source§impl<'a, I> Clone for BasicEagerInstructionFetcher<'a, I>where
I: Instruction + Clone,
impl<'a, I> Clone for BasicEagerInstructionFetcher<'a, I>where
I: Instruction + Clone,
Source§fn clone(&self) -> BasicEagerInstructionFetcher<'a, I>
fn clone(&self) -> BasicEagerInstructionFetcher<'a, I>
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl<'a, I> Copy for BasicEagerInstructionFetcher<'a, I>where
I: Instruction + Copy,
Source§impl<I> Debug for BasicEagerInstructionFetcher<'_, I>where
I: Instruction,
impl<I> Debug for BasicEagerInstructionFetcher<'_, I>where
I: Instruction,
Source§impl<I, Memory> InstructionFetcher<I, Memory> for BasicEagerInstructionFetcher<'_, I>where
I: Instruction,
Memory: VirtualMemory,
impl<I, Memory> InstructionFetcher<I, Memory> for BasicEagerInstructionFetcher<'_, I>where
I: Instruction,
Memory: VirtualMemory,
Source§type Peeked = ()
type Peeked = ()
Nothing, the decoded stream is where the instruction stays and the position is the fetcher’s own, so a threaded handler loads each operand it uses straight from there
Source§unsafe fn peek_instruction(
&mut self,
_memory: &Memory,
) -> FetchInstructionResult<I, ()>
unsafe fn peek_instruction( &mut self, _memory: &Memory, ) -> FetchInstructionResult<I, ()>
Source§unsafe fn peeked_instruction<'a>(&'a self, (): &'a ()) -> &'a I
unsafe fn peeked_instruction<'a>(&'a self, (): &'a ()) -> &'a I
Source§unsafe fn advance(&mut self, instruction_size: u8)
unsafe fn advance(&mut self, instruction_size: u8)
instruction_size bytes that
Self::peek_instruction() has just returned. Read moreSource§unsafe fn fetch_instruction(
&mut self,
_memory: &Memory,
) -> FetchInstructionResult<I>
unsafe fn fetch_instruction( &mut self, _memory: &Memory, ) -> FetchInstructionResult<I>
Source§impl<I, Memory> ProgramCounter<<<<I as Instruction>::Hart as HartConfig>::Reg as Register>::Type, Memory> for BasicEagerInstructionFetcher<'_, I>where
I: Instruction,
Memory: VirtualMemory,
impl<I, Memory> ProgramCounter<<<<I as Instruction>::Hart as HartConfig>::Reg as Register>::Type, Memory> for BasicEagerInstructionFetcher<'_, I>where
I: Instruction,
Memory: VirtualMemory,
Source§unsafe fn try_set_pc_relative(
&mut self,
instruction_size: u8,
offset: i32,
) -> bool
unsafe fn try_set_pc_relative( &mut self, instruction_size: u8, offset: i32, ) -> bool
Moves within the decoded stream instead of resolving an address and converting it back,
which is what going through Self::set_pc() would do.
One comparison and one test are all this needs to recognize every target it cannot resolve:
one past the end of the decoded stream, a backwards branch that ran off its start, and an
unaligned one. BasicEagerInstructions::decode() refuses a return trap inside the code,
so a branch to the trap fails the bounds check here too and is answered by
Self::failed_branch() like any other target this refuses.
Source§unsafe fn failed_branch(
&mut self,
memory: &Memory,
) -> Result<ControlFlow<()>, ExecutionError<<<<I as Instruction>::Hart as HartConfig>::Reg as Register>::Type>>
unsafe fn failed_branch( &mut self, memory: &Memory, ) -> Result<ControlFlow<()>, ExecutionError<<<<I as Instruction>::Hart as HartConfig>::Reg as Register>::Type>>
Turns the refused target back into an address and hands it to Self::set_pc(), which is
where the rules about what is and is not an instruction address live.
Source§fn get_pc(
&self,
) -> <<<I as Instruction>::Hart as HartConfig>::Reg as Register>::Type
fn get_pc( &self, ) -> <<<I as Instruction>::Hart as HartConfig>::Reg as Register>::Type
Source§fn set_pc(
&mut self,
_memory: &Memory,
pc: <<<I as Instruction>::Hart as HartConfig>::Reg as Register>::Type,
) -> Result<ControlFlow<()>, ExecutionError<<<<I as Instruction>::Hart as HartConfig>::Reg as Register>::Type>>
fn set_pc( &mut self, _memory: &Memory, pc: <<<I as Instruction>::Hart as HartConfig>::Reg as Register>::Type, ) -> Result<ControlFlow<()>, ExecutionError<<<<I as Instruction>::Hart as HartConfig>::Reg as Register>::Type>>
Source§fn old_pc(&self, instruction_size: u8) -> Address
fn old_pc(&self, instruction_size: u8) -> Address
instruction. Read moreSource§fn set_pc_relative(
&mut self,
memory: &Memory,
instruction_size: u8,
offset: i32,
) -> Result<ControlFlow<()>, ExecutionError<Address>>where
Self: ProgramCounter<Address, Memory>,
fn set_pc_relative(
&mut self,
memory: &Memory,
instruction_size: u8,
offset: i32,
) -> Result<ControlFlow<()>, ExecutionError<Address>>where
Self: ProgramCounter<Address, Memory>,
ExecutionResult::Branch, continuing offset bytes from the instruction being
executed. Read more