Files
scc/libs/ir/mir/include/scc_mir.h
zzy aa4292a30e feat(mir): 添加函数调用和返回指令支持
添加了间接调用函数emit_indirect_call用于处理寄存器调用,
修改直接调用函数emit_direct_call使用相对分支形式,
为函数元数据添加need_va_args字段标记变参函数需求。

refactor(prolog-epilog): 重构函数序言和尾声处理逻辑

将prolog/epilog回调函数参数从void*改为scc_mir_instr_vec_t*,
添加need_epilog回调函数用于判断是否需要插入尾声代码,
修改pass处理逻辑以支持动态插入序言和尾声代码。

feat(win64-abi): 实现Windows x64平台序言尾声生成功能

实现prologue函数生成栈帧设置和变参处理代码,
实现epilogue函数生成栈清理和返回指令,
添加need_epilog判断函数识别返回指令类型并触发尾声插入。
2026-05-20 21:11:48 +08:00

88 lines
2.6 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_MIR_H__
#define __SCC_MIR_H__
#include <scc_cfg.h>
// 伪指令 opcode负数所有后端通用约定
typedef enum {
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;
union {
struct {
int size;
int align;
int vreg;
} alloc;
} data;
} scc_mir_instr_t;
#define SCC_MIR_BBLOCK_VALUES_PTR(bb) ((void *)(&(bb)->values))
// 栈槽信息(由 FrameLayout Pass 填充)
typedef struct scc_mir_stack_slot {
int slot_id;
int size; // 通常是 8 字节 (指针大小)
int alignment; // 对齐要求
int offset; // 相对于 RSP 的偏移 (最终确定)
} 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 {
int need_va_args;
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 / 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)
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_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);
return &scc_vec_at(SCC_MIR_FUNC_META(func)->stack_slots, slot);
}
#endif /* __SCC_MIR_H__ */