feat(mir): 添加栈偏移操作数类型并重构内存访问表示

- 将 MIR 中的 SCC_MIR_OP_MEM 替换为更精确的 SCC_MIR_OP_STACK_SLOT 和
  SCC_MIR_OP_STACK_OFFSET 类型
- 在 x86_64 指令选择中更新相应的内存操作数处理逻辑
- 修改寄存器分配器中的栈槽操作数类型检查
- 更新 IR 转机器码过程中的内存操作数转换

refactor(hir): 使用 tree_dump_node 输出函数节点

- 将 hir_dump 中的函数名输出从 append 改为 node 类型

refactor(frame-layout): 重构栈帧布局传递实现结构

- 引入函数指针实现方式替代直接函数实现
- 将栈帧分配功能集成到 MIR 传递流程中
- 移除独立的 frame_layout 实现文件

refactor(prolog-epilog): 添加函数序言/尾声传递框架

- 为 Windows x64 平台初始化序言/尾声生成器
- 在 MIR 传递阶段添加序言/尾声处理步骤

refactor(win64): 更新 Windows x64 目标平台接口

- 重命名寄存器分配填充函数为 scc_win_pc_x64_reg_alloc_fill
- 添加栈帧分配和序言/尾声初始化函数
- 修正参数传递中的栈槽操作数类型

refactor(dump): 改进 MIR 输出格式

- 将基本块显示改为分支节点类型
- 更新操作数类型的显示处理

chore: 添加 x86 编码相关数据结构定义

- 新增 scc_x86_encode.h 头文件包含内存操作数和指令编码接口定义
This commit is contained in:
zzy
2026-05-13 18:47:44 +08:00
parent 68eac24152
commit 3df858fb85
20 changed files with 662 additions and 85 deletions

View File

@@ -1,27 +1,78 @@
#include <arch/x86_64_reg_alloc.h>
#include <target/scc_win64.h>
#include <core_pass/scc_frame_layout.h>
#include <core_pass/scc_reg_alloc.h>
// #include <core_pass/scc_frame_layout.h>
// #include <core_pass/scc_prolog_epilog.h>
// #include <core_pass/scc_reg_alloc.h>
#include <scc_mir_module.h>
#include <scc_mir_pass.h>
void scc_frame_layout(scc_frame_layout_t *ctx, scc_mir_module_t *module) {
Assert(ctx && ctx->impl_fn && module);
scc_vec_foreach(module->cfg_module.funcs, i) {
if (i == 0)
continue;
ctx->impl_fn(ctx, module, &scc_vec_at(module->cfg_module.funcs, i));
}
}
void scc_prolog_epilog(scc_prolog_epilog_t *ctx, scc_mir_module_t *module) {
Assert(ctx && ctx->epilog && ctx->prolog && module);
scc_vec_foreach(module->cfg_module.funcs, i) {
if (i == 0)
continue;
scc_mir_func_t *func = &scc_vec_at(module->cfg_module.funcs, i);
scc_vec_foreach(func->bblocks, i) {
scc_cfg_bblock_id_t bb_id = scc_vec_at(func->bblocks, i);
scc_cfg_bblock_t *bb =
scc_cfg_module_unsafe_get_bblock(&module->cfg_module, bb_id);
Assert(bb != nullptr);
scc_mir_instr_vec_t *old_instrs = SCC_MIR_BBLOCK_VALUES(bb);
scc_mir_instr_vec_t new_instrs;
scc_vec_init(new_instrs);
if (i == 0) {
} else if (i == scc_vec_size(func->bblocks) - 1) {
// FIXME epilog it maybe used in ret instr
}
scc_vec_foreach(*old_instrs, i) {
scc_mir_instr_t ins = scc_vec_at(*old_instrs, i);
if (ins.opcode == SCC_MIR_PSUEDO_ALLOCA) {
continue;
}
scc_vec_push(new_instrs, ins);
}
scc_vec_free(*old_instrs);
*old_instrs = new_instrs;
}
}
}
void scc_mir_pass(scc_mir_module_t *mir_module, scc_mir_pass_stage_t stage) {
scc_reg_alloc_ctx_t reg_alloc_ctx = {
.func = nullptr, .instrs = nullptr, .ops = {0}};
scc_reg_alloc_fill_arch_x86(&reg_alloc_ctx.ops);
scc_reg_alloc_fill_win_x64(&reg_alloc_ctx.ops);
scc_win_pc_x64_reg_alloc_fill(&reg_alloc_ctx.ops);
scc_reg_alloc(&reg_alloc_ctx, mir_module);
if (stage == SCC_MIR_STAGE_REGALLOC) {
return;
}
scc_frame_layout_t frame_layout_ctx = {0};
scc_win_pc_x64_frame_alloc_init(&frame_layout_ctx);
scc_frame_layout(&frame_layout_ctx, mir_module);
if (stage == SCC_MIR_STAGE_FRAME_LAYOUT) {
return;
}
scc_prolog_epilog_t prolog_epilog_ctx = {0};
scc_win_pc_x64_prolog_epilog_init(&prolog_epilog_ctx);
scc_prolog_epilog(&prolog_epilog_ctx, mir_module);
if (stage == SCC_MIR_STAGE_PROLOGUE_EPILOGUE) {
return;
}