Is there any difference between this:
rem $s0, $t0, $t1
and this:
div $t0, $t1
mfhi $s0
I know that the first one works but I'm not sure about the second. Is it the same thing?
Is there any difference between this:
rem $s0, $t0, $t1
and this:
div $t0, $t1
mfhi $s0
I know that the first one works but I'm not sure about the second. Is it the same thing?
older MIPS didn't have rem
, only a div
that put the results into special registers, to avoid microarchitectural problems with write-back to the register file from a high latency instruction in a simple pipeline.
It's not the mfhi
that's computing the remainder, it's div
(producing its result in the lo=quotient
and hi=remainder
special registers). mfhi
is just "Move from HI"; it copies from that special register to a general-purpose register.
The names come from the mult
instruction (which like div
has higher latency than add
or any other integer ALU instruction supported by original MIPS I), which produces a double-width result in LO and HI. (Getting result from mult in mips and
In MIPS, what is HI and LO).
If the destinations of mult
and div
were general-purpose registers, then in the cycle the results were ready, there might also be an add
or lw
or whatever other result that the pipeline needed to write to the register file in the same cycle. And those instructions produce 2 word results each. Using special LO/HI registers avoids write-back conflicts from both causes.
Also remember that MIPS stands for Minimally Interlocked Pipeline Stages, so a major design goal for early MIPS was to not have hardware even check for data dependencies, and leave that up to software to not try to read a result before it was ready. Making mult
/ mfhi
/ mflo
special also helps with that, because there isn't a dependency through a normal GP register.
But more modern MIPS CPUs have a much larger transistor budget, and can support instructions like mul
and rem
that put their results in GP registers even though they have higher latency than normal ALU instructions.
I'm not sure when they were added to the ISA; whether that was in the era of high-performance out-of-order execution MIPS CPUs like r10000.