Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@
#
# ── What ships ────────────────────────────────────────────────────────────────
#
# One build variant per platform/arch: lightning + rex-jit + camera + chd.
# One build variant per platform/arch: lightning + gpujit + camera + chd.
#
# It is a lightning build (interpreter with breakpoint checks and the traceback
# buffer stripped — no interactive debugging) and carries the REX3 draw-shader
# JIT. It does not carry the experimental MIPS JIT (`jitv2`) or the N64 dev
# buffer stripped — no interactive debugging) and carries the graphics JITs
# (`gpujit`: REX3 draw shaders, IMPACT raster pipelines). It does not carry the experimental MIPS JIT (`jitv2`) or the N64 dev
# board (`ultra64`); those are source-build opt-ins (see iris-gui/Cargo.toml).
# (The v1 MIPS JIT, `jit`, was removed from the tree in 33c4e68.) The
# former "standard" (non-lightning), `pcap`, `-jitv2`, and separate `-r5000`
Expand Down Expand Up @@ -214,11 +214,11 @@ jobs:
- target: x86_64-pc-windows-msvc
arch: x64
runs-on: windows-latest
cli_features: "rex-jit,lightning"
cli_features: "gpujit,lightning"
- target: aarch64-pc-windows-msvc
arch: arm64
runs-on: windows-11-arm
cli_features: "rex-jit,lightning"
cli_features: "gpujit,lightning"
steps:
- uses: actions/checkout@v5
with:
Expand Down Expand Up @@ -383,8 +383,8 @@ jobs:
- name: Build all binaries
run: |
cargo build --release --target ${{ matrix.target }} -p iris-gui --features iris/lightning,bundled
cargo build --release --bin iris --target ${{ matrix.target }} --features rex-jit,lightning
cargo build --release --bin iris-ci --target ${{ matrix.target }} --features rex-jit,lightning
cargo build --release --bin iris --target ${{ matrix.target }} --features gpujit,lightning
cargo build --release --bin iris-ci --target ${{ matrix.target }} --features gpujit,lightning

# ── Code signing setup ──────────────────────────────────────────────────

Expand Down Expand Up @@ -522,7 +522,7 @@ jobs:

if [ "$IDENTITY" != "-" ]; then
# See the GUI bundle signing above: the JIT entitlement keeps the
# notarized CLI binaries (built with rex-jit) from being killed by
# notarized CLI binaries (built with gpujit) from being killed by
# the hardened runtime on their first JITed REX3 draw.
codesign --force --options runtime --timestamp \
--entitlements installer/iris-gui-notarized.entitlements \
Expand Down Expand Up @@ -808,8 +808,8 @@ jobs:

- name: Build iris CLI and iris-ci
run: |
cargo build --release --bin iris --target ${{ matrix.target }} --features rex-jit,lightning
cargo build --release --bin iris-ci --target ${{ matrix.target }} --features rex-jit,lightning
cargo build --release --bin iris --target ${{ matrix.target }} --features gpujit,lightning
cargo build --release --bin iris-ci --target ${{ matrix.target }} --features gpujit,lightning

- name: Package Core tarball
run: |
Expand Down Expand Up @@ -935,8 +935,8 @@ jobs:
- name: Build iris CLI + iris-ci (cross)
run: |
set -eux
cargo build --release --bin iris --target "$TARGET" --features rex-jit,lightning
cargo build --release --bin iris-ci --target "$TARGET" --features rex-jit,lightning
cargo build --release --bin iris --target "$TARGET" --features gpujit,lightning
cargo build --release --bin iris-ci --target "$TARGET" --features gpujit,lightning

# The release profile keeps debug info (debug = 1) and the host `strip`
# can't read a riscv64 ELF, so strip iris-gui with the cross strip here and
Expand Down
7 changes: 5 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,11 @@ hashes are given where a change is easiest to understand by reading the commit.

### Build / features

- **`gpujit` turns on every graphics JIT** (`rex-jit` and `gr4-jit`):
`--features lightning,gpujit`.
- **`gpujit` turns on every graphics JIT** (`rex-jit` and `gr4-jit`) and is
the recommended build: `--features lightning,gpujit`. The GUI and the
release binaries now carry it, so IMPACT gets its raster JIT out of the
box. `IRIS_NO_JIT` now turns the IMPACT JIT off too (and `mgras jit on`
refuses), which keeps the Mac App Store build interpreter-only.
- **`gr2 trace` and `mgras trace` need `gputrace`, like `rex trace`.** On with
`developer`; plain and `lightning` builds add `--features gputrace`.
Without it the per-access trace check on GR2 and IMPACT register reads
Expand Down
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ system (shell, networking, X11). It is **not** cycle-accurate

