Introduction
RISC-V is an open instruction set: a small base integer set plus named extensions. The base comes in a 32-bit form (RV32I, with the reduced RV32E), a 64-bit form (RV64I) and a 128-bit form (RV128I, not decoded here). Instructions are 32 bits long, or 16 bits with the C extension, and the length encoding leaves room for 48, 64 and longer instructions that no standard extension has used. Code runs on the ESP32-C3 and C6, the Raspberry Pi Pico 2, the Linux “riscv64” ports and many microcontrollers.
These pages describe the instruction set as the explorer’s own disassembler reads it. The
decoder is in explorer/cpu/riscv/, is our own code, and is checked against
llvm-mc (see How it is checked). Each instruction has an
anchor, so that a disassembled instruction links to its entry.
What the disassembly asks for
An executable (ELF) with machine number 243 opens with this decoder. The options bar offers:
- Mode: which extensions to decode. The default, “From the file”, reads the
architecture string in the
.riscv.attributessection (for examplerv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0; the word size comes from the ELF class). A file without that section is decoded with every extension on. Presets override it, including the all-extensions superset for RV32 and RV64. - Register names: ABI names (
a0,sp) or numbers (x10,x2), see registers. - Pseudo-instructions: on (
li,mv,ret,beqz) or off (the instruction as encoded), see pseudo-instructions.
Decoding is by encoding, and extensions rarely share one. Where two do, the profile decides: the
compressed c.jal (RV32) and c.addiw (RV64) share an encoding, so the word size
chooses; Zcmp’s cm.push and Zcmt’s cm.jt use encodings that Zcd gives to
c.fsdsp, so they are decoded only when the profile has no Zcd (the superset presets have Zcd, so
they show c.fsdsp; the “Hazard3 / RP2350 class” preset has Zcmp and no Zcd).
The instruction at every 2-byte step is decoded and laid out in columns, so that code reached through a jump into the middle of a longer instruction can be read. Each instruction has a status: documented, HINT, reserved or illegal (see HINT, reserved and illegal).
Extensions the decoder reads
Versions are those of the RISC-V ISA manual of 2026-01-20 (docs.riscv.org).
| Extension | Version | What it adds | Page |
|---|---|---|---|
| I, E | 2.1, 2.0 | Base integer instructions; E has 16 registers | RV32I and RV64I |
| M, Zmmul | 2.0, 1.0 | Multiply and divide; multiply only | M and A |
| A (Zaamo, Zalrsc), Zacas, Zabha | 2.1, 1.0, 1.0 | Atomics, compare-and-swap, byte and halfword atomics | M and A |
| F, D, Q, Zfh, Zfhmin, Zfa, Zfbfmin | 2.2, 2.2, 2.2, 1.0, 1.0, 1.0, 1.0 | Floating point | Floating point |
| C (Zca, Zcf, Zcd), Zcb, Zcmp, Zcmt | 2.0, 1.0 | 16-bit instructions and code-size reduction | Compressed |
| Zba, Zbb, Zbc, Zbs | 1.0 | Bit manipulation | Bit manipulation |
| Zbkb, Zbkc, Zbkx, Zknd, Zkne, Zknh, Zksed, Zksh | 1.0.1 | Scalar cryptography | Cryptography |
| Zicsr, Zifencei | 2.0 | CSR access; instruction-fetch fence | System |
| Zicbom, Zicboz, Zicbop | 1.0.0 | Cache-block management, zeroing, prefetch | System |
| Zimop | 1.0 | May-be-operations | System |
| Zawrs, Zihintpause, Zihintntl, Zicond | 1.01, 2.0, 1.0, 1.0.0 | Wait on reservation set; pause; non-temporal hints; conditional zero | System |
| Machine and supervisor instructions | 1.13 | mret, sret, wfi, sfence.vma, Svinval, Smrnmi, debug dret | System |
| H | 1.0 | Hypervisor: virtual-machine loads and stores, hfence | Hypervisor |
| V, Zvbb, Zvbc, Zvkb, Zvkg, Zvkned, Zvknha, Zvknhb, Zvksed, Zvksh, Zvfbfmin, Zvfbfwma | 1.0 | Vector instructions | Vector |
Not described
Known to exist, not decoded (they show as unknown encodings, with the extension that would define them where this decoder can tell):
- RV128I, and the 48-bit and longer instruction formats (no standard extension defines one);
- Zfinx, Zdinx, Zhinx, Zhinxmin (floating point in the integer registers), Zilsd and Zclsd (register pairs on RV32), Zalasr (load-acquire, store-release), Zcmop (compressed may-be-operations), Zicfiss and Zicfilp (control-flow integrity), Ztso and Zicntr/Zihpm (these have no instructions of their own);
- the vector extensions’ sub-extensions that add nothing new to decode (Zve*, Zvl*, Zvfh and Zvfhmin use the base encodings), and the experimental and vendor extensions (the encodings reserved for custom use are shown as unknown);
- P (packed SIMD), still under development.
Unknown: what a custom or vendor extension’s encoding means; the effect of an instruction beyond the one-line description (these pages describe encodings and operands, the manual describes behaviour).
How it is checked
The decoder is compared with llvm-mc --disassemble (LLVM 22) over every 16-bit encoding and millions
of 32-bit encodings for each profile, with the text of the instruction compared; with llvm-objdump
on ELF files built with clang; and with the small RV32 disassembler in the emulators’ debugger. The CSR names
are compared with llvm’s for all 4096 numbers. The numbers are in the project notes; the decoder says where
llvm and the manual differ (see HINT, reserved and illegal).
Links
- The RISC-V unprivileged ISA manual (docs.riscv.org), the source of the instruction listings;
- The privileged architecture manual (docs.riscv.org), for the CSRs and the machine and supervisor instructions;
- riscv-opcodes, the machine-readable encoding tables;
- The RISC-V ELF psABI, for
.riscv.attributesand e_flags.