Skip to main content
RISC-V is an open-source instruction set architecture (ISA) based on reduced instruction set computer (RISC) principles. Its modular design allows implementations to include only the features they need.

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: x0 through x31, each 64 bits wide
    • x0 is 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)
Division/Remainder:
  • DIV: Signed division
  • DIVU: Unsigned division
  • REM: Signed remainder
  • REMU: Unsigned remainder
All operations have 32-bit “W” variants (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 / 0 returns all 1s (-1 in two’s complement)
  • x % 0 returns x
This simplifies zkVM implementations by avoiding special-case handling.

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: Swap
  • AMOADD: Add
  • AMOAND: Bitwise AND
  • AMOOR: Bitwise OR
  • AMOXOR: Bitwise XOR
  • AMOMIN: Signed minimum
  • AMOMAX: Signed maximum
  • AMOMINU: Unsigned minimum
  • AMOMAXU: Unsigned maximum
Each operation has word (32-bit) and doubleword (64-bit) variants.

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)
These are used to implement more complex atomic operations like compare-and-swap.

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.W for 32-bit reservations
  • reservation_d (virtual register 33): Used by LR.D/SC.D for 64-bit reservations

Width-Matched Pairing

The two reservation registers enforce width-matched pairing:
  • LR.W sets reservation_w and clears reservation_d
  • LR.D sets reservation_d and clears reservation_w
This cross-clear ensures that SC.W after LR.D (or vice versa) always fails, since the SC checks only its own width’s reservation register.

Store-Conditional Behavior

On SC execution:
  1. The prover supplies VirtualAdvice constrained to {0,1}\{0, 1\} (success/failure)
  2. On success (advice = 0):
    • Constraint forces reservation address to match rs1
    • Value in rs2 is stored to memory
    • Destination register rd receives 0
  3. On failure (advice = 1):
    • Store is a no-op (original memory value is written back)
    • Destination register rd receives 1
  4. 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

Source Code (Rust/C/C++)

  LLVM IR

RISC-V Assembly

RISC-V ELF Binary

Jolt Tracer → Execution Trace

Zero-Knowledge Proof

Jolt SDK Integration

The jolt-sdk crate handles cross-compilation automatically:
#[jolt::provable]
fn my_program(input: u64) -> u64 {
    // Your code here
    input * 2 + 1
}
The #[jolt::provable] macro automatically:
  1. Compiles the function to a RISC-V ELF binary
  2. Generates prove(), verify(), and analyze() functions
  3. 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
Guest programs run in a simplified execution environment with flat memory addressing and no operating system.

Further Reading

Official RISC-V Resources

LLVM and Compilation

Jolt-Specific

Build docs developers (and LLMs) love