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:
| 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 | |
|---|---|---|---|---|---|---|---|---|
| inst[6:5]=00 | LOAD | LOAD-FP | custom-0 | MISC-MEM | OP-IMM | AUIPC | OP-IMM-32 | >32b |
| inst[6:5]=01 | STORE | STORE-FP | custom-1 | AMO | OP | LUI | OP-32 | >32b |
| inst[6:5]=10 | MADD | MSUB | NMSUB | NMADD | OP-FP | OP-V | custom-2 | >32b |
| inst[6:5]=11 | BRANCH | JALR | reserved | JAL | SYSTEM | OP-VE | custom-3 | >32b |
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:
| Mnemonic | Ext | Fmt | Major opcode | Operation |
|---|---|---|---|---|
| LUI | I | U | LUI | rd = imm20 << 12 (sext on RV64) |
| AUIPC | I | U | AUIPC | rd = pc + (imm20 << 12) |
| JAL | I | J | JAL | rd = pc+4; pc += offset (±1 MiB) |
| JALR | I | I | JALR | rd = pc+4; pc = (rs1+imm) & ~1 |
| BEQ | I | B | BRANCH | branch if rs1 == rs2 (±4 KiB) |
| BNE | I | B | BRANCH | branch if rs1 != rs2 |
| BLT | I | B | BRANCH | branch if rs1 < rs2 signed |
| BGE | I | B | BRANCH | branch if rs1 >= rs2 signed |
| BLTU | I | B | BRANCH | branch if rs1 < rs2 unsigned |
| BGEU | I | B | BRANCH | branch if rs1 >= rs2 unsigned |
| LB | I | I | LOAD | load byte, sign-extend |
| LH | I | I | LOAD | load halfword, sign-extend |
| LW | I | I | LOAD | load word (sext on RV64) |
| LBU | I | I | LOAD | load byte, zero-extend |
| LHU | I | I | LOAD | load halfword, zero-extend |
| SB | I | S | STORE | store low byte of rs2 |
| SH | I | S | STORE | store low halfword |
| SW | I | S | STORE | store word |
| ADDI | I | I | OP-IMM | rd = rs1 + sext(imm12) |
| SLTI | I | I | OP-IMM | rd = rs1 < imm signed ? 1 : 0 |
| SLTIU | I | I | OP-IMM | rd = rs1 < imm unsigned ? 1 : 0 |
| XORI | I | I | OP-IMM | rd = rs1 ^ sext(imm) |
| ORI | I | I | OP-IMM | rd = rs1 | sext(imm) |
| ANDI | I | I | OP-IMM | rd = rs1 & sext(imm) |
| SLLI | I | I | OP-IMM | logical left shift by shamt |
| SRLI | I | I | OP-IMM | logical right shift |
| SRAI | I | I | OP-IMM | arithmetic right shift (bit 30 set) |
| ADD | I | R | OP | rd = rs1 + rs2 |
| SUB | I | R | OP | rd = rs1 - rs2 (bit 30) |
| SLL | I | R | OP | shift left by rs2 low bits |
| SLT | I | R | OP | signed compare to 0/1 |
| SLTU | I | R | OP | unsigned compare (SNEZ with rs1=x0) |
| XOR | I | R | OP | bitwise xor |
| SRL | I | R | OP | logical right shift by rs2 |
| SRA | I | R | OP | arithmetic right shift by rs2 |
| OR | I | R | OP | bitwise or |
| AND | I | R | OP | bitwise and |
| FENCE | I | I | MISC-MEM | order pred set before succ set (I/O/R/W) |
| FENCE.TSO | I | I | MISC-MEM | fm=1000: RW,RW minus store-to-load |
| PAUSE | I | I | MISC-MEM | spin-wait hint (pred=W, succ=0) |
| ECALL | I | I | SYSTEM | requested trap: environment call |
| EBREAK | I | I | SYSTEM | requested trap: debugger breakpoint |
| LWU | I64 | I | LOAD | load word, zero-extend |
| LD | I64 | I | LOAD | load doubleword |
| SD | I64 | S | STORE | store doubleword |
| ADDIW | I64 | I | OP-IMM-32 | rd = sext32(rs1[31:0] + imm) |
| SLLIW | I64 | I | OP-IMM-32 | 32-bit left shift, sext32 |
| SRLIW | I64 | I | OP-IMM-32 | 32-bit logical right shift |
| SRAIW | I64 | I | OP-IMM-32 | 32-bit arithmetic right shift |
| ADDW | I64 | R | OP-32 | rd = sext32(rs1+rs2) |
| SUBW | I64 | R | OP-32 | rd = sext32(rs1-rs2) |
| SLLW | I64 | R | OP-32 | 32-bit shift by rs2[4:0] |
| SRLW | I64 | R | OP-32 | 32-bit logical right |
| SRAW | I64 | R | OP-32 | 32-bit arithmetic right |
| FENCE.I | Zifencei | I | MISC-MEM | order prior stores before later instruction fetches (this hart) |
| CSRRW | Zicsr | I | SYSTEM | atomic swap CSR/rs1 |
| CSRRS | Zicsr | I | SYSTEM | read CSR, set rs1 mask bits |
| CSRRC | Zicsr | I | SYSTEM | read CSR, clear mask bits |
| CSRRWI | Zicsr | I | SYSTEM | swap with 5-bit uimm |
| CSRRSI | Zicsr | I | SYSTEM | set bits from uimm |
| CSRRCI | Zicsr | I | SYSTEM | clear bits from uimm |
| MUL | M | R | OP | low XLEN of product |
| MULH | M | R | OP | high half, signed x signed |
| MULHSU | M | R | OP | high half, signed x unsigned |
| MULHU | M | R | OP | high half, unsigned |
| DIV | M | R | OP | signed divide toward zero |
| DIVU | M | R | OP | unsigned divide |
| REM | M | R | OP | signed remainder (dividend sign) |
| REMU | M | R | OP | unsigned remainder |
| MULW | M64 | R | OP-32 | sext32 32-bit product |
| DIVW | M64 | R | OP-32 | 32-bit signed divide |
| DIVUW | M64 | R | OP-32 | 32-bit unsigned divide |
| REMW | M64 | R | OP-32 | 32-bit signed remainder |
| REMUW | M64 | R | OP-32 | 32-bit unsigned remainder |
| LR.W | A | R | AMO | load-reserved, register reservation |
| SC.W | A | R | AMO | store-conditional; rd = 0 on success |
| AMOSWAP.W | A | R | AMO | atomic swap: rd = M[rs1]; M[rs1] = op(rd, rs2) |
| AMOADD.W | A | R | AMO | atomic add: rd = M[rs1]; M[rs1] = op(rd, rs2) |
| AMOXOR.W | A | R | AMO | atomic xor: rd = M[rs1]; M[rs1] = op(rd, rs2) |
| AMOAND.W | A | R | AMO | atomic and: rd = M[rs1]; M[rs1] = op(rd, rs2) |
| AMOOR.W | A | R | AMO | atomic or: rd = M[rs1]; M[rs1] = op(rd, rs2) |
| AMOMIN.W | A | R | AMO | atomic signed min: rd = M[rs1]; M[rs1] = op(rd, rs2) |
| AMOMAX.W | A | R | AMO | atomic signed max: rd = M[rs1]; M[rs1] = op(rd, rs2) |
| AMOMINU.W | A | R | AMO | atomic unsigned min: rd = M[rs1]; M[rs1] = op(rd, rs2) |
| AMOMAXU.W | A | R | AMO | atomic unsigned max: rd = M[rs1]; M[rs1] = op(rd, rs2) |
| LR.D | A64 | R | AMO | load-reserved, register reservation |
| SC.D | A64 | R | AMO | store-conditional; rd = 0 on success |
| AMOSWAP.D | A64 | R | AMO | atomic swap: rd = M[rs1]; M[rs1] = op(rd, rs2) |
| AMOADD.D | A64 | R | AMO | atomic add: rd = M[rs1]; M[rs1] = op(rd, rs2) |
| AMOXOR.D | A64 | R | AMO | atomic xor: rd = M[rs1]; M[rs1] = op(rd, rs2) |
| AMOAND.D | A64 | R | AMO | atomic and: rd = M[rs1]; M[rs1] = op(rd, rs2) |
| AMOOR.D | A64 | R | AMO | atomic or: rd = M[rs1]; M[rs1] = op(rd, rs2) |
| AMOMIN.D | A64 | R | AMO | atomic signed min: rd = M[rs1]; M[rs1] = op(rd, rs2) |
| AMOMAX.D | A64 | R | AMO | atomic signed max: rd = M[rs1]; M[rs1] = op(rd, rs2) |
| AMOMINU.D | A64 | R | AMO | atomic unsigned min: rd = M[rs1]; M[rs1] = op(rd, rs2) |
| AMOMAXU.D | A64 | R | AMO | atomic unsigned max: rd = M[rs1]; M[rs1] = op(rd, rs2) |
| FLW | F | I | LOAD-FP | load single (NaN-boxed on FLEN=64) |
| FSW | F | S | STORE-FP | store single, raw bits |
| FMADD.S | F | R4 | MADD | (rs1 x rs2) + rs3, one rounding |
| FMSUB.S | F | R4 | MSUB | (rs1 x rs2) - rs3 |
| FNMSUB.S | F | R4 | NMSUB | -(rs1 x rs2) + rs3 |
| FNMADD.S | F | R4 | NMADD | -(rs1 x rs2) - rs3 |
| FADD.S | F | R | OP-FP | single add |
| FSUB.S | F | R | OP-FP | single subtract |
| FMUL.S | F | R | OP-FP | single multiply |
| FDIV.S | F | R | OP-FP | single divide |
| FSQRT.S | F | R | OP-FP | single square root |
| FSGNJ.S | F | R | OP-FP | rs1 bits with rs2 sign (FMV.S) |
| FSGNJN.S | F | R | OP-FP | with inverted rs2 sign (FNEG.S) |
| FSGNJX.S | F | R | OP-FP | with xored signs (FABS.S) |
| FMIN.S | F | R | OP-FP | minimumNumber semantics |
| FMAX.S | F | R | OP-FP | maximumNumber semantics |
| FCVT.W.S | F | R | OP-FP | single to int32, Table 27 clipping |
| FCVT.WU.S | F | R | OP-FP | single to uint32 |
| FMV.X.W | F | R | OP-FP | raw bits FP to integer (sext on RV64) |
| FEQ.S | F | R | OP-FP | quiet equality to 0/1 |
| FLT.S | F | R | OP-FP | signaling less-than |
| FLE.S | F | R | OP-FP | signaling less-or-equal |
| FCLASS.S | F | R | OP-FP | 10-bit one-hot class mask |
| FCVT.S.W | F | R | OP-FP | int32 to single |
| FCVT.S.WU | F | R | OP-FP | uint32 to single |
| FMV.W.X | F | R | OP-FP | raw bits integer to FP (boxes) |
| FCVT.L.S | F64 | R | OP-FP | single to int64 |
| FCVT.LU.S | F64 | R | OP-FP | single to uint64 |
| FCVT.S.L | F64 | R | OP-FP | int64 to single |
| FCVT.S.LU | F64 | R | OP-FP | uint64 to single |
| FLD | D | I | LOAD-FP | load double |
| FSD | D | S | STORE-FP | store double |
| FMADD.D | D | R4 | MADD | double fused multiply-add |
| FMSUB.D | D | R4 | MSUB | (rs1 x rs2) - rs3 |
| FNMSUB.D | D | R4 | NMSUB | -(rs1 x rs2) + rs3 |
| FNMADD.D | D | R4 | NMADD | -(rs1 x rs2) - rs3 |
| FADD.D | D | R | OP-FP | double add |
| FSUB.D | D | R | OP-FP | double subtract |
| FMUL.D | D | R | OP-FP | double multiply |
| FDIV.D | D | R | OP-FP | double divide |
| FSQRT.D | D | R | OP-FP | double square root |
| FSGNJ.D | D | R | OP-FP | sign inject |
| FSGNJN.D | D | R | OP-FP | sign inject negate |
| FSGNJX.D | D | R | OP-FP | sign inject xor |
| FMIN.D | D | R | OP-FP | minimumNumber |
| FMAX.D | D | R | OP-FP | maximumNumber |
| FCVT.S.D | D | R | OP-FP | double to single (rounds) |
| FCVT.D.S | D | R | OP-FP | single to double (exact) |
| FEQ.D | D | R | OP-FP | quiet equality |
| FLT.D | D | R | OP-FP | signaling less-than |
| FLE.D | D | R | OP-FP | signaling less-or-equal |
| FCLASS.D | D | R | OP-FP | class mask |
| FCVT.W.D | D | R | OP-FP | double to int32 |
| FCVT.WU.D | D | R | OP-FP | double to uint32 |
| FCVT.D.W | D | R | OP-FP | int32 to double (exact) |
| FCVT.D.WU | D | R | OP-FP | uint32 to double (exact) |
| FCVT.L.D | D64 | R | OP-FP | double to int64 |
| FCVT.LU.D | D64 | R | OP-FP | double to uint64 |
| FMV.X.D | D64 | R | OP-FP | raw bits to integer (RV64) |
| FCVT.D.L | D64 | R | OP-FP | int64 to double |
| FCVT.D.LU | D64 | R | OP-FP | uint64 to double |
| FMV.D.X | D64 | R | OP-FP | raw 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?