```
cargo run --release # interpreter
cargo run --release --features lightning,rex-jit # recommended for speed
cargo run --release --features jitv2,rex-jit # enable MIPS JIT v2 (experimental)
cargo run --release --features lightning,gpujit # recommended for speed (gpujit = rex-jit,gr4-jit)
cargo run --release --features jitv2,gpujit # enable MIPS JIT v2 (experimental)
cargo run --release -- --cpu r5000 # CPU is a runtime choice, not a feature
cargo run -p iris-gui --release # GUI front-end
```
Expand Down
11 changes: 11 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,17 @@ tcache = []
# Panics at the exact diverging access instead of letting corruption surface as
# a guest crash much later. Very slow; diagnostic only.
tcache_verify = ["tcache"]
# Cache parity/ECC injection and the Cache Error exception, for SGI's IDE
# cache diagnostics (dcache1, icache1, scache1): Status.CE forcing the ECC
# register into stored check bits, Index_Load_Tag loading check bits into CP0
# ECC, and the Cache Error a mismatch raises. Nothing but a diagnostic ever
# observes any of it, and it costs a check on every D-cache miss and a Status
# sync on every exception, so it is off by default.
cache-ecc = []
# Decoded-instruction cache for the shadow cache (src/cpu/decode_cache.rs).
# Always built now; this flag does nothing and is kept so command lines that
# still pass `--features decode-cache` keep working.
decode-cache = []
default = ["tlbvmap", "rexdiag"]
# Cranelift-based JIT compiler for REX3 graphics draw shaders.
rex-jit = ["cranelift-codegen", "cranelift-frontend", "cranelift-jit", "cranelift-module", "cranelift-native"]
Expand Down
18 changes: 9 additions & 9 deletions FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Select with `cargo build --release --features <comma-separated-list>`; add
| `default` | Default bundle: `tlbvmap` and `rexdiag`. | `tlbvmap`, `rexdiag` |
| `rex-jit` | Cranelift compiler for Newport draw shaders; complements precompiled shaders. | `cranelift-codegen`, `cranelift-frontend`, `cranelift-jit`, `cranelift-module`, `cranelift-native` |
| `gr4-jit` | Cranelift compiler for IMPACT (GR4) raster pipelines (RSS/TE1 shaders). | `cranelift-codegen`, `cranelift-frontend`, `cranelift-jit`, `cranelift-module`, `cranelift-native` |
| `gpujit` | Every graphics JIT, so one name covers both. | `rex-jit`, `gr4-jit` |
| `gpujit` | Every graphics JIT; the recommended build. Hosts that forbid JIT code (the Mac App Store sandbox) set `IRIS_NO_JIT` at run time. | `rex-jit`, `gr4-jit` |
| `jitv2` | Experimental whole-page MIPS compiler; implies transparent caching. | `tcache`, `cranelift-codegen`, `cranelift-frontend`, `cranelift-jit`, `cranelift-module`, `cranelift-native`, `target-lexicon`, `region`, `wasmtime-jit-icache-coherence` |
| `jitv2_opcodefusion` | Optional JIT fusion, off by default after live delay-slot failures. | `jitv2` |
| `j2wp` | Compatibility alias for `jitv2`; no separate compiler mode. | `jitv2` |
Expand All @@ -53,15 +53,15 @@ Select with `cargo build --release --features <comma-separated-list>`; add

Cargo also exposes these **implicit optional-dependency features**:
`cranelift-codegen`, `cranelift-frontend`, `cranelift-jit`, `cranelift-module`, `cranelift-native`, `region`, `target-lexicon`, `wasmtime-jit-icache-coherence`. They enable library dependencies,
not complete emulator capabilities; use `jitv2` or `rex-jit` for a working
not complete emulator capabilities; use `jitv2` or `gpujit` for a working
compiler configuration. `dep:` entries above suppress implicit feature names
for PCAP/host-service dependencies.

### iris-gui

Source: [iris-gui/Cargo.toml](iris-gui/Cargo.toml). There is no GUI-specific
default feature bundle. Its `iris` dependency always enables `rex-jit` and
retains the core default features. GUI `--no-default-features` alone does not
default feature bundle. Its `iris` dependency always enables `gpujit` (the
App Store build turns the JITs off at run time with `IRIS_NO_JIT`) and retains the core default features. GUI `--no-default-features` alone does not
turn off those dependency defaults.

