#ifndef __SCC_X86_MIR_H__ #define __SCC_X86_MIR_H__ #include "../scc_mir.h" #include #include #include #include #include typedef struct { int opcode; uint8_t num_operands; scc_x86_operand_value_t operands[6]; scc_pos_t src_loc; } scc_x86_instr_t; // x86 后端指令:首字段 int opcode(正 = scc_x86_iform_t,负 = 伪指令) typedef union scc_mir_x86_instr { scc_mir_instr_t instr; scc_x86_instr_t x86_instr; } scc_mir_x86_instr_t; typedef SCC_VEC(scc_mir_x86_instr_t) scc_mir_x86_instr_vec_t; // ── 基本块 values 强制转换 ────────────────────────────────────────────── #define SCC_MIR_X86_BBLOCK_INSTRS(bb) ((scc_mir_x86_instr_vec_t *)&bb->values) #define SCC_MIR_X86_BBLOCK_INSTRS_C(bb) \ ((const scc_mir_x86_instr_vec_t *)&bb->values) // ── vreg 编码 ────────────────────────────────────────────────────────── static inline bool scc_x86_op_is_vreg(const scc_x86_operand_value_t *op) { return op->kind == SCC_X86_OPR_REG && (int)op->reg >= (int)SCC_X86_REG_COUNT; } static inline int scc_x86_op_get_vreg(const scc_x86_operand_value_t *op) { return (int)op->reg - (int)SCC_X86_REG_COUNT; } static inline void scc_x86_op_set_preg(scc_x86_operand_value_t *op, scc_x86_reg_t preg) { op->kind = SCC_X86_OPR_REG; op->reg = preg; } // slot_id 编码为 base=INVALID, disp=slot_id static inline scc_x86_operand_value_t scc_x86_op_slot(int slot_id) { scc_x86_operand_value_t o = {.kind = SCC_X86_OPR_MEM}; o.mem.base = SCC_X86_REG_INVALID; o.mem.index = SCC_X86_REG_INVALID; o.mem.scale = 1; o.mem.disp.displacement = slot_id; o.mem.disp.displacement_bits = 0; return o; } static inline bool scc_x86_op_is_slot(const scc_x86_operand_value_t *op) { return op->kind == SCC_X86_OPR_MEM && op->mem.base == SCC_X86_REG_INVALID; } static inline int scc_x86_op_slot_id(const scc_x86_operand_value_t *op) { return op->mem.disp.displacement; } static inline void scc_mir_x86_instr_0(scc_mir_x86_instr_t *out, int opcode, scc_pos_t pos) { out->x86_instr.opcode = opcode; out->x86_instr.num_operands = 0; out->x86_instr.src_loc = pos; } static inline void scc_mir_x86_instr_1(scc_mir_x86_instr_t *out, int opcode, scc_x86_operand_value_t op0, scc_pos_t pos) { out->x86_instr.opcode = opcode; out->x86_instr.num_operands = 1; out->x86_instr.operands[0] = op0; out->x86_instr.src_loc = pos; } static inline void scc_mir_x86_instr_2(scc_mir_x86_instr_t *out, int opcode, scc_x86_operand_value_t op0, scc_x86_operand_value_t op1, scc_pos_t pos) { out->x86_instr.opcode = opcode; out->x86_instr.num_operands = 2; out->x86_instr.operands[0] = op0; out->x86_instr.operands[1] = op1; out->x86_instr.src_loc = pos; } static inline void scc_mir_x86_instr_3(scc_mir_x86_instr_t *out, int opcode, scc_x86_operand_value_t op0, scc_x86_operand_value_t op1, scc_x86_operand_value_t op2, scc_pos_t pos) { out->x86_instr.opcode = opcode; out->x86_instr.num_operands = 3; out->x86_instr.operands[0] = op0; out->x86_instr.operands[1] = op1; out->x86_instr.operands[2] = op2; out->x86_instr.src_loc = pos; } #endif /* __SCC_X86_MIR_H__ */