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:
61
libs/ir/mir/include/arch/scc_x86_isel.h
Normal file
61
libs/ir/mir/include/arch/scc_x86_isel.h
Normal file
@@ -0,0 +1,61 @@
|
||||
#ifndef __SCC_X86_ISEL_H__
|
||||
#define __SCC_X86_ISEL_H__
|
||||
|
||||
#include <scc_lir_module.h>
|
||||
#include <scc_tree_dump.h>
|
||||
|
||||
#include "../core_pass/scc_abi_lowering.h"
|
||||
#include "scc_x86_mir.h"
|
||||
|
||||
typedef struct scc_x86_64_isel {
|
||||
scc_mir_x86_instr_vec_t instrs;
|
||||
scc_mir_func_t *func;
|
||||
scc_pos_t pos;
|
||||
scc_abi_lowering_t abi_lowering;
|
||||
} scc_x86_64_isel_t;
|
||||
|
||||
void scc_isel_x86_64(scc_mir_module_t *mir_module,
|
||||
const scc_lir_module_t *lir_module,
|
||||
scc_x86_64_isel_t *isel);
|
||||
|
||||
// Utils
|
||||
void scc_x86_emit_move(scc_x86_64_isel_t *isel, scc_x86_operand_value_t dst,
|
||||
scc_x86_operand_value_t src, u8 size);
|
||||
scc_x86_operand_value_t scc_x86_lir_val_to_mir_op(scc_x86_64_isel_t *isel,
|
||||
const scc_lir_val_t *val);
|
||||
static inline void emit_direct_call(scc_x86_64_isel_t *isel,
|
||||
const char *callee) {
|
||||
(void)callee;
|
||||
scc_mir_x86_instr_t instr = {0};
|
||||
scc_mir_x86_instr_1(&instr, SCC_X86_IFORM_CALL_NEAR_GPRV,
|
||||
scc_x86_op_relbr(0), scc_pos_create());
|
||||
scc_vec_push(isel->instrs, instr);
|
||||
}
|
||||
static inline void emit_ret(scc_x86_64_isel_t *isel) {
|
||||
scc_mir_x86_instr_t instr = {0};
|
||||
scc_mir_x86_instr_0(&instr, SCC_X86_IFORM_RET_NEAR, scc_pos_create());
|
||||
scc_vec_push(isel->instrs, instr);
|
||||
}
|
||||
|
||||
#define add_instr_0(isel, iform) \
|
||||
do { \
|
||||
scc_mir_x86_instr_t instr; \
|
||||
scc_mir_x86_instr_0(&instr, (iform), (isel)->pos); \
|
||||
scc_vec_push((isel)->instrs, instr); \
|
||||
} while (0)
|
||||
|
||||
#define add_instr_1(isel, iform, arg1) \
|
||||
do { \
|
||||
scc_mir_x86_instr_t instr; \
|
||||
scc_mir_x86_instr_1(&instr, (iform), (arg1), (isel)->pos); \
|
||||
scc_vec_push((isel)->instrs, instr); \
|
||||
} while (0)
|
||||
|
||||
#define add_instr_2(isel, iform, arg1, arg2) \
|
||||
do { \
|
||||
scc_mir_x86_instr_t instr; \
|
||||
scc_mir_x86_instr_2(&instr, (iform), (arg1), (arg2), (isel)->pos); \
|
||||
scc_vec_push((isel)->instrs, instr); \
|
||||
} while (0)
|
||||
|
||||
#endif /* __SCC_X86_ISEL_H__ */
|
||||
134
libs/ir/mir/include/arch/scc_x86_mir.h
Normal file
134
libs/ir/mir/include/arch/scc_x86_mir.h
Normal file
@@ -0,0 +1,134 @@
|
||||
#ifndef __SCC_X86_MIR_H__
|
||||
#define __SCC_X86_MIR_H__
|
||||
|
||||
#include "../scc_mir.h"
|
||||
#include <scc_cfg.h>
|
||||
#include <scc_pos.h>
|
||||
#include <x86/scc_x86_encode.h>
|
||||
#include <x86/scc_x86_iform.h>
|
||||
#include <x86/scc_x86_reg.h>
|
||||
|
||||
typedef struct {
|
||||
int opcode;
|
||||
uint8_t num_operands;
|
||||
scc_x86_operand_value_t operands[6];
|
||||
scc_pos_t src_loc;
|
||||
} scc_x86_instr_t;
|
||||
|
||||
// x86 后端指令:首字段 int opcode(正 = scc_x86_iform_t,负 = 伪指令)
|
||||
typedef union scc_mir_x86_instr {
|
||||
scc_mir_instr_t instr;
|
||||
scc_x86_instr_t x86_instr;
|
||||
} scc_mir_x86_instr_t;
|
||||
|
||||
typedef SCC_VEC(scc_mir_x86_instr_t) scc_mir_x86_instr_vec_t;
|
||||
|
||||
// ── 基本块 values 强制转换 ──────────────────────────────────────────────
|
||||
|
||||
#define SCC_MIR_X86_BBLOCK_INSTRS(bb) ((scc_mir_x86_instr_vec_t *)&bb->values)
|
||||
#define SCC_MIR_X86_BBLOCK_INSTRS_C(bb) \
|
||||
((const scc_mir_x86_instr_vec_t *)&bb->values)
|
||||
|
||||
// ── vreg 编码 ──────────────────────────────────────────────────────────
|
||||
static inline bool scc_x86_op_is_vreg(const scc_x86_operand_value_t *op) {
|
||||
return op->kind == SCC_X86_OPR_REG &&
|
||||
(int)op->reg >= (int)SCC_X86_REG_COUNT;
|
||||
}
|
||||
static inline int scc_x86_op_get_vreg(const scc_x86_operand_value_t *op) {
|
||||
return (int)op->reg - (int)SCC_X86_REG_COUNT;
|
||||
}
|
||||
static inline void scc_x86_op_set_preg(scc_x86_operand_value_t *op,
|
||||
scc_x86_reg_t preg) {
|
||||
op->kind = SCC_X86_OPR_REG;
|
||||
op->reg = preg;
|
||||
}
|
||||
|
||||
// ── 未解析栈槽编码 (base=INVALID, disp=slot_id) ──────────────────────
|
||||
static inline bool scc_x86_op_is_slot(const scc_x86_operand_value_t *op) {
|
||||
return op->kind == SCC_X86_OPR_MEM && op->mem.base == SCC_X86_REG_INVALID;
|
||||
}
|
||||
static inline int scc_x86_op_slot_id(const scc_x86_operand_value_t *op) {
|
||||
return op->mem.disp;
|
||||
}
|
||||
|
||||
// ── 指令构建辅助 ──────────────────────────────────────────────────────
|
||||
static inline void scc_mir_x86_instr_0(scc_mir_x86_instr_t *out, int opcode,
|
||||
scc_pos_t pos) {
|
||||
out->x86_instr.opcode = opcode;
|
||||
out->x86_instr.num_operands = 0;
|
||||
out->x86_instr.src_loc = pos;
|
||||
}
|
||||
static inline void scc_mir_x86_instr_1(scc_mir_x86_instr_t *out, int opcode,
|
||||
scc_x86_operand_value_t op0,
|
||||
scc_pos_t pos) {
|
||||
out->x86_instr.opcode = opcode;
|
||||
out->x86_instr.num_operands = 1;
|
||||
out->x86_instr.operands[0] = op0;
|
||||
out->x86_instr.src_loc = pos;
|
||||
}
|
||||
static inline void scc_mir_x86_instr_2(scc_mir_x86_instr_t *out, int opcode,
|
||||
scc_x86_operand_value_t op0,
|
||||
scc_x86_operand_value_t op1,
|
||||
scc_pos_t pos) {
|
||||
out->x86_instr.opcode = opcode;
|
||||
out->x86_instr.num_operands = 2;
|
||||
out->x86_instr.operands[0] = op0;
|
||||
out->x86_instr.operands[1] = op1;
|
||||
out->x86_instr.src_loc = pos;
|
||||
}
|
||||
static inline void scc_mir_x86_instr_3(scc_mir_x86_instr_t *out, int opcode,
|
||||
scc_x86_operand_value_t op0,
|
||||
scc_x86_operand_value_t op1,
|
||||
scc_x86_operand_value_t op2,
|
||||
scc_pos_t pos) {
|
||||
out->x86_instr.opcode = opcode;
|
||||
out->x86_instr.num_operands = 3;
|
||||
out->x86_instr.operands[0] = op0;
|
||||
out->x86_instr.operands[1] = op1;
|
||||
out->x86_instr.operands[2] = op2;
|
||||
out->x86_instr.src_loc = pos;
|
||||
}
|
||||
|
||||
// ── 常用操作数构造器 ──────────────────────────────────────────────────
|
||||
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_operand_value_t scc_x86_op_vreg(int vreg) {
|
||||
scc_x86_operand_value_t o = {
|
||||
.kind = SCC_X86_OPR_REG,
|
||||
.reg = (scc_x86_reg_t)((int)SCC_X86_REG_COUNT + 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, .imm = 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, .imm = imm};
|
||||
return o;
|
||||
}
|
||||
// slot_id 编码为 base=INVALID, disp=slot_id
|
||||
static inline scc_x86_operand_value_t scc_x86_op_slot(int slot_id) {
|
||||
scc_x86_operand_value_t o = {.kind = SCC_X86_OPR_MEM};
|
||||
o.mem.base = SCC_X86_REG_INVALID;
|
||||
o.mem.index = SCC_X86_REG_INVALID;
|
||||
o.mem.scale = 1;
|
||||
o.mem.disp = slot_id;
|
||||
return o;
|
||||
}
|
||||
static inline scc_x86_operand_value_t scc_x86_op_symbol(const char *sym) {
|
||||
scc_x86_operand_value_t o = {.kind = SCC_X86_OPR_IMM,
|
||||
.imm = (i64)(usize)sym};
|
||||
(void)o;
|
||||
// symbol 暂用一个近似值占位,编码阶段处理重定位
|
||||
return o;
|
||||
}
|
||||
static inline scc_x86_operand_value_t
|
||||
scc_x86_op_block(scc_cfg_bblock_id_t bid) {
|
||||
scc_x86_operand_value_t o = {.kind = SCC_X86_OPR_RELBR, .imm = 0};
|
||||
(void)bid;
|
||||
return o;
|
||||
}
|
||||
|
||||
#endif /* __SCC_X86_MIR_H__ */
|
||||
8
libs/ir/mir/include/arch/scc_x86_reg_alloc.h
Normal file
8
libs/ir/mir/include/arch/scc_x86_reg_alloc.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef __SCC_X86_REG_ALLOC_H__
|
||||
#define __SCC_X86_REG_ALLOC_H__
|
||||
|
||||
#include "../core_pass/scc_reg_alloc.h"
|
||||
|
||||
void scc_reg_alloc_fill_arch_x86(scc_reg_alloc_op_t *ops);
|
||||
|
||||
#endif /* __SCC_X86_REG_ALLOC_H__ */
|
||||
@@ -1,66 +0,0 @@
|
||||
#ifndef __SCC_X86_64_ISEL_H__
|
||||
#define __SCC_X86_64_ISEL_H__
|
||||
|
||||
#include <scc_lir_module.h>
|
||||
#include <scc_tree_dump.h>
|
||||
|
||||
#include <x86/scc_x86_iform.h>
|
||||
#include <x86/scc_x86_reg.h>
|
||||
|
||||
#include "../core_pass/scc_abi_lowering.h"
|
||||
#include "../scc_mir_module.h"
|
||||
|
||||
typedef struct scc_x86_64_isel {
|
||||
scc_mir_instr_vec_t instrs;
|
||||
scc_mir_func_t *func;
|
||||
scc_abi_lowering_t abi_lowering;
|
||||
} scc_x86_64_isel_t;
|
||||
|
||||
void scc_isel_x86_64(scc_mir_module_t *mir_module,
|
||||
const scc_lir_module_t *lir_module,
|
||||
scc_x86_64_isel_t *isel);
|
||||
|
||||
static void add_instr(scc_x86_64_isel_t *isel, const scc_mir_instr_t *instr) {
|
||||
scc_vec_push(isel->instrs, *instr);
|
||||
}
|
||||
|
||||
static inline void add_instr_0(scc_x86_64_isel_t *isel,
|
||||
scc_x86_iform_t opcode) {
|
||||
scc_mir_instr_t out = {.opcode = opcode, .num_operands = 0};
|
||||
add_instr(isel, &out);
|
||||
}
|
||||
|
||||
static inline void add_instr_1(scc_x86_64_isel_t *isel, scc_x86_iform_t opcode,
|
||||
scc_mir_operand_t op1) {
|
||||
scc_mir_instr_t out = {.opcode = opcode, .num_operands = 1};
|
||||
out.operands[0] = op1;
|
||||
add_instr(isel, &out);
|
||||
}
|
||||
|
||||
static inline void add_instr_2(scc_x86_64_isel_t *isel, scc_x86_iform_t opcode,
|
||||
scc_mir_operand_t op1, scc_mir_operand_t op2) {
|
||||
scc_mir_instr_t out = {.opcode = opcode, .num_operands = 2};
|
||||
out.operands[0] = op1;
|
||||
out.operands[1] = op2;
|
||||
add_instr(isel, &out);
|
||||
}
|
||||
|
||||
static inline scc_mir_operand_t reg_operand(scc_x86_reg_t reg) {
|
||||
return (scc_mir_operand_t){.kind = SCC_MIR_OP_PREG, .preg = reg};
|
||||
}
|
||||
|
||||
// Utils
|
||||
|
||||
void scc_x86_emit_move(scc_x86_64_isel_t *isel, scc_mir_operand_t dst,
|
||||
scc_mir_operand_t src, u8 size);
|
||||
scc_mir_operand_t scc_x86_lir_val_to_mir_op(scc_x86_64_isel_t *isel,
|
||||
const scc_lir_val_t *val);
|
||||
static inline void emit_call(scc_x86_64_isel_t *isel, const char *callee) {
|
||||
scc_mir_operand_t sym = {.kind = SCC_MIR_OP_SYMBOL, .symbol = callee};
|
||||
add_instr_1(isel, SCC_X86_IFORM_CALL_NEAR_GPRV, sym);
|
||||
}
|
||||
static inline void emit_ret(scc_x86_64_isel_t *isel) {
|
||||
add_instr_0(isel, SCC_X86_IFORM_RET_NEAR);
|
||||
}
|
||||
|
||||
#endif /* __SCC_X86_64_ISEL_H__ */
|
||||
@@ -1,8 +0,0 @@
|
||||
#ifndef __SCC_X86_64_REG_ALLOC_H__
|
||||
#define __SCC_X86_64_REG_ALLOC_H__
|
||||
|
||||
#include "../core_pass/scc_reg_alloc.h"
|
||||
|
||||
void scc_reg_alloc_fill_arch_x86(scc_reg_alloc_op_t *ops);
|
||||
|
||||
#endif /* __SCC_X86_64_REG_ALLOC_H__ */
|
||||
@@ -4,9 +4,12 @@
|
||||
#include "../scc_mir_module.h"
|
||||
#include <scc_lir_module.h>
|
||||
|
||||
// 所有回调通过 void* userdata / void* out_op 保持类型无关
|
||||
typedef void (*scc_abi_lower_fn)(void *user_data, const scc_lir_instr_t *instr);
|
||||
typedef scc_mir_operand_t (*scc_abi_lower_param_fn)(void *userdata,
|
||||
const scc_lir_val_t *val);
|
||||
// lower_param 将 LIR 值转化为后端操作数,写入 out_op(后端知道实际类型)
|
||||
typedef void (*scc_abi_lower_param_fn)(void *userdata,
|
||||
const scc_lir_val_t *val,
|
||||
void *out_op);
|
||||
|
||||
typedef struct scc_abi_lowering {
|
||||
scc_abi_lower_fn lower_call;
|
||||
|
||||
@@ -7,37 +7,46 @@ typedef enum {
|
||||
SCC_REG_ALLOC_OP_ACCESS_READ = 0,
|
||||
SCC_REG_ALLOC_OP_ACCESS_WRITE = 1,
|
||||
SCC_REG_ALLOC_OP_ACCESS_READWRITE = 2,
|
||||
} scc_op_access_t;
|
||||
} scc_reg_op_access_t;
|
||||
|
||||
// 后端回调表 —— 框架通过回调获取/修改指令,不感知具体布局
|
||||
typedef struct scc_reg_alloc_op {
|
||||
// preg → [slot]
|
||||
void (*emit_spill)(scc_mir_instr_vec_t *ctx, int preg, int slot);
|
||||
// [slot] → preg
|
||||
void (*emit_reload)(scc_mir_instr_vec_t *ctx, int preg, int slot);
|
||||
// preg → preg
|
||||
void (*emit_copy)(scc_mir_instr_vec_t *ctx, int dst_preg, int src_preg,
|
||||
int size);
|
||||
|
||||
// 通用寄存器申请 / 释放
|
||||
int (*acquire_reg)(void *ctx); // 返回一个物理寄存器编号
|
||||
void (*release_reg)(void *ctx, int preg); // 归还该寄存器
|
||||
|
||||
// 显式标记某个寄存器已占用 / 未占用(用于隐式寄存器、固定分配等)
|
||||
// ── 寄存器池 ──
|
||||
int (*acquire_reg)(void *ctx);
|
||||
void (*release_reg)(void *ctx, int preg);
|
||||
void (*mark_reg_used)(void *ctx, int preg);
|
||||
void (*clean_mark_regs)(void *ctx);
|
||||
|
||||
// ---- 指令信息查询(只读) ----
|
||||
scc_op_access_t (*get_operand_access)(void *ctx, int opcode, int op_idx);
|
||||
// ── 指令信息 ──
|
||||
int (*instr_opcode)(const void *instr);
|
||||
int (*instr_num_operands)(const void *instr);
|
||||
bool (*op_is_vreg)(const void *instr, int idx);
|
||||
int (*op_get_vreg)(const void *instr, int idx);
|
||||
void (*op_set_preg)(void *instr, int idx, int preg);
|
||||
void (*op_set_slot)(void *instr, int idx, int slot);
|
||||
// 读写属性与隐式寄存器
|
||||
scc_reg_op_access_t (*get_operand_access)(void *ctx, int opcode,
|
||||
int op_idx);
|
||||
void (*get_implicit_regs)(void *ctx, int opcode, const int **out_uses,
|
||||
const int **out_defs);
|
||||
|
||||
// ── 伪指令处理 ──
|
||||
bool (*is_pseudo)(const void *instr);
|
||||
void (*handle_pseudo)(scc_mir_func_t *func, void *instr, void *out);
|
||||
|
||||
// ── 溢出/重载(写入 out 向量) ──
|
||||
void (*emit_spill)(void *out, int preg, int slot);
|
||||
void (*emit_reload)(void *out, int preg, int slot);
|
||||
void (*emit_copy)(void *out, int dst_preg, int src_preg, int size);
|
||||
} scc_reg_alloc_op_t;
|
||||
|
||||
typedef struct scc_reg_alloc_ctx {
|
||||
scc_reg_alloc_op_t ops;
|
||||
scc_mir_module_t *module;
|
||||
scc_mir_func_t *func;
|
||||
scc_mir_instr_vec_t *instrs;
|
||||
} scc_reg_alloc_ctx_t;
|
||||
|
||||
// 通用寄存器分配入口:遍历所有函数/基本块,对每条指令做 vreg → preg 分配
|
||||
void scc_reg_alloc(scc_reg_alloc_ctx_t *ctx, scc_mir_module_t *module);
|
||||
|
||||
#endif /* __SCC_REG_ALLOC__ */
|
||||
#endif /* __SCC_REG_ALLOC_H__ */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -4,9 +4,13 @@
|
||||
#include "scc_mir.h"
|
||||
#include <scc_lir_module.h>
|
||||
|
||||
typedef SCC_VEC(char) scc_mir_instr_vec_t;
|
||||
|
||||
typedef scc_lir_symbol_meta_vec_t scc_mir_symbol_meta_vec_t;
|
||||
|
||||
typedef SCC_VEC(scc_mir_func_meta_t *) scc_mir_func_meta_vec_t;
|
||||
typedef struct scc_mir_module {
|
||||
usize instr_size;
|
||||
scc_cfg_module_t cfg_module;
|
||||
scc_mir_func_meta_vec_t func_metas;
|
||||
scc_mir_symbol_meta_vec_t symbol_metas;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __SCC_WIN64_H__
|
||||
#define __SCC_WIN64_H__
|
||||
|
||||
#include "../arch/x86_64_isel.h"
|
||||
#include "../arch/scc_x86_isel.h"
|
||||
#include "../core_pass/scc_frame_layout.h"
|
||||
#include "../core_pass/scc_prolog_epilog.h"
|
||||
#include "../core_pass/scc_reg_alloc.h"
|
||||
|
||||
Reference in New Issue
Block a user