#include #include 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; }