# qbe.mbt API Documentation (doc)

> 📖 Project deep-dive guide (architecture, pipelines, algorithms, testing): [guide.mbt.md](guide.mbt.md)

This directory provides API documentation for each MoonBit package in the qbe.mbt compilation backend, based on each package's `pkg.generated.mbti` (generated by `moon info`) and source code comments.

[中文版本 (Chinese Version)](zh/README.md)

## Package Overview

Packages are listed in compilation pipeline order:

| Phase | Package | API Doc | Description |
| --- | --- | --- | --- |
| Data Structures | `types` | [types.md](types.md) | SSA IR: `Fn`/`Blk`/`Ins`/`Phi`/`Jump`/`Con`/`Tmp` etc. |
| Utilities | `util` | [util.md](util.md) | Error types, string interning, output, sorting |
| Lexing | `lexer` | [lexer.md](lexer.md) | IL text → token sequence |
| Parsing | `parser` | [parser.md](parser.md) | Token sequence → `Fn`/`Dat`/`Typ` |
| CFG Analysis | `cfg` | [cfg.md](cfg.md) | Predecessors, dominators, dominance frontiers, loops, aliasing |
| SSA Construction | `ssa` | [ssa.md](ssa.md) | Use chains, phi insertion, memopt/loadopt/copy |
| Constant Folding | `fold` | [fold.md](fold.md) | Constant instruction evaluation |
| Wasm ABI | `target_wasm/abi` | [abi_wasm.md](abi_wasm.md) | Wasm calling convention: keep Par/Arg, Call simplification |
| Wasm Instruction Selection | `target_wasm/isel` | [isel_wasm.md](isel_wasm.md) | Wasm op mapping, address mode decomposition, CFG→structured control flow |
| Wasm Assembly Output | `target_wasm/emit` | [emit_wasm.md](emit_wasm.md) | WAT text format output |
| ABI Processing | `target_amd64/abi` | [abi.md](abi.md) | Platform-specific ABI for parameters/return values |
| Instruction Selection | `target_amd64/isel` | [isel.md](isel.md) | amd64 instruction pattern selection |
| Liveness Analysis | `live` | [live.md](live.md) | in/out live sets |
| Register Spilling | `spill` | [spill.md](spill.md) | Stack spilling under register pressure |
| Register Allocation | `rega` | [rega.md](rega.md) | Virtual → physical registers |
| Assembly Output | `target_amd64/emit` | [emit.md](emit.md) | Render GAS assembly |
| RISC-V ABI | `target_rv64/abi` | [abi_rv64.md](abi_rv64.md) | rv64 calling convention: A0-A7/FA0-FA7 parameters and returns |
| RISC-V Instruction Selection | `target_rv64/isel` | [isel_rv64.md](isel_rv64.md) | rv64 instruction mapping, compare+branch merging |
| RISC-V Assembly Output | `target_rv64/emit` | [emit_rv64.md](emit_rv64.md) | RISC-V GAS text output |
| LoongArch ABI | `target_la64/abi` | [abi_la64.md](abi_la64.md) | la64 (LP64D) calling convention: A0-A7/FA0-FA7 parameters and returns |
| LoongArch Instruction Selection | `target_la64/isel` | [isel_la64.md](isel_la64.md) | la64 instruction mapping, comparison lowering to slt/sltu |
| LoongArch Assembly Output | `target_la64/emit` | [emit_la64.md](emit_la64.md) | LoongArch GAS text output (data + float pool) |
| ARM64 ABI | `target_arm64/abi` | [abi_arm64.md](abi_arm64.md) | AAPCS64: x0-x7/v0-v7 parameters, x8 hidden result pointer, HFA, stack args |
| ARM64 Instruction Selection | `target_arm64/isel` | [isel_arm64.md](isel_arm64.md) | arm64 instruction mapping, immediate folding, compare+branch merging |
| ARM64 Assembly Output | `target_arm64/emit` | [emit_arm64.md](emit_arm64.md) | AArch64 GAS text output (reference snapshot syntax) |
| SSA Interpreter | `interp` | [interp.md](interp.md) | direct pre-isel IR execution with built-in runtime |
| CLI Entry | `cmd/main` | [cmd_main.md](cmd_main.md) | Command-line arguments and pipeline orchestration |

## Pipeline Overview

```
            ┌──────┐  ┌───────┐
   src.ssa ─►│lexer │─►│parser │─┐
            └──────┘  └───────┘ │
                                  ▼
                              ┌─────┐
                              │types│  Fn/Dat/Typ
                              └─────┘
                                  │
   ┌──────────────────────────────┼──────────────────────────────┐
   │                                ▼                              │
   │  cfg.fillrpo/preds/dom/fron/loop/alias                        │
   │                                │                              │
   │                                ▼                              │
   │           ssa.filluse → ssa.memopt → ssa.phiins → renblk     │
   │                                │                              │
   │                                ▼                              │
   │           ssa.loadopt → ssa.copy → fold.fold                  │
   │                                │                              │
   │                                ▼                              │
   │                          abi.abi                              │
   │                                │                              │
   │                                ▼                              │
   │                          isel.isel                           │
   │                                │                              │
   │                                ▼                              │
   │           live.filllive → spill.fillcost → spill.spill        │
   │                                │                              │
   │                                ▼                              │
   │           rega.rega → cfg.simpljmp                           │
   │                                │                              │
   └────────────────────────────────┼─────────────────────────────┘
                                    ▼
                              emit.emitfn
                                    │
                                    ▼
                               out.s (GAS assembly)
```

