slli
slli
rd, rs1, shamt
rd = rs1 << shamt
R
31–25funct7
24–20rs2
19–15rs1
14–12funct3
11–7rd
6–0opcode
I
31–20imm[11:0]
19–15rs1
14–12funct3
11–7rd
6–0opcode
S
31–25imm[11:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:0]
6–0opcode
B
31–25imm[12,10:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:1,11]
6–0opcode
U
31–12imm[31:12]
11–7rd
6–0opcode
J
31–12imm[20,10:1,11,19:12]
11–7rd
6–0opcode

slli shifts bits to the left by a fixed amount. It is the same operation as sll — slide the bits left, fill the right with 0s, drop what falls off the left, doubling the value for each place moved (the sll page explains the mechanics) — but the number of places to shift is written into the instruction as a constant rather than read from a register. The extra i means immediate, the term for a constant baked into the instruction.

The form is slli rd, rs1, amount, where amount is a fixed number from 0 to 31. So slli t1, t0, 3 always shifts t0 left by 3 places, multiplying it by 8.

This is one of the most common instructions in real programs, because of how arrays work in memory. Each item in an array of 32-bit values takes 4 bytes, so to find item number i you multiply i by 4 — and multiplying by 4 is shifting left by 2. The recurring pattern is: shift the index to turn it into a byte offset, add the array's starting address, then load. You will write it constantly, and spotting the shift-add-load trio makes other people's assembly far easier to read.

Use slli whenever the shift distance is known as you write the code, which is most of the time; use the register form sll only when the amount is computed while running. The example shifts 5 left by 3, giving 5 times 8, or 40.

li t0, 5
slli t1, t0, 3   # t1 = 5 << 3 = 40  (5 * 8)