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:
@@ -2,30 +2,23 @@
|
||||
#include <x86/scc_x86_iform.h>
|
||||
|
||||
#include <arch/x86_64_isel.h>
|
||||
#include <core_pass/scc_abi_lowering.h>
|
||||
#include <core_pass/scc_prolog_epilog.h>
|
||||
#include <target/scc_win64.h>
|
||||
|
||||
static const int WIN64_DEFAULT_ALIGN = 8;
|
||||
static const int WIN64_STACK_ALIGN = 16;
|
||||
|
||||
typedef struct {
|
||||
scc_hashtable_t *vreg2slot;
|
||||
int offset;
|
||||
} frame_layout_ctx_t;
|
||||
|
||||
static void transit_vreg(scc_mir_func_meta_t *func, scc_mir_operand_t *op) {
|
||||
Assert(op->kind == SCC_MIR_OP_VREG);
|
||||
}
|
||||
|
||||
static void frame_alloc_impl(frame_layout_ctx_t *ctx,
|
||||
static void frame_alloc_impl(scc_frame_layout_t *ctx,
|
||||
scc_mir_module_t *mir_module,
|
||||
scc_mir_func_t *mir_func) {
|
||||
/*
|
||||
WIN ABI
|
||||
*/
|
||||
ctx->offset = 8; // called ret address
|
||||
|
||||
ctx->offset = 8;
|
||||
scc_mir_func_meta_t *func_meta = SCC_MIR_FUNC_META(mir_func);
|
||||
scc_vec_foreach(mir_func->bblocks, i) {
|
||||
scc_cfg_bblock_id_t id = scc_vec_at(mir_func->bblocks, i);
|
||||
@@ -35,8 +28,19 @@ static void frame_alloc_impl(frame_layout_ctx_t *ctx,
|
||||
scc_vec_foreach(*instrs, j) {
|
||||
scc_mir_instr_t *ins = &scc_vec_at(*instrs, j);
|
||||
for (int k = 0; k < ins->num_operands; k += 1) {
|
||||
if (ins->operands[k].kind == SCC_MIR_OP_VREG) {
|
||||
transit_vreg(func_meta, &ins->operands[k]);
|
||||
scc_mir_operand_t *op = &ins->operands[k];
|
||||
if (op->kind == SCC_MIR_OP_VREG) {
|
||||
Panic("vreg not supported in frame layout");
|
||||
} else if (op->kind == SCC_MIR_OP_STACK_SLOT) {
|
||||
scc_mir_stack_slot_t *slot =
|
||||
scc_mir_unsafe_slot(mir_func, op->stack_slot);
|
||||
op->kind = SCC_MIR_OP_STACK_OFFSET;
|
||||
if (slot->offset == 0) {
|
||||
// FIXME align
|
||||
ctx->offset += slot->size;
|
||||
slot->offset = ctx->offset;
|
||||
}
|
||||
op->stack_offset = slot->offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,6 +51,11 @@ static void frame_alloc_impl(frame_layout_ctx_t *ctx,
|
||||
// 16 字节栈对齐
|
||||
ctx->offset =
|
||||
(total_size + WIN64_STACK_ALIGN - 1) & ~(WIN64_STACK_ALIGN - 1);
|
||||
func_meta->frame_size = ctx->offset;
|
||||
}
|
||||
|
||||
void scc_win_pc_x64_frame_alloc_init(scc_frame_layout_t *ctx) {
|
||||
ctx->impl_fn = frame_alloc_impl;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -99,6 +108,11 @@ static void epilogue(void *userdata, const scc_mir_func_t *func) {
|
||||
add_instr_1(isel, SCC_X86_IFORM_POP_GPRV_58, reg_operand(SCC_X86_REG_RBP));
|
||||
}
|
||||
|
||||
void scc_win_pc_x64_prolog_epilog_init(scc_prolog_epilog_t *ctx) {
|
||||
ctx->prolog = prologue;
|
||||
ctx->epilog = epilogue;
|
||||
}
|
||||
|
||||
static void lower_call(void *userdata, const scc_lir_instr_t *instr) {
|
||||
scc_x86_64_isel_t *isel = userdata;
|
||||
/*
|
||||
@@ -174,7 +188,7 @@ static scc_mir_operand_t lower_param(void *userdata, const scc_lir_val_t *val) {
|
||||
case 3:
|
||||
return reg_operand(SCC_X86_REG_R9);
|
||||
default:
|
||||
return (scc_mir_operand_t){.kind = SCC_MIR_OP_MEM,
|
||||
return (scc_mir_operand_t){.kind = SCC_MIR_OP_STACK_SLOT,
|
||||
.stack_slot = -val->data.arg};
|
||||
}
|
||||
}
|
||||
@@ -231,14 +245,9 @@ static void mark_reg_used(void *ctx, int preg) {
|
||||
}
|
||||
static void clean_mark_regs(void *ctx) { reg_mask = 0; }
|
||||
|
||||
void scc_reg_alloc_fill_win_x64(scc_reg_alloc_op_t *ops) {
|
||||
void scc_win_pc_x64_reg_alloc_fill(scc_reg_alloc_op_t *ops) {
|
||||
ops->acquire_reg = acquire_reg;
|
||||
ops->release_reg = release_reg;
|
||||
ops->mark_reg_used = mark_reg_used;
|
||||
ops->clean_mark_regs = clean_mark_regs;
|
||||
}
|
||||
|
||||
void scc_win_pc_x64_prolog_epilog(scc_prolog_epilog_t *prolog_epilog) {
|
||||
prolog_epilog->prolog = prologue;
|
||||
prolog_epilog->epilog = epilogue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user