1
\$\begingroup\$

I noticed that RISC-V, like some other RISC architectures, by convention treats register 1 specially, using it as the link register, holding the return address for function calls.

If most code follows this convention, since instructions are aligned to 4 bytes, then r1 will follow that alignment, so the lower two bits will be predictably zero, and could be hardwired to zero, saving a few transistors. (Admittedly a tiny saving on the scale of today's chips, but it makes a good concrete example.)

But of course this is only a convention. r1 can be used otherwise; as far as the hardware is concerned, it is a general-purpose register. That doesn't mean code is particularly likely to need to treat it as a general register with all 32 bits available (since there are thirty other registers that can be used that way), but it does mean in an out of order implementation, it participates in register renaming.

When the register renaming circuitry is mapping architectural registers to a larger number of physical registers, would the existence of special registers complicate things? For example, had the architecture been defined so that the low two bits of r1 were hardwired to zero, would an out of order implementation then have an extra complication of having to track the fact that such and such a particular physical register is actually a renaming of that special register, so as to be ready to throw away any 1's that an operation might try to write into those low two bits?

Or, more generally: once CPUs start going out of order, if some registers are treated specially, does the hardware then start needing extra logic gates to keep track of which registers are renamed from the special ones?

\$\endgroup\$
  • 1
    \$\begingroup\$ It seems to me that the retire-unit, which eventually posts results back to the registers in-order would simply do so. If some bits are hardwired within some particular register, say R1, it would only mean they couldn't be written even if the re-order buffer result value had non-zero bits in it. Or do you imagine something else? \$\endgroup\$ – jonk Mar 25 at 10:14
  • 1
    \$\begingroup\$ Out-of-order execution implies a queue of instructions waiting for results (re-order buffer.) This queue has a result field along with the decoded instruction being executed. When the instruction completes, the field is updated. A separate retire-unit continually observes the top of the queue for completion of that specific instruction (which may complete many cycles after some others have completed.) When it completes, the retire-unit posts the result field into the associated register and continues posting the result fields of following instructions if they are also done (and if it can.) \$\endgroup\$ – jonk Mar 25 at 10:30
  • 1
    \$\begingroup\$ The EAX register exists, of course. Along with other accessible registers to the programmer. It just doesn't get written until the retire unit decides to transfer the result field from a completed instruction. In the re-order buffer, it's just a result field. A decoded instruction (RISC in the P II case) allocates a functional unit using a registration station and initiates execution. The functional unit posts the result (or link to it) into the result field when it completes, freeing the functional unit. (I worked at Intel on chipsets for the P II family back in the late 1990's.) \$\endgroup\$ – jonk Mar 25 at 10:38
  • 1
    \$\begingroup\$ The job of the retire unit is to then continually examine the re-order buffer for completed RISC instructions where their results have been posted and then to perform the transfer to the actual register and free up the re-order buffer entry for more RISC instructions. On the P II, the retire unit can post up to three of these per clock. \$\endgroup\$ – jonk Mar 25 at 10:42
  • 1
    \$\begingroup\$ That choice is a matter of design. In the MIPS R2000, there are no interlocks for the registers. So if you are dumb enough to use one in a following instruction that is too close (the next one), you'll get a stale value. But it's just extra logic if you want to arrange your re-order buffer so that if one entry in the buffer requires a posted result from an earlier one that isn't complete, it doesn't initiate allocation of a functional unit from the registration station and instead waits busy. Different designers may use different methods here. \$\endgroup\$ – jonk Mar 25 at 10:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.