Load Cancelling
Sequential loads to the same register exhibit “load cancelling”: non-terminal (i.e. not the last in a sequence) loads are completely discarded and only the last load will take effect.
This behaviour is required for passing some of the CPU MEM DLY
tests in
Amidog’s CPU test.
note
“Load” here refers to any kind of value move into a register, not only memory loads. This is
specially important for instructions like jal
, bltzal
and bgezal
, which modify ra
and also
exhibit load cancelling.
Example
Consider the following program:
lb t0, 0($a0) // load value at address in a0 to t0
lb t0, 0($a1) // load value at address in a1 to t0
nop
nop
Since both loads have t0
as their target register, load cancelling will happen and the first load
will not be visible at any point in time. That is, up until the first nop
, the value of t0
remains unchanged. It is only at the second nop
that the value of t0
changes to that of the
value loaded by the second load:
lb t0, 0($a0) // t0 unchanged
lb t0, 0($a1) // t0 unchanged
nop // t0 unchanged
nop // t0 changed to the value loaded by second instruction
Here’s another example:
lb t0, 0($a0) // t0 unchanged
addi t0, r0, 0x0001 // moves 0x0001 into t0
nop // t0 is still 0x0001 - the first load was cancelled