- 修改x86_64_isel.h接口,将func_meta替换为func指针,并添加新的isel函数原型 - 添加x86_64_reg_alloc.h头文件,提供架构特定的寄存器分配操作填充函数 - 更新frame_layout.h定义frame_layout上下文结构 - 重构reg_alloc.h中的寄存器分配操作结构体,将ops从指针改为值类型, 并将mark_reg_unused重命名为clean_mark_regs - 扩展scc_mir.h中的函数元数据,添加vregs_count字段和虚拟寄存器管理函数 - 重新定义MIR pass阶段枚举,添加FRAME_LAYOUT和PROLOGUE_EPILOGUE阶段 - 添加win64目标相关头文件和实现,提供Windows x64 ABI降低和寄存器分配填充 - 更新虚拟寄存器表示格式从$到%,修复alloca指令处理 - 重构寄存器分配算法,改进虚拟寄存器到物理寄存器/栈槽的映射机制 - 完善MIR pass调度,支持多阶段处理流程
84 lines
2.7 KiB
C
84 lines
2.7 KiB
C
#include <arch/x86_64_isel.h>
|
|
#include <arch/x86_64_reg_alloc.h>
|
|
|
|
static void x86_emit_spill(scc_mir_instr_vec_t *ctx, int preg, int slot) {
|
|
scc_mir_instr_t ins = {
|
|
.opcode = SCC_X86_IFORM_MOV_MEMV_GPRV,
|
|
.num_operands = 2,
|
|
.operands = {{.kind = SCC_MIR_OP_MEM, .stack_slot = slot},
|
|
{.kind = SCC_MIR_OP_PREG, .preg = preg}}};
|
|
scc_vec_push(*ctx, ins);
|
|
}
|
|
|
|
static void x86_emit_reload(scc_mir_instr_vec_t *ctx, int preg, int slot) {
|
|
scc_mir_instr_t ins = {
|
|
.opcode = SCC_X86_IFORM_MOV_GPRV_MEMV,
|
|
.num_operands = 2,
|
|
.operands = {{.kind = SCC_MIR_OP_PREG, .preg = preg},
|
|
{.kind = SCC_MIR_OP_MEM, .stack_slot = slot}}};
|
|
scc_vec_push(*ctx, ins);
|
|
}
|
|
|
|
static void x86_emit_copy(scc_mir_instr_vec_t *ctx, int dst_preg, int src_preg,
|
|
int size) {
|
|
scc_mir_instr_t ins = {
|
|
.opcode = SCC_X86_IFORM_MOV_GPRV_GPRV_89,
|
|
.num_operands = 2,
|
|
.operands = {{.kind = SCC_MIR_OP_PREG, .preg = dst_preg},
|
|
{.kind = SCC_MIR_OP_PREG, .preg = src_preg}}};
|
|
scc_vec_push(*ctx, ins);
|
|
}
|
|
|
|
/* ---- 临时寄存器 ---- */
|
|
static int x86_acquire_temp_reg(void *vctx) { return SCC_X86_REG_R11; }
|
|
|
|
static void x86_release_temp_reg(void *vctx, int preg) { /* 简单模式无需操作 */
|
|
}
|
|
|
|
/* ---- 操作数读写属性 ---- */
|
|
static scc_op_access_t x86_get_operand_access(void *vctx, int opcode,
|
|
int op_idx) {
|
|
switch (opcode) {
|
|
default:
|
|
return SCC_REG_ALLOC_OP_ACCESS_READWRITE; // 保守
|
|
}
|
|
}
|
|
|
|
/* ---- 隐式寄存器 ---- */
|
|
static void x86_get_implicit_regs(void *vctx, int opcode, const int **uses,
|
|
const int **defs) {
|
|
static const int empty[] = {-1};
|
|
static const int rax[] = {SCC_X86_REG_RAX, -1};
|
|
static const int rdx[] = {SCC_X86_REG_RDX, -1};
|
|
static const int rax_rdx[] = {SCC_X86_REG_RAX, SCC_X86_REG_RDX, -1};
|
|
static const int cl[] = {SCC_X86_REG_CL, -1};
|
|
|
|
switch (opcode) {
|
|
case SCC_X86_IFORM_IDIV_GPRV:
|
|
case SCC_X86_IFORM_DIV_GPRV:
|
|
*uses = rax_rdx;
|
|
*defs = rax_rdx;
|
|
break;
|
|
case SCC_X86_IFORM_CQO:
|
|
*uses = rax;
|
|
*defs = rax_rdx;
|
|
break;
|
|
case SCC_X86_IFORM_SAR_GPRV_CL:
|
|
*uses = cl;
|
|
*defs = empty;
|
|
break;
|
|
default:
|
|
*uses = empty;
|
|
*defs = empty;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void scc_reg_alloc_fill_arch_x86(scc_reg_alloc_op_t *ops) {
|
|
ops->emit_spill = x86_emit_spill;
|
|
ops->emit_reload = x86_emit_reload;
|
|
ops->emit_copy = x86_emit_copy;
|
|
ops->get_operand_access = x86_get_operand_access;
|
|
ops->get_implicit_regs = x86_get_implicit_regs;
|
|
}
|