Files
scc/libs/ir2mcode/src/scc_ir2sccf.c
zzy aa8a1ff8ce feat(compiler): 启用 ir2mcode 和 sccf2target 库并实现 x86_64 代码生成
- 在 cbuild.toml 中启用 ir2mcode 和 sccf2target 依赖库
- 修改 justfile 中的构建命令,使用 release 模式并更新 tokei 统计排除 mcode 目录
- 重构 LIR 中的地址操作数类型,将 SCC_LIR_INSTR_KIND_ADDR 重命名为 SCC_LIR_INSTR_KIND_MEM
- 实现完整的 MIR 到 x86_64 机器码转换,包括:
  - 添加 move、compare、binary operation 等指令发射函数
  - 实现条件分支和跳转指令生成
  - 支持算术、逻辑、移位等基本操作
  - 添加调用和返回指令处理
  - 实现栈分配和寄存器分配功能
- 完善 ir2mcode 模块,将 MIR 指令转换为机器码
- 更新 ir2sccf 模块,集成机器码生成功能
- 添加 mcode 库的架构支持和内存管理功能
- 修复 PE 文件生成中的空指针检查问题
2026-05-05 15:59:31 +08:00

120 lines
4.3 KiB
C

#include <scc_ir2sccf.h>
static inline void scc_ir_sym_to_sccf_sym(const scc_cfg_symbol_t *symbol,
sccf_sym_t *sym) {
switch (symbol->kind) {
case SCC_CFG_SYMBOL_KIND_DATA:
sym->sccf_sym_type = SCCF_SYM_TYPE_DATA;
break;
case SCC_CFG_SYMBOL_KIND_FUNC:
sym->sccf_sym_type = SCCF_SYM_TYPE_FUNC;
break;
case SCC_CFG_SYMBOL_KIND_EXTERN:
sym->sccf_sym_type = SCCF_SYM_TYPE_EXTERN;
break;
}
switch (symbol->linkage) {
case SCC_CFG_SYMBOL_LINK_GLOABL:
sym->sccf_sym_bind = SCCF_SYM_BIND_GLOBAL;
break;
case SCC_CFG_SYMBOL_LINK_LOCAL:
sym->sccf_sym_bind = SCCF_SYM_BIND_LOCAL;
break;
default:
break;
}
}
static inline void scc_ir_symbol_to_sect_data(const scc_cfg_symbol_t *symbol,
sccf_sect_data_t *sect_data) {
// scc_vec_foreach(value->data.const_array.fields, j) {
// scc_vec_push(ctx->sect_data,
// scc_vec_at(value->data.const_array.fields, j));
// }
}
void scc_ir2sccf(sccf_builder_t *builder, scc_mir_module_t *mir_module) {
// mir_module->symbol_metas
// mir_module->cfg_module.funcs
sccf_builder_init(builder);
sccf_sect_data_t sect_data;
scc_vec_init(sect_data);
scc_vec_foreach(mir_module->cfg_module.symbols, i) {
scc_cfg_symbol_t *symbol =
&scc_vec_at(mir_module->cfg_module.symbols, i);
if (symbol->name == nullptr) {
LOG_ERROR("Symbol name is null");
continue;
}
sccf_sym_t sym = (sccf_sym_t){
.sccf_sect_offset = scc_vec_size(sect_data),
.sccf_sym_size =
4, // FIXME on windows using rel32, on linux using ?
};
scc_ir_sym_to_sccf_sym(symbol, &sym);
scc_ir_symbol_to_sect_data(symbol, &sect_data);
usize sym_idx = sccf_builder_add_symbol(builder, symbol->name, &sym);
Assert(sym_idx != 0);
}
sccf_sect_data_t sect_code = {0};
scc_vec_init(sect_code);
scc_mcode_t mcode = {0};
scc_mcode_init(&mcode, SCC_MCODE_ARCH_X86_64);
scc_vec_foreach(mir_module->cfg_module.funcs, i) {
if (i == 0)
continue;
scc_mir_func_t *func = &scc_vec_at(mir_module->cfg_module.funcs, i);
sccf_sym_t *sym = sccf_builder_get_symbol_unsafe(builder, func->name);
Assert(sym != nullptr);
sym->sccf_sect_offset = scc_vec_size(mcode.mcode);
scc_vec_foreach(func->bblocks, i) {
scc_cfg_bblock_id_t id = scc_vec_at(func->bblocks, i);
const scc_cfg_bblock_t *bb =
scc_cfg_module_unsafe_get_bblock(&mir_module->cfg_module, id);
scc_mir_instr_vec_t *instrs = SCC_MIR_BBLOCK_VALUES(bb);
scc_vec_foreach(*instrs, i) {
const scc_mir_instr_t *ins = &scc_vec_at(*instrs, i);
// FIXME reloc symbol needed
scc_ir2mcode_emit_instr(&mcode, ins);
}
}
}
scc_vec_unsafe_from_buffer(sect_code, scc_vec_unsafe_get_data(mcode.mcode),
scc_vec_size(mcode.mcode));
// u8 *buf = scc_vec_unsafe_get_data(ctx->sect_mcode.mcode);
// scc_vec_foreach(ctx->builder->relocs, i) {
// sccf_reloc_t *reloc = &scc_vec_at(ctx->builder->relocs, i);
// if (reloc->sym_idx == 0) {
// Panic("relocate to an invalid symbol");
// }
// sccf_sym_t *sym = &scc_vec_at(ctx->builder->symtab, reloc->sym_idx);
// if (sym->sccf_sym_type != SCCF_SYM_TYPE_EXTERN) {
// Assert(reloc->reloc_type == SCCF_RELOC_TYPE_REL);
// if (sym->sccf_sect_type == SCCF_SECT_CODE &&
// sym->sccf_sym_type == SCCF_SYM_TYPE_FUNC) {
// i64 target_off = sym->sccf_sect_offset;
// i64 next_off = reloc->offset + reloc->addend;
// i32 rel = (i32)(target_off - next_off);
// // FIXME 写入到指令的偏移字段(小端)
// *(i32 *)(&buf[reloc->offset]) = rel;
// reloc->reloc_type = SCCF_RELOC_TYPE_EMPTY;
// }
// }
// }
sccf_builder_add_text_section(builder, &sect_code);
sccf_builder_add_data_section(builder, &sect_data);
}