Supported Extensions
Jolt currently supports the RV64IMAC instruction set:- RV64I: Base 64-bit integer instruction set
- M: Integer multiplication and division extension
- A: Atomic memory operations extension
- C: Compressed instruction extension
RV64I (Base Integer ISA)
RV64I is the base 64-bit integer instruction set, providing:- 32 registers:
x0throughx31, each 64 bits widex0is hardwired to zero (always reads as 0, writes are ignored)
- Fixed-width instructions: All instructions are 32 bits (before compression)
- Load/store architecture: Arithmetic operates only on registers; memory is accessed via dedicated load/store instructions
Instruction Categories
Arithmetic:ADD, SUB, ADDI, ADDW, SUBW, ADDIW
Logical: AND, OR, XOR, ANDI, ORI, XORI
Shifts: SLL, SRL, SRA, SLLI, SRLI, SRAI, SLLW, SRLW, SRAW
Comparisons: SLT, SLTU, SLTI, SLTIU
Branches: BEQ, BNE, BLT, BGE, BLTU, BGEU
Jumps: JAL, JALR
Loads: LB, LH, LW, LD, LBU, LHU, LWU
Stores: SB, SH, SW, SD
Upper immediates: LUI, AUIPC
Addressing Mode
All memory accesses use base-plus-offset addressing:address = register[rs1] + immediate_offset
This simple addressing mode keeps the ISA regular and simplifies implementation.
Reference
For detailed instruction formats and encoding, see Chapter 2 of the RISC-V Specification.M Extension (Multiply/Divide)
The M extension adds integer multiplication and division operations: Multiplication:MUL: Multiply (lower 64 bits)MULH: Multiply signed × signed (upper 64 bits)MULHU: Multiply unsigned × unsigned (upper 64 bits)MULHSU: Multiply signed × unsigned (upper 64 bits)
DIV: Signed divisionDIVU: Unsigned divisionREM: Signed remainderREMU: Unsigned remainder
MULW, DIVW, etc.) that operate on the lower 32 bits and sign-extend the result to 64 bits.
Division by Zero
Unlike some ISAs, RISC-V defines the result of division by zero rather than trapping:x / 0returns all 1s (-1in two’s complement)x % 0returnsx
Reference
For detailed instruction formats and encoding, see Chapter 7 of the RISC-V Specification.A Extension (Atomics)
The A extension adds atomic read-modify-write operations and load-reserved/store-conditional pairs.Atomic Memory Operations (AMO)
Atomic operations read a value from memory, perform an operation, and write the result back atomically:AMOSWAP: SwapAMOADD: AddAMOAND: Bitwise ANDAMOOR: Bitwise ORAMOXOR: Bitwise XORAMOMIN: Signed minimumAMOMAX: Signed maximumAMOMINU: Unsigned minimumAMOMAXU: Unsigned maximum
Load-Reserved/Store-Conditional (LR/SC)
LR/SC provides a more flexible atomic primitive:LR.W/LR.D: Load-reserved (word/doubleword)SC.W/SC.D: Store-conditional (word/doubleword)
Jolt’s LR/SC Implementation
Jolt implements LR/SC using virtual sequences with width-specific reservation registers:- reservation_w (virtual register 32): Used by
LR.W/SC.Wfor 32-bit reservations - reservation_d (virtual register 33): Used by
LR.D/SC.Dfor 64-bit reservations
Width-Matched Pairing
The two reservation registers enforce width-matched pairing:LR.Wsetsreservation_wand clearsreservation_dLR.Dsetsreservation_dand clearsreservation_w
SC.W after LR.D (or vice versa) always fails, since the SC checks only its own width’s reservation register.
Store-Conditional Behavior
OnSC execution:
- The prover supplies
VirtualAdviceconstrained to (success/failure) - On success (advice = 0):
- Constraint forces reservation address to match
rs1 - Value in
rs2is stored to memory - Destination register
rdreceives 0
- Constraint forces reservation address to match
- On failure (advice = 1):
- Store is a no-op (original memory value is written back)
- Destination register
rdreceives 1
- Both reservation registers are cleared (per RISC-V spec)
Reference
For detailed instruction formats and encoding, see Chapter 8 of the RISC-V Specification.C Extension (Compressed Instructions)
The C extension provides 16-bit encodings for common operations, reducing code size by approximately 25-30%.Key Features
- 16-bit instructions for frequently used operations
- Register encoding: Uses 3-bit register specifiers for a subset of registers (
x8-x15) - Immediate encoding: Smaller immediate values, optimized for common cases
- Free intermixing: Compressed instructions can be intermixed with standard 32-bit instructions at any point
Jolt’s Handling
The Jolt tracer expands compressed instructions to their 32-bit equivalents before execution. This simplifies the core zkVM implementation while still supporting compressed code. The expansion happens transparently during the trace generation phase, so the proving system only handles standard 32-bit RISC-V instructions.Reference
For detailed instruction formats and encoding, see Chapter 16 of the RISC-V Specification.Compilation to RISC-V
Jolt proves execution of RISC-V ELF binaries, which can be produced from any language with an LLVM frontend.Supported Languages
- Rust: Primary language for Jolt guest programs
- C/C++: Via LLVM/Clang
- Any LLVM-supported language: Zig, Swift, Kotlin Native, etc.
Compilation Pipeline
Jolt SDK Integration
Thejolt-sdk crate handles cross-compilation automatically:
#[jolt::provable] macro automatically:
- Compiles the function to a RISC-V ELF binary
- Generates
prove(),verify(), andanalyze()functions - Handles serialization of inputs/outputs
Instruction Set Limitations
Not Supported
Jolt currently does not support:- F/D extensions: Floating-point operations (single/double precision)
- V extension: Vector operations
- Privileged modes: Machine mode, supervisor mode, user mode
- Exceptions/interrupts: Traps, system calls (except via host I/O)
- Virtual memory: Page tables, TLBs
Further Reading
Official RISC-V Resources
- RISC-V Specifications - Official specs for all extensions
- RISC-V ISA Manual - Complete instruction set reference
- RISC-V Assembly Programmer’s Manual - Assembly programming guide
LLVM and Compilation
- LLVM RISC-V Backend - LLVM’s RISC-V code generation
- RISC-V Toolchain - GCC and binutils for RISC-V
Jolt-Specific
- Jolt tracer implementation - How Jolt executes RISC-V instructions
- Instruction constraints - How instruction correctness is proven