feat(lir): 修改HIR到LIR转换以支持可变参数函数

- 移除SCC_LIR_LEA指令类型,改用SCC_LIR_LOAD_ADDR
- 在scc_lir_func_meta_t中添加is_va_arg字段用于标识可变参数函数
- 修改scc_hir2lir函数参数类型,移除const限定符
- 更新比较操作的指令映射逻辑,将条件信息存储在metadata中
- 调整代码结构,在各个switch case分支中统一使用"} break"格式

fix(x86-isel): 修复x86指令选择中的立即数和重定位处理

- 修改emit_direct_call函数以正确处理全局符号重定位
- 更新立即数字段访问从imm到imm0
- 添加新的重定位操作数类型SCC_X86_OPR_RELOC
- 实现重定位目标类型的完整处理逻辑,包括基本块和符号

refactor(x86-mir): 重构x86操作数结构以支持重定位机制

- 将内存操作数的disp字段改为结构体形式包含displacement信息
- 移除不再使用的常用操作数构造器函数
- 保留并完善slot操作数构造器
- 更新内存操作数的调试输出格式

feat(ir2mcode): 添加重定位表支持以处理符号引用

- 定义新的重定位结构体scc_reloc_t用于记录重定位信息
- 修改scc_ir2mcode_emit_instr函数签名以传递重定位表
- 实现重定位补丁应用功能scc_ir2mcode_patch
- 更新机器码生成流程以收集和处理重定位信息

refactor(ir2sccf): 重构SCEF文件生成以支持重定位处理

- 提取独立的emit_mir_module函数处理MIR模块的机器码生成
- 实现基本块间重定位的地址解析和补丁应用
- 改进符号重定位的处理机制
- 简化机器码段数据的最终处理流程
This commit is contained in:
zzy
2026-05-21 16:19:49 +08:00
parent aa4292a30e
commit 41d060d7e7
19 changed files with 608 additions and 227 deletions

View File

