CPU dispatch & ISA decode
The CPU<Core, Bus> generic
#![allow(unused)] fn main() { pub struct CPU<C: CoreOps, B> { cores: Vec<C>, current: usize, bus: B, } }
C: CoreOps— ISA-specific core (e.g.RVCore). The generic boundary means xemu can host multiple ISAs; a LoongArch stub exists inxemu/xcore/src/arch/loongarch/.B— the bus type. Single-hart carriesBusinline; multi-hart carriesArc<Mutex<Bus>>when true SMP lands (Phase 11 RFC).
Per-instruction flow
- Tick devices.
bus.tick()advances ACLINT mtime (every step), drives the UART and PLIC on a slower cadence (every 64 steps), and collects IRQ lines. - Sync interrupts.
sync_interrupts()copies the atomic IRQ bitmap intomip. - Check pending interrupts. If any enabled, higher-priority
interrupt is pending,
pending_trapis set and the rest of the step is skipped. - Fetch. Read the instruction word at
pcvia the MMU. - Decode. First check the decoded-instruction cache (per-hart 4 K direct-mapped). On miss, run the pest-based pattern matcher.
- Execute. Dispatch on
DecodedInst, updatingnpc(and registers / CSRs / memory as side effects). - Retire.
self.pc = self.npc. Ifpending_trapis set,commit_trap()writes the trap vector address tonpcfirst.
Decoder
xcore/src/arch/riscv/isa/decode/ contains ~200 instruction
patterns expressed in pest. Each pattern captures the opcode fields
into a DecodedInst::* variant:
R/I/S/B/U/J— standard formatsFR— floating-point with explicitrm(rounding mode) fieldFR4— FMA-style 4-register (fmadd,fmsub, ...)C*— compressed variants
The match tree after decode is the dispatch loop — one big match
on DecodedInst calling per-instruction handlers.
Decoded-instruction cache
Phase P4 of the perf roadmap:
#![allow(unused)] fn main() { struct ICacheLine { pc: usize, // guest virtual address ctx_tag: u32, // bumped on any mapping change raw: u32, // raw instruction word (sanity) decoded: DecodedInst, } icache: [ICacheLine; 4096] // per-hart, direct-mapped }
ctx_tag invalidates implicitly on:
satpwritessfence.vma- Privilege-mode transitions that change the effective translation
fence.i
Self-modifying code: every guest store invalidates the whole icache
(simple, correct, loses the icache effect only on code-writing
guests — rare). See
../spec/perfHotPath/SPEC.md for
the full invariant set.
Trace
LOG=trace emits one line per instruction with PC, mnemonic,
operands, and the resulting GPR delta. Very verbose — use it only
for focused debugging.