61 lines
2.6 KiB
Markdown
61 lines
2.6 KiB
Markdown
# Lab3:指令选择与汇编生成
|
||
|
||
## 1. 本实验定位
|
||
|
||
本仓库当前提供了一个“最小可运行”的 IR -> AArch64 汇编示例链路。
|
||
Lab3 的目标是在该示例基础上扩展后端语义覆盖范围,逐步把更多 SysY IR 正确翻译为目标平台汇编代码。
|
||
|
||
## 2. Lab3 要求
|
||
|
||
需要同学完成:
|
||
|
||
1. 熟悉 MIR 相关数据结构与后端阶段接口。
|
||
2. 理解当前 IR -> MIR -> 汇编输出的最小实现流程。
|
||
3. 在现有框架上扩展后端代码生成能力,使其覆盖课程要求的 SysY 语义。
|
||
|
||
## 3. 相关文件
|
||
|
||
以下文件与本实验内容相关,建议优先阅读。
|
||
|
||
- `include/mir/MIR.h`
|
||
- `src/mir/Lowering.cpp`
|
||
- `src/mir/RegAlloc.cpp`
|
||
- `src/mir/FrameLowering.cpp`
|
||
- `src/mir/AsmPrinter.cpp`
|
||
|
||
## 4. 当前最小示例实现说明
|
||
|
||
当前 IR -> 汇编仅覆盖最小子集:
|
||
|
||
1. 仅支持单函数 `main`、单基本块的最小流程。
|
||
2. 仅支持由当前 Lab2 最小 IR 产生的 `alloca`、`load`、`store`、`add`、`ret`。
|
||
3. 局部变量与中间结果当前统一采用栈槽模型:所有值先映射到栈槽,再通过固定寄存器 `w0`、`w8`、`w9` 配合 `ldur/stur/add` 生成汇编。
|
||
4. `RegAlloc` 当前仅执行最小一致性检查,不实现真实寄存器分配。
|
||
5. `FrameLowering` 当前会插入最小序言/尾声,并按 16 字节对齐栈帧。
|
||
|
||
说明:当前阶段后端主要用于演示完整流程。即使中间值可以暂存在寄存器中,也会先写回栈槽,而不是直接构造更接近最终机器代码的寄存器流。后续实验中,同学可按需求继续扩展指令选择、寄存器分配、调用约定与控制流相关功能。
|
||
|
||
## 5. 构建与运行
|
||
|
||
```bash
|
||
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
||
cmake --build build -j "$(nproc)"
|
||
```
|
||
|
||
## 6. Lab3 验证方式
|
||
|
||
可先用单个样例检查汇编输出是否基本正确:
|
||
|
||
```bash
|
||
./build/bin/compiler --emit-asm test/test_case/functional/simple_add.sy
|
||
```
|
||
|
||
推荐使用统一脚本验证 “源码 -> 汇编 -> 可执行程序” 整体链路。`--run` 模式下会自动读取同名 `.in`,并将程序输出与退出码和同名 `.out` 比对,用于验证后端代码生成的正确性:
|
||
|
||
```bash
|
||
./scripts/verify_asm.sh test/test_case/functional/simple_add.sy test/test_result/function/asm --run
|
||
```
|
||
|
||
若最终输出 `输出匹配: test/test_case/simple_add.out`,说明当前示例用例 `return a + b` 的完整后端链路已经跑通。
|
||
但最终不能只检查 `simple_add`。完成 Lab3 后,应对 `test/test_case` 下全部测试用例逐个回归,确认代码生成结果能够通过统一验证;如有需要,也可以自行编写批量测试脚本统一执行。
|