Appendix B.
RISC-V Instruction Set Summary
• imm: signed immediate in imm11:0
• uimm: 5-bit unsigned immediate in imm4:0
• upimm: 20 upper bits of a 32-bit immediate, in imm31:12
• Address: memory address: rs1 + SignExt(imm11:0)
• [Address]: data at memory location Address
• BTA: branch target address: PC + SignExt({imm12:1, 1'b0})
• JTA: jump target address: PC + SignExt({imm20:1, 1'b0})
• label: text indicating instruction address
• SignExt: value sign-extended to 32 bits
• ZeroExt: value zero-extended to 32 bits
• csr: control and status register
Figure B.1 RISC-V 32-bit instruction formats
Table B.1 RV32I: RISC-V integer instructions
op funct3 funct7 Type Instruction Description Operation
0000011 (3) 000 – I lb rd, imm(rs1) load byte rd = SignExt([Address]7:0)
0000011 (3) 001 – I lh rd, imm(rs1) load half rd = SignExt([Address]15:0)
0000011 (3) 010 – I lw rd, imm(rs1) load word rd = [Address]31:0
0000011 (3) 100 – I lbu rd, imm(rs1) load byte unsigned rd = ZeroExt([Address]7:0)
0000011 (3) 101 – I lhu rd, imm(rs1) load half unsigned rd = ZeroExt([Address]15:0)
0010011 (19) 000 – I addi rd, rs1, imm add immediate rd = rs1 + SignExt(imm)
*
0010011 (19) 001 0000000 I slli rd, rs1, uimm shift left logical immediate rd = rs1 << uimm
0010011 (19) 010 – I slti rd, rs1, imm set less than immediate rd = (rs1 < SignExt(imm))
0010011 (19) 011 – I sltiu rd, rs1, imm set less than imm. unsigned rd = (rs1 < SignExt(imm))
0010011 (19) 100 – I xori rd, rs1, imm xor immediate rd = rs1 ^ SignExt(imm)
0010011 (19) 101 0000000* I srli rd, rs1, uimm shift right logical immediate rd = rs1 >> uimm
0010011 (19) 101 0100000* I srai rd, rs1, uimm shift right arithmetic imm. rd = rs1 >>> uimm
0010011 (19) 110 – I ori rd, rs1, imm or immediate rd = rs1 | SignExt(imm)
0010011 (19) 111 – I andi rd, rs1, imm and immediate rd = rs1 & SignExt(imm)
0010111 (23) – – U auipc rd, upimm add upper immediate to PC rd = {upimm, 12'b0} + PC
0100011 (35) 000 – S sb rs2, imm(rs1) store byte [Address]7:0 = rs27:0
0100011 (35) 001 – S sh rs2, imm(rs1) store half [Address]15:0 = rs215:0
0100011 (35) 010 – S sw rs2, imm(rs1) store word [Address]31:0 = rs2
0110011 (51) 000 0000000 R add rd, rs1, rs2 add rd = rs1 + rs2
0110011 (51) 000 0100000 R sub rd, rs1, rs2 sub rd = rs1 — rs2
0110011 (51) 001 0000000 R sll rd, rs1, rs2 shift left logical rd = rs1 << rs24:0
0110011 (51) 010 0000000 R slt rd, rs1, rs2 set less than rd = (rs1 < rs2)
0110011 (51) 011 0000000 R sltu rd, rs1, rs2 set less than unsigned rd = (rs1 < rs2)
0110011 (51) 100 0000000 R xor rd, rs1, rs2 xor rd = rs1 ^ rs2
0110011 (51) 101 0000000 R srl rd, rs1, rs2 shift right logical rd = rs1 >> rs24:0
0110011 (51) 101 0100000 R sra rd, rs1, rs2 shift right arithmetic rd = rs1 >>> rs24:0
0110011 (51) 110 0000000 R or rd, rs1, rs2 or rd = rs1 | rs2
0110011 (51) 111 0000000 R and rd, rs1, rs2 and rd = rs1 & rs2
0110111 (55) – – U lui rd, upimm load upper immediate rd = {upimm, 12’b0}
1100011 (99) 000 – B beq rs1, rs2, label branch if = if (rs1 == rs2) PC = BTA
1100011 (99) 001 – B bne rs1, rs2, label branch if ≠ if (rs1 ≠ rs2) PC = BTA
1100011 (99) 100 – B blt rs1, rs2, label branch if < if (rs1 < rs2) PC = BTA
1100011 (99) 101 – B bge rs1, rs2, label branch if ≥ if (rs1 ≥ rs2) PC = BTA
1100011 (99) 110 – B bltu rs1, rs2, label branch if < unsigned if (rs1 < rs2) PC = BTA
1100011 (99) 111 – B bgeu rs1, rs2, label branch if ≥ unsigned if (rs1 ≥ rs2) PC = BTA
1100111 (103) 000 – I jalr rd, rs1, imm jump and link register PC = rs1 + SignExt(imm), rd = PC + 4
1101111 (111) – – J jal rd, label jump and link PC = JTA, rd = PC + 4
*
encoded in instr31:25, the upper seven bits of the immediate field
Table B.7 RISC-V pseudoinstructions
Pseudoinstruction RISC-V Instructions Description Operation
nop addi x0, x0, 0 no operation
li rd, imm11:0 addi rd, x0, imm11:0 load 12-bit immediate rd = SignExtend(imm11:0)
*
li rd, imm31:0 lui rd, imm31:12 load 32-bit immediate rd = imm31:0
addi rd, rd, imm11:0
mv rd, rs1 addi rd, rs1, 0 move (also called “register copy”) rd = rs1
not rd, rs1 xori rd, rs1, —1 one’s complement rd = ~rs1
neg rd, rs1 sub rd, x0, rs1 two’s complement rd = —rs1
seqz rd, rs1 sltiu rd, rs1, 1 set if = 0 rd = (rs1 == 0)
snez rd, rs1 sltu rd, x0, rs1 set if ≠ 0 rd = (rs1 ≠ 0)
sltz rd, rs1 slt rd, rs1, x0 set if < 0 rd = (rs1 < 0)
sgtz rd, rs1 slt rd, x0, rs1 set if > 0 rd = (rs1 > 0)
beqz rs1, label beq rs1, x0, label branch if = 0 if (rs1 == 0) PC = label
bnez rs1, label bne rs1, x0, label branch if ≠ 0 if (rs1 ≠ 0) PC = label
blez rs1, label bge x0, rs1, label branch if ≤ 0 if (rs1 ≤ 0) PC = label
bgez rs1, label bge rs1, x0, label branch if ≥ 0 if (rs1 ≥ 0) PC = label
bltz rs1, label blt rs1, x0, label branch if < 0 if (rs1 < 0) PC = label
bgtz rs1, label blt x0, rs1, label branch if > 0 if (rs1 > 0) PC = label
ble rs1, rs2, label bge rs2, rs1, label branch if ≤ if (rs1 ≤ rs2) PC = label
bgt rs1, rs2, label blt rs2, rs1, label branch if > if (rs1 > rs2) PC = label
bleu rs1, rs2, label bgeu rs2, rs1, label branch if ≤ (unsigned) if (rs1 ≤ rs2) PC = label
bgtu rs1, rs2, label bltu rs2, rs1, offset branch if > (unsigned) if (rs1 > rs2) PC = label
j label jal x0, label jump PC = label
jal label jal ra, label jump and link PC = label, ra = PC + 4
jr rs1 jalr x0, rs1, 0 jump register PC = rs1
jalr rs1 jalr ra, rs1, 0 jump and link register PC = rs1, ra = PC + 4
ret jalr x0, ra, 0 return from function PC = ra
call label jal ra, label call nearby function PC = label, ra = PC + 4
*
call label auipc ra, offset31:12 call far away function PC = PC + offset, ra = PC + 4
jalr ra, ra, offset11:0
*
la rd, symbol auipc rd, symbol31:12 load address of global variable rd = PC + symbol
addi rd, rd, symbol11:0
*
l{b|h|w} rd, symbol auipc rd, symbol31:12 load global variable rd = [PC + symbol]
l{b|h|w} rd, symbol11:0(rd)
*
s{b|h|w} rs2, symbol, rs1 auipc rs1, symbol31:12 store global variable [PC + symbol] = rs2
s{b|h|w} rs2, symbol11:0(rs1)
csrr rd, csr csrrs rd, csr, x0 read CSR rd = csr
csrw csr, rs1 csrrw x0, csr, rs1 write CSR csr = rs1
*
If bit 11 of the immediate / offset / symbol is 1, the upper immediate is incremented by 1. symbol and offset are the 32-bit PC-relative addresses of a label
and a global variable, respectively.
Table B.8 Privileged / CSR instructions
op funct3 Type Instruction Description Operation
1110011 (115) 000 I ecall transfer control to OS (imm=0)
1110011 (115) 000 I ebreak transfer control to debugger (imm=1)
1110011 (115) 000 I uret return from user exception (rs1=0,rd=0,imm=2) PC = uepc
1110011 (115) 000 I sret return from supervisor exception (rs1=0,rd=0,imm=258) PC = sepc
1110011 (115) 000 I mret return from machine exception (rs1=0,rd=0,imm=770) PC = mepc
1110011 (115) 001 I csrrw rd,csr,rs1 CSR read/write (imm=CSR number) rd = csr,csr = rs1
1110011 (115) 010 I csrrs rd,csr,rs1 CSR read/set (imm=CSR number) rd = csr,csr = csr | rs1
1110011 (115) 011 I csrrc rd,csr,rs1 CSR read/clear (imm=CSR number) rd = csr,csr = csr & ~rs1
1110011 (115) 101 I csrrwi rd,csr,uimm CSR read/write immediate (imm=CSR number) rd = csr,csr = ZeroExt(uimm)
1110011 (115) 110 I csrrsi rd,csr,uimm CSR read/set immediate (imm=CSR number) rd = csr,
csr = csr | ZeroExt(uimm)
1110011 (115) 111 I csrrci rd,csr,uimm CSR read/clear immediate (imm=CSR number) rd = csr,
csr = csr & ~ZeroExt(uimm)
For privileged / CSR instructions, the 5-bit unsigned immediate, uimm, is encoded in the rs1 field.