# 1. I-Type shift instruction

Related reference articles:

# RISC-V teaching plan

The above RISC-V instruction set explanation (2) I-Type integer register-immediate instruction introduces 6 instructions in I-type, this article will continue to introduce the rest of the integer register-immediate instruction in I-type (here is Shift instructions belonging to the I-type) and integer register-immediate instructions in the U-type.

Figure 1 shows a shift instruction with an immediate number of moves, and other shift instructions will be introduced later. It can be seen from the machine coding format that these three instructions are somewhat different from the six I-type instructions mentioned above. The I-immediate of this article is divided into two parts:

The imm[10] (bit 30 of the machine code) in imm[11:5] is used to distinguish the shift type, where the bit 30 of the machine code of the SLLI and SRLI instructions is 0, and the bit 30 of the machine code of the SRAI instruction is 1 [ 1].

imm[4:0] or shamt [4:0] (shift amount) means the shift amount. It can be seen that the range of shamt of SLLI, SRLI, and SRAI is [4:0], this is because in RV32I, the maximum The shift amount is 31 bits, which is 2^5 – 1.

Figure 1 Shift instruction machine encoding format [1]

## 1.1. SLLI

SLLI (shift left logical immediate), the immediate logical left shift instruction format is SLLI rd, rs1, shamt. x[rd] = x[rs1] ≪ shamt

Its machine code is shown in Figure 2. The OP-IMM of SLLI is 001_0011, funct3 is 001, and IMM[10] is 0. How many bits to move is determined by imm[4:0]. This instruction shifts the value in rs1 to the left by shamt[4:0], fills the low-order bits of rs1 with zeros, and writes the result to rd.

Example:

**SLLI x13, x12, 3**

Shifts the value in the x12 register to the left by 3 bits and writes the result to the x13 register.

OP-IMM is 001_0011

funct3 is 001

shamt is 5’b0_0011

bits 25-31 are 7’b000_0000

rs1 is 5’b0_1100

rd is 5’b0_1101

So the machine code corresponding to **SLLI x13, x12, 3** is 0000000_00011_01100_001_01101_0010011, and the corresponding hexadecimal is 32’h0036_1693

Figure 2 SLLI machine encoding format [2]

## 1.2. SRLI

SRLI (shift right logical immediate), the immediate logical right shift instruction format is SRLI rd, rs1, shamt . x[rd] = x[rs1] ≫ shamt

Its machine code is shown in Figure 3. The OP-IMM of SRLI is 001_0011, funct3 is 101, and IMM[10] is 0. This instruction shifts the value in rs1 right by shamt[4:0] bits, fills the high bits of rs1 with zeros, and writes the result to rd.

Example:

**SRLI x13, x12, 5**

Shift the value in register x12 right by 5 bits and write the result to x13

Figure 3 SRLI machine encoding format [2]

## 1.3. SRAI

SRAI (shift right arithmetic immediate), the immediate arithmetic right shift instruction format is SRAI rd, rs1, shamt . x[rd] = x[rs1] ≫ shamt

Its machine code is shown in Figure 4, SRAI’s OP-IMM is 001_0011, funct3 is 101, and IMM[10] is 1. This instruction shifts the value in rs1 to the right by shamt[4:0] bits, the high-order bits of rs1 are filled with the original rs1[31] (the sign bit is filled), and the result is written into rd.

Example:

**SRAI x13, x12, 3**

Arithmetic right shifts the value in the x12 register by 3 bits and writes the result to x13

Figure 4 SRAI machine encoding format [2]

**Notice:**

**The OP-IMM and funct3 codes of SRLI and SRAI are all the same, and the instruction [1] is distinguished by the value of imm[10].**

## 1.4. Example to distinguish between arithmetic right shift and logical right shift

Pay attention to distinguishing between arithmetic right shift and logical right shift, such as 1100_1100 (the 8-bit number is described here, and the number actually stored in the register in RV32I is 32-bit),

1100_1100 Arithmetic right shift three places, the result is **111** 1_1001

0011_0011 Arithmetic right shift three places, the result is **000** 0_0110

And 1100_1100 logically shifted to the right by three bits results in **000** 1_1001

0011_0011 logically shifted right by three bits, the result is **000** 0_0110

# 2. U-Type integer register – immediate instruction

The AUIPC in the two U-type instructions introduced here no longer operates on general-purpose registers (x0-x31) but operates on the program counter (PC).

Figure 5 is the machine code format of LUI and AUIPC. Comparing it with the machine code of I-type, we can see that this type does not have rs1 and funct3, but a 20-bit immediate number (12-bit immediate value in I-type) position of the number is included).

Note that the instruction opcodes in U-type are not the same. The same as I-type, the immediate corresponding to U-type is fixed to 20 bits and is named U-immediate[31:12], as shown in Figure 5.

Figure 5 U-type integer register-immediate instruction[1]

## 2.1. LUI

LUI (load upper immediate), the upper immediate data load instruction format is LUI rd, immediate. x[rd] = sext(immediate[31:12] << 12)

Its machine code is shown in Figure 6, and the opcode of LUI is 011_0111. This instruction is to write U-immediate into the upper 20 bits of rd and fill the lower 12 bits of rd with zeros.

example instruction,

LUI x8, 0xf0000

Load 0xf000_0000 into the x8 register

opcode is 011_0111

rd is 5’b01000

immediate[31:12] is 1111_0000_0000_0000_0000

The corresponding 32-bit machine code is 1111_0000_0000_0000_0000_01000_0110111, which is simplified with hexadecimal to get 32’hF000_0437

Figure 6 LUI machine encoding format [2]

## 2.2. AUIPC

AUIPC (add upper immediate to PC), the format of PC plus immediate instruction is AUIPC rd, immediate. x[rd] = pc + sext(immediate[31:12] << 12)

Its machine code is shown in Figure 7, and the opcode of AUIPC is 001_0111. This instruction is to sign-extend the 20-bit immediate value, move it to the left by 12 bits, add it to the current PC, and write the result to the rd register.

Figure 7 AUIPC machine encoding format [2]

Command example:

**AUIPC x12, 0xf00**

Add 0xf0_0000 to the current PC and load it into the x12 register.

**Notice:**

**Most immediates are small or require all XLEN bits. RISC-V chooses asymmetric immediate splitting (12 bits in regular instructions, plus 20 bits for special upload immediate instructions, such as LUI) to increase the opcode space available for regular instructions [1].**

**The combination of 12-bit immediates in AUIPC and JALR (covered in a later article) can transfer control to any 32-bit PC-relative address, while AUIPC plus a 12-bit immediate offset in regular load or store instructions can Access any 32-bit PC-relative data address.**

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

# 3. Article reference

[1] *Riscv.org* , 2021. [Online]. Available: https://riscv.org/wp-content/uploads/2019/12/riscv-spec-20191213.pdf. [Accessed: 22- Feb- 2021] .

[2] D. Patterson and A. Waterman, *The RISC-V reader*. Berkeley: Strawberry Canyon LLC, 2018.