@@ -234,7 +234,7 @@ static scc_lir_op_t map_binop(scc_hir_op_type_t op, cbool is_float) {
case SCC_HIR_OP_SAR:
return SCC_LIR_SAR;
default:
return map_cmp_cond(op, is_float);
return SCC_LIR_CMP;
}
}
return SCC_LIR_NOP;
@@ -263,15 +263,19 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
scc_lir_val_t rhs = ir_value_to_lir_operand(ctx, value->data.op.rhs);
scc_lir_op_t op = map_binop(value->data.op.op, is_float);
scc_lir_instr_t instr = {.op = op,
.size = size,
.ext = ext,
.to = SCC_LIR_VREG(dst_vreg),
.arg0 = lhs,
.arg1 = rhs};
scc_lir_instr_t instr = {
.op = op,
.size = size,
.ext = ext,
.to = SCC_LIR_VREG(dst_vreg),
.arg0 = lhs,
.arg1 = rhs,
};
if (op == SCC_LIR_CMP) {
instr.metadata.cond = map_cmp_cond(value->data.op.op, is_float);
}
scc_lir_builder_add_instr(ctx, &instr);
break;
}
} break;
case SCC_HIR_VALUE_TAG_LOAD: {
scc_lir_val_t addr =
ir_value_to_lir_operand(ctx, value->data.load.target);
@@ -281,8 +285,7 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
.to = SCC_LIR_VREG(dst_vreg),
.arg0 = addr};
scc_lir_builder_add_instr(ctx, &instr);
break;
}
} break;
case SCC_HIR_VALUE_TAG_STORE: {
scc_lir_val_t data =
ir_value_to_lir_operand(ctx, value->data.store.value);
@@ -291,8 +294,7 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
scc_lir_instr_t instr = {
.op = SCC_LIR_STORE, .size = size, .arg0 = data, .arg1 = addr};
scc_lir_builder_add_instr(ctx, &instr);
break;
}
} break;
case SCC_HIR_VALUE_TAG_GET_ELEM_PTR: {
// 将指针运算转换为 LEA
scc_lir_val_t base =
@@ -333,15 +335,14 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
scc_lir_val_t addr =
SCC_LIR_ADDR(dst_vreg, -1, index.data.reg, elem_size);
// 更简单的做法:使用 LEA 指令,参数为 base 和 index由后端展开
scc_lir_instr_t instr = {.op = SCC_LIR_LEA,
scc_lir_instr_t instr = {.op = SCC_LIR_LOAD_ADDR,
.size = SCC_LIR_SIZE_64,
.to = SCC_LIR_VREG(dst_vreg),
.arg0 = base,
.arg1 = index};
// 实际需要将 index * elem_size 的信息编码,这里简化,假设后端处理
scc_lir_builder_add_instr(ctx, &instr);
break;
}
} break;
case SCC_HIR_VALUE_TAG_ALLOC: {
// alloca 指令:分配栈空间
scc_hir_type_t *alloc_ty =
@@ -355,8 +356,7 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
.to = SCC_LIR_VREG(dst_vreg),
.metadata.alloca = {alloc_size, alloc_size}};
scc_lir_builder_add_instr(ctx, &instr);
break;
}
} break;
case SCC_HIR_VALUE_TAG_CALL: {
scc_hir_func_t *callee = scc_hir_module_get_func(
ctx->hir_module, value->data.call.callee.func_ref);
@@ -381,8 +381,7 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
// metadata.call.args 指针仍指向 malloc 内存,
// 这会导致内存泄漏。实际实现中应使用 arena
// 分配或随函数释放。此处为示例简化。
break;
}
} break;
case SCC_HIR_VALUE_TAG_BRANCH: {
scc_lir_val_t cond =
ir_value_to_lir_operand(ctx, value->data.branch.cond);
@@ -392,15 +391,13 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
.metadata.br = {value->data.branch.true_bblock,
value->data.branch.false_bblock}};
scc_lir_builder_add_instr(ctx, &instr);
break;
}
} break;
case SCC_HIR_VALUE_TAG_JUMP: {
scc_lir_instr_t instr = {.op = SCC_LIR_JMP,
.metadata.jmp_target =
value->data.jump.target_bblock};
scc_lir_builder_add_instr(ctx, &instr);
break;
}
} break;
case SCC_HIR_VALUE_TAG_RET: {
scc_lir_val_t ret_val;
if (value->data.ret.ret_val != SCC_HIR_REF_nullptr) {
@@ -411,8 +408,7 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
scc_lir_instr_t instr = {.op = SCC_LIR_RET,
.metadata.ret_val = ret_val};
scc_lir_builder_add_instr(ctx, &instr);
break;
}
} break;
case SCC_HIR_VALUE_TAG_CONV: {
// 类型转换:使用 MOV 指令配合扩展/截断
scc_lir_val_t src =
@@ -429,8 +425,7 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
.to = SCC_LIR_VREG(dst_vreg),
.arg0 = src};
scc_lir_builder_add_instr(ctx, &instr);
break;
}
} break;
default:
// 不生成指令的节点(如 CONST_INT, FUNC_ARG_REF不会调用本函数
break;
@@ -447,6 +442,7 @@ static void translate_func(ir2lir_ctx_t *ctx, scc_hir_func_t *ir_func) {
.attr = SCC_LIR_ATTR_NONE,
.frame_size = 0,
.vregs_count = 0,
.is_va_arg = false,
};
scc_vec_push(ctx->lir_module->func_metas, lir_func_meta);
ctx->current_func = ir_func;
@@ -483,7 +479,7 @@ static void translate_func(ir2lir_ctx_t *ctx, scc_hir_func_t *ir_func) {
scc_hashtable_drop(&ctx->value_to_vreg);
}
void scc_hir2lir(scc_lir_module_t *module, const scc_hir_cprog_t *cprog) {
void scc_hir2lir(scc_lir_module_t *module, scc_hir_cprog_t *cprog) {
Assert(module != nullptr && cprog != nullptr);
// FIXME

View File

@@ -18,8 +18,6 @@ static const char *op_to_string(scc_lir_op_t op) {
return "store";
case SCC_LIR_STORE_ADDR:
return "store.addr";
case SCC_LIR_LEA:
return "lea";
case SCC_LIR_ADD:
return "add";
case SCC_LIR_SUB:
@@ -236,7 +234,6 @@ void scc_lir_dump_ins(scc_lir_dump_ctx_t *ctx, const scc_lir_instr_t *ins) {
scc_tree_dump_append(td, " <- ");
dump_operand(ctx, &ins->arg0);
break;
case SCC_LIR_LEA:
case SCC_LIR_NEG:
case SCC_LIR_NOT:
case SCC_LIR_FNEG:
@@ -419,7 +416,8 @@ void scc_lir_dump_func(scc_lir_dump_ctx_t *ctx, const scc_lir_func_t *func) {
scc_lir_func_meta_t *meta = SCC_LIR_FUNC_META(func);
// 函数头部
scc_tree_dump_begin_line(td);
scc_tree_dump_node(td, "func @%s", func->name ? func->name : "<anon>");
scc_tree_dump_node(td, "func @%s%s", func->name ? func->name : "<anon>",
meta->is_va_arg ? "(...)" : "()");
scc_tree_dump_append_fmt(td, " (vregs: %u, frame: %d)", meta->vregs_count,
meta->frame_size);
if (meta->attr != SCC_LIR_ATTR_NONE) {