references/custom-isa.md
# Custom ISA target modeling
Use this checklist for a toy, vendor, or reverse-engineered guest ISA that QEMU does not
support. It extends the frontend rules to target, CPU, machine, and test plumbing. Grounded in
the checked-out target layout and in repeated custom-ISA work (a 2026-07/08 STC32/MCS-251
target modeling effort produced `target/mcs251/*` plus `tests/functional/stc32/test_isa.py`).
## 1. Inspect before copying
- Read the nearest comparable target under `target/`; for a small 16-bit ISA,
`target/avr/` shows a compact layout (`Kconfig`, `cpu.c`, `cpu.h`, `helper.c`,
`translate.c`, `insn.decode`, `machine.c`, `meson.build`).
- Read how that target registers its decoder, CPU type, helpers, migration state, and gdbstub.
- Read `configs/targets/` for a matching `<target>-softmmu.mak` and the Kconfig select lines.
- Record the QEMU revision in `audit.md`; target APIs and file names differ between versions.
## 2. Enable the target
- Add `target/<arch>/` sources and follow the nearest target's `Kconfig` and `meson.build`
wiring instead of inventing a new build shape.
- For decodetree, the checked-out `target/avr/meson.build` shows the shape:
`decodetree.process('insn.decode', extra_args: ['--decode', 'decode_insn',
'--insnwidth', '<width>'])`, with `translate.c` including `"decode-insn.c.inc"`.
- Add the target makefile under `configs/targets/` and configure with
`--target-list=<target>-softmmu` in a named `builds/build-<target>/` directory.
- Keep the initial machine minimal: RAM, one console UART, one timer, and the interrupt/trap
model the ISA needs; this machine exists to run instruction and machine tests.
## 3. CPU state and helpers
- Define CPU state in `cpu.h`/`cpu.c` following the nearest target: QOM type registration,
reset values, realize checks, and any CPU properties.
- Put instruction helpers in `helper.c` and declare them with the tree's
`DEF_HELPER_FLAGS_*` mechanism; inspect `include/tcg/tcg.h` for the current flag names and
semantics before marking a helper as side-effect free.
- Compute PC and TB exits consistently: update the architectural PC, set
`ctx->base.is_jmp` when the TB must end, and raise exceptions through the target's exception
helpers rather than returning normally.
- Expose control/status registers (CSR-like state) through helpers only when the ISA defines
them; keep the state in the CPU object and document the mapping in `audit.md`.
## 4. Decoder and translation registration
- Write `insn.decode` with fields and formats for every encoding group; reuse argument sets
where fields repeat. Record the encoding table in `audit.md`.
- Implement `static bool trans_<NAME>(DisasContext *ctx, arg_<NAME> *a)` functions in
`translate.c`; return `false` when the encoding is not handled so the caller can reject it.
- Register the decoder the way the nearest target does. Some targets include the generated
decoder directly; others call a target translation-init function. Inspect the checked-out
target before choosing.
- Add feature and privilege gates before emitting IR, and reject reserved or invalid encodings
with the target's illegal-instruction exception.
## 5. TCG op mapping
- Prefer direct TCG ops for simple integer, logic, shift, and select instructions.
- Use helpers for complex state, division/softfloat, memory ordering, and exception-heavy
semantics; keep long work out of translation.
- Verify each mapping against the ISA definition and record it per instruction group.
- Distinguish translated native behavior from helper or fallback behavior in tests and logs.
## 6. Per-instruction functional tests
Add `tests/functional/<target>/test_isa.py` (the real STC32 work created this file and edited
it repeatedly):
- subclass `qemu_test.QemuSystemTest` and select the new machine;
- build or ship a tiny guest binary that executes each instruction group and reports results over
the UART or through the exit status; pin a SHA-256 when the binary is an external asset;
- cover valid encodings, invalid/illegal encodings, and feature-disabled behavior;
- register tests in `tests/functional/<target>/meson.build` using the arrays the parent
`tests/functional/meson.build` expects, for example
`tests_<target>_system_thorough = ['isa']`; the parent registers a test named
`func-<target>-isa` in the matching suites;
- run it from the QEMU source root with the build's Meson, for example
`builds/build-<target>/pyvenv/bin/meson test -C builds/build-<target> func-<target>-isa`;
verify the exact test name in the checked-out Meson files.
## 7. qtest coverage
- Add `tests/qtest/<machine>-test.c` for machine creation and memory-map probes; keep the test
behavioral (the guest-visible interface), not tied to the translator implementation.
- Register it in `tests/qtest/meson.build` under the matching architecture bucket and run
`builds/build-<target>/pyvenv/bin/meson test -C builds/build-<target> qtest-<target>/<name>`.
## 8. Build and verify
- `ninja -C builds/build-<target> qemu-system-<target>` builds the target binary.
- Run the functional and qtest suites after every instruction-group change, not only at the end.
- Use `-accel tcg,one-insn-per-tb=on` and bounded `-d op,out_asm` logs when an instruction
boundary or host-code mapping is unclear.
- Record commands, logs, and results under `.oh-my-qemu/<task-slug>/`.
## 9. Record the coverage in `audit.md`
Fill in [the ISA coverage template](../assets/isa-coverage-template.md) and keep it next to the
audit record: instruction group, pattern names, `trans_*` function, TCG mapping or helper, test
name, and PASS/FAIL/INCONCLUSIVE. List unimplemented instructions explicitly instead of letting
them raise a generic illegal instruction by accident.
## 10. Inspect the checked-out tree
File names, decodetree options, CPU type macros, helper flags, Meson registration, and test
framework APIs differ between QEMU versions. Locate each of them in the checked-out tree before
using them, and record the revision and any version-specific finding in `audit.md`.
SKILL.md
---
# SPDX-FileCopyrightText: Copyright (c) 2026 Process Mission
# SPDX-License-Identifier: MIT
name: qemu-tcg-frontend
description: Use for adding, reviewing, or debugging guest ISA decode and translation in a QEMU TCG frontend, including feature gates, exceptions, PC/TB behavior, and focused instruction tests.
---
# QEMU TCG Frontend
## Audit workflow
For a non-trivial task that writes to the workspace, use only the needed entries under
`.oh-my-qemu/<task-slug>/`: `audit.md` (baseline, plan, decisions, evidence, verification, and
gaps), `commands.md` (redacted commands, working directories, and results), `logs/` (decisive
build, test, and runtime output), `scripts/` (probes, parsers, and harnesses), and `output/`
(generated deliverables, third-party dependencies, and non-QEMU binaries). Keep QEMU's own build
tree at source-root `builds/build-<target>/`, never an unqualified `build/`. In a Git worktree,
add `.agents/`, `.oh-my-qemu/`, and `builds/` to the file from
`git rev-parse --git-path info/exclude` before writing artifacts or configuring QEMU; preserve
existing entries and avoid duplicates. Never stage or commit these paths; stage source only when
the user explicitly requests that separate action. At handoff, reconcile `git status --short`
with the baseline and report the task directory, build directory, source changes, pre-existing
changes, and unresolved gaps.
## Source comment hygiene
Keep file-header comments minimal: SPDX/copyright plus at most a one-line
component identity. Do not put implementation strategy, framework choice/defense,
"modeled contract" pointers, neighboring-device convention, or review/audit
rationale in source. Comment only key ISA/decode/backend code, in one to three
lines with at most one brief public QEMU or ISA reference; do not expand it into
a design or translation essay. Never write `.oh-my-qemu/...`, `output/...`,
`audit.md`, evidence paths, round/milestone/AC status, review notes, commands,
progress, or absolute host paths into source. When `qemu-workflow` is installed,
run its `source-comments` gate on changed source files.
## QEMU upstream boundary
QEMU's official GitLab and mailing lists are upstream channels. A patch becomes an upstream
contribution when it is sent to the maintainers selected through `MAINTAINERS`. Do not prepare or
send agent-generated code, documentation, commit messages, or patches for upstream submission; see
the checked-out tree's `docs/devel/code-provenance.rst`. Research, debugging, analysis, local
experiments, verification, and workflow guidance remain allowed. Local branches, commits, patch
files, pushes, and pull requests are not by themselves upstream contributions; perform those Git
actions only when requested.
## Workflow
1. Record the ISA version, encoding, feature/privilege gates, exception behavior, PC/TB rules,
and allowed source paths.
2. Inspect the checked-out decoder and the nearest comparable target before choosing decodetree,
direct TCG ops, or a helper.
3. Work in small reviewable rounds; record changed paths, verification, review result, and gaps.
4. Build the target and run focused valid, invalid, and disabled-feature instruction tests.
5. Capture bounded TCG logs only when needed; distinguish translated, helper, and fallback paths.
## Frontend contract
Record in `audit.md`: ISA version and privilege requirements; instruction encoding, aliases, and
operand sign/zero extension; XLEN/vector/FPU constraints; expected illegal-instruction cases; the
helper-versus-direct-op decision; and the tests that prove semantics and invalid encodings. Use
[the ISA coverage template](assets/isa-coverage-template.md) for per-instruction coverage.
## Decoder rules
For decodetree targets, reuse existing fields, formats, and argument sets; confirm
fixedmask/fixedbits uniqueness; handle overlap groups intentionally; use field functions for
transformed immediates; and keep ordering consistent with nearby extensions. For hand decoders,
preserve existing fallback and illegal-instruction behavior.
## Decoder collision and priority debugging
When an instruction decodes to the wrong pattern or a pattern is unreachable:
1. List the patterns that match the same instruction word and compare fixedbits/fixedmask.
2. Rebuild and read the decodetree generator error or generated decoder path reported by Meson;
conflicts fail generation or leave a later pattern unreachable.
3. Order patterns from most specific to most general; comment intentional overlap groups and add
a negative test for every shadowed encoding.
4. Record the pattern order and tested encodings in `audit.md`.
## `trans_*` rules
Before emitting IR, gate:
- CPU/ISA feature;
- privilege/virtualization mode;
- XLEN/operand width;
- reserved bits and invalid immediates;
- vector/FPU state where relevant;
- alignment or memory-mode constraints if architectural.
Use direct TCG ops for simple integer/logical/shift/select operations. Use helpers for complex
state, softfloat/crypto/vector libraries, or exception-heavy semantics.
## Helper side-effect flags
Helper flags tell TCG which globals a helper reads or writes and whether the call has side
effects; a helper that raises an exception or mutates guest-visible state must keep those effects
visible. Failure example: a raising helper declared with the no-side-effects flag looks removable
to TCG, so the call can be dropped or reordered when its result is unused. The build still
succeeds; only a guest test that depends on the exception or state write fails. Inspect the
checked-out flag definitions (in `include/tcg/tcg.h`) and add such a test.
## PC and TB rules
Check target conventions for:
- `pc_next` advancement;
- PC update before exceptions;
- branch/direct-block chaining;
- `ctx->base.is_jmp` state;
- page-boundary behavior;
- single-step and interrupt trigger behavior.
Wrong PC state corrupts exceptions, gdbstub state, and replay/debug evidence.
## Custom ISA modeling
For a new toy, vendor, or reverse-engineered ISA target, use
[custom-isa.md](references/custom-isa.md): target enablement, decode and translation
registration, TCG op mapping, CPU state and control-register helpers, per-instruction functional
tests, qtest coverage, and build targets. Keep the frontend testable per instruction group.
## Verification expectations
- Build the target translator.
- Add focused `tests/tcg/<target>/` coverage when applicable; otherwise add a functional
per-instruction test.
- Cover edge values, invalid encodings, feature-disabled behavior, and privilege errors.
- Use `-accel tcg,one-insn-per-tb=on` when debugging instruction boundaries.
- Store TCG logs under `.oh-my-qemu/<task-slug>/logs/`.
## Upstream references
- `docs/devel/code-provenance.rst`
- `docs/devel/decodetree.rst`
- `docs/devel/tcg.rst`
- `docs/devel/tcg-ops.rst`
- `docs/devel/submitting-a-patch.rst`
- `target/riscv/` (decodetree and `insn_trans/` implementation examples)
Paths can differ between QEMU versions; locate them in the checked-out tree.