RV32/64G Instruction Set Listings

Part I Linux boot: required Vol. I (Unprivileged) pp. 584–596 · ~2 min read

G = IMAFD + Zicsr + Zifencei — the general-purpose bundle the RISC-V project defines as its stable software target (add C for RV64GC, the Linux distribution baseline). This chapter is the reference spine of Volume I: the major-opcode map and the complete instruction listings.

Table 72: the major opcode map

For 32-bit instructions (inst[1:0] = 11), bits [6:5] × [4:2] select the major opcode — your first-level decode ROM:

RISC-V base opcode map (Table 72), inst[1:0]=11
000001010011100101110111
inst[6:5]=00LOADLOAD-FPcustom-0MISC-MEMOP-IMMAUIPCOP-IMM-32>32b
inst[6:5]=01STORESTORE-FPcustom-1AMOOPLUIOP-32>32b
inst[6:5]=10MADDMSUBNMSUBNMADDOP-FPOP-Vcustom-2>32b
inst[6:5]=11BRANCHJALRreservedJALSYSTEMOP-VEcustom-3>32b
Dotted-underlined cells have explanations — click one.

The full G listing, searchable

Every RV64G instruction, with its format, major opcode, and a one-line semantic — each mnemonic links to the chapter page carrying its full encoding diagram and behavior:

