If we could redesign a CPU that would not need to have 8/16/32 bit registers (only 64 bit) and planned on only running NEW programs (no backports), would it make sense that we'd only have 64 bit registers?
(no al
/ah
/ax
/eax
/etc registers)
Not planning on designing a CPU, just curious.
You're right that you certainly wouldn't include high-8 partial registers, and likely wouldn't include 8 and 16-bit operand-size except for load/store and sign/zero-extend. Operations on uint8_t data can be done by zero-extending to 32/64 when needed, often not needing to redo extension between operations, except before stuff like right-shift or division where high garbage would be a problem.
Have a look at AArch64. Unlike x86 extending to x86-64, they started fresh with the machine-code format and registers to make a clean new design. They have 32 and 64-bit operand-size for most instructions, like most modern 64-bit RISC ISAs.
With instructions to zero-extend or sign-extend narrow values from registers or memory, and even some addressing modes that use a 32-bit register as an index to a 64-bit pointer, intended to support cases like foo(int *p, int idx) { return p[idx]; }
where the index has to be sign-extended to pointer-width somehow.
Even DEC Alpha, which was aggressively 64-bit, has some support for some common 32-bit operations.
Of course, it's just a matter of naming conventions whether you do MIPS64 dadd $t0, $t1, $t2
vs. add $t0, $t1, $t2
for a 64-bit vs. 32-bit add, with the operand-size implied by the mnemonic, or AArch64 add x0, x1, x2
vs. add w0, w1, w2
with the operand-size implied by the register names (x0..31
instead of w0..31
as the names for their low halves).
MIPS64 doesn't have features like AArch64's ldr x0, [x1, w2, uxtw]
(indexed addressing mode, zero-extending the low 32 bits of x2
, aka w2
). So MIPS doesn't need separate names for separate register widths, because it's not mixing widths in the same instruction. It uses a prefix for the mnemonic (d
for double-word) to indicate what kind of operation this is. (I'm glossing over the fact that MIPS64 requires 32-bit instructions other than shifts to have their inputs and outputs correctly sign-extended to 64-bit, or something like that.)
But really it's not fundamentally different, it's not like the low halves are a different register. You could design an asm syntax for MIPS64 where addu $t1w, $t2w, $t3w
meant 32-bit, and the same with $t1d
meant 64-bit.
PowerPC uses l
(long = 64-bit) vs. w
(word = 32-bit) for a lot of mnemonics, so it's similar to MIPS's style.
One assumption I'm making is that writing a "narrow" register zero-extends into the full register, like AArch64 and x86-64 for 32-bit registers.
But unlike x86-64 for legacy 8 and 16-bit partial registers, which merge with the old value because those semantics date back to 8086 and 386, before pipelined implementations, and before out-of-order exec was even considered for x86 to make it obvious that false dependencies were bad.
You'd definitely do implicit zero-extension like AArch64 add w0, w1, w2
, and provide bitfield-insert instructions for merging. Or let software do it with AND/OR.