pub struct Decoded {
pub op: Op,
pub rs: u8,
pub rt: u8,
pub rd: u8,
pub sa: u32,
pub imm: u16,
pub dest: u8,
pub target: u32,
}Expand description
A decoded instruction: the operation plus its raw encoded fields.
The fields are kept as encoded (rs, rt, rd, sa, imm) rather than
resolved into “operands”, because the load-delay interlock matches on the
fields whether or not they are used as sources
(see crate::pipeline::load_interlocks). Resolving them away would make
that check impossible to state correctly.
Fields§
§op: OpThe operation.
rs: u8rs field, bits 25..21.
rt: u8rt field, bits 20..16.
rd: u8rd field, bits 15..11.
sa: u32Shift amount, bits 10..6 — already adjusted by +32 for the *32 forms,
so it is the effective amount the shift helpers expect.
imm: u16Immediate, bits 15..0, unextended.
dest: u8The general register this writes, or 0 for none. $zero is never
actually written, so 0 doubles as “no destination”.
target: u32The J-type 26-bit target field, bits 25..0. Shifted left 2 and combined with the delay slot’s region bits to form the address.
Implementations§
Source§impl Decoded
impl Decoded
Sourcepub const fn is_load(self) -> bool
pub const fn is_load(self) -> bool
Does this instruction load into a general register?
The load-delay interlock keys off this: only a load result is unavailable in time to bypass, which is why the interlock exists at all.
Sourcepub const fn is_store_conditional(self) -> bool
pub const fn is_store_conditional(self) -> bool
Does this instruction write rt with a value the DC stage produces
without going to memory for it?
SC/SCD are the only such forms: they write the success flag to rt
whether or not the store happens (UM §16 p. 487, “A successful SC
instruction sets the contents of general purpose register rt to 1; an
unsuccessful SC instruction sets it to 0”). They are therefore stores
that also have a register destination — a shape nothing else in the
integer set has, and one that a is_load-vs-store dichotomy silently
gets wrong in both directions.
Deliberately not folded into Self::is_load: the load-delay
interlock exists because a memory result is not ready in time, and the
SC flag is not a memory result. Treating it as a load would stall a
cycle the hardware does not.
Sourcepub const fn targets_fpr(self) -> bool
pub const fn targets_fpr(self) -> bool
Does this instruction target a floating-point register?
Always false for the integer subset. Present because the load-delay
interlock does not cross the GPR/FPR boundary, so the check needs to
know which file a destination belongs to.