Skip to content

Developer Manual

This manual is for people who modify or extend Lince — adding peripherals, ISA frontends, or JIT passes; changing the execution model; or working on the RTEMS pass-rate goal. It explains not just what the code does but how it is conceived and why each decision was made. For running or embedding Lince, see the User Manual.

Read this first

The repository's CLAUDE.md is the canonical statement of the project's identity, frozen technical decisions, coding conventions, and the Architectural Decision Records (ADR-001..004). Every page here is the prose expansion of it and must stay consistent with it.

The big picture

flowchart TD
    app["lince_app (lince-emu CLI)"] --> rt["lince_runtime<br/>(Emulator, scheduler, GDB, ELF loader)"]
    rt --> core["lince_core<br/>(SPARC V8 ISA, CpuState, decoder, traps, FPU)"]
    rt --> per["lince_peripherals<br/>(IRQMP/IRQAMP, GPTIMER, APBUART, …)"]
    rt --> jit["lince_jit (LLVM ORCv2)"]
    rt --> arch["lince_arch_sparc (SPARC → IR)"]
    per --> bus["lince_bus (SystemBus, RAM)"]
    jit --> ir["lince_ir (arch-neutral IR, GuestState)"]
    arch --> ir
    core --> if["lince_interfaces (types, I* seams)"]
    ir --> if
    bus --> if

Dependencies flow one way: interfaces ← core, bus ← peripherals ← runtime ← app, and the translation stack layers as interfaces ← ir ← {arch/sparc, jit} ← runtime. lince_ir works on an opaque GuestState blob — a byte-addressed snapshot of the guest CPU registers carrying no ISA-specific knowledge — and so does not depend on lince_core; any ISA frontend can target it. These boundaries are enforced, not aspirational — see Layers and modules.

Where to start

Topic Page
How the whole thing is conceived Architecture overview
Module/layer graph and dependency rules Layers and modules
The non-negotiable design rules and why Design principles
The frozen decisions and ADRs Design decisions
Switch interpreter vs LLVM JIT, the run loop Execution model
Arch-neutral IR and the tiered LLVM JIT IR and LLVM JIT
Adding a new ISA frontend (e.g. ARM) Adding a frontend
SPARC traps, register windows, interrupts Traps and interrupts
Round-robin & MultiThread SMP, time, events Multicore and timing
Bus, memory API, endianness Memory and bus
The IPeripheral framework Peripheral system
Per-target (lince_*) reference Modules
Status, roadmap, performance Development
Generated C++ API C++ API

How to extend Lince

Goal Start at
Add a peripheral Peripherals → Custom peripherals
Add an ISA frontend Adding a frontend
Add a SoC recipe Configuration + Memory and bus
Add a test Testing