| GUI feature | Purpose | Enables |
Expand Down Expand Up @@ -443,7 +443,7 @@ and offline-tool controls are included so they are not mistaken for GUI settings
| `IRIS_NO_FETCH_VERIFY` | 1 suppresses fetchverify checks in a fetchverify build. | [src/cpu/mips_exec.rs](src/cpu/mips_exec.rs) |
| `IRIS_NO_IDLE` | Any presence disables idle parking. | [src/cpu/idle_park.rs](src/cpu/idle_park.rs) |
| `IRIS_NO_INLINE_MEM` | Any presence disables JIT inline memory emission. | [src/cpu/jitv2/codegen.rs](src/cpu/jitv2/codegen.rs) |
| `IRIS_NO_JIT` | Any presence disables the REX3 shader JIT; does not select the MIPS engine. | [src/dev/ng1/rex3.rs](src/dev/ng1/rex3.rs) |
| `IRIS_NO_JIT` | Any presence disables the REX3 shader JIT and the IMPACT raster JIT; does not select the MIPS engine. | [src/dev/ng1/rex3.rs](src/dev/ng1/rex3.rs) |
| `IRIS_OPT_SPEED` | Presence selects speed optimization in offline PCP/corpus measurements. | [src/bin/jitv2_pcp_dump.rs](src/bin/jitv2_pcp_dump.rs) |
| `IRIS_PRINT_OFFSETS` | Presence runs the opt-in layout-offset print test. | [src/cpu/jitv2/mod.rs](src/cpu/jitv2/mod.rs) |
| `IRIS_QOS` | HostGL QoS: default/off disables promotion; quiet suppresses logging. | [iris-hostgl/src/qos.rs](iris-hostgl/src/qos.rs) |
Expand Down Expand Up @@ -471,10 +471,10 @@ both crates; these examples and implementation notes explain the tradeoffs.

Build variants:
```
cargo run --release --features lightning,rex-jit # recommended for best speed
cargo run --release --features lightning,gpujit # recommended for best speed
cargo run --release --features lightning # disable emulator breakpoints for a little bit more speed
cargo run --release --features rex-jit # enable REX3 graphics JIT compiler
cargo run --release --features jitv2,rex-jit # MIPS JIT v2 (experimental; see "JIT compilers")
cargo run --release --features gpujit # enable the graphics JITs (rex-jit + gr4-jit)
cargo run --release --features jitv2,gpujit # MIPS JIT v2 (experimental; see "JIT compilers")
cargo run --release --features idle-pause # park the CPU thread while the guest idles instead of spinning a host core
cargo run --release --features ci_clock # synthetic deterministic CP0 Count clock (CI/snapshot validator only; loses realtime desktop timing)
cargo run --release --features pcap # bridge guest networking onto a real host interface via libpcap instead of the built-in NAT gateway. See [network] in iris.toml.
Expand Down Expand Up @@ -575,7 +575,7 @@ JIT v2 section for tuning. (The original speculative, tiered MIPS JIT was
removed in August 2026; jitv2 replaces it.)

```
cargo run --release --features jitv2,rex-jit
cargo run --release --features jitv2,gpujit
```

What it does today: compiles on a pool of background threads (`[jitv2]
Expand Down
2 changes: 1 addition & 1 deletion HELP.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ emulating the Indy.

The **iris-gui status bar MIPS** figure (or the CLI window title `MIPS` readout)
is **real throughput**: MIPS instructions executed per wall-clock second on the
host. `lightning` builds and the JIT stack (`--features jitv2,rex-jit`) give
host. `lightning` builds and the JIT stack (`--features jitv2,gpujit`) give
higher MIPS; the hinv MHz string stays the same.

