- 移除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模块的机器码生成 - 实现基本块间重定位的地址解析和补丁应用 - 改进符号重定位的处理机制 - 简化机器码段数据的最终处理流程
533 lines
19 KiB
C
533 lines
19 KiB
C
/**
|
||
* @file scc_hir2lir.c
|
||
* @brief 将高级 IR (scc_ir) 降级为低层 LIR (scc_lir)
|
||
*/
|
||
|
||
#include <scc_hashtable.h>
|
||
#include <scc_hir2lir.h>
|
||
|
||
/* ---------- 转换上下文 ---------- */
|
||
typedef struct {
|
||
scc_hir_module_t *hir_module;
|
||
scc_lir_module_t *lir_module;
|
||
|
||
scc_lir_func_t *current_func;
|
||
scc_lir_instr_vec_t instrs;
|
||
|
||
scc_hashtable_t value_to_vreg; // ir_value_ref_t -> unsigned int vreg
|
||
scc_hashtable_t func_decl_map; // ir_func_ref_t -> const char* (用于调用)
|
||
} ir2lir_ctx_t;
|
||
|
||
static void ir2lir_ctx_init(ir2lir_ctx_t *ctx, scc_lir_module_t *lir_module,
|
||
scc_hir_module_t *hir_module) {
|
||
ctx->hir_module = hir_module;
|
||
ctx->lir_module = lir_module;
|
||
scc_hashtable_usize_init(&ctx->value_to_vreg);
|
||
scc_hashtable_usize_init(&ctx->func_decl_map);
|
||
}
|
||
|
||
static void ir2lir_ctx_drop(ir2lir_ctx_t *ctx) {
|
||
scc_hashtable_drop(&ctx->value_to_vreg);
|
||
scc_hashtable_drop(&ctx->func_decl_map);
|
||
}
|
||
|
||
static scc_lir_val_t ir_value_to_lir_operand(ir2lir_ctx_t *ctx,
|
||
scc_hir_value_ref_t val_ref);
|
||
static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
|
||
scc_hir_value_ref_t value_ref);
|
||
|
||
static void ir_type_to_lir_size_ext(scc_hir_type_t *type, u8 *out_size,
|
||
scc_lir_ext_t *out_ext) {
|
||
switch (type->tag) {
|
||
case SCC_HIR_TYPE_i8:
|
||
*out_size = SCC_LIR_SIZE_8;
|
||
*out_ext = SCC_LIR_EXT_SEXT;
|
||
break;
|
||
case SCC_HIR_TYPE_u8:
|
||
*out_size = SCC_LIR_SIZE_8;
|
||
*out_ext = SCC_LIR_EXT_ZEXT;
|
||
break;
|
||
case SCC_HIR_TYPE_i16:
|
||
*out_size = SCC_LIR_SIZE_16;
|
||
*out_ext = SCC_LIR_EXT_SEXT;
|
||
break;
|
||
case SCC_HIR_TYPE_u16:
|
||
*out_size = SCC_LIR_SIZE_16;
|
||
*out_ext = SCC_LIR_EXT_ZEXT;
|
||
break;
|
||
case SCC_HIR_TYPE_i32:
|
||
*out_size = SCC_LIR_SIZE_32;
|
||
*out_ext = SCC_LIR_EXT_SEXT;
|
||
break;
|
||
case SCC_HIR_TYPE_u32:
|
||
*out_size = SCC_LIR_SIZE_32;
|
||
*out_ext = SCC_LIR_EXT_ZEXT;
|
||
break;
|
||
case SCC_HIR_TYPE_i64:
|
||
*out_size = SCC_LIR_SIZE_64;
|
||
*out_ext = SCC_LIR_EXT_SEXT;
|
||
break;
|
||
case SCC_HIR_TYPE_u64:
|
||
*out_size = SCC_LIR_SIZE_64;
|
||
*out_ext = SCC_LIR_EXT_ZEXT;
|
||
break;
|
||
case SCC_HIR_TYPE_f32:
|
||
*out_size = SCC_LIR_SIZE_32;
|
||
*out_ext = SCC_LIR_EXT_FLOAT;
|
||
break;
|
||
case SCC_HIR_TYPE_f64:
|
||
*out_size = SCC_LIR_SIZE_64;
|
||
*out_ext = SCC_LIR_EXT_FLOAT;
|
||
break;
|
||
case SCC_HIR_TYPE_PTR:
|
||
*out_size = SCC_LIR_SIZE_64;
|
||
*out_ext = SCC_LIR_EXT_NONE;
|
||
break;
|
||
case SCC_HIR_TYPE_void:
|
||
*out_size = 0;
|
||
*out_ext = SCC_LIR_EXT_NONE;
|
||
break;
|
||
default:
|
||
Panic("unsupported IR type in lowering");
|
||
}
|
||
}
|
||
|
||
static inline void scc_lir_builder_add_instr(ir2lir_ctx_t *ctx,
|
||
scc_lir_instr_t *instr) {
|
||
scc_vec_push(ctx->instrs, *instr);
|
||
}
|
||
|
||
// 获取或创建 IR 值对应的虚拟寄存器
|
||
static int get_vreg_for_value(ir2lir_ctx_t *ctx, scc_hir_value_ref_t val_ref) {
|
||
void *found =
|
||
scc_hashtable_get(&ctx->value_to_vreg, (void *)(usize)val_ref);
|
||
if (found)
|
||
return (int)(usize)found;
|
||
|
||
int vreg = ++(SCC_LIR_FUNC_META(ctx->current_func)->vregs_count);
|
||
Assert(vreg != 0);
|
||
scc_hashtable_set(&ctx->value_to_vreg, (void *)(usize)val_ref,
|
||
(void *)(usize)vreg);
|
||
return vreg;
|
||
}
|
||
|
||
// 获取 LIR 操作数:若为常量/全局符号则直接构造,否则返回对应 vreg
|
||
static scc_lir_val_t ir_value_to_lir_operand(ir2lir_ctx_t *ctx,
|
||
scc_hir_value_ref_t val_ref) {
|
||
scc_hir_value_t *val = scc_hir_module_get_value(ctx->hir_module, val_ref);
|
||
Assert(val != nullptr);
|
||
|
||
switch (val->tag) {
|
||
case SCC_HIR_VALUE_TAG_INTEGER: {
|
||
return SCC_LIR_IMM(val->data.integer);
|
||
}
|
||
case SCC_HIR_VALUE_TAG_DECIMAL: {
|
||
TODO();
|
||
}
|
||
case SCC_HIR_VALUE_TAG_GLOBAL_ALLOC: {
|
||
// 全局变量地址作为符号
|
||
scc_hir_value_t *global_val = scc_hir_module_get_value(
|
||
ctx->hir_module, val->data.global_alloc.value);
|
||
return SCC_LIR_SYMBOL(global_val->name);
|
||
}
|
||
case SCC_HIR_VALUE_TAG_FUNC_ARG_REF: {
|
||
// 函数参数:预先已分配 vreg
|
||
return SCC_LIR_ARG(val->data.arg_ref.idx);
|
||
}
|
||
case SCC_HIR_VALUE_TAG_NULLPTR: {
|
||
scc_ap_t ap;
|
||
ap.data.digit = 0;
|
||
ap.capacity = -1;
|
||
return SCC_LIR_IMM(ap);
|
||
}
|
||
default: {
|
||
// 其他所有产生值的指令:确保其指令已生成,然后返回 vreg
|
||
// 注意:这里可能会递归调用 translate_ir_value,因此需要先检查是否已翻译
|
||
void *found =
|
||
scc_hashtable_get(&ctx->value_to_vreg, (void *)(uintptr_t)val_ref);
|
||
if (!found) {
|
||
translate_hir_value(ctx, val, val_ref);
|
||
}
|
||
unsigned int vreg = (unsigned int)(uintptr_t)scc_hashtable_get(
|
||
&ctx->value_to_vreg, (void *)(uintptr_t)val_ref);
|
||
return SCC_LIR_VREG(vreg);
|
||
}
|
||
}
|
||
}
|
||
|
||
static scc_lir_cond_t map_cmp_cond(scc_hir_op_type_t op, cbool is_float) {
|
||
if (is_float) {
|
||
switch (op) {
|
||
case SCC_HIR_OP_EQ:
|
||
return SCC_LIR_COND_FEQ;
|
||
case SCC_HIR_OP_NEQ:
|
||
return SCC_LIR_COND_FNE;
|
||
case SCC_HIR_OP_LT:
|
||
return SCC_LIR_COND_FLT;
|
||
case SCC_HIR_OP_LE:
|
||
return SCC_LIR_COND_FLE;
|
||
case SCC_HIR_OP_GT:
|
||
return SCC_LIR_COND_FGT;
|
||
case SCC_HIR_OP_GE:
|
||
return SCC_LIR_COND_FGE;
|
||
default:
|
||
Panic("invalid float cmp");
|
||
}
|
||
} else {
|
||
// 默认为有符号比较 (无符号需额外处理类型)
|
||
switch (op) {
|
||
case SCC_HIR_OP_EQ:
|
||
return SCC_LIR_COND_EQ;
|
||
case SCC_HIR_OP_NEQ:
|
||
return SCC_LIR_COND_NE;
|
||
case SCC_HIR_OP_LT:
|
||
return SCC_LIR_COND_SLT;
|
||
case SCC_HIR_OP_LE:
|
||
return SCC_LIR_COND_SLE;
|
||
case SCC_HIR_OP_GT:
|
||
return SCC_LIR_COND_SGT;
|
||
case SCC_HIR_OP_GE:
|
||
return SCC_LIR_COND_SGE;
|
||
default:
|
||
Panic("invalid int cmp");
|
||
}
|
||
}
|
||
return SCC_LIR_COND_EQ;
|
||
}
|
||
|
||
static scc_lir_op_t map_binop(scc_hir_op_type_t op, cbool is_float) {
|
||
if (is_float) {
|
||
switch (op) {
|
||
case SCC_HIR_OP_ADD:
|
||
return SCC_LIR_FADD;
|
||
case SCC_HIR_OP_SUB:
|
||
return SCC_LIR_FSUB;
|
||
case SCC_HIR_OP_MUL:
|
||
return SCC_LIR_FMUL;
|
||
case SCC_HIR_OP_DIV:
|
||
return SCC_LIR_FDIV;
|
||
default:
|
||
Panic("unsupported float binop");
|
||
}
|
||
} else {
|
||
switch (op) {
|
||
case SCC_HIR_OP_ADD:
|
||
return SCC_LIR_ADD;
|
||
case SCC_HIR_OP_SUB:
|
||
return SCC_LIR_SUB;
|
||
case SCC_HIR_OP_MUL:
|
||
return SCC_LIR_MUL;
|
||
case SCC_HIR_OP_DIV:
|
||
return SCC_LIR_DIV_S;
|
||
case SCC_HIR_OP_MOD:
|
||
return SCC_LIR_REM_S;
|
||
case SCC_HIR_OP_AND:
|
||
return SCC_LIR_AND;
|
||
case SCC_HIR_OP_OR:
|
||
return SCC_LIR_OR;
|
||
case SCC_HIR_OP_XOR:
|
||
return SCC_LIR_XOR;
|
||
case SCC_HIR_OP_SHL:
|
||
return SCC_LIR_SHL;
|
||
case SCC_HIR_OP_SHR:
|
||
return SCC_LIR_SHR;
|
||
case SCC_HIR_OP_SAR:
|
||
return SCC_LIR_SAR;
|
||
default:
|
||
return SCC_LIR_CMP;
|
||
}
|
||
}
|
||
return SCC_LIR_NOP;
|
||
}
|
||
|
||
static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
|
||
scc_hir_value_ref_t value_ref) {
|
||
// 防止重复翻译
|
||
if (scc_hashtable_get(&ctx->value_to_vreg, (void *)(uintptr_t)value_ref))
|
||
return;
|
||
|
||
scc_hir_type_t *ty = scc_hir_module_get_type(ctx->hir_module, value->type);
|
||
u8 size = 0;
|
||
scc_lir_ext_t ext = SCC_LIR_EXT_NONE;
|
||
if (ty != nullptr) {
|
||
ir_type_to_lir_size_ext(ty, &size, &ext);
|
||
}
|
||
bool is_float = (ext == SCC_LIR_EXT_FLOAT);
|
||
|
||
// 为当前指令分配目标虚拟寄存器
|
||
unsigned int dst_vreg = get_vreg_for_value(ctx, value_ref);
|
||
|
||
switch (value->tag) {
|
||
case SCC_HIR_VALUE_TAG_OP: {
|
||
scc_lir_val_t lhs = ir_value_to_lir_operand(ctx, value->data.op.lhs);
|
||
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,
|
||
};
|
||
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;
|
||
case SCC_HIR_VALUE_TAG_LOAD: {
|
||
scc_lir_val_t addr =
|
||
ir_value_to_lir_operand(ctx, value->data.load.target);
|
||
scc_lir_instr_t instr = {.op = SCC_LIR_LOAD,
|
||
.size = size,
|
||
.ext = ext,
|
||
.to = SCC_LIR_VREG(dst_vreg),
|
||
.arg0 = addr};
|
||
scc_lir_builder_add_instr(ctx, &instr);
|
||
} break;
|
||
case SCC_HIR_VALUE_TAG_STORE: {
|
||
scc_lir_val_t data =
|
||
ir_value_to_lir_operand(ctx, value->data.store.value);
|
||
scc_lir_val_t addr =
|
||
ir_value_to_lir_operand(ctx, value->data.store.target);
|
||
scc_lir_instr_t instr = {
|
||
.op = SCC_LIR_STORE, .size = size, .arg0 = data, .arg1 = addr};
|
||
scc_lir_builder_add_instr(ctx, &instr);
|
||
} break;
|
||
case SCC_HIR_VALUE_TAG_GET_ELEM_PTR: {
|
||
// 将指针运算转换为 LEA
|
||
scc_lir_val_t base =
|
||
ir_value_to_lir_operand(ctx, value->data.get_elem_ptr.src_addr);
|
||
scc_lir_val_t index = SCC_LIR_IMM(0);
|
||
if (value->data.get_elem_ptr.index)
|
||
ir_value_to_lir_operand(ctx, value->data.get_elem_ptr.index);
|
||
|
||
// 计算元素大小
|
||
scc_hir_type_t *ptr_ty = scc_hir_module_get_type_by_value(
|
||
ctx->hir_module, value->data.get_elem_ptr.src_addr);
|
||
scc_hir_type_t *elem_ty = nullptr;
|
||
if (ptr_ty->tag == SCC_HIR_TYPE_PTR) {
|
||
elem_ty = scc_hir_module_get_type(ctx->hir_module,
|
||
ptr_ty->data.pointer.base);
|
||
} else if (ptr_ty->tag == SCC_HIR_TYPE_ARRAY) {
|
||
elem_ty = scc_hir_module_get_type(ctx->hir_module,
|
||
ptr_ty->data.array.base);
|
||
}
|
||
Assert(elem_ty != nullptr);
|
||
int elem_size = 0;
|
||
// 简化:仅处理基本类型
|
||
if (elem_ty->tag == SCC_HIR_TYPE_i32 ||
|
||
elem_ty->tag == SCC_HIR_TYPE_u32)
|
||
elem_size = 4;
|
||
else if (elem_ty->tag == SCC_HIR_TYPE_i64 ||
|
||
elem_ty->tag == SCC_HIR_TYPE_u64)
|
||
elem_size = 8;
|
||
else if (elem_ty->tag == SCC_HIR_TYPE_i8 ||
|
||
elem_ty->tag == SCC_HIR_TYPE_u8)
|
||
elem_size = 1;
|
||
else if (elem_ty->tag == SCC_HIR_TYPE_ARRAY)
|
||
elem_size = 8; // FIXME ptr size
|
||
else
|
||
Panic("unsupported element type for getelemptr");
|
||
|
||
// 构造地址表达式:base + index * elem_size
|
||
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_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;
|
||
case SCC_HIR_VALUE_TAG_ALLOC: {
|
||
// alloca 指令:分配栈空间
|
||
scc_hir_type_t *alloc_ty =
|
||
scc_hir_module_get_type(ctx->hir_module, ty->data.pointer.base);
|
||
// 计算大小和对齐(简化)
|
||
int alloc_size = 8; // 默认
|
||
if (alloc_ty->tag == SCC_HIR_TYPE_i32)
|
||
alloc_size = 4;
|
||
scc_lir_instr_t instr = {.op = SCC_LIR_ALLOCA,
|
||
.size = SCC_LIR_SIZE_64,
|
||
.to = SCC_LIR_VREG(dst_vreg),
|
||
.metadata.alloca = {alloc_size, alloc_size}};
|
||
scc_lir_builder_add_instr(ctx, &instr);
|
||
} 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);
|
||
int arg_count = scc_vec_size(value->data.call.args);
|
||
scc_lir_val_t *lir_args = scc_malloc(sizeof(scc_lir_val_t) * arg_count);
|
||
for (int i = 0; i < arg_count; i++) {
|
||
scc_hir_value_ref_t arg_ref = scc_vec_at(value->data.call.args, i);
|
||
lir_args[i] = ir_value_to_lir_operand(ctx, arg_ref);
|
||
}
|
||
|
||
scc_lir_instr_t instr = {
|
||
.op = SCC_LIR_CALL,
|
||
.size = size,
|
||
.to = SCC_LIR_VREG(dst_vreg),
|
||
.metadata.call = {.callee = callee->name,
|
||
.args = lir_args,
|
||
.arg_count = arg_count,
|
||
.ret_vreg = SCC_LIR_VREG(dst_vreg),
|
||
.clobber_mask = 0}};
|
||
scc_lir_builder_add_instr(ctx, &instr);
|
||
// 注意:lir_args 内存将随指令结构体复制到基本块向量中,但
|
||
// metadata.call.args 指针仍指向 malloc 内存,
|
||
// 这会导致内存泄漏。实际实现中应使用 arena
|
||
// 分配或随函数释放。此处为示例简化。
|
||
} break;
|
||
case SCC_HIR_VALUE_TAG_BRANCH: {
|
||
scc_lir_val_t cond =
|
||
ir_value_to_lir_operand(ctx, value->data.branch.cond);
|
||
scc_lir_instr_t instr = {
|
||
.op = SCC_LIR_BR,
|
||
.arg0 = cond,
|
||
.metadata.br = {value->data.branch.true_bblock,
|
||
value->data.branch.false_bblock}};
|
||
scc_lir_builder_add_instr(ctx, &instr);
|
||
} 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;
|
||
case SCC_HIR_VALUE_TAG_RET: {
|
||
scc_lir_val_t ret_val;
|
||
if (value->data.ret.ret_val != SCC_HIR_REF_nullptr) {
|
||
ret_val = ir_value_to_lir_operand(ctx, value->data.ret.ret_val);
|
||
} else {
|
||
ret_val = SCC_LIR_NONE();
|
||
}
|
||
scc_lir_instr_t instr = {.op = SCC_LIR_RET,
|
||
.metadata.ret_val = ret_val};
|
||
scc_lir_builder_add_instr(ctx, &instr);
|
||
} break;
|
||
case SCC_HIR_VALUE_TAG_CONV: {
|
||
// 类型转换:使用 MOV 指令配合扩展/截断
|
||
scc_lir_val_t src =
|
||
ir_value_to_lir_operand(ctx, value->data.conv.operand);
|
||
scc_lir_ext_t conv_ext = SCC_LIR_EXT_NONE;
|
||
if (value->data.conv.conv_type == CONV_SEXT)
|
||
conv_ext = SCC_LIR_EXT_SEXT;
|
||
else if (value->data.conv.conv_type == CONV_ZEXT)
|
||
conv_ext = SCC_LIR_EXT_ZEXT;
|
||
// TRUNC 用 NONE 即可(MOV 截断)
|
||
scc_lir_instr_t instr = {.op = SCC_LIR_MOV,
|
||
.size = size,
|
||
.ext = conv_ext,
|
||
.to = SCC_LIR_VREG(dst_vreg),
|
||
.arg0 = src};
|
||
scc_lir_builder_add_instr(ctx, &instr);
|
||
} break;
|
||
default:
|
||
// 不生成指令的节点(如 CONST_INT, FUNC_ARG_REF)不会调用本函数
|
||
break;
|
||
}
|
||
}
|
||
|
||
static void translate_func(ir2lir_ctx_t *ctx, scc_hir_func_t *ir_func) {
|
||
scc_hir_func_meta_t *func_meta = SCC_HIR_FUNC_META(ir_func);
|
||
|
||
scc_lir_func_meta_t *lir_func_meta =
|
||
scc_malloc(sizeof(scc_lir_func_meta_t));
|
||
Assert(lir_func_meta != nullptr);
|
||
*lir_func_meta = (scc_lir_func_meta_t){
|
||
.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;
|
||
ir_func->meta = lir_func_meta;
|
||
|
||
// 预先为所有参数分配虚拟寄存器
|
||
scc_vec_foreach(func_meta->params, i) {
|
||
scc_hir_value_ref_t param_ref = scc_vec_at(func_meta->params, i);
|
||
get_vreg_for_value(ctx, param_ref);
|
||
}
|
||
|
||
scc_vec_foreach(ir_func->bblocks, i) {
|
||
scc_hir_bblock_ref_t bb_ref = scc_vec_at(ir_func->bblocks, i);
|
||
scc_hir_bblock_t *bb =
|
||
scc_hir_module_get_bblock(ctx->hir_module, bb_ref);
|
||
|
||
scc_vec_init(ctx->instrs);
|
||
|
||
// 翻译指令
|
||
scc_vec_foreach(bb->values, j) {
|
||
scc_hir_value_ref_t val_ref =
|
||
scc_vec_at(*SCC_HIR_BBLOCK_VALUES(bb), j);
|
||
scc_hir_value_t *val =
|
||
scc_hir_module_get_value(ctx->hir_module, val_ref);
|
||
translate_hir_value(ctx, val, val_ref);
|
||
}
|
||
|
||
bb->values = *(scc_cfg_value_vec_t *)&ctx->instrs;
|
||
// MOVE
|
||
scc_vec_init(ctx->instrs);
|
||
}
|
||
|
||
// 清理本次函数翻译的临时映射
|
||
scc_hashtable_drop(&ctx->value_to_vreg);
|
||
}
|
||
|
||
void scc_hir2lir(scc_lir_module_t *module, scc_hir_cprog_t *cprog) {
|
||
Assert(module != nullptr && cprog != nullptr);
|
||
|
||
// FIXME
|
||
module->cfg_module = cprog->module.cfg_module;
|
||
|
||
ir2lir_ctx_t ctx;
|
||
ir2lir_ctx_init(&ctx, module, &cprog->module);
|
||
|
||
// 1. 处理全局变量
|
||
for (usize i = 0; i < scc_vec_size(cprog->global_vals); i++) {
|
||
scc_hir_value_ref_t gv_ref = scc_vec_at(cprog->global_vals, i);
|
||
scc_hir_value_t *galloc =
|
||
scc_hir_module_get_value(&cprog->module, gv_ref);
|
||
Assert(galloc->tag == SCC_HIR_VALUE_TAG_GLOBAL_ALLOC);
|
||
scc_hir_value_t *val = scc_hir_module_get_value(
|
||
&cprog->module, galloc->data.global_alloc.value);
|
||
scc_hir_buffer_t *data = &val->data.const_array.fields;
|
||
scc_lir_symbol_id_t id = scc_lir_module_add_data(
|
||
module, galloc->name, SCC_CFG_SYMBOL_KIND_DATA,
|
||
scc_vec_unsafe_get_data(*data), scc_vec_size(*data), 0);
|
||
Assert(id != SCC_CFG_ID_nullptr);
|
||
}
|
||
|
||
// 2. 处理函数声明 (外部函数)
|
||
for (usize i = 0; i < scc_vec_size(cprog->func_decls); i++) {
|
||
scc_hir_func_ref_t func_ref = scc_vec_at(cprog->func_decls, i);
|
||
scc_hir_func_t *func =
|
||
scc_hir_module_get_func(&cprog->module, func_ref);
|
||
if (!func)
|
||
continue;
|
||
scc_lir_symbol_id_t id =
|
||
scc_lir_module_add_func_decl(module, func->name);
|
||
Assert(id != SCC_CFG_ID_nullptr);
|
||
// 记录映射,供调用时使用
|
||
scc_hashtable_set(&ctx.func_decl_map, (void *)(uintptr_t)func_ref,
|
||
(void *)func->name);
|
||
}
|
||
|
||
// 3. 处理函数定义
|
||
for (usize i = 0; i < scc_vec_size(cprog->func_defs); i++) {
|
||
scc_hir_func_ref_t func_ref = scc_vec_at(cprog->func_defs, i);
|
||
scc_hir_func_t *func =
|
||
scc_hir_module_get_func(&cprog->module, func_ref);
|
||
if (!func)
|
||
continue;
|
||
translate_func(&ctx, func);
|
||
}
|
||
|
||
ir2lir_ctx_drop(&ctx);
|
||
}
|