# qbe.mbt 演示样例 (demo)

本目录提供一组 QBE IL (`.ssa`) 源文件，演示 qbe.mbt 编译后端接受的中间表示语法与语义。

## 使用方法

通过 `cmd/main` 编译单个 `.ssa` 文件，生成 amd64_sysv 汇编：

```bash
moon run cmd/main --target native -- demo/01_arith.ssa -o demo/01_arith.s
# 或直接输出到 stdout
moon run cmd/main --target native -- demo/02_control_flow.ssa
```

调试 dump (输出到 stderr)：

```bash
moon run cmd/main --target native -- demo/03_loop_phi.ssa -dM      # 打印内存优化后
moon run cmd/main --target native -- demo/03_loop_phi.ssa -dN      # 打印支配者与 SSA 构造
moon run cmd/main --target native -- demo/03_loop_phi.ssa -dC      # 打印 copy 传播
moon run cmd/main --target native -- demo/03_loop_phi.ssa -dA      # 打印 ABI 处理
moon run cmd/main --target native -- demo/03_loop_phi.ssa -dI      # 打印指令选择
moon run cmd/main --target native -- demo/03_loop_phi.ssa -dL      # 打印活跃变量
moon run cmd/main --target native -- demo/03_loop_phi.ssa -dS      # 打印溢出代价与分配
moon run cmd/main --target native -- demo/03_loop_phi.ssa -dR      # 打印寄存器分配
```

## 汇编并运行

`10_fibonacci.ssa` 只导出 `$fib`，没有 `main`，所以要配一个 C driver 来调用。
先生成与主机匹配的汇编，再用 clang 汇编链接：

```bash
# macOS (Apple Silicon)：arm64 + Mach-O
moon run cmd/main --target native -- -t arm64 -G m -o /tmp/fib.s demo/10_fibonacci.ssa

# Linux/x86-64：默认 amd64_sysv ELF（不需要 -G m）
moon run cmd/main --target native -- -o /tmp/fib.s demo/10_fibonacci.ssa
```

```c
/* /tmp/main.c */
#include <stdio.h>
long fib(long n);
int main(void) { printf("fib(10) = %ld\n", fib(10)); return 0; }
```

```bash
clang -O0 -o /tmp/fibdemo /tmp/fib.s /tmp/main.c
/tmp/fibdemo        # fib(10) = 55
```

也可以一步到位运行（见 [../scripts/run_fib_demo.sh](../scripts/run_fib_demo.sh)）：

```bash
./scripts/run_fib_demo.sh 10     # fib(10) = 55
```

不想汇编的话，内置解释器可以直接跑：

```bash
moon run cmd/main --target native -- --run fib,10 demo/10_fibonacci.ssa   # 55
```

## 直接生成可执行文件（自带 main）

`11_main.ssa` 导出了 C 的 `main`，所以产出的 `.o` 不需要额外 driver，
直接用系统 C 编译器链接即可运行：

```bash
# 方案 B（默认，自包含）：产出 .qbe_build/11_main.o
moon run --target native cmd/main -- --emit obj demo/11_main.ssa

# 用 gcc 或 clang 直接链接
gcc   -o /tmp/hello .qbe_build/11_main.o && /tmp/hello
# 或
clang -o /tmp/hello .qbe_build/11_main.o && /tmp/hello
```

输出：

    Hello from qbe.mbt!

其中对 libc `putchar` 的调用由链接器解析（对象里是 `BRANCH26` 外部重定位）。

## 演示文件列表

| 文件 | 主题 | 展示特性 |
| --- | --- | --- |
| [01_arith.ssa](01_arith.ssa) | 基础算术 | `add`/`sub`/`mul`、`ret`、`w`/`l` 类型 |
| [02_control_flow.ssa](02_control_flow.ssa) | 控制流 | `jnz` 条件跳转、多基本块 |
| [03_loop_phi.ssa](03_loop_phi.ssa) | 循环与 phi | `phi` 节点、`jmp`、循环结构 |
| [04_recursion.ssa](04_recursion.ssa) | 递归调用 | `call`、递归函数 |
| [05_float.ssa](05_float.ssa) | 浮点运算 | `d`/`s` 类型、浮点常量 |
| [06_memory.ssa](06_memory.ssa) | 内存访问 | `load`/`store`、`alloc`、全局数据 |
| [07_data.ssa](07_data.ssa) | 数据段 | `data`、字符串/数值、`type` |
| [08_compare.ssa](08_compare.ssa) | 比较 | 有/无符号、整数/浮点比较 |
| [09_bitwise.ssa](09_bitwise.ssa) | 位运算 | `and`/`or`/`xor`、`sar`/`shr`/`shl` |
| [10_fibonacci.ssa](10_fibonacci.ssa) | 综合示例 | 迭代斐波那契，phi + 循环 + 长 |
| [11_main.ssa](11_main.ssa) | 可执行 main | `export main`、调用 libc `putchar`、字符串 data、`.o` 直接链接 |
| [12_builder_capi.c](12_builder_capi.c) | C API 构造器 | 在 C 中通过 `qbe_*` 构造 `$tri`（循环 + phi）和 `$add`，输出 arm64 汇编与 Mach-O `.o` |
| [13_builder_rust/](13_builder_rust/) | Rust 构造器 | 用 crates.io `qopple` crate 在 Rust 中构造 `$add`/`$tri`/`$fib`/`$my_sqrt`，打印 QBE IL、JIT 调用并解析 libc `sqrt` |

## IL 语法速查

- 函数定义：`function <cls> $name(<cls> %arg, ...) { ... }`
- 基本块：`@label`
- 临时变量：`%name`，类型后缀：`w` (32位), `l` (64位), `s` (单精度浮点), `d` (双精度浮点)
- 常量：`42`, `-1`, `d_2.0`, `s_1.5`
- 全局符号：`$name`
- 指令：`%r =<cls> op <args>`
- 控制流：`jmp @label`，`jnz %cond, @then, @else`，`ret %val`

更完整的指令集可参考 [test/](../test/) 目录的回归测试。

## 程序化构造（不使用 .ssa）

除文本 IL 之外，也可以用 `ir_builder` 直接构造与解析器完全相同的 IR。C 侧完整示例：
[12_builder_capi.c](12_builder_capi.c) 通过 [`include/qbe_builder.h`](../include/qbe_builder.h)
的 `qbe_*` ABI 构造 `$tri`（带块参数/phi 的循环）与 `$add`，打印可再次解析的 QBE IL
文本与 arm64 汇编，并写出自包含 Mach-O 对象；[12_builder_capi_driver.c](12_builder_capi_driver.c) 链接这些对象并调用：

```bash
./scripts/run_builder_demo.sh
# tri(10)=55 add(20,22)=42
```

Rust 版见 [13_builder_rust/](13_builder_rust/)（对应 [`rust/`](../rust/README.md) crate 的
Cranelift/inkwell 风格接口）：

```bash
./scripts/run_builder_rust_demo.sh
# JIT: add(20,22)=42  tri(10)=55  fib(10)=55
```

接口说明见 [`doc/ir_builder.md`](../doc/ir_builder.md)（[中文](../doc/zh/ir_builder.md)），
更小的 C 入门示例见 [`examples/capi/`](../examples/capi/README.md)。
