Introduction
Each row gives the opcode (bits 6:0 in binary), funct3 and funct7 (or the top bits of the immediate) that identify an
instruction; “rv64” marks the instructions that exist only on RV64 (and RV128). On RV64 the 32-bit forms (addw,
lw ...) work on the low 32 bits and sign-extend the result. A write to x0 is discarded; when
the whole encoding is otherwise a defined instruction with no side effect it is a
HINT. Operands are written as the explorer writes them, destination first.
RV32E is the same instruction set with 16 registers.
Upper immediates, jumps and branches
| Instruction | Operands | Opcode | funct3 | What it does |
|---|---|---|---|---|
lui | rd, imm20 | 0110111 | rd = imm20 << 12 (sign-extended on RV64). | |
auipc | rd, imm20 | 0010111 | rd = pc + (imm20 << 12). | |
jal | rd, offset | 1101111 | rd = pc + 4; pc += offset (±1 MiB, even). | |
jalr | rd, imm(rs1) | 1100111 | 000 | rd = pc + 4; pc = (rs1 + imm) with bit 0 cleared. |
beq | rs1, rs2, offset | 1100011 | 000 | Branch (±4 KiB) if rs1 = rs2. |
bne | rs1, rs2, offset | 1100011 | 001 | Branch if rs1 ≠ rs2. |
blt | rs1, rs2, offset | 1100011 | 100 | Branch if rs1 < rs2, signed. |
bge | rs1, rs2, offset | 1100011 | 101 | Branch if rs1 ≥ rs2, signed. |
bltu | rs1, rs2, offset | 1100011 | 110 | Branch if rs1 < rs2, unsigned. |
bgeu | rs1, rs2, offset | 1100011 | 111 | Branch if rs1 ≥ rs2, unsigned. |
The decoder shows the target of a branch or jal as an address (or a symbol name when the ELF file has
one); jalr targets are known only at run time. A jal or jalr that writes
ra (or t0) is shown as a call, one that writes x0 through ra or
t0 as a return.
Loads and stores
| Instruction | Operands | Opcode | funct3 | What it does |
|---|---|---|---|---|
lb | rd, imm(rs1) | 0000011 | 000 | Load a byte, sign-extended. |
lh | rd, imm(rs1) | 0000011 | 001 | Load a halfword, sign-extended. |
lw | rd, imm(rs1) | 0000011 | 010 | Load a word, sign-extended on RV64. |
ld (rv64) | rd, imm(rs1) | 0000011 | 011 | Load a doubleword. |
lbu | rd, imm(rs1) | 0000011 | 100 | Load a byte, zero-extended. |
lhu | rd, imm(rs1) | 0000011 | 101 | Load a halfword, zero-extended. |
lwu (rv64) | rd, imm(rs1) | 0000011 | 110 | Load a word, zero-extended. |
sb | rs2, imm(rs1) | 0100011 | 000 | Store the low byte. |
sh | rs2, imm(rs1) | 0100011 | 001 | Store the low halfword. |
sw | rs2, imm(rs1) | 0100011 | 010 | Store the low word. |
sd (rv64) | rs2, imm(rs1) | 0100011 | 011 | Store the doubleword. |
The offset is a 12-bit signed number. The base instruction set allows misaligned accesses to trap or to be emulated; the decoder does not say which.
Arithmetic, logic and shifts
| Instruction | Operands | Opcode | funct3 | funct7 / top bits | What it does |
|---|---|---|---|---|---|
addi | rd, rs1, imm | 0010011 | 000 | rd = rs1 + imm. addi x0, x0, 0 is the nop. | |
slti | rd, rs1, imm | 0010011 | 010 | rd = 1 if rs1 < imm (signed). | |
sltiu | rd, rs1, imm | 0010011 | 011 | rd = 1 if rs1 < imm (unsigned; imm is sign-extended first). | |
xori | rd, rs1, imm | 0010011 | 100 | rd = rs1 xor imm. | |
ori | rd, rs1, imm | 0010011 | 110 | rd = rs1 or imm. | |
andi | rd, rs1, imm | 0010011 | 111 | rd = rs1 and imm. | |
slli | rd, rs1, shamt | 0010011 | 001 | 000000 (rv64: 6-bit shamt) / 0000000 (rv32) | Shift left. On RV32 shamt bit 5 set is reserved. |
srli | rd, rs1, shamt | 0010011 | 101 | 000000 / 0000000 | Shift right, logical. |
srai | rd, rs1, shamt | 0010011 | 101 | 010000 / 0100000 | Shift right, arithmetic. |
add | rd, rs1, rs2 | 0110011 | 000 | 0000000 | rd = rs1 + rs2. |
sub | rd, rs1, rs2 | 0110011 | 000 | 0100000 | rd = rs1 − rs2. |
sll | rd, rs1, rs2 | 0110011 | 001 | 0000000 | Shift left by the low 5 (RV32) or 6 (RV64) bits of rs2. |
slt | rd, rs1, rs2 | 0110011 | 010 | 0000000 | Set if less than, signed. |
sltu | rd, rs1, rs2 | 0110011 | 011 | 0000000 | Set if less than, unsigned. |
xor | rd, rs1, rs2 | 0110011 | 100 | 0000000 | Bitwise xor. |
srl | rd, rs1, rs2 | 0110011 | 101 | 0000000 | Shift right, logical. |
sra | rd, rs1, rs2 | 0110011 | 101 | 0100000 | Shift right, arithmetic. |
or | rd, rs1, rs2 | 0110011 | 110 | 0000000 | Bitwise or. |
and | rd, rs1, rs2 | 0110011 | 111 | 0000000 | Bitwise and. |
RV64I word instructions
These work on the low 32 bits of the operands and sign-extend the 32-bit result. They are reserved on RV32.
| Instruction | Operands | Opcode | funct3 | funct7 |
|---|---|---|---|---|
addiw | rd, rs1, imm | 0011011 | 000 | |
slliw | rd, rs1, shamt | 0011011 | 001 | 0000000 |
srliw | rd, rs1, shamt | 0011011 | 101 | 0000000 |
sraiw | rd, rs1, shamt | 0011011 | 101 | 0100000 |
addw | rd, rs1, rs2 | 0111011 | 000 | 0000000 |
subw | rd, rs1, rs2 | 0111011 | 000 | 0100000 |
sllw | rd, rs1, rs2 | 0111011 | 001 | 0000000 |
srlw | rd, rs1, rs2 | 0111011 | 101 | 0000000 |
sraw | rd, rs1, rs2 | 0111011 | 101 | 0100000 |
Fences and environment calls
| Instruction | Operands | Encoding | What it does |
|---|---|---|---|
fence | pred, succ | opcode 0001111, funct3 000; fm = bits 31:28, pred = 27:24, succ = 23:20 (each: i, o, r, w) | Orders memory and I/O accesses of the predecessor set before those of the successor set. With rd, rs1 or fm set it is reserved; with an empty set it is a HINT. |
fence.tso | 1000 0011 0011 in 31:20, rest as fence | Orders loads before loads and stores, and stores before stores. | |
pause | 0x0100000f (fence with pred = w, succ = none) | Zihintpause hint for spin-wait loops. | |
ecall | 0x00000073 | Environment call: a system call or a request to the next privilege level. | |
ebreak | 0x00100073 | Breakpoint. |
fence.i (Zifencei), the CSR instructions (Zicsr) and the privileged instructions are on the
system page.