# Lab3：指令选择与汇编生成

## 1. 本实验定位

本仓库当前提供了一个“最小可运行”的 IR -> AArch64 汇编示例链路。  
Lab3 的目标是在该示例基础上扩展后端语义覆盖范围，逐步把更多 SysY IR 正确翻译为目标平台汇编代码。

## 2. Lab3 要求

需要同学完成：

1. 熟悉 MIR 相关数据结构与后端阶段接口。
2. 理解当前 IR -> MIR -> 汇编输出的最小实现流程。
3. 在现有框架上扩展后端代码生成能力，使其覆盖课程要求的 SysY 语义。

## 3. 当前代码框架（与 Lab3 直接相关）

1. MIR 定义与目标相关抽象
   - `include/mir/MIR.h`
   - `src/mir/MIRContext.cpp`
   - `src/mir/MIRFunction.cpp`
   - `src/mir/MIRBasicBlock.cpp`
   - `src/mir/MIRInstr.cpp`
   - `src/mir/Register.cpp`

2. IR -> MIR 与汇编生成
   - `src/mir/Lowering.cpp`
   - `src/mir/RegAlloc.cpp`
   - `src/mir/FrameLowering.cpp`
   - `src/mir/AsmPrinter.cpp`

3. 入口流程
   - `src/main.cpp`
   - `include/utils/CLI.h`
   - `src/utils/CLI.cpp`

## 4. Lab3 需要补充的内容

1. 必须修改的文件
   - `src/mir/Lowering.cpp`
   - `src/mir/RegAlloc.cpp`
   - `src/mir/FrameLowering.cpp`
   - `src/mir/AsmPrinter.cpp`
   - `include/mir/MIR.h`（当现有 MIR 数据结构或接口不够用时）
   - `src/mir/MIRInstr.cpp`（当需要新增机器指令或操作数表达时）
   - `src/mir/MIRFunction.cpp`（当需要扩展栈帧或机器函数状态时）
   - `src/mir/Register.cpp`（当需要扩展物理/虚拟寄存器表示时）

2. 视实现需要可能修改
   - `src/main.cpp`（当需要调整输出阶段行为时）
   - `src/utils/CLI.cpp`（当需要扩展后端相关命令行选项时）
   - `scripts/verify_asm.sh`（当需要扩展统一验证脚本时）

## 5. 当前最小示例实现说明

当前 IR -> 汇编仅覆盖最小子集：

1. 仅支持单函数 `main`、单基本块的最小流程。
2. 仅支持由当前 Lab2 最小 IR 产生的 `alloca`、`load`、`store`、`add`、`ret`。
3. 局部变量与中间结果当前统一采用栈槽模型：所有值先映射到栈槽，再通过固定寄存器 `w0`、`w8`、`w9` 配合 `ldur/stur/add` 生成汇编。
4. `RegAlloc` 当前仅执行最小一致性检查，不实现真实寄存器分配。
5. `FrameLowering` 当前会插入最小序言/尾声，并按 16 字节对齐栈帧。


说明：当前阶段后端主要用于演示完整流程。即使中间值可以暂存在寄存器中，也会先写回栈槽，而不是直接构造更接近最终机器代码的寄存器流。后续实验中，同学可按需求继续扩展指令选择、寄存器分配、调用约定与控制流相关功能。

## 6. 构建与运行

```bash
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j "$(nproc)"
```

## 7. Lab3 验证方式

项目编译后按提供测试输入回归：

```bash
./build/bin/compiler --emit-asm test/test_case/simple_add.sy
```

推荐使用统一脚本验证 “源码 -> 汇编 -> 可执行程序” 整体链路，用于验证后端代码生成的正确性：

```bash
./scripts/verify_asm.sh test/test_case/simple_add.sy test/test_result/asm --run
```

若最终输出 `退出码: 3`，说明当前最小子集示例 `return a + b` 的完整后端链路已经跑通。
