Home > Mobile >  Instructions with Long (32 and 64 bit) immediate operands in RISC processors
Instructions with Long (32 and 64 bit) immediate operands in RISC processors

Time:07-26

Are operations with large immediate numbers possible in RISC processors, when the size of the immediate operand does not allow to place it in the 32-bit instruction word (standard for RISC architectures). Say we want to store a 32-bit or 64-bit immediate in a register, or execute a simple arithmetic instruction with an integer of that size.

Here are some examples in a pseudocode.

Let r1 and r2 are register names, and imm32 is an immediate operand of 32-bit length, while imm64 is an immediate operand of 64-bit size.

We want to execute the following instructions, written in pseudocode like:

1) r1 = imm32
2) r1 = imm64
3) r1 = r2   imm32
4) r1 = r2 - imm64

Are such instructions possible on popular RISC platforms? For example, we can consider such well known architectures, as MIPS, RISC-V, SPARC, DEC Alpha64 (dead, but famous processor family), ARM and Power. If they are possible, what would be the code for these instructions and how are they kept in memory when a RISC-instruction word contains only 32 bits? If they aren't, what is the program simulation for the pseudocode, given above?

CodePudding user response:

By the pidgeonhole principle, not all n bit constants will fit an n or less bit instruction word if that word also encodes other things. So no, RISC architectures with fixed instruction length cannot support arbitrary immediates.

To work around this, the immediate has to be first loaded into a register so it can then be used with a register-operand variant of the instruction. Some assemblers can do this automatically. The immediate may then still be to big to be loaded in one chunk. The following two techniques are commonly used to work around this:

  1. load the immediate from a nearby literal pool using a pc relative addressing mode
  2. load the immediate with a sequence of instructions where each instruction sets some bits of the immediate (e.g. one instruction loads the low 16 bit, the second sets the high 16 bit)

In modern RISC designs, approach (2) is usually recommended and the processor likely employs macro fusion to perform the two or more load-immediate instructions in one step.

Note that besides being able to work around this limitation, modern RISC architectures usually try to make the limited space for immediates as useful as possible. For example, ARM does not just store an immediate but rather an immediate and a rotation amount, permitting many commonly used constants and bit patterns (in case of Thumb2) to be used directly.

CodePudding user response:

Yes of course. Being RISC doesn't mean having fixed-length instructions. It simply means the architecture is RISC-V Expanded Instruction-Length Encoding

See also

CodePudding user response:

Are operations with large immediate numbers possible in RISC processors?

Nope, at least not in general, they usually aren't, as you might guess. This is because most RISC processors have a fixed instruction encoding length, and therefore cannot encode immediates larger than (or equal to) the length of the instruction itself.

In order to work with large immediates, you usually have pseudo-instructions that are understood by the assembler (but don't really exist) and then split into multiple instruction when assembling.

As an example, in MIPS 32-bit all instructions are 4 bytes long (32-bit), so even only using one bit for the opcode itself, you wouldn't be able to work with immediates larger than 31 bits. In fact, immediates in MIPS 32-bit can only take at most 16 of the 32 bits of an instruction. To load a large immediate into a register you have to use two instructions: LUI (Load Upper Immediate) plus another ALU instruction to modify the lower 16-bits. The assembler provides the LI (Load Immediate) pseudo-instruction, which is assembled into two instructions.

# Load 0x12345678 into $t0
LUI $t0, 0x1234
ORI $t0, $t0, 0x5678

Other architectures (notably ARM) often mix data with code in order to work with large immediates, using load instructions to get the immediate into a register, and using the instruction pointer to locate it:

ldr    r0, [pc, #0]
.short 0x0000
.word  0x12345678

And again the assembler might implement pseudo-instructions to do the same operation in a way that is clearer to understand by programmers, like in this case ldr r0, =IMMEDIATE using "unified assembler language" syntax that can encode both into Thumb and ARM instructions.

  • Related