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 |
001 0011 |
000 |
n/a |
andi rd, rs1, imm |
bitwise AND immediate | R[rd] = R[rs1] & imm |
001 0011 |
111 |
n/a | |
ori rd, rs1, imm |
bitwise OR immediate | R[rd] = R[rs1] | imm |
001 0011 |
110 |
n/a | |
xori rd, rs1, imm |
bitwise XOR immediate | R[rd] = R[rs1] ^ 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;
}
|
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 |
000 |
|
blt rs1, rs2, label |
branch if less than (signed) |
if (R[rs1] < R[rs2]) {
PC = PC + offset
}
|
110 0011 |
000 |
|
bltu rs1, rs2, label |
branch if less than (unsigned) | 110 0011 |
000 |
||
bge rs1, rs2, label |
branch if greater or equal (signed) |
if (R[rs1] >= R[rs2]) {
PC = PC + offset
}
|
110 0011 |
000 |
|
bgeu rs1, rs2, label |
branch if greater or equal (unsigned) | 110 0011 |
000 |
||
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 |
imm = immu << 12
R[rd] = PC + imm
|
011 0111 |
n/a |
lui rd, immu |
load upper immediate |
imm = immu << 12
R[rd] = imm
|
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 | 010 1111 |
010 |
00010 | aq | rl |
lr.d rd, rs1, rs2 |
load reserved (RV64 only) | 010 1111 |
011 |
00010 | aq | rl |
|
sc.w rd, rs1, rs2 |
store conditional | 010 1111 |
010 |
00011 | aq | rl |
|
sc.d rd, rs1, rs2 |
store conditional (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 | R[rd] = (R[rs1][31:0] + R[rs2][31:0])[31:0] (sign-extend) |
011 1011 |
000 |
000 0000 |
subw rd, rs1, rs2 |
SUBTRACT | 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 | R[rd] = (R[rs1][31:0] << R[rs2])[31:0] (sign-extend) |
011 1011 |
001 |
000 0000 |
|
srlw rd, rs1, rs2 |
shift right logical | R[rd] = (R[rs1][31:0] >> R[rs2])[31:0] (zero-extend) |
011 1011 |
101 |
000 0000 |
|
sraw rd, rs1, rs2 |
shift right arithmetic | 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 | R[rd] = (R[rs1] + imm)[31:0] (sign-extend) |
001 1011 |
000 |
n/a | |
slliw rd, rs1, imm |
shift left logical immediate | R[rd] = (R[rs1][31:0] << imm)[31:0] (sign-extend) |
001 1011 |
001 |
000 0000 |
|
srliw rd, rs1, imm |
shift right logical immediate | R[rd] = (R[rs1][31:0] >> imm)[31:0] (zero-extend) |
001 1011 |
101 |
000 0000 |
|
sraiw rd, rs1, imm |
shift right arithmetic immediate | 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)
Instruction | Name | Description | Opcode | Funct3 | Funct7 | |
---|---|---|---|---|---|---|
RV32M (R-type) |
mul rd, rs1, rs2 |
MUL | R[rd][(XLEN-1):0] = R[rs1] * R[rs2] |
011 0011 |
000 |
000 0001 |
mulh rd, rs1, rs2 |
MULH | R[rd][(2×XLEN-1):XLEN] = R[rs1] * R[rs2] (rs1 and rs2 signed) |
011 0011 |
001 |
000 0001 |
|
mulhu rd, rs1, rs2 |
MULHU | R[rd][(2×XLEN-1):XLEN] = R[rs1] * R[rs2] (rs1 and rs2 unsigned) |
011 0011 |
011 |
000 0001 |
|
mulhsu rd, rs1, rs2 |
MULHSU | R[rd][(2×XLEN-1):XLEN] = R[rs1] * R[rs2] (signed rs1 and unsigned rs2) |
011 0011 |
010 |
000 0001 |
|
div rd, rs1, rs2 |
quotient (signed) | R[rd] = R[rs1] / R[rs2] (signed integer division) |
011 0011 |
100 |
000 0001 |
|
divu rd, rs1, rs2 |
quotient (unsigned) | R[rd] = R[rs1] / R[rs2] (unsigned integer division) |
011 0011 |
101 |
000 0001 |
|
rem rd, rs1, rs2 |
remainder (signed) | R[rd] = R[rs1] % R[rs2] (signed remainder) |
011 0011 |
110 |
000 0001 |
|
remu rd, rs1, rs2 |
remainder (unsigned) | R[rd] = R[rs1] % R[rs2] (unsigned remainder) |
011 0011 |
111 |
000 0001 |
|
RV64M (R-type) |
mulw rd, rs1, rs2 |
MULW | R[rd][31:0] = R[rs1][31:0] * R[rs2][31:0] (sign-extend) |
011 1011 |
000 |
000 0001 |
divw rd, rs1, rs2 |
quotient (signed) | R[rd][31:0] = R[rs1][31:0] / R[rs2][31:0] (R[rs1][31:0] and R[rs2][31:0] signed) |
011 1011 |
100 |
000 0001 |
|
divuw rd, rs1, rs2 |
quotient (unsigned) | R[rd][31:0] = R[rs1][31:0] / R[rs2][31:0] (rs1 and rs2 unsigned) |
011 1011 |
101 |
000 0001 |
|
remw rd, rs1, rs2 |
remainder (signed) | R[rd] = R[rs1] % R[rs2] (signed remainder) |
011 1011 |
110 |
000 0001 |
|
remuw rd, rs1, rs2 |
remainder (unsigned) | R[rd] = R[rs1] % R[rs2] (unsigned remainder) |
011 1011 |
111 |
000 0001 |