RISC-V ISA Reference
Instruction Encoding Templates
| 31 | 25 | 24 20 | 1915 | 14 12 | 11 7 | 6 0 | |
|---|---|---|---|---|---|---|---|
| R-type | funct7 | rs2 | rs1 | funct3 | rd | opcode | |
| I-type | imm[11:0] | ||||||
| S-Type | imm[11:5] | rs2 | imm[4:0] | ||||
| B-type | imm[12|10:5] | imm [4:1|11] | |||||
| J-type | imm[20|10:1|11|19:12] | rd | |||||
| U-type | imm[31:12] | ||||||
RV32I Base Integer Instruction Set
Arithmetic Instructions
| Instruction | Name | Description | Opcode | Funct3 | Funct7 | |
|---|---|---|---|---|---|---|
| R-type | add rd, rs1, rs2 |
add | R[rd] = R[rs1] + R[rs2] |
011 0011 |
000 |
000 0000 |
sub rd, rs1, rs2 |
subtract | R[rd] = R[rs1] - R[rs2] |
011 0011 |
000 |
010 0000 |
|
and rd, rs1, rs2 |
bitwise and | R[rd] = R[rs1] & R[rs2] |
011 0011 |
111 |
000 0000 |
|
or rd, rs1, rs2 |
bitwise or | R[rd] = R[rs1] | R[rs2] |
011 0011 |
110 |
000 0000 |
|
xor rd, rs1, rs2 |
bitwise xor | R[rd] = R[rs1] ^ R[rs2] |
011 0011 |
100 |
000 0000 |
|
sll rd, rs1, rs2 |
shift left logical | R[rd] = R[rs1] << R[rs2] |
011 0011 |
001 |
000 0000 |
|
srl rd, rs1, rs2 |
shift right logical | R[rd] = R[rs1] >> R[rs2](zero-extend) |
011 0011 |
101 |
000 0000 |
|
sra rd, rs1, rs2 |
shift right arithmetic | R[rd] = R[rs1] >> R[rs2](sign-extend) |
011 0011 |
101 |
010 0000 |
|
slt rd, rs1, rs2 |
set less than (signed) |
if (R[rs1] < R[rs2]) {
R[rd] = 1;
} else {
R[rd] = 0;
}
|
011 0011 |
010 |
000 0000 |
|
sltu rd, rs1, rs2 |
set less than (unsigned) | 011 0011 |
011 |
000 0000 |
I-type | addi rd, rs1, imm |
add immediate | R[rd] = R[rs1] + imm(sign-extend imm) |
001 0011 |
000 |
n/a |
andi rd, rs1, imm |
bitwise and immediate | R[rd] = R[rs1] & imm(sign-extend imm) |
001 0011 |
111 |
n/a | |
ori rd, rs1, imm |
bitwise or immediate | R[rd] = R[rs1] | imm(sign-extend imm) |
001 0011 |
110 |
n/a | |
xori rd, rs1, imm |
bitwise xor immediate | R[rd] = R[rs1] ^ imm(sign-extend imm) |
001 0011 |
100 |
n/a | |
slti rd, rs1, imm |
set less than immediate (signed) |
if (R[rs1] < imm) {
R[rd] = 1;
} else {
R[rd] = 0;
}(sign-extend imm)
|
001 0011 |
010 |
n/a | |
sltiu rd, rs1, imm |
set less than immediate (unsigned) | 001 0011 |
011 |
n/a | ||
slli rd, rs1, imm |
shift left logical immediate | R[rd] = R[rs1] << imm[4:0] |
001 0011 |
001 |
000 0000 |
|
srli rd, rs1, imm |
shift right logical immediate | R[rd] = R[rs1] >> imm[4:0](zero-extend) |
001 0011 |
101 |
000 0000 |
|
srai rd, rs1, imm |
shift right arithmetic immediate | R[rd] = R[rs1] >> imm[4:0](sign-extend) |
001 0011 |
101 |
010 0000 |
Memory Instructions
| Instruction | Name | Description | Opcode | Funct3 | |
|---|---|---|---|---|---|
| I-type | lb rd, imm(rs1) |
load byte | R[rd] = M[R[rs1] + imm][7:0](sign-extend) |
000 0011 |
000 |
lbu rd, imm(rs1) |
load byte (unsigned) | R[rd] = M[R[rs1] + imm][7:0](zero-extend) |
000 0011 |
100 |
|
lh rd, imm(rs1) |
load half-word | R[rd] = M[R[rs1] + imm][15:0](sign-extend) |
000 0011 |
001 |
|
lhu rd, imm(rs1) |
load half-word (unsigned) | R[rd] = M[R[rs1] + imm][15:0](zero-extend) |
000 0011 |
101 |
|
lw rd, imm(rs1) |
load word | R[rd] = M[R[rs1] + imm][31:0](sign-extend in RV64I) |
000 0011 |
010 |
|
| S-Type | sb rs2, imm(rs1) |
store byte | M[R[rs1] + imm][7:0] = R[rs2][7:0] |
010 0011 |
000 |
sh rs2, imm(rs1) |
store half-word | M[R[rs1] + imm][15:0] = R[rs2][15:0] |
010 0011 |
001 |
|
sw rs2, imm(rs1) |
store word | M[R[rs1] + imm][31:0] = R[rs2][31:0] |
010 0011 |
010 |
Control Instructions
| Instruction | Name | Description | Opcode | Funct3 | |
|---|---|---|---|---|---|
| B-type | beq rs1, rs2, label |
branch if equal |
if (R[rs1] == R[rs2]) {
PC = PC + offset
}
|
110 0011 |
000 |
bne rs1, rs2, label |
branch if not equal |
if (R[rs1] != R[rs2]) {
PC = PC + offset
}
|
110 0011 |
001 |
|
blt rs1, rs2, label |
branch if less than (signed) |
if (R[rs1] < R[rs2]) {
PC = PC + offset
}
|
110 0011 |
100 |
|
bltu rs1, rs2, label |
branch if less than (unsigned) | 110 0011 |
110 |
||
bge rs1, rs2, label |
branch if greater or equal (signed) |
if (R[rs1] >= R[rs2]) {
PC = PC + offset
}
|
110 0011 |
101 |
|
bgeu rs1, rs2, label |
branch if greater or equal (unsigned) | 110 0011 |
111 |
||
| J-type | jal rd, label |
jump and link |
R[rd] = PC + 4
PC = PC + offset
|
110 1111 |
n/a |
| I-type | jalr rd, rs1, label |
jump and link register |
R[rd] = PC + 4
PC = R[rs1] + imm
|
110 0111 |
000 |
Other Instructions
| Instruction | Name | Description | Opcode | Funct3 | |
|---|---|---|---|---|---|
| U-type | auipc rd, immu |
add upper immediate to PC |
R[rd] = PC + imm << 12(sign-extend shifted immediate)
|
011 0111 |
n/a |
lui rd, immu |
load upper immediate |
R[rd] = imm << 12(sign-extend shifted immediate)
|
011 0111 |
n/a | |
| I-type | ebreak |
environment BREAK | asks the debugger to do something (imm=0) | 111 0011 |
000 |
ecall |
environment ECALL | asks the OS to do something (imm=1) | 111 0011 |
000 |
RV32A/RV64A Standard Extension for Atomic Instructions (partial list)
The following table lists the load-reserved and store-conditional instructions that are available for RV32 and RV64. For documentation of the atomic memory operations (amo) see the RISC-V Instruction Set Manual, Vol. 1, Chapter 9.4
| Instruction | Name | Opcode | Funct3 | Funct7 | |
|---|---|---|---|---|---|
| R-type | lr.w rd, rs1, rs2 |
load reserved word | 010 1111 |
010 |
00010 | aq | rl |
lr.d rd, rs1, rs2 |
load reserved double-word (RV64 only) | 010 1111 |
011 |
00010 | aq | rl |
|
sc.w rd, rs1, rs2 |
store conditional word | 010 1111 |
010 |
00011 | aq | rl |
|
sc.d rd, rs1, rs2 |
store conditional double-word (RV64 only) | 010 1111 |
011 |
00011 | aq | rl |
RV64I Base Integer Instruction Set (in addition to RV32I)
The 15 instructions in the RV64I set build on the RV32I variants by providing support for 64-bit load/store operations and extensions of operations on 32-bit values and results. There is a more detailed discussion of the problems that arise in extension in the class notes.
| Instruction | Name | Description | Opcode | Funct3 | Funct7 | |
|---|---|---|---|---|---|---|
| R-type | addw rd, rs1, rs2 |
add word | R[rd] = (R[rs1][31:0] + R[rs2][31:0])[31:0](sign-extend) |
011 1011 |
000 |
000 0000 |
subw rd, rs1, rs2 |
subtract word | R[rd] = (R[rs1][31:0] - R[rs2][31:0])[31:0](sign-extend) |
011 1011 |
000 |
010 0000 |
|
sllw rd, rs1, rs2 |
shift left logical word | R[rd] = (R[rs1][31:0] << R[rs2])[31:0](sign-extend) |
011 1011 |
001 |
000 0000 |
|
srlw rd, rs1, rs2 |
shift right logical word | R[rd] = (R[rs1][31:0] >> R[rs2])[31:0](zero-extend) |
011 1011 |
101 |
000 0000 |
|
sraw rd, rs1, rs2 |
shift right arithmetic word | R[rd] = (R[rs1][31:0] >> R[rs2])[31:0](sign-extend) |
011 1011 |
101 |
010 0000 |
|
| I-type | slli rd, rs1, imm |
shift left logical immediate | R[rd] = R[rs1] << imm[5:0] |
001 0011 |
001 |
n/a |
srli rd, rs1, imm |
shift right logical immediate | R[rd] = R[rs1] >> imm[5:0](zero-extend) |
001 0011 |
101 |
n/a | |
srai rd, rs1, imm |
shift right arithmetic immediate | R[rd] = R[rs1] >> imm[5:0](sign-extend) |
001 0011 |
101 |
n/a | |
addiw rd, rs1, imm |
add immediate word | R[rd] = (R[rs1] + imm)[31:0](sign-extend imm and result) |
001 1011 |
000 |
n/a | |
slliw rd, rs1, imm |
shift left logical immediate word | R[rd] = (R[rs1][31:0] << imm)[31:0](sign-extend) |
001 1011 |
001 |
000 0000 |
|
srliw rd, rs1, imm |
shift right logical immediate word | R[rd] = (R[rs1][31:0] >> imm)[31:0](zero-extend) |
001 1011 |
101 |
000 0000 |
|
sraiw rd, rs1, imm |
shift right arithmetic immediate word | R[rd] = (R[rs1][31:0] >> imm)[31:0](sign-extend) |
001 1011 |
101 |
010 0000 |
|
| Load/Store (I-type/S-type) |
lwu rd, imm(rs1) |
load word (unsigned) | R[rd] = M[R[rs1] + imm][31:0](zero-extend) |
000 0011 |
110 |
n/a |
ld rd, imm(rs1) |
load double word | R[rd] = M[R[rs1] + imm] |
000 0011 |
011 |
n/a | |
sd rs2, imm(rs1) |
store double word | M[R[rs1] + imm] = R[rs2] |
010 0011 |
011 |
n/a |
Standard Extension for Integer Multiplication and Division (RV32M and RV64M)
Let XLEN = the width of an integer register in bits.
| Instruction | Name | Description | Opcode | Funct3 | Funct7 | |
|---|---|---|---|---|---|---|
| RV32M (R-type) |
mul rd, rs1, rs2 |
multiply | R[rd] = R[rs1] * R[rs2] |
011 0011 |
000 |
000 0001 |
mulh rd, rs1, rs2 |
multiply upper half | R[rd] = (R[rs1] * R[rs2])[(2×XLEN-1):XLEN](R[rs1] and R[rs2] signed) |
011 0011 |
001 |
000 0001 |
|
mulhu rd, rs1, rs2 |
multiply upper half unsigned | R[rd] = (R[rs1] * R[rs2])[(2×XLEN-1):XLEN](R[rs1] and R[rs2] unsigned) |
011 0011 |
011 |
000 0001 |
|
mulhsu rd, rs1, rs2 |
multiply upper half signed × unsigned | R[rd] = (R[rs1] * R[rs2])[(2×XLEN-1):XLEN](signed R[rs1] and unsigned R[rs2]) |
011 0011 |
010 |
000 0001 |
|
div rd, rs1, rs2 |
quotient (signed) | R[rd] = R[rs2] == 0 ? -1 : R[rs1] / R[rs2](R[rs1] and R[rs2] signed, the quotient of a signed division with overflow is equal to the dividend) |
011 0011 |
100 |
000 0001 |
|
divu rd, rs1, rs2 |
quotient (unsigned) | R[rd] = R[rs2] == 0 ? -1 : R[rs1] / R[rs2](R[rs1] and R[rs2] unsigned) |
011 0011 |
101 |
000 0001 |
|
rem rd, rs1, rs2 |
remainder (signed) | R[rd] = R[rs2] == 0 ? R[rs1] : R[rs1] % R[rs2](R[rs1] and R[rs2] signed) |
011 0011 |
110 |
000 0001 |
|
remu rd, rs1, rs2 |
remainder (unsigned) | R[rd] = R[rs2] == 0 ? R[rs1] : R[rs1] % R[rs2](R[rs1] and R[rs2] unsigned) |
011 0011 |
111 |
000 0001 |
|
| RV64M (R-type) |
mulw rd, rs1, rs2 |
multiply word | R[rd] = R[rs1][31:0] * R[rs2][31:0](sign-extend) |
011 1011 |
000 |
000 0001 |
divw rd, rs1, rs2 |
quotient (signed) word | R[rd] = R[rs2][31:0] == 0 ? -1 : R[rs1][31:0] / R[rs2][31:0](R[rs1][31:0] and R[rs2][31:0] signed, result is sign-extended, the quotient of a signed division with overflow is equal to the dividend) |
011 1011 |
100 |
000 0001 |
|
divuw rd, rs1, rs2 |
quotient (unsigned) word | R[rd] = R[rs2][31:0] == 0 ? -1 : R[rs1][31:0] / R[rs2][31:0](R[rs1][31:0] and R[rs2][31:0] unsigned, result is sign-extended) |
011 1011 |
101 |
000 0001 |
|
remw rd, rs1, rs2 |
remainder (signed) word | R[rd] = R[rs2][31:0] == 0 ? R[rs1][31:0] : R[rs1][31:0] % R[rs2][31:0](R[rs1][31:0] and R[rs2][31:0] signed, result is sign-extended) |
011 1011 |
110 |
000 0001 |
|
remuw rd, rs1, rs2 |
remainder (unsigned) word | R[rd] = R[rs2][31:0] == 0 ? R[rs1][31:0] : R[rs1][31:0] % R[rs2][31:0](R[rs1][31:0] and R[rs2][31:0] unsigned, result is sign-extended) |
011 1011 |
111 |
000 0001 |