feat(mir): 添加x86架构相关头文件并重构MIR指令表示

- 创建scc_x86_mir.h头文件,定义x86后端MIR指令结构和操作数构造器
- 创建scc_x86_isel.h头文件,定义x86_64指令选择器和相关工具函数
- 创建scc_x86_reg_alloc.h头文件,定义x86寄存器分配架构特定接口
- 移除旧的x86_64_isel.h和x86_64_reg_alloc.h文件
- 重构scc_mir.h中的指令表示,使用联合体存储伪指令数据
- 更新ABI lowering回调参数,使用void指针保持类型无关
- 扩展寄存器分配操作接口,添加指令信息查询和伪指令处理功能
- 更新目标文件包含路径以使用新的头文件命名
This commit is contained in:
zzy
2026-05-20 11:07:05 +08:00
parent 2c13ac54df
commit c6e3bb2e20
22 changed files with 792 additions and 788 deletions

View File

@@ -1,53 +1,29 @@
// scc_mir.h (示意)
#ifndef __SCC_MIR_H__
#define __SCC_MIR_H__
#include <scc_lir.h>
#include <scc_cfg.h>
// 伪指令 opcode负数所有后端通用约定
typedef enum {
SCC_MIR_OP_NONE,
SCC_MIR_OP_STACK_OFFSET, // 已分配的内存
SCC_MIR_OP_STACK_SLOT, // 栈空间
SCC_MIR_OP_VREG, // 虚拟寄存器
SCC_MIR_OP_PREG, // 物理寄存器
SCC_MIR_OP_IMM, // 立即数
SCC_MIR_OP_SYMBOL, // 符号地址(用于重定位)
SCC_MIR_OP_BLOCK // 基本块引用(label)
} scc_mir_op_kind_t;
typedef struct scc_mir_operand {
scc_mir_op_kind_t kind;
union {
int vreg; // 虚拟寄存器索引
int preg; // 物理寄存器
i64 imm; // 立即数
const char *symbol; // 符号名
int stack_slot; // 栈槽 ID (由 FrameLayout 分配)
int stack_offset; // 栈偏移
scc_lir_bblock_id_t block_id; // 目标基本块
};
} scc_mir_operand_t;
typedef enum {
SCC_MIR_PSUEDO_ALLOCA = -1,
} scc_mir_psuedo_op_t;
SCC_MIR_PSEUDO_NONE = 0,
SCC_MIR_PSEUDO_ALLOCA = -1,
SCC_MIR_PSEUDO_VA_START = -2,
} scc_mir_pseudo_t;
typedef struct scc_mir_instr {
int opcode; // 目标特定的指令编码 (如 X86::ADD32rr)
int num_operands; // 实际使用的操作数个数
scc_mir_operand_t
operands[8]; // 固定小数组RISC 风格指令通常不超过 4 操作数
scc_pos_t src_loc; // 调试信息 (继承自 LIR)
int opcode;
union {
struct {
int size;
int align;
int vreg;
} alloc;
} data;
} scc_mir_instr_t;
typedef SCC_VEC(scc_mir_instr_t) scc_mir_instr_vec_t;
typedef scc_cfg_bblock_t scc_mir_bblock_t;
typedef struct scc_mir_bblock_meta {
} scc_mir_bblock_meta_t;
#define SCC_MIR_BBLOCK_VALUES(bblock) \
((scc_mir_instr_vec_t *)&((bblock)->values))
#define SCC_MIR_BBLOCK_VALUES_PTR(bb) ((void *)(&(bb)->values))
// 栈槽信息(由 FrameLayout Pass 填充)
typedef struct scc_mir_stack_slot {
int slot_id;
int size; // 通常是 8 字节 (指针大小)
@@ -56,18 +32,22 @@ typedef struct scc_mir_stack_slot {
} scc_mir_stack_slot_t;
typedef SCC_VEC(scc_mir_stack_slot_t) scc_mir_stack_slot_vec_t;
typedef scc_cfg_bblock_t scc_mir_bblock_t;
// 函数元数据 —— 不包含任何指令结构,由各后端自行定义指令布局
typedef scc_cfg_func_t scc_mir_func_t;
typedef struct scc_mir_func_meta {
// 栈帧信息 (由 FrameLayout Pass 填充)
int frame_size;
int stack_alignment;
int vregs_count;
// 寄存器分配信息
void *target_data; // 目标后端私有数据,例如 x86_64_func_info_t*
scc_mir_stack_slot_vec_t stack_slots;
// vreg -> phys reg and stack slot index
// positive means stack slot index
// negative means physic register
// vreg -> phys reg / stack slot
// 0 = not mapped (still a vreg)
// >0 = stack slot index
// <0 = physical register (negated)
scc_hashtable_t vreg2physic;
} scc_mir_func_meta_t;
#define SCC_MIR_FUNC_META(func) ((scc_mir_func_meta_t *)(func)->meta)
@@ -75,11 +55,28 @@ typedef struct scc_mir_func_meta {
void scc_mir_func_meta_init(scc_mir_func_meta_t *func_meta);
int scc_mir_alloc_vreg(scc_mir_func_t *func);
void scc_mir_vreg_op(const scc_mir_func_t *func, int vreg,
scc_mir_operand_t *out);
void scc_mir_vreg_map2preg(scc_mir_func_t *func, int vreg, int preg);
int scc_mir_vreg_map2slot(scc_mir_func_t *func, int vreg, int size, int align);
// 从 vreg2physic 表中查询映射结果:
// 返回 0 → 该 vreg 仍为 vreg未映射
// 返回 1 → 已映射到物理寄存器,*out_preg 有效
// 返回 -1 → 已溢出到栈槽,*out_slot 有效
static inline int scc_mir_vreg_lookup(const scc_mir_func_t *func, int vreg,
int *out) {
scc_mir_func_meta_t *meta = SCC_MIR_FUNC_META(func);
isize idx =
(isize)scc_hashtable_get(&meta->vreg2physic, (void *)(usize)vreg);
if (idx == 0)
return 0;
if (idx < 0) {
*out = (int)-idx;
return 1;
}
*out = (int)idx;
return -1;
}
static inline scc_mir_stack_slot_t *
scc_mir_unsafe_slot(const scc_mir_func_t *func, int slot) {
Assert(slot > 0);