Files
scc/libs/mcode/include/x86/scc_x86_encode.h
zzy 31d7e91ef1 refactor(ast2ir): 重构ABI类型系统并修复union结构问题
- 将scc_ast_def.h中的attr_of从union改为struct以修复结构定义问题
- 添加type_abi依赖到ast2ir模块的cbuild.toml配置文件中
- 重命名scc_ast2ir.h中的abi字段为type_abi,并更新相关初始化函数签名
- 移除废弃的scc_abi_type.h和相关平台ABI头文件
- 添加辅助函数is_variadic_marker和fixed_param_count用于处理可变参数
- 添加数组和聚合类型初始化的辅助函数
2026-06-01 12:14:13 +08:00

166 lines
4.9 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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;
};
u8 size_bits;
} scc_x86_operand_value_t;
static inline scc_x86_operand_value_t scc_x86_op_preg(scc_x86_reg_t reg,
u8 size_bits) {
scc_x86_operand_value_t o = {
.kind = SCC_X86_OPR_REG,
.reg = reg,
.size_bits = size_bits,
};
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, u8 size_bits) {
scc_x86_operand_value_t o = {
.kind = SCC_X86_OPR_REG,
.reg = scc_x86_op_vreg_reg(vreg),
.size_bits = size_bits,
};
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,
.size_bits = 32,
};
return o;
}
static inline scc_x86_operand_value_t scc_x86_op_imm(i64 imm, u8 size_bits) {
scc_x86_operand_value_t o = {
.kind = SCC_X86_OPR_IMM,
.simm0 = imm,
.size_bits = size_bits,
};
return o;
}
static inline scc_x86_operand_value_t scc_x86_op_mem(scc_x86_mem_t mem,
u8 size_bits) {
scc_x86_operand_value_t o = {
.kind = SCC_X86_OPR_MEM,
.mem = mem,
.size_bits = size_bits,
};
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;
op.size_bits = 0;
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;
op.size_bits = 32;
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;
op.size_bits = 32;
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;
op.size_bits = 32;
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
op.size_bits = 0;
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);
scc_x86_iform_t scc_x86_iclass_to_iform(scc_x86_iclass_t iclass,
const scc_x86_operand_value_t *ops,
int num_ops);
#endif /* __SCC_X86_ENCODE_H__ */