There is an old tradition with the RISC canon : the very first register reads as zero.
Either it's a convention and it's set by software, or the register set is hardwired to 0. In both cases the register is meant to simplify some computations and save some opcodes.
This was known to the CDC6600 developers back in the 60s/70s, you would start a program by setting B0 to 0. See Wikipedia. I also had private conversations a log time ago with a CDC user about this... I'm not sure about the POWER architecture but this convention persisted in the MIPS architecture, got adopted by the Alpha AXP architecture (though it's R31) and is still vigorous in RISC-V.
Famously, many other architectures didn't follow this convention and this is typical when your register set is small (16 or fewer registers) like ARM.
My opinion about this is : I used to follow it (in F-CPU FC0 in y2k) but now I don't.
- One reason is that the registers are often a scarce resource. 1/32 of your hardware is very little until you need it.
- Another reason is that SRAM blocks in FPGA don't play well with special cases : they are uniform so adding a "Read As Zero" entry adds gates and increases the latency (even so slightly but still).
- Yet another reason is that this was motivated by a reduced opcode space (one of the aspects of the RISC canon). But don't mistake opcode space size, and opcode complexity : with highly orthogonal instructions, size is less of a problem. It can even save a bit of decoding logic.
- I have others that I might mention later.
My approach today is
- Don't hardwire a register to 0. If you need 0, you'll set a register to this value. I estimate it's "pretty infrequent".
- There are already many other "special purpose registers" in my designs : the A and D registers, PC... and they use quite a lot of registers already...
- Design instructions that explicitly perform their intended function. For example : NOP might be an assembly macro that encodes "OR R0 R0 R0" but in more advanced architectures, this would waste two register set reads, one boolean operation and a register set write... Have a true NOP opcode that explicitly conveys the intent.
- If you want to have a "write ignore" register, just pick one where it's available. Even an address register might work (as long as you don't read the corresponding D register after that).
.
TODO : list all the use cases of the RAZ/WI (Read As Zero/Write Ignored) gimmick.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.