Menu Close

U-Type Integer Register-Immediate Instructions – RISC-V Instruction Set Explanation (3)

Posted in Risc-V

The two U-type instructions introduced here operate on the program counter (PC) rather than the general-purpose registers (x0-x31), and are represented by the AUIPC opcode.

Figure 1 shows the machine code formats of LUI and AUIPC, and comparing them with the machine code of the I-type instructions, it can be seen that the U-type instructions do not have rs1 and funct3 fields, but instead have a 20-bit immediate value (including the 12-bit immediate value in the I-type instructions).

Note that the opcode of U-type instructions is different from that of I-type instructions. Like the I-type instructions, the immediate value in U-type instructions is fixed at 20 bits and is named U-immediate[31:12], as shown in Figure 1.

U-Type Integer Register-Immediate Instructions.
Figure 1 U-Type Integer Register-Immediate Instructions.

1. LUI

Load Upper Immediate

Instruction Format:

LUI rd,immediate。x[rd] = sext(immediate[31:12] << 12)

The machine code for LUI is shown in Figure 2, with opcode 011_0111. This instruction writes the U-immediate value to the top 20 bits of the rd register, with the lower 12 bits of rd set to zero.

Figure 2 - LUI machine Code Format
Figure 2 – LUI machine Code Format

1.1 Example

LUI x8,0xf0000

To load 0xf000_0000 into the x8 register:

  1. opcode [o-6]: 011_0111
  2. rd [7-11]: 5’b01000
  3. immediate[31:12] :1111_0000_0000_0000_0000
  4. 32 bit machine code: 1111_0000_0000_0000_0000_01000_0110111 ( 32’hF000_0437)

Notice:

  • 32′  – 32 bit
  • b01000  b – binary
  • hF000_0437 h – Hex

2. AUIPC

Add Upper Immediate to PC

Instruction Format:

AUIPC rd,immediate。x[rd] = pc + sext(immediate[31:12] << 12)

The machine code for AUIPC is shown in Figure 3, with opcode 001_0111. This instruction sign-extends the 20-bit immediate value, left-shifts it by 12 bits, adds it to the current PC value, and writes the result to the rd register.

Related:   R-Type Integer Register-Register Instructions - RISC-V Instruction Set Explanation (4)
AUIPC machine code format
Figure 3 – AUIPC machine code format

2.1 Example

AUIPC x12,0xf00

To add 0xf0_0000 to the current PC and load the result into the x12 register

  • The instruction opcode for AUIPC is 0x17 (binary: 0010111).
  • The destination register is x12, encoded as rd=0x0C (binary: 01100).
  • The immediate value is 0xF0, which is sign-extended to fill bits 31:12 of the 32-bit immediate field. Therefore, imm[31:12] is 0xFFFFF000.
  • When assembled, the immediate field is shifted left by 12 bits to obtain the final immediate value of 0xFFFFF000 << 12, which is 0xFFFFF000_00000000.
  • Finally, the bytes are arranged in little-endian order to obtain the 32-bit machine code value 1000_0111_0000_0000_0110_0000_0001_0111 of 0x8700_6017.

Notice:

Most immediates are either very small or require all XLEN bits. RISC-V has chosen asymmetric immediate encoding (12 bits for regular instructions, plus 20 bits for special “upward” instructions like LUI) to increase the opcode space available for regular instructions.

The combination of the 12-bit immediate in AUIPC and JALR (which we will cover in a subsequent article) can be used to transfer control to any 32-bit PC-relative address, while AUIPC added to the 12-bit immediate offset in a regular load or store instruction can access any 32-bit PC-relative data address.

The current PC can be obtained by setting the U-immediate of AUIPC to 0.

Leave a Reply