### Wasm Pipeline

```
            ┌──────┐  ┌───────┐
   src.ssa ─►│lexer │─►│parser │─┐
            └──────┘  └───────┘ │
                                  ▼
                              ┌─────┐
                              │types│  Fn/Dat/Typ
                              └─────┘
                                  │
   ┌──────────────────────────────┼──────────────────────────────┐
   │                                ▼                              │
   │  cfg.fillrpo/preds/dom/fron/loop/alias                        │
   │                                │                              │
   │                                ▼                              │
   │           ssa.filluse → ssa.memopt → ssa.phiins → renblk     │
   │                                │                              │
   │                                ▼                              │
   │           ssa.loadopt → ssa.copy → fold.fold                  │
   │                                │                              │
   │                                ▼                              │
   │                       abi_wasm.abi_wasm                       │
   │                                │                              │
   │                                ▼                              │
   │                      isel_wasm.isel_wasm                      │
   │                                │                              │
   │                                ▼                              │
   │              [skip spill/rega — wasm has no physical regs]    │
   │                                │                              │
   └────────────────────────────────┼─────────────────────────────┘
                                    ▼
                              emit_wasm.emit_fn
                                    │
                                    ▼
                               out.wat (WAT text)
```

Each stage with a `-d*` flag outputs an IL-form snapshot to stderr in debug mode; see [cmd_main.md](cmd_main.md) for the flag table.

All three differential targets (`amd64_sysv`, `arm64`, `rv64`) are
byte-for-byte identical to the frozen `vendor/qbe` reference (661ceb2) for
every debug flag and for the emitted assembly.

## Project Links

- Overview: [README.mbt.md](../README.mbt.md)
- Demo examples: [demo/](../demo/README.md)
- Regression tests: [test/](../test/)
- Coding conventions: [AGENTS.md](../AGENTS.md)

### RISC-V 64 Pipeline

```
parse → fillrpo → fillpreds → filluse → memopt
      → filldom → fillfron → filllive(false) → phiins → renblk → filluse → ssacheck
      → fillloop → fillalias → loadopt → filluse → ssacheck
      → copy → filluse → fold
      → abi_rv64 → fillpreds → filluse
      → isel_rv64
      → init_rv64_target()   ← switch TargetCfg (register layout)
      → fillrpo → filllive → fillcost → spill → rega
      → fillrpo → simpljmp → fillrpo → fillpreds
      → emit_rv64
```

rv64 shares the same `spill`/`rega` with amd64: target differences are switched at runtime via `types.target_cfg` (see [types.md](types.md) TargetCfg section).
rv64 emits `data` segments and the floating-point constant pool byte-identically to `vendor/qbe -t rv64`; differential validation runs via `python compare.py --target rv64` and the independent `tools/check_rv64_asm.py` assembler gate.

```
la64 (LoongArch64, LP64D):
  parse → cfg/ssa/live/fold passes
      → abi_la64 → fillpreds → filluse
      → isel_la64
      → init_la64_target()   ← switch TargetCfg (register layout)
      → fillrpo → filllive → fillcost → spill → rega
      → simpljmp
      → emit_la64 (+ data sections + float constant pool)
```

la64 shares the same `spill`/`rega` with amd64 and rv64 via `types.target_cfg`.
It has no upstream differential reference baseline; its snapshots are
hand-verified against the LoongArch ELF psABI. It emits data sections and the
floating-point constant pool, like rv64.

```
interp (direct SSA execution):
  parse → lay out data segment → bind args
      → interpret pre-isel IR (phi, calls, memory, builtins)
      → Result[InterpValue, QbeError]
```

```
arm64 (AArch64, AAPCS64 ELF):
  parse → cfg/ssa/live/fold passes
      → abi_arm64 → fillpreds → filluse
      → isel_arm64
      → init_arm64_target()  ← switch TargetCfg (register layout)
      → fillrpo → filllive → fillcost → spill → rega
      → simpljmp
      → emit_arm64 (+ data sections + float constant pool)
```

arm64 shares `spill`/`rega` with the other targets via `types.target_cfg`.
It is validated byte-for-byte against `vendor/qbe/qbe -t arm64`: 5684/5684 IR
dumps and 406/406 assembly for both the ELF (`-G e`) and Mach-O (`-G m`)
flavors. The pinned reference's unsupported features (dynamic `alloc`,
`truncd`, ...) fail identically on both sides.

The interpreter bypasses ABI/isel/regalloc entirely and executes the
source-semantics IR; see [interp.md](interp.md).
