rd, rs1, rs2rd = rs1 << (rs2 & 31)sll shifts the bits of a number sideways. Picture the 32 bits of a register laid out in a row; a shift slides them all left or right by some number of positions. sll slides them left — its name is short for shift left logical. The form sll rd, rs1, rs2 takes the value in rs1, shifts it left by the number of places given in rs2, and writes the result to rd.
When bits slide left, two things happen at the ends: the empty positions opening up on the right are filled with 0s, and any bits pushed off the left edge are simply discarded.
Here is why shifting is useful rather than just curious: sliding the bits one place to the left doubles the number, exactly the way adding a 0 to the end of a decimal number multiplies it by ten. Shift left by 1 to multiply by 2, by 2 to multiply by 4, by 3 to multiply by 8 — each extra place doubles again. Since shifting is cheaper for the processor than a full multiply, this is the fast way to multiply by powers of two, and it is heavily used for stepping through arrays, where each element sits a fixed power-of-two number of bytes from the last.
The shift amount here comes from a register, useful when it is computed while the program runs. If the amount is a fixed constant, use slli instead. The example shifts 3 left by 2 places, multiplying it by 4 to give 12.
li t0, 3 li t1, 2 sll t2, t0, t1 # t2 = 12