1

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.

Sep Roland
  • 33,889
  • 7
  • 43
  • 76
Kladskull
  • 10,332
  • 20
  • 69
  • 111
  • 3
    It is a possibility, but 32 bit operations are so common, it's generally worth having special support for them. – fuz Jul 20 '22 at 23:13
  • well it is possible of course, they already exist. – old_timer Jul 21 '22 at 02:30
  • 1
    Nothing prohibits or limits using full 64 bit registers with no fractions of them. Likewise alu operations can all be 64 bit. It would be strongly recommended that you still provide some sort of 8/16/32 bit loads and stores, with possibly zero or sign extention or an additional instruction to do the mask/shift and sign or zero extension if you want to take a load/store risc like approach. Everything can be 64 bit based but 8 and 16 and 32 bit items still exist (parse/search a string in memory for example). – old_timer Jul 21 '22 at 02:37
  • You can look at the various existing 64 bit (register) processors to see how they solve these problems. Also be careful with terms like 64 bit instruction set, do you mean the instructions are 64 bits or the registers are 64 bit or what? the first two obvious 64 bit register based instruction sets that one thinks of have 32 bit instructions. generally you dont need that many bits for the instruction unless you are planning on a zillion general purpose registers. – old_timer Jul 21 '22 at 02:40
  • if it is clean slate then how can it be backwards compatible with anything? – old_timer Jul 21 '22 at 02:40
  • @old_timer E.g. Alpha had no 8/16 bit memory ops initially. It really sucked. You were expected to manually shift and mask to perform these. – fuz Jul 21 '22 at 04:45
  • 1
    **Agner Fog** already had a similar idea, see https://www.forwardcom.info/ – vitsoft Jul 21 '22 at 07:01

1 Answers1

3

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.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847