Skip to main content

Interlock

Enum Interlock 

Source
pub enum Interlock {
    Ldi,
    Dcb,
    Dcm,
    Icb,
    Itm,
    Mci,
    Cop,
    Cp0i,
    Exception,
}
Expand description

The documented interlocks (UM Table 4-3).

Held as a named enum rather than a bare cycle count so a stall is always attributable — “why did this stall” is answerable from a trace.

Variants§

§

Ldi

Load interlock — 1 cycle (UM §4.6.5).

Deliberately imprecise, matching hardware: it fires when the next instruction’s rs or rt field equals the load’s rt, whether or not that field is actually used as a source. See load_interlocks.

§

Dcb

Data cache busy — a cached store keeps the cache busy for its DC and WB stages, so a following cache access stalls 1 cycle (UM §4.6.7).

§

Dcm

Data cache miss — the fill cost is 8..=9 + M PCycles (UM Table 11-1).

§

Icb

Instruction cache busy (UM §4.6.3).

§

Itm

Instruction micro-TLB miss — 3 PCycles (UM §4.6.2).

§

Mci

Multi-cycle interlock: MULT/DIV/FPU stall the whole pipeline for the documented count (UM Tables 3-12, 7-14).

§

Cop

Cache operation (UM Table 4-3).

§

Cp0i

CP0 bypass interlock — 1 PCycle (UM §4.6.9, p. 113).

Named but never raised. On hardware it fires when an instruction that caused an exception reaches WB while the next instruction in DC reads any CP0 register. Here, taking an exception already flushes the pipeline and stalls for the 2-PCycle epilogue, so the two triggers overlap and no case distinguishes them — charging this on top would invent a cycle the hardware may not spend. Separating them needs the timing set n64-systemtest ships default-off, the same instrument ledger C-1 waits on.

The variant stays because Interlock enumerates the documented taxonomy, and a gap in a taxonomy is worth more than a silently missing row. This doc previously said it fires, in the present tense, which is the comment-is-not-an-implementation hazard docs/engineering-lessons.md §3.3c describes – the cost was itself recorded as undocumented in three files while sitting in the very paragraph they cited (§3.3b).

§

Exception

Taking an exception — 2 PCycles (UM §4.7, p. 114).

Not strictly one of Table 4-3’s eight interlocks: the pipeline stalls while the epilogue runs and the aborted instructions drain. Named here so a trace can attribute the cycles rather than showing an unexplained gap.

Trait Implementations§

Source§

impl Clone for Interlock

Source§

fn clone(&self) -> Interlock

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Interlock

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for Interlock

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Hash for Interlock

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for Interlock

Source§

fn eq(&self, other: &Interlock) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for Interlock

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Copy for Interlock

Source§

impl Eq for Interlock

Source§

impl StructuralPartialEq for Interlock

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,