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

@@ -5,30 +5,91 @@
#include <arch/scc_x86_mir.h>
#include <x86/scc_x86_encode.h>
#include <x86/scc_x86_iform.h>
#include <x86/scc_x86_patch.h>
#include <x86/scc_x86_reg.h>
void mir_x86_to_mcode(scc_mcode_t *mcode, const scc_mir_x86_instr_t *_ins) {
void mir_x86_to_mcode(scc_mcode_t *mcode, scc_reloc_vec_t *relocs,
const scc_mir_x86_instr_t *_ins) {
Assert(mcode != nullptr && _ins != nullptr);
int skip_reloc = relocs == nullptr;
scc_x86_instr_t *ins = (void *)_ins;
if (ins->opcode < 0 || ins->opcode >= SCC_X86_IFORM_COUNT) {
return;
}
scc_x86_operand_value_t ops[8] = {0};
scc_reloc_t reloc = {0};
for (int i = 0; i < ins->num_operands; i++) {
if (scc_x86_op_is_vreg(&ins->operands[i]))
scc_x86_operand_value_t *op_ptr = &ins->operands[i];
if (scc_x86_op_is_vreg(op_ptr))
Panic("can't convert vreg to mcode");
if (scc_x86_op_is_slot(&ins->operands[i]))
if (scc_x86_op_is_slot(op_ptr))
Panic("can't convert unresolved slot to mcode");
ops[i] = ins->operands[i];
ops[i] = *op_ptr;
if (op_ptr->kind == SCC_X86_OPR_RELOC) {
ops[i].kind = op_ptr->reloc.kind;
switch (op_ptr->reloc.kind) {
case SCC_X86_OPR_RELBR:
ops[i].imm0 = 0;
break;
default:
TODO();
break;
}
if (skip_reloc) {
continue;
}
if (skip_reloc != SCC_RELOC_TARGET_NONE) {
LOG_FATAL("can't using twice reloc in one instr");
continue;
}
reloc.addend = op_ptr->reloc.addend;
reloc.arch_type = (int)op_ptr->reloc.kind;
reloc.size = 0;
reloc.offset = scc_mcode_size(mcode);
if (op_ptr->reloc.target == SCC_X86_RELOC_TARGET_SYMBOL) {
reloc.target_kind = SCC_RELOC_TARGET_SYMBOL;
reloc.symbol = op_ptr->reloc.global_name;
} else if (op_ptr->reloc.target == SCC_X86_RELOC_TARGET_BBLOCK) {
reloc.target_kind = SCC_RELOC_TARGET_BBLOCK;
reloc.bblock_id = op_ptr->reloc.bblock_id;
} else {
TODO();
}
}
}
scc_x86_encode_inst(mcode, ins->opcode, ops);
if (!skip_reloc && reloc.target_kind != SCC_RELOC_TARGET_NONE) {
reloc.offset = scc_mcode_size(mcode);
scc_vec_push(*relocs, reloc);
}
}
void scc_ir2mcode_emit_instr(scc_mcode_t *mcode,
void mir_x86_patch(scc_mcode_t *mcode, scc_reloc_t *reloc, i64 value) {
// return;
scc_x86_patch_type_t patch_type = SCC_X86_PATCH_NONE;
switch (reloc->arch_type) {
case SCC_X86_OPR_RELBR:
patch_type = SCC_X86_PATCH_PC32;
break;
default:
Panic("unsupported reloc type");
break;
}
scc_x86_patch(mcode, patch_type, reloc->offset + reloc->addend, value);
}
void scc_ir2mcode_emit_instr(scc_mcode_t *mcode, scc_reloc_vec_t *relocs,
const scc_mir_instr_t *mir_instr) {
mir_x86_to_mcode(mcode, (const scc_mir_x86_instr_t *)mir_instr);
mir_x86_to_mcode(mcode, relocs, (const scc_mir_x86_instr_t *)mir_instr);
}
void scc_ir2mcode(scc_mcode_t *mcode, const scc_mir_module_t *mir_module) {
void scc_ir2mcode_patch(scc_mcode_t *mcode, scc_reloc_t *reloc, i64 value) {
mir_x86_patch(mcode, reloc, value);
}
void scc_ir2mcode(scc_mcode_t *mcode, scc_reloc_vec_t *relocs,
const scc_mir_module_t *mir_module) {
Assert(mir_module != nullptr && mcode != nullptr);
scc_vec_foreach(mir_module->cfg_module.funcs, i) {
if (i == 0)
continue;
@@ -42,7 +103,7 @@ void scc_ir2mcode(scc_mcode_t *mcode, const scc_mir_module_t *mir_module) {
scc_vec_foreach(*instrs, i) {
const scc_mir_instr_t *ins =
scc_vec_sized_at_ptr(*instrs, mir_module->instr_size, i);
scc_ir2mcode_emit_instr(mcode, ins);
scc_ir2mcode_emit_instr(mcode, relocs, ins);
}
}
}