- 在 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 文件生成中的空指针检查问题
120 lines
4.3 KiB
C
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, §_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, §_code);
|
|
sccf_builder_add_data_section(builder, §_data);
|
|
}
|