#ifndef __SCC_X86_64_ISEL_H__ #define __SCC_X86_64_ISEL_H__ #include #include #include #include #include "../core_pass/scc_abi_lowering.h" #include "../scc_mir_module.h" typedef struct scc_x86_64_isel { scc_mir_instr_vec_t instrs; scc_lir_func_meta_t *func_meta; scc_abi_lowering_t abi_lowering; } scc_x86_64_isel_t; static void add_instr(scc_x86_64_isel_t *isel, const scc_mir_instr_t *instr) { scc_vec_push(isel->instrs, *instr); } static inline void add_instr_0(scc_x86_64_isel_t *isel, scc_x86_iform_t opcode) { scc_mir_instr_t out = {.opcode = opcode, .num_operands = 0}; add_instr(isel, &out); } static inline void add_instr_1(scc_x86_64_isel_t *isel, scc_x86_iform_t opcode, scc_mir_operand_t op1) { scc_mir_instr_t out = {.opcode = opcode, .num_operands = 1}; out.operands[0] = op1; add_instr(isel, &out); } static inline void add_instr_2(scc_x86_64_isel_t *isel, scc_x86_iform_t opcode, scc_mir_operand_t op1, scc_mir_operand_t op2) { scc_mir_instr_t out = {.opcode = opcode, .num_operands = 2}; out.operands[0] = op1; out.operands[1] = op2; add_instr(isel, &out); } static inline scc_mir_operand_t reg_operand(scc_x86_reg_t reg) { return (scc_mir_operand_t){.kind = SCC_MIR_OP_PREG, .preg = reg}; } // Utils void scc_x86_emit_move(scc_x86_64_isel_t *isel, scc_mir_operand_t dst, scc_mir_operand_t src, u8 size); scc_mir_operand_t scc_x86_lir_val_to_mir_op(scc_x86_64_isel_t *isel, const scc_lir_val_t *val); static inline void emit_call(scc_x86_64_isel_t *isel, const char *callee) { scc_mir_operand_t sym = {.kind = SCC_MIR_OP_SYMBOL, .symbol = callee}; add_instr_1(isel, SCC_X86_IFORM_CALL_NEAR_GPRV, sym); } static inline void emit_ret(scc_x86_64_isel_t *isel) { add_instr_0(isel, SCC_X86_IFORM_RET_NEAR); } #endif /* __SCC_X86_64_ISEL_H__ */