Just for fun, let’s compare what happens on different processor architectures when you load a value from memory into a larger register. Possible responses are
- Unable: The processor does not support loading data into a larger register.
- Zero-extend: The processor zero-extends the small value to the large value.
- Sign-extend: The processor sign-extends the small value to the large value.
- Either: The processor has separate instructions for sign and zero extension.
- (blank): Does not apply because the processor doesn’t have registers larger than this.
Processor | From byte | From 16-bit | From 32-bit |
---|---|---|---|
8086 | Unable | ||
Alpha AXP | Unable | Unable | Sign-extend |
Alpha AXP with BWX | Zero-extend | Zero-extend | Sign-extend |
80386 | Either | Either | |
x86-64 | Either | Either | Either |
Intel ia64 | Zero-extend | Zero-extend | Zero-extend |
MIPS | Either | Either | Either |
PowerPC | Zero-extend | Either | Either |
SH-4 | Sign-extend | Sign-extend | |
ARM | Either | Either | Either |
68000 | Unable | Unable | |
SPARC | Either | Either | Either |
RISC-V | Either | Either | Either |
Notes:
- The Alpha AXP with BWX is the only processor on the list where the extension mode changes between zero and sign, depending on size. This is a historical artifact: It inherited the “sign-extend” entry from the “Alpha AXP” row above it, but it turns out that bytes are usually zero-extended, so the BWX extension chose zero-extension for bytes. Words went along with bytes to minimize the weirdness.
- The x86-64 supports both zero-extended 32-to-64 loads and sign-extended 32-to-64 loads, but the zero-extended load offers a more compact encoding.
We can organize the processors by how they choose to extend small values to larger values:
Unable | 8086, 68000, Alpha AXP (bytes and words) |
---|---|
Zero-extend | ia64, PowerPC (bytes) |
Sign-extend | Alpha AXP, SH-4 |
Either | 80386, x86-64, MIPS, ARM, SPARC, RISC-V |
Mixed | Alpha AXP with BWX, PowerPC |
Wouldn’t “leave rest of register as is” be an option? Like moving into AL for example.
As I understand, in pipelined implementations, it’s preferable to avoid partial-register results. RISC ISAs tend to perform ALU operations on full registers and provide smaller-sized loads and stores for convenience.
68k and x86 processors retained their predecessors’ behaviour for compatibility and simply had to deal with the extra complexity when pipelined and superscalar implementations came along. Even x86-64 automatically zero-extends 32-bit results to 64 bits.
PDP-11: From byte: Sign-extend
The m68k can do direct 16-to-32-bit sign-extended loads via movea.w to address registers. I suppose that’s a fairly limited incantation and could be missed easily – M68K PRM p. 4-119.