Files
scc/libs/mcode/include/x86/scc_x86_encode.h
zzy d78b91894e refactor(ast2ir): 提取模块访问函数并优化类型大小计算
- 添加 scc_ast2ir_mir_module 内联函数统一访问模块
- 替换所有直接访问 ctx->builder.cprog->module 的地方
- 移除重复的 scc_hir_type_size 函数实现
- 添加 scc_hir_module_type_size 函数到模块接口
- 更新所有类型大小计算调用使用新函数

feat(hir): 增强构建器安全性和全局变量处理

- 为 scc_hir_builder_integer 添加空指针检查断言
- 修复 scc_hir_builder_global_alloca 中全局变量类型设置
- 改进 scc_hir_builder_get_elem_ptr 处理空指针索引情况
- 重构字符串常量生成使用 get_elem_ptr 构建器函数

refactor(lir): 简化地址表达式表示并增强内置函数支持

- 移除复杂地址结构体 scc_lir_addr_t
- 简化 scc_lir_instr 结构体中的地址表示
- 移除 STORE_ADDR 操作码
- 添加 memcpy 和 memset 内置函数操作码
- 在符号元数据中使用联合体替代嵌套结构体

feat(hir2lir): 完善 HIR 到 LIR 转换中的内置函数处理

- 添加 ensure_vreg 辅助函数确保虚拟寄存器操作数
- 正确处理全局变量地址符号引用
- 优化 GET_ELEM_PTR 转换使用类型大小计算
- 完整实现所有内置函数(BUILTIN)的 LIR 转换
- 包括 memcpy、memset、va_start、va_arg、va_end、va_copy 等
2026-05-22 15:15:18 +08:00

139 lines
4.2 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;
};
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__ */