The guest's MHz comes from the CP0 Count rate, which is fixed: Count ticks at
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ boots to a usable system: shell, networking, X11, the works.
- Cranelift JIT compiler for MIPS to host code (`jitv2`, optional, experimental),
plus a REX3 draw pipeline of 400+ precompiled specialised draw functions and an
optional REX3 shader JIT (`rex-jit`), and an IMPACT raster pipeline JIT
(`gr4-jit`)
(`gr4-jit`); `gpujit` turns on both
- Copy-on-write disk overlay, and CHD images with MAME-style `.diff.chd` sidecars.
Crash all day, base image stays clean
- Hot-swappable CD-ROM with runtime disc switching
Expand Down Expand Up @@ -181,7 +181,8 @@ are in [FEATURES.md](FEATURES.md#emulated-cpu).

Optional `jitv2` compiles MIPS code; `rex-jit` compiles Newport draw shaders
alongside the precompiled drawing routines; `gr4-jit` compiles IMPACT raster
pipelines. See
pipelines. `gpujit` turns on both graphics JITs and is the recommended
build (`--features lightning,gpujit`). See
[FEATURES.md](FEATURES.md#jit-compilers) for their behavior, defaults,
limitations, persistent caches, and corpus-measurement tools.

Expand Down
4 changes: 2 additions & 2 deletions iris-gui-README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ cargo run -p iris-gui --release

The first build compiles libchdman-rs, the camera backends (nokhwa / V4L),
and Cranelift. CHD and camera support are unconditional in the core; iris-gui
also enables `rex-jit`. Device use is configured at runtime.
also enables `gpujit` (the REX3 and IMPACT graphics JITs). Device use is configured at runtime.

A debug build (`cargo run -p iris-gui` without `--release`) is fine for
iterating on the GUI itself but uses an unoptimized iris core, which means
Expand Down Expand Up @@ -338,7 +338,7 @@ iris/
├── Cargo.toml [workspace] iris, iris-gui, iris-hostcall; iris-hostgl excluded
├── src/ iris library + CLI
└── iris-gui/
├── Cargo.toml depends on iris with rex-jit; CHD/camera built into core
├── Cargo.toml depends on iris with gpujit; CHD/camera built into core
├── build.rs APP_VERSION (from RELEASE_VERSION or the crate version)
├── assets/ icons, default NVRAM
└── src/
Expand Down
10 changes: 6 additions & 4 deletions iris-gui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,12 @@ hostcall = ["iris/hostcall"]
hostgl = ["hostcall", "iris/hostgl"]

[dependencies]
# The GUI always enables REX3 shader compilation. CHD, camera, DaynaPort,
# and Ultra64 device support are unconditional in the core and selected at
# runtime; Ultra64 requires an external gopher64 bridge peer.
iris = { path = "..", features = ["rex-jit"] }
# The GUI always enables the graphics JITs (`gpujit`: REX3 draw shaders and
# IMPACT raster pipelines); the `appstore` build turns both off at run time
# with IRIS_NO_JIT. CHD, camera, DaynaPort, and Ultra64 device support are
# unconditional in the core and selected at runtime; Ultra64 requires an
# external gopher64 bridge peer.
iris = { path = "..", features = ["gpujit"] }
eframe = { version = "0.36", default-features = false, features = ["default_fonts", "glow", "wayland", "x11"] }
egui = "0.36"
crossbeam-channel = "0.5"
Expand Down
2 changes: 1 addition & 1 deletion iris-gui/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ fn main() -> eframe::Result<()> {
std::env::set_var("IRIS_CHD_DIFF_DIR", d.join("iris").join("chd-diffs"));
}
// Force the interpreter on the Mac App Store build. Cranelift (MIPS JIT and
// the always-on REX3 draw-shader JIT) allocates executable memory with
// the always-on REX3 draw-shader and IMPACT raster JITs) allocates executable memory with
// mmap+mprotect, not MAP_JIT. The App Sandbox only permits MAP_JIT pages
// (com.apple.security.cs.allow-jit is the sole code-signing entitlement MAS
// allows; allow-unsigned-executable-memory / disable-executable-page-
Expand Down
2 changes: 1 addition & 1 deletion profile.sh
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
#!/bin/bash
PERFFLAGS="-F 200 -g --call-graph dwarf" cargo flamegraph --profile profiling --features rex-jit,lightning,jitv2 --bin iris
PERFFLAGS="-F 200 -g --call-graph dwarf" cargo flamegraph --profile profiling --features gpujit,lightning,jitv2 --bin iris
26 changes: 26 additions & 0 deletions rules/perf/hot-path-inlining-must-be-explicit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Hot-path inlining must be stated, not left to the inliner

`CpuCache::fetch` runs once per interpreted instruction. It used to inline into
`step_int` because the inliner happened to judge it small enough, with its miss
path `fill_l1i_line` inlined into it.

1431f560 added a 4-word `ic_raw` snapshot to `fill_l1i_line`, a cold path. That
grew `fetch` past the inliner's budget, and `fetch` became an out-of-line call
on every instruction. Bare-metal iris-bench (lightning, R4400, full cache) fell
to ×0.84 of `main` (`sys/uncached` ×0.51, `int/branch` ×0.75). IRIX dhrystone
went 71428 → 58823.

Found by bisecting the bare-metal suite, then confirmed with
`nm -C --size-sort … | grep 'CpuCache<16384.*fetch'`: the symbol exists only
in the slow build.

Rules:
- A per-instruction hit path gets `#[inline(always)]` (`CpuCache::fetch`,
`ShadowCache::fetch`, `DecodeCache::fetch`).
- Its miss path gets `#[inline(never)] #[cold]` (`fill_l1i_line`,
`DecodeCache::fetch_slow`), so changes there cannot move the hot path.
- After touching anything reachable from `fetch`, `read`, `write` or
`step_int`, check the symbol table: a new out-of-line symbol for a hot
function is the regression.

Fixed in 28d8c01a (back to ×1.02 of `main`).
Loading
Loading