Files
scc/libs/ir/lir/include/scc_lir.h
zzy ea553718f0 feat(compiler): 实现HIR到LIR的函数定义标记和直接/间接调用区分
- 在HIR函数元数据中添加defined字段来标记函数是否已定义
- 在AST到IR转换过程中设置函数定义状态
- 修改LIR模块函数声明接口以支持定义状态参数
- 实现直接调用和间接调用的区别处理,通过符号查找确定调用类型
- 更新LIR调用指令结构以支持直接和间接调用的不同表示方式
- 调整x86后端指令选择以正确处理不同类型的调用

fix(x86-isel): 优化x86指令发射和操作数大小处理

- 移除move/load/store函数中的size参数,改由操作数本身携带大小信息
- 简化x86指令操作数结构,减少操作数数量限制
- 添加专门的mov系列表单选择函数,根据操作数类型和大小自动选择正确的指令形式
- 修正间接调用的指令形式为CALL_NEAR_MEMV而非GPRV
- 添加向量版本的load/store/move发射函数

refactor(reg-alloc): 更新寄存器分配迭代器接口

- 为分配迭代器的替换方法添加size参数,以便正确处理不同大小的寄存器
2026-05-23 15:33:54 +08:00

276 lines
7.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.
/**
* @file scc_lir.h
* @brief 低层中间表示 (Low-Level IR) - 实用精简版
*
* 设计原则:
* - 依赖 scc_core.h 和 scc_utils.h (仅使用哈希表)
* - 保留所有核心功能复杂地址、并行复制、VA 支持、符号引用
* - 基本块使用稳定 ID通过哈希表快速查找
* - 预留属性位掩码 (attr),未来可扩展 align、packed、weak 等
* - 无字符串池、无类型缓存,保持简单
*/
#ifndef __SCC_LIR_H__
#define __SCC_LIR_H__
#include <scc_ap.h>
#include <scc_cfg.h>
#include <scc_core.h>
#include <scc_hashtable.h>
#include <scc_pos.h>
typedef enum scc_lir_attr {
SCC_LIR_ATTR_NONE = 0,
SCC_LIR_ATTR_STATIC = 1 << 0, // 内部链接
SCC_LIR_ATTR_WEAK = 1 << 1, // 弱符号
SCC_LIR_ATTR_VIS_HIDDEN = 1 << 2, // 符号可见性 hidden
SCC_LIR_ATTR_NOINLINE = 1 << 3,
SCC_LIR_ATTR_ALWAYSINLINE = 1 << 4,
// 对齐值可编码在 attr 的高位,例如:
// #define SCC_LIR_ATTR_ALIGN(n) (((n) << 8) | SCC_LIR_ATTR_ALIGN_FLAG)
} scc_lir_attr_t;
typedef enum {
SCC_LIR_INSTR_KIND_NONE, // 无操作数
SCC_LIR_INSTR_KIND_ARG, // 参数
SCC_LIR_INSTR_KIND_VREG, // 虚拟寄存器
// SCC_LIR_INSTR_KIND_PREG, // 物理寄存器 (后端定义编号)
SCC_LIR_INSTR_KIND_IMM, // 整数立即数
SCC_LIR_INSTR_KIND_FIMM, // 浮点立即数
SCC_LIR_INSTR_KIND_SYMBOL, // 全局符号 (函数名、全局变量、字符串常量)
SCC_LIR_INSTR_KIND_MEM, // 复杂地址表达式 (base + index*scale + offset)
} scc_lir_instr_kind_t;
typedef struct scc_lir_instr {
scc_lir_instr_kind_t kind;
union {
int arg;
int reg; // VREG 或 PREG 索引
scc_ap_t imm; // 整型立即数
f64 fimm; // 浮点立即数
const char *symbol; // 符号名 (生命周期由前端管理)
} data;
} scc_lir_val_t;
/* 构造宏 */
#define SCC_LIR_NONE() ((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_NONE})
#define SCC_LIR_VREG(n) \
((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_VREG, .data.reg = (n)})
#define SCC_LIR_IMM(v) \
((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_IMM, .data.imm = (v)})
#define SCC_LIR_FIMM(v) \
((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_FIMM, .data.fimm = (v)})
#define SCC_LIR_SYMBOL(s) \
((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_SYMBOL, .data.symbol = (s)})
#define SCC_LIR_ARG(n) \
((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_ARG, .data.arg = (n)})
#define SCC_LIR_SIZE_8 1
#define SCC_LIR_SIZE_16 2
#define SCC_LIR_SIZE_32 4
#define SCC_LIR_SIZE_64 8
typedef enum {
SCC_LIR_EXT_NONE,
SCC_LIR_EXT_SEXT,
SCC_LIR_EXT_ZEXT,
SCC_LIR_EXT_FLOAT
} scc_lir_ext_t;
typedef enum {
/* 数据移动 */
SCC_LIR_MOV,
SCC_LIR_LOAD,
SCC_LIR_LOAD_ADDR,
SCC_LIR_STORE,
/* 整数算术 */
SCC_LIR_ADD,
SCC_LIR_SUB,
SCC_LIR_MUL,
SCC_LIR_DIV_S,
SCC_LIR_DIV_U,
SCC_LIR_REM_S,
SCC_LIR_REM_U,
SCC_LIR_AND,
SCC_LIR_OR,
SCC_LIR_XOR,
SCC_LIR_SHL,
SCC_LIR_SHR,
SCC_LIR_SAR,
SCC_LIR_NEG,
SCC_LIR_NOT,
/* 浮点算术 */
SCC_LIR_FADD,
SCC_LIR_FSUB,
SCC_LIR_FMUL,
SCC_LIR_FDIV,
SCC_LIR_FNEG,
SCC_LIR_FCVT,
/* 比较 */
SCC_LIR_CMP,
/* 控制流 */
SCC_LIR_BR,
SCC_LIR_JMP,
SCC_LIR_JMP_INDIRECT,
SCC_LIR_CALL,
SCC_LIR_CALL_INDIRECT,
SCC_LIR_RET,
/* 并行复制 */
SCC_LIR_PARALLEL_COPY,
/* 可变参数 */
SCC_LIR_VA_START,
SCC_LIR_VA_ARG,
SCC_LIR_VA_END,
SCC_LIR_VA_COPY,
/* 内置方法 */
SCC_LIR_MEMCPY,
SCC_LIR_MEMSET,
/* 栈管理 */
SCC_LIR_ALLOCA,
SCC_LIR_NOP
} scc_lir_op_t;
typedef enum {
SCC_LIR_COND_EQ,
SCC_LIR_COND_NE,
SCC_LIR_COND_SLT,
SCC_LIR_COND_SLE,
SCC_LIR_COND_SGT,
SCC_LIR_COND_SGE,
SCC_LIR_COND_ULT,
SCC_LIR_COND_ULE,
SCC_LIR_COND_UGT,
SCC_LIR_COND_UGE,
SCC_LIR_COND_FEQ,
SCC_LIR_COND_FNE,
SCC_LIR_COND_FLT,
SCC_LIR_COND_FLE,
SCC_LIR_COND_FGT,
SCC_LIR_COND_FGE
} scc_lir_cond_t;
typedef scc_cfg_bblock_id_t scc_lir_bblock_id_t;
typedef struct scc_lir_ins {
scc_lir_op_t op;
u8 size;
scc_lir_ext_t ext;
scc_lir_val_t to;
scc_lir_val_t arg0;
scc_lir_val_t arg1;
/// @brief debug 信息
scc_pos_t src_loc;
union {
scc_lir_cond_t cond;
// base + index * scale + offset
struct scc_lir_addr {
int scale; // 比例因子 (1, 2, 4, 8)
i64 offset; // 常量偏移
} addr;
struct scc_lir_br {
scc_lir_bblock_id_t true_target;
scc_lir_bblock_id_t false_target;
} br;
scc_lir_bblock_id_t jmp_target;
struct scc_lir_call {
scc_lir_val_t *args;
int arg_count;
scc_lir_val_t ret_vreg;
u64 clobber_mask;
union {
const char *callee_name;
scc_lir_val_t callee_target;
};
} call;
scc_lir_val_t ret_val;
struct scc_lir_parallel_copy {
scc_lir_val_t *dests;
scc_lir_val_t *srcs;
int num_copies;
} parallel_copy;
struct scc_lir_alloca {
int size_bytes;
int align_bytes;
} alloca;
struct {
scc_lir_val_t ap;
scc_lir_val_t last;
} va_start;
struct {
scc_lir_val_t ap;
int type_size;
int type_align;
char is_float;
scc_lir_val_t to;
} va_arg;
struct {
scc_lir_val_t ap;
} va_end;
struct {
scc_lir_val_t dest;
scc_lir_val_t src;
} va_copy;
struct {
scc_lir_val_t dest;
scc_lir_val_t src;
scc_lir_val_t size;
} memcpy;
struct {
scc_lir_val_t dest;
scc_lir_val_t value;
scc_lir_val_t size;
} memset;
} metadata;
} scc_lir_instr_t;
typedef SCC_VEC(scc_lir_instr_t) scc_lir_instr_vec_t;
typedef scc_cfg_bblock_t scc_lir_bblock_t;
#define SCC_LIR_BBLOCK_VALUES(bblock) \
((scc_lir_instr_vec_t *)&((bblock)->values))
typedef scc_cfg_func_t scc_lir_func_t;
typedef struct scc_lir_func_meta {
int vregs_count;
int frame_size;
int is_va_arg;
scc_lir_attr_t attr;
} scc_lir_func_meta_t;
#define SCC_LIR_FUNC_META(func) ((scc_lir_func_meta_t *)(func)->meta)
typedef scc_cfg_symbol_id_t scc_lir_symbol_id_t;
typedef scc_cfg_symbol_t scc_lir_symbol_t;
typedef union scc_lir_symbol_meta {
struct {
scc_lir_func_t *func; // 指向函数体(若为定义)
} func;
struct {
u8 *init_data; // 初始化数据(若为 NULL 则零初始化)
usize size; // 数据大小(字节)
int align; // 对齐要求
} data;
} scc_lir_symbol_meta_t;
#define SCC_LIR_SYMBOL_META(symbol) ((scc_lir_symbol_meta_t *)(symbol)->meta)
#endif /* __SCC_LIR_H__ */