#ifndef __SCC_X86_ENCODE_H__ #define __SCC_X86_ENCODE_H__ #include "../scc_mcode.h" #include "scc_x86_iform.h" #include "scc_x86_reg.h" typedef struct { i64 displacement; u32 displacement_bits; } scc_x86_disp_t; typedef struct { scc_x86_reg_t seg; scc_x86_reg_t base; scc_x86_reg_t index; u32 scale; scc_x86_disp_t disp; } scc_x86_mem_t; typedef enum { SCC_X86_RELOC_TARGET_SYMBOL, SCC_X86_RELOC_TARGET_BBLOCK, } scc_x86_reloc_target_t; typedef struct scc_x86_reloc_op { scc_x86_operand_kind_t kind; // 原始操作数类型 scc_x86_reloc_target_t target; union { i64 imm; int bblock_id; // 如果 kind == RELBR const char *global_name; // 如果 kind == SYMBOL }; i64 addend; // 额外常量偏移,用于 sym+addend } scc_x86_reloc_op_t; typedef struct { scc_x86_operand_kind_t kind; union { scc_x86_reg_t reg; i32 brdisp; i64 simm0; u64 imm0; u8 imm1; scc_x86_mem_t mem; scc_x86_reloc_op_t reloc; }; usize size; } scc_x86_operand_value_t; static inline scc_x86_operand_value_t scc_x86_op_preg(scc_x86_reg_t reg) { scc_x86_operand_value_t o = {.kind = SCC_X86_OPR_REG, .reg = reg}; return o; } static inline scc_x86_reg_t scc_x86_op_vreg_reg(int vreg) { return (int)SCC_X86_REG_COUNT + vreg; } static inline scc_x86_operand_value_t scc_x86_op_vreg(int vreg) { scc_x86_operand_value_t o = { .kind = SCC_X86_OPR_REG, .reg = scc_x86_op_vreg_reg(vreg), }; return o; } static inline scc_x86_operand_value_t scc_x86_op_relbr(i32 rel) { scc_x86_operand_value_t o = {.kind = SCC_X86_OPR_RELBR, .brdisp = rel}; return o; } static inline scc_x86_operand_value_t scc_x86_op_imm(i64 imm) { scc_x86_operand_value_t o = {.kind = SCC_X86_OPR_IMM, .simm0 = imm}; return o; } static inline scc_x86_operand_value_t scc_x86_op_mem(scc_x86_mem_t mem) { scc_x86_operand_value_t o = {.kind = SCC_X86_OPR_MEM, .mem = mem}; return o; } // 1. 全局符号重定位(绝对地址加载:MOV reg, imm32/64) static inline scc_x86_operand_value_t scc_x86_op_reloc_global_imm(const char *sym, i64 addend) { scc_x86_operand_value_t op = {.kind = SCC_X86_OPR_RELOC}; op.reloc.kind = SCC_X86_OPR_IMM; op.reloc.target = SCC_X86_RELOC_TARGET_SYMBOL; op.reloc.global_name = sym; op.reloc.addend = addend; return op; } static inline scc_x86_operand_value_t scc_x86_op_reloc_global_relrip(const char *sym, i64 addend) { scc_x86_operand_value_t op = {.kind = SCC_X86_OPR_RELOC}; op.reloc.kind = SCC_X86_OPR_MEM; op.reloc.target = SCC_X86_RELOC_TARGET_SYMBOL; op.reloc.global_name = sym; op.reloc.addend = addend; return op; } // 2. 全局符号重定位(相对跳转/调用:CALL/JMP rel32) static inline scc_x86_operand_value_t scc_x86_op_reloc_global_relbr(const char *sym, i64 addend) { scc_x86_operand_value_t op = {.kind = SCC_X86_OPR_RELOC}; op.reloc.kind = SCC_X86_OPR_RELBR; op.reloc.target = SCC_X86_RELOC_TARGET_SYMBOL; op.reloc.global_name = sym; op.reloc.addend = addend; return op; } // 3. 基本块重定位(相对跳转) static inline scc_x86_operand_value_t scc_x86_op_reloc_block(int bid, i64 addend) { scc_x86_operand_value_t op = {.kind = SCC_X86_OPR_RELOC}; op.reloc.kind = SCC_X86_OPR_RELBR; op.reloc.target = SCC_X86_RELOC_TARGET_BBLOCK; op.reloc.bblock_id = bid; op.reloc.addend = addend; return op; } // 4. 如果需要支持符号的内存寻址(如 [RIP + sym]),可扩展 kind = // SCC_X86_OPR_MEM static inline scc_x86_operand_value_t scc_x86_op_reloc_global_mem(const char *sym, i64 addend) { scc_x86_operand_value_t op = {.kind = SCC_X86_OPR_RELOC}; op.reloc.kind = SCC_X86_OPR_MEM; op.reloc.target = SCC_X86_RELOC_TARGET_SYMBOL; op.reloc.global_name = sym; op.reloc.addend = addend; // 编码时需生成 RIP 相对寻址的 ModRM/SIB return op; } /* 按 iform 发射一条指令,ops 数组长度需与 iform 定义的操作数数目一致 */ int scc_x86_encode_inst(scc_mcode_t *mcode, scc_x86_iform_t iform, const scc_x86_operand_value_t *ops); #endif /* __SCC_X86_ENCODE_H__ */