This “green card” is longer than one page, due to the accessible web format. We compensate by supplementing these lookup tables with references to the official ISA and/or assembly manuals where appropriate. For a two-sided reference card with the same information, check out the PDF reference card on our course website.
Reference: The official RISC-V unprivileged ISA specification, RV32I Base Integer Instruction Set, Version 2.1. In practice, the ASM Manual will have everything you need.
1RV32I Base Integer Instruction Set¶
1.1Arithmetic¶
Table 1:RV32I Instructions: Arithmetic
| Instruction | Name | Description | Type | Opcode | Funct3 | Funct7 |
|---|---|---|---|---|---|---|
add rd rs1 rs2 | ADD | R[rd] = R[rs1] + R[rs2] | R | 011 0011 | 000 | 000 0000 |
sub rd rs1 rs2 | SUBtract | R[rd] = R[rs1] - R[rs2] | R | 011 0011 | 000 | 010 0000 |
and rd rs1 rs2 | bitwise AND | R[rd] = R[rs1] & R[rs2] | R | 011 0011 | 111 | 000 0000 |
or rd rs1 rs2 | bitwise OR | R[rd] = R[rs1] | R[rs2] | R | 011 0011 | 110 | 000 0000 |
xor rd rs1 rs2 | bitwise XOR | R[rd] = R[rs1] ^ R[rs2] | R | 011 0011 | 100 | 000 0000 |
sll rd rs1 rs2 | Shift Left Logical | R[rd] = R[rs1] << R[rs2] | R | 011 0011 | 001 | 000 0000 |
srl rd rs1 rs2 | Shift Right Logical | R[rd] = R[rs1] >> R[rs2] (Zero-extend) | R | 011 0011 | 101 | 000 0000 |
sra rd rs1 rs2 | Shift Right Arithmetic | R[rd] = R[rs1] >> R[rs2] (Sign-extend) | R | 011 0011 | 101 | 010 0000 |
slt rd rs1 rs2 | Set Less Than | if (R[rs1] < R[rs2]) { R[rd] = 1 } else { R[rd] = 0 } | R | 011 0011 | 010 | 000 0000 |
sltu rd rs1 rs2 | Set Less Than (Unsigned) | if (R[rs1] < R[rs2]) { R[rd] = 1 } else { R[rd] = 0 } | R | 011 0011 | 011 | 000 0000 |
addi rd rs1 imm | ADD Immediate | R[rd] = R[rs1] + imm | I | 001 0011 | 000 | - |
andi rd rs1 imm | bitwise AND Immediate | R[rd] = R[rs1] & imm | I | 001 0011 | 111 | - |
ori rd rs1 imm | bitwise OR Immediate | R[rd] = R[rs1] | imm | I | 001 0011 | 110 | - |
xori rd rs1 imm | bitwise XOR Immediate | R[rd] = R[rs1] ^ imm | I | 001 0011 | 100 | - |
slli rd rs1 imm | Shift Left Logical Immediate | R[rd] = R[rs1] << imm | I* | 001 0011 | 001 | 000 0000 |
srli rd rs1 imm | Shift Right Logical Immediate | R[rd] = R[rs1] >> imm (Zero-extend) | I* | 001 0011 | 101 | 000 0000 |
srai rd rs1 imm | Shift Right Arithmetic Immediate | R[rd] = R[rs1] >> imm (Sign-extend) | I* | 001 0011 | 101 | 010 0000 |
slti rd rs1 imm | Set Less Than Immediate (signed) | if (R[rs1] < imm) { R[rd] = 1 } else { R[rd] = 0 } | I | 001 0011 | 010 | - |
sltiu rd rs1, imm | Set Less Than Immediate (Unsigned) | if (R[rs1] < imm) { R[rd] = 1 } else { R[rd] = 0 } | I | 001 0011 | 011 | - |
1.2Memory¶
Table 2:RV32I Instructions: Memory
| Instruction | Name | Description | Type | Opcode | Funct3 |
|---|---|---|---|---|---|
lb rd imm(rs1) | Load Byte | R[rd] = M[R[rs1] + imm][7:0] (Sign-extend) | I | 000 0011 | 000 |
lbu rd imm(rs1) | Load Byte (Unsigned) | R[rd] = M[R[rs1] + imm][7:0] (Zero-extend) | I | 000 0011 | 100 |
lh rd imm(rs1) | Load Half-word | R[rd] = M[R[rs1] + imm][15:0] (Sign-extend) | I | 000 0011 | 001 |
lhu rd imm(rs1) | Load Half-word (Unsigned) | R[rd] = M[R[rs1] + imm][15:0] (Zero-extend) | I | 000 0011 | 101 |
lw rd imm(rs1) | Load Word | R[rd] = M[R[rs1] + imm][31:0] | I | 000 0011 | 010 |
sb rs2 imm(rs1) | Store Byte | M[R[rs1] + imm][7:0] = R[rs2][7:0] | S | 010 0011 | 000 |
sh rs2 imm(rs1) | Store Half-word | M[R[rs1] + imm][15:0] = R[rs2][15:0] | S | 010 0011 | 001 |
sw rs2 imm(rs1) | Store Word | M[R[rs1] + imm][31:0] = R[rs2][31:0] | S | 010 0011 | 010 |
1.3Control¶
Table 3:RV32I Instructions: Control
| Instruction | Name | Description | Type | Opcode | Funct3 | Funct7 |
|---|---|---|---|---|---|---|
beq rs1 rs2 label | Branch if EQual | if (R[rs1] == R[rs2]) PC = PC + offset | B | 110 0011 | 000 | |
bne rs1 rs2 label | Branch if Not Equal | if (R[rs1] != R[rs2]) PC = PC + offset | B | 110 0011 | 001 | |
blt rs1 rs2 label | Branch if Less Than (signed) | if (R[rs1] < R[rs2]) PC = PC + offset | B | 110 0011 | 100 | |
bltu rs1 rs2 label | Branch if Less Than (Unsigned) | if (R[rs1] < R[rs2]) PC = PC + offset | B | 110 0011 | 110 | |
bge rs1 rs2 label | Branch if Greater or Equal (signed) | if (R[rs1] >= R[rs2]) PC = PC + offset | B | 110 0011 | 101 | |
bgeu rs1 rs2 label | Branch if Greater or Equal (Unsigned) | if (R[rs1] >= R[rs2]) PC = PC + offset | B | 110 0011 | 111 | |
jal rd label | Jump And Link | R[rd] = PC + 4;PC = PC + offset | J | 110 1111 | ||
jalr rd rs1 imm | Jump And Link Register | R[rd] = PC + 4;PC = R[rs1] + imm | I | 110 0111 | 000 |
1.4Other¶
Table 4:RV32I Instructions: Other
| Instruction | Name | Description | Type | Opcode | Funct3 |
|---|---|---|---|---|---|
auipc rd immu | Add Upper Imm to PC | imm = immu << 12R[rd] = PC + imm | U | 001 0111 | |
lui rd immu | Load Upper Immediate | imm = immu << 12R[rd] = imm | U | 011 0111 | |
ebreak | Environment BREAK | Asks the debugger to do something (imm = 0) | I | 111 0011 | 000 |
ecall | Environment CALL | Asks the OS to do something (imm = 1) | I | 111 0011 | 000 |
Table 5:RV32I Extension Instructions
| Instruction | Name | Description |
|---|---|---|
mul rd rs1 rs2 | Multiply (part of mul ISA extension) | R[rd] = (R[rs1]) * (R[rs2]) |
2Pseudoinstructions¶
See the ASM Manual and this 2024 GitHub issue discussion.
Table 6:RV32I Common Pseudoinstructions
| Pseudoinstruction | Name | Description | Translation |
|---|---|---|---|
beqz rs1 label | Branch if EQuals Zero | if (R[rs1] == 0)PC = PC + offset | beq rs1 x0 label |
bnez rs1 label | Branch if Not Equals Zero | if (R[rs1] != 0)PC = PC + offset | bne rs1 x0 label |
j label | Jump | PC = PC + offset | jal x0 label |
jal label | Jump and Link | R[ra] = PC + 4PC = PC + offset | jal ra label |
jr rs1 | Jump Register | PC = R[rs1] | jalr x0 rs1 0 |
la rd label | Load absolute Address | R[rd] = &label | auipc, addi |
li rd imm | Load Immediate | R[rd] = imm | lui (if needed), addi |
mv rd rs1 | MoVe | R[rd] = R[rs1] | addi rd rs1 0 |
neg rd rs1 | NEGate | R[rd] = -(R[rs1]) | sub rd x0 rs1 |
nop | No OPeration | do nothing | addi x0 x0 0 |
not rd rs1 | bitwise NOT | R[rd] = ~(R[rs1]) | xori rd rs1 -1 |
ret | RETurn | PC = R[ra] | jalr x0 ra 0 |
3Register Convention¶
See the table from the ASM Manual, which we find the most useful. Other references include the RISC-V ELF psABI Specification (RISC-V Calling Conventions), which supercedes Volume I, V2.1, 2014: Chapter 18 Calling Convention.
Table 7:RV32I Register Convention
| Register(s) | Name | Description | Saver |
|---|---|---|---|
x0 | zero | Constant 0 | - |
x1 | ra | Return Address | Caller |
x2 | sp | Stack Pointer | |
x3 | gp | Global Pointer | |
x4 | tp | Thread Pointer | |
x5-7 | t0-2 | Temporary Registers | Caller |
x8 | s0 / fp | Saved Register 0 / Frame Pointer | |
x9 | s1 | Saved Register | |
x10-11 | a0-1 | Function Arguments / Return Values | Caller |
x12-17 | a2-7 | Function Arguments | Caller |
x18-x27 | s2-11 | Saved Registers | Callee |
x28-31 | t3-6 | Temporaries | Caller |
4Instruction Types¶
Table 8:RV32I Instruction Types
| Type | 3125 | 2420 | 1915 | 1412 | 117 | 60 |
|---|---|---|---|---|---|---|
| R | funct7 | rs2 | rs1 | funct3 | rd | opcode |
| I | imm[11:0] | rs1 | funct3 | rd | opcode | |
| I* | funct7 | imm[4:0] | rs1 | funct3 | rd | opcode |
| S | imm[11:5] | rs2 | rs1 | funct3 | imm[4:0] | opcode |
| B | imm[12|10:5] | rs2 | rs1 | funct3 | imm[4:1|11] | opcode |
| U | imm[31:12] | rd | opcode | |||
| J | imm[20|10:1|11|19:12] | rd | opcode | |||