158/158
MnemonicExtFmtMajor opcodeOperation
LUIIULUIrd = imm20 << 12 (sext on RV64)
AUIPCIUAUIPCrd = pc + (imm20 << 12)
JALIJJALrd = pc+4; pc += offset (±1 MiB)
JALRIIJALRrd = pc+4; pc = (rs1+imm) & ~1
BEQIBBRANCHbranch if rs1 == rs2 (±4 KiB)
BNEIBBRANCHbranch if rs1 != rs2
BLTIBBRANCHbranch if rs1 < rs2 signed
BGEIBBRANCHbranch if rs1 >= rs2 signed
BLTUIBBRANCHbranch if rs1 < rs2 unsigned
BGEUIBBRANCHbranch if rs1 >= rs2 unsigned
LBIILOADload byte, sign-extend
LHIILOADload halfword, sign-extend
LWIILOADload word (sext on RV64)
LBUIILOADload byte, zero-extend
LHUIILOADload halfword, zero-extend
SBISSTOREstore low byte of rs2
SHISSTOREstore low halfword
SWISSTOREstore word
ADDIIIOP-IMMrd = rs1 + sext(imm12)
SLTIIIOP-IMMrd = rs1 < imm signed ? 1 : 0
SLTIUIIOP-IMMrd = rs1 < imm unsigned ? 1 : 0
XORIIIOP-IMMrd = rs1 ^ sext(imm)
ORIIIOP-IMMrd = rs1 | sext(imm)
ANDIIIOP-IMMrd = rs1 & sext(imm)
SLLIIIOP-IMMlogical left shift by shamt
SRLIIIOP-IMMlogical right shift
SRAIIIOP-IMMarithmetic right shift (bit 30 set)
ADDIROPrd = rs1 + rs2
SUBIROPrd = rs1 - rs2 (bit 30)
SLLIROPshift left by rs2 low bits
SLTIROPsigned compare to 0/1
SLTUIROPunsigned compare (SNEZ with rs1=x0)
XORIROPbitwise xor
SRLIROPlogical right shift by rs2
SRAIROParithmetic right shift by rs2
ORIROPbitwise or
ANDIROPbitwise and
FENCEIIMISC-MEMorder pred set before succ set (I/O/R/W)
FENCE.TSOIIMISC-MEMfm=1000: RW,RW minus store-to-load
PAUSEIIMISC-MEMspin-wait hint (pred=W, succ=0)
ECALLIISYSTEMrequested trap: environment call
EBREAKIISYSTEMrequested trap: debugger breakpoint
LWUI64ILOADload word, zero-extend
LDI64ILOADload doubleword
SDI64SSTOREstore doubleword
ADDIWI64IOP-IMM-32rd = sext32(rs1[31:0] + imm)
SLLIWI64IOP-IMM-3232-bit left shift, sext32
SRLIWI64IOP-IMM-3232-bit logical right shift
SRAIWI64IOP-IMM-3232-bit arithmetic right shift
ADDWI64ROP-32rd = sext32(rs1+rs2)
SUBWI64ROP-32rd = sext32(rs1-rs2)
SLLWI64ROP-3232-bit shift by rs2[4:0]
SRLWI64ROP-3232-bit logical right
SRAWI64ROP-3232-bit arithmetic right
FENCE.IZifenceiIMISC-MEMorder prior stores before later instruction fetches (this hart)
CSRRWZicsrISYSTEMatomic swap CSR/rs1
CSRRSZicsrISYSTEMread CSR, set rs1 mask bits
CSRRCZicsrISYSTEMread CSR, clear mask bits
CSRRWIZicsrISYSTEMswap with 5-bit uimm
CSRRSIZicsrISYSTEMset bits from uimm
CSRRCIZicsrISYSTEMclear bits from uimm
MULMROPlow XLEN of product
MULHMROPhigh half, signed x signed
MULHSUMROPhigh half, signed x unsigned
MULHUMROPhigh half, unsigned
DIVMROPsigned divide toward zero
DIVUMROPunsigned divide
REMMROPsigned remainder (dividend sign)
REMUMROPunsigned remainder
MULWM64ROP-32sext32 32-bit product
DIVWM64ROP-3232-bit signed divide
DIVUWM64ROP-3232-bit unsigned divide
REMWM64ROP-3232-bit signed remainder
REMUWM64ROP-3232-bit unsigned remainder
LR.WARAMOload-reserved, register reservation
SC.WARAMOstore-conditional; rd = 0 on success
AMOSWAP.WARAMOatomic swap: rd = M[rs1]; M[rs1] = op(rd, rs2)
AMOADD.WARAMOatomic add: rd = M[rs1]; M[rs1] = op(rd, rs2)
AMOXOR.WARAMOatomic xor: rd = M[rs1]; M[rs1] = op(rd, rs2)
AMOAND.WARAMOatomic and: rd = M[rs1]; M[rs1] = op(rd, rs2)
AMOOR.WARAMOatomic or: rd = M[rs1]; M[rs1] = op(rd, rs2)
AMOMIN.WARAMOatomic signed min: rd = M[rs1]; M[rs1] = op(rd, rs2)
AMOMAX.WARAMOatomic signed max: rd = M[rs1]; M[rs1] = op(rd, rs2)
AMOMINU.WARAMOatomic unsigned min: rd = M[rs1]; M[rs1] = op(rd, rs2)
AMOMAXU.WARAMOatomic unsigned max: rd = M[rs1]; M[rs1] = op(rd, rs2)
LR.DA64RAMOload-reserved, register reservation
SC.DA64RAMOstore-conditional; rd = 0 on success
AMOSWAP.DA64RAMOatomic swap: rd = M[rs1]; M[rs1] = op(rd, rs2)
AMOADD.DA64RAMOatomic add: rd = M[rs1]; M[rs1] = op(rd, rs2)
AMOXOR.DA64RAMOatomic xor: rd = M[rs1]; M[rs1] = op(rd, rs2)
AMOAND.DA64RAMOatomic and: rd = M[rs1]; M[rs1] = op(rd, rs2)
AMOOR.DA64RAMOatomic or: rd = M[rs1]; M[rs1] = op(rd, rs2)
AMOMIN.DA64RAMOatomic signed min: rd = M[rs1]; M[rs1] = op(rd, rs2)
AMOMAX.DA64RAMOatomic signed max: rd = M[rs1]; M[rs1] = op(rd, rs2)
AMOMINU.DA64RAMOatomic unsigned min: rd = M[rs1]; M[rs1] = op(rd, rs2)
AMOMAXU.DA64RAMOatomic unsigned max: rd = M[rs1]; M[rs1] = op(rd, rs2)
FLWFILOAD-FPload single (NaN-boxed on FLEN=64)
FSWFSSTORE-FPstore single, raw bits
FMADD.SFR4MADD(rs1 x rs2) + rs3, one rounding
FMSUB.SFR4MSUB(rs1 x rs2) - rs3
FNMSUB.SFR4NMSUB-(rs1 x rs2) + rs3
FNMADD.SFR4NMADD-(rs1 x rs2) - rs3
FADD.SFROP-FPsingle add
FSUB.SFROP-FPsingle subtract
FMUL.SFROP-FPsingle multiply
FDIV.SFROP-FPsingle divide
FSQRT.SFROP-FPsingle square root
FSGNJ.SFROP-FPrs1 bits with rs2 sign (FMV.S)
FSGNJN.SFROP-FPwith inverted rs2 sign (FNEG.S)
FSGNJX.SFROP-FPwith xored signs (FABS.S)
FMIN.SFROP-FPminimumNumber semantics
FMAX.SFROP-FPmaximumNumber semantics
FCVT.W.SFROP-FPsingle to int32, Table 27 clipping
FCVT.WU.SFROP-FPsingle to uint32
FMV.X.WFROP-FPraw bits FP to integer (sext on RV64)
FEQ.SFROP-FPquiet equality to 0/1
FLT.SFROP-FPsignaling less-than
FLE.SFROP-FPsignaling less-or-equal
FCLASS.SFROP-FP10-bit one-hot class mask
FCVT.S.WFROP-FPint32 to single
FCVT.S.WUFROP-FPuint32 to single
FMV.W.XFROP-FPraw bits integer to FP (boxes)
FCVT.L.SF64ROP-FPsingle to int64
FCVT.LU.SF64ROP-FPsingle to uint64
FCVT.S.LF64ROP-FPint64 to single
FCVT.S.LUF64ROP-FPuint64 to single
FLDDILOAD-FPload double
FSDDSSTORE-FPstore double
FMADD.DDR4MADDdouble fused multiply-add
FMSUB.DDR4MSUB(rs1 x rs2) - rs3
FNMSUB.DDR4NMSUB-(rs1 x rs2) + rs3
FNMADD.DDR4NMADD-(rs1 x rs2) - rs3
FADD.DDROP-FPdouble add
FSUB.DDROP-FPdouble subtract
FMUL.DDROP-FPdouble multiply
FDIV.DDROP-FPdouble divide
FSQRT.DDROP-FPdouble square root
FSGNJ.DDROP-FPsign inject
FSGNJN.DDROP-FPsign inject negate
FSGNJX.DDROP-FPsign inject xor
FMIN.DDROP-FPminimumNumber
FMAX.DDROP-FPmaximumNumber
FCVT.S.DDROP-FPdouble to single (rounds)
FCVT.D.SDROP-FPsingle to double (exact)
FEQ.DDROP-FPquiet equality
FLT.DDROP-FPsignaling less-than
FLE.DDROP-FPsignaling less-or-equal
FCLASS.DDROP-FPclass mask
FCVT.W.DDROP-FPdouble to int32
FCVT.WU.DDROP-FPdouble to uint32
FCVT.D.WDROP-FPint32 to double (exact)
FCVT.D.WUDROP-FPuint32 to double (exact)
FCVT.L.DD64ROP-FPdouble to int64
FCVT.LU.DD64ROP-FPdouble to uint64
FMV.X.DD64ROP-FPraw bits to integer (RV64)
FCVT.D.LD64ROP-FPint64 to double
FCVT.D.LUD64ROP-FPuint64 to double
FMV.D.XD64ROP-FPraw bits to FP (RV64)

Hardware Designer Notes

This table-page doubles as a verification artifact: 158 rows ≈ your decode coverage matrix. Cross off each mnemonic as directed tests land, and diff the extension chips against your misa bits (Vol II ch. 3) — advertising G means every row above decodes.

Minimal Linux-boot hart MUST

  • Decode majors from {inst[6:5], inst[4:2]} exactly per Table 72
  • Keep custom instructions inside custom-0..3; treat reserved majors as illegal (your documented choice under UNSPECIFIED)

MAY simplify / trap-and-emulate

  • Use this page as the coverage checklist: a Linux-bootable RV64GC core implements every row here plus the C expansions (ch. I·28)

Check yourself — the G target & opcode map

1.What exactly does the G in RV64G stand for?

2.Your decoder reads inst[6:5]=00, inst[4:2]=100, inst[1:0]=11. Which unit gets the instruction?

3.Where should your custom accelerator instructions live in the 32-bit encoding space?

3 questions