feat(lir): 修改HIR到LIR转换以支持可变参数函数
- 移除SCC_LIR_LEA指令类型,改用SCC_LIR_LOAD_ADDR - 在scc_lir_func_meta_t中添加is_va_arg字段用于标识可变参数函数 - 修改scc_hir2lir函数参数类型,移除const限定符 - 更新比较操作的指令映射逻辑,将条件信息存储在metadata中 - 调整代码结构,在各个switch case分支中统一使用"} break"格式 fix(x86-isel): 修复x86指令选择中的立即数和重定位处理 - 修改emit_direct_call函数以正确处理全局符号重定位 - 更新立即数字段访问从imm到imm0 - 添加新的重定位操作数类型SCC_X86_OPR_RELOC - 实现重定位目标类型的完整处理逻辑,包括基本块和符号 refactor(x86-mir): 重构x86操作数结构以支持重定位机制 - 将内存操作数的disp字段改为结构体形式包含displacement信息 - 移除不再使用的常用操作数构造器函数 - 保留并完善slot操作数构造器 - 更新内存操作数的调试输出格式 feat(ir2mcode): 添加重定位表支持以处理符号引用 - 定义新的重定位结构体scc_reloc_t用于记录重定位信息 - 修改scc_ir2mcode_emit_instr函数签名以传递重定位表 - 实现重定位补丁应用功能scc_ir2mcode_patch - 更新机器码生成流程以收集和处理重定位信息 refactor(ir2sccf): 重构SCEF文件生成以支持重定位处理 - 提取独立的emit_mir_module函数处理MIR模块的机器码生成 - 实现基本块间重定位的地址解析和补丁应用 - 改进符号重定位的处理机制 - 简化机器码段数据的最终处理流程
This commit is contained in:
@@ -5,6 +5,6 @@
|
||||
#include "scc_lir_module.h"
|
||||
#include <scc_hir.h>
|
||||
|
||||
void scc_hir2lir(scc_lir_module_t *module, const scc_hir_cprog_t *cprog);
|
||||
void scc_hir2lir(scc_lir_module_t *module, scc_hir_cprog_t *cprog);
|
||||
|
||||
#endif /* __SCC_IR2LIR_H__ */
|
||||
|
||||
@@ -98,7 +98,6 @@ typedef enum {
|
||||
SCC_LIR_LOAD_ADDR,
|
||||
SCC_LIR_STORE,
|
||||
SCC_LIR_STORE_ADDR,
|
||||
SCC_LIR_LEA,
|
||||
|
||||
/* 整数算术 */
|
||||
SCC_LIR_ADD,
|
||||
@@ -253,6 +252,7 @@ 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)
|
||||
|
||||
@@ -234,7 +234,7 @@ static scc_lir_op_t map_binop(scc_hir_op_type_t op, cbool is_float) {
|
||||
case SCC_HIR_OP_SAR:
|
||||
return SCC_LIR_SAR;
|
||||
default:
|
||||
return map_cmp_cond(op, is_float);
|
||||
return SCC_LIR_CMP;
|
||||
}
|
||||
}
|
||||
return SCC_LIR_NOP;
|
||||
@@ -263,15 +263,19 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
|
||||
scc_lir_val_t rhs = ir_value_to_lir_operand(ctx, value->data.op.rhs);
|
||||
scc_lir_op_t op = map_binop(value->data.op.op, is_float);
|
||||
|
||||
scc_lir_instr_t instr = {.op = op,
|
||||
.size = size,
|
||||
.ext = ext,
|
||||
.to = SCC_LIR_VREG(dst_vreg),
|
||||
.arg0 = lhs,
|
||||
.arg1 = rhs};
|
||||
scc_lir_instr_t instr = {
|
||||
.op = op,
|
||||
.size = size,
|
||||
.ext = ext,
|
||||
.to = SCC_LIR_VREG(dst_vreg),
|
||||
.arg0 = lhs,
|
||||
.arg1 = rhs,
|
||||
};
|
||||
if (op == SCC_LIR_CMP) {
|
||||
instr.metadata.cond = map_cmp_cond(value->data.op.op, is_float);
|
||||
}
|
||||
scc_lir_builder_add_instr(ctx, &instr);
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
case SCC_HIR_VALUE_TAG_LOAD: {
|
||||
scc_lir_val_t addr =
|
||||
ir_value_to_lir_operand(ctx, value->data.load.target);
|
||||
@@ -281,8 +285,7 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
|
||||
.to = SCC_LIR_VREG(dst_vreg),
|
||||
.arg0 = addr};
|
||||
scc_lir_builder_add_instr(ctx, &instr);
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
case SCC_HIR_VALUE_TAG_STORE: {
|
||||
scc_lir_val_t data =
|
||||
ir_value_to_lir_operand(ctx, value->data.store.value);
|
||||
@@ -291,8 +294,7 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
|
||||
scc_lir_instr_t instr = {
|
||||
.op = SCC_LIR_STORE, .size = size, .arg0 = data, .arg1 = addr};
|
||||
scc_lir_builder_add_instr(ctx, &instr);
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
case SCC_HIR_VALUE_TAG_GET_ELEM_PTR: {
|
||||
// 将指针运算转换为 LEA
|
||||
scc_lir_val_t base =
|
||||
@@ -333,15 +335,14 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
|
||||
scc_lir_val_t addr =
|
||||
SCC_LIR_ADDR(dst_vreg, -1, index.data.reg, elem_size);
|
||||
// 更简单的做法:使用 LEA 指令,参数为 base 和 index,由后端展开
|
||||
scc_lir_instr_t instr = {.op = SCC_LIR_LEA,
|
||||
scc_lir_instr_t instr = {.op = SCC_LIR_LOAD_ADDR,
|
||||
.size = SCC_LIR_SIZE_64,
|
||||
.to = SCC_LIR_VREG(dst_vreg),
|
||||
.arg0 = base,
|
||||
.arg1 = index};
|
||||
// 实际需要将 index * elem_size 的信息编码,这里简化,假设后端处理
|
||||
scc_lir_builder_add_instr(ctx, &instr);
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
case SCC_HIR_VALUE_TAG_ALLOC: {
|
||||
// alloca 指令:分配栈空间
|
||||
scc_hir_type_t *alloc_ty =
|
||||
@@ -355,8 +356,7 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
|
||||
.to = SCC_LIR_VREG(dst_vreg),
|
||||
.metadata.alloca = {alloc_size, alloc_size}};
|
||||
scc_lir_builder_add_instr(ctx, &instr);
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
case SCC_HIR_VALUE_TAG_CALL: {
|
||||
scc_hir_func_t *callee = scc_hir_module_get_func(
|
||||
ctx->hir_module, value->data.call.callee.func_ref);
|
||||
@@ -381,8 +381,7 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
|
||||
// metadata.call.args 指针仍指向 malloc 内存,
|
||||
// 这会导致内存泄漏。实际实现中应使用 arena
|
||||
// 分配或随函数释放。此处为示例简化。
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
case SCC_HIR_VALUE_TAG_BRANCH: {
|
||||
scc_lir_val_t cond =
|
||||
ir_value_to_lir_operand(ctx, value->data.branch.cond);
|
||||
@@ -392,15 +391,13 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
|
||||
.metadata.br = {value->data.branch.true_bblock,
|
||||
value->data.branch.false_bblock}};
|
||||
scc_lir_builder_add_instr(ctx, &instr);
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
case SCC_HIR_VALUE_TAG_JUMP: {
|
||||
scc_lir_instr_t instr = {.op = SCC_LIR_JMP,
|
||||
.metadata.jmp_target =
|
||||
value->data.jump.target_bblock};
|
||||
scc_lir_builder_add_instr(ctx, &instr);
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
case SCC_HIR_VALUE_TAG_RET: {
|
||||
scc_lir_val_t ret_val;
|
||||
if (value->data.ret.ret_val != SCC_HIR_REF_nullptr) {
|
||||
@@ -411,8 +408,7 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
|
||||
scc_lir_instr_t instr = {.op = SCC_LIR_RET,
|
||||
.metadata.ret_val = ret_val};
|
||||
scc_lir_builder_add_instr(ctx, &instr);
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
case SCC_HIR_VALUE_TAG_CONV: {
|
||||
// 类型转换:使用 MOV 指令配合扩展/截断
|
||||
scc_lir_val_t src =
|
||||
@@ -429,8 +425,7 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
|
||||
.to = SCC_LIR_VREG(dst_vreg),
|
||||
.arg0 = src};
|
||||
scc_lir_builder_add_instr(ctx, &instr);
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
// 不生成指令的节点(如 CONST_INT, FUNC_ARG_REF)不会调用本函数
|
||||
break;
|
||||
@@ -447,6 +442,7 @@ static void translate_func(ir2lir_ctx_t *ctx, scc_hir_func_t *ir_func) {
|
||||
.attr = SCC_LIR_ATTR_NONE,
|
||||
.frame_size = 0,
|
||||
.vregs_count = 0,
|
||||
.is_va_arg = false,
|
||||
};
|
||||
scc_vec_push(ctx->lir_module->func_metas, lir_func_meta);
|
||||
ctx->current_func = ir_func;
|
||||
@@ -483,7 +479,7 @@ static void translate_func(ir2lir_ctx_t *ctx, scc_hir_func_t *ir_func) {
|
||||
scc_hashtable_drop(&ctx->value_to_vreg);
|
||||
}
|
||||
|
||||
void scc_hir2lir(scc_lir_module_t *module, const scc_hir_cprog_t *cprog) {
|
||||
void scc_hir2lir(scc_lir_module_t *module, scc_hir_cprog_t *cprog) {
|
||||
Assert(module != nullptr && cprog != nullptr);
|
||||
|
||||
// FIXME
|
||||
|
||||
@@ -18,8 +18,6 @@ static const char *op_to_string(scc_lir_op_t op) {
|
||||
return "store";
|
||||
case SCC_LIR_STORE_ADDR:
|
||||
return "store.addr";
|
||||
case SCC_LIR_LEA:
|
||||
return "lea";
|
||||
case SCC_LIR_ADD:
|
||||
return "add";
|
||||
case SCC_LIR_SUB:
|
||||
@@ -236,7 +234,6 @@ void scc_lir_dump_ins(scc_lir_dump_ctx_t *ctx, const scc_lir_instr_t *ins) {
|
||||
scc_tree_dump_append(td, " <- ");
|
||||
dump_operand(ctx, &ins->arg0);
|
||||
break;
|
||||
case SCC_LIR_LEA:
|
||||
case SCC_LIR_NEG:
|
||||
case SCC_LIR_NOT:
|
||||
case SCC_LIR_FNEG:
|
||||
@@ -419,7 +416,8 @@ void scc_lir_dump_func(scc_lir_dump_ctx_t *ctx, const scc_lir_func_t *func) {
|
||||
scc_lir_func_meta_t *meta = SCC_LIR_FUNC_META(func);
|
||||
// 函数头部
|
||||
scc_tree_dump_begin_line(td);
|
||||
scc_tree_dump_node(td, "func @%s", func->name ? func->name : "<anon>");
|
||||
scc_tree_dump_node(td, "func @%s%s", func->name ? func->name : "<anon>",
|
||||
meta->is_va_arg ? "(...)" : "()");
|
||||
scc_tree_dump_append_fmt(td, " (vregs: %u, frame: %d)", meta->vregs_count,
|
||||
meta->frame_size);
|
||||
if (meta->attr != SCC_LIR_ATTR_NONE) {
|
||||
|
||||
@@ -25,10 +25,10 @@ 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_RELBRZ,
|
||||
scc_x86_op_relbr(0), scc_pos_create());
|
||||
scc_x86_operand_value_t op = scc_x86_op_reloc_global_relbr(callee, 0);
|
||||
scc_mir_x86_instr_1(&instr, SCC_X86_IFORM_CALL_NEAR_RELBRZ, op,
|
||||
scc_pos_create());
|
||||
scc_vec_push(isel->instrs, instr);
|
||||
}
|
||||
|
||||
|
||||
@@ -43,15 +43,23 @@ static inline void scc_x86_op_set_preg(scc_x86_operand_value_t *op,
|
||||
op->reg = preg;
|
||||
}
|
||||
|
||||
// ── 未解析栈槽编码 (base=INVALID, disp=slot_id) ──────────────────────
|
||||
// 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.displacement = slot_id;
|
||||
o.mem.disp.displacement_bits = 0;
|
||||
return o;
|
||||
}
|
||||
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;
|
||||
return op->mem.disp.displacement;
|
||||
}
|
||||
|
||||
// ── 指令构建辅助 ──────────────────────────────────────────────────────
|
||||
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;
|
||||
@@ -89,46 +97,4 @@ static inline void scc_mir_x86_instr_3(scc_mir_x86_instr_t *out, int opcode,
|
||||
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__ */
|
||||
|
||||
@@ -32,17 +32,34 @@ void scc_x86_instr_dump(scc_tree_dump_t *td, const scc_mir_x86_instr_t *instr) {
|
||||
scc_tree_dump_append_fmt(td, "$%s", preg_name(op->reg));
|
||||
break;
|
||||
case SCC_X86_OPR_IMM:
|
||||
scc_tree_dump_append_fmt(td, "%ld", op->imm);
|
||||
scc_tree_dump_append_fmt(td, "%ld", op->imm0);
|
||||
break;
|
||||
case SCC_X86_OPR_MEM:
|
||||
if (scc_x86_op_is_slot(op))
|
||||
scc_tree_dump_append_fmt(td, "[slot:%d]",
|
||||
scc_x86_op_slot_id(op));
|
||||
else
|
||||
scc_tree_dump_append_fmt(td, "[sp%+d]", op->mem.disp);
|
||||
scc_tree_dump_append_fmt(
|
||||
td, "[sp %c %llu]",
|
||||
op->mem.disp.displacement >= 0 ? '+' : '-',
|
||||
op->mem.disp.displacement < 0 ? -op->mem.disp.displacement
|
||||
: op->mem.disp.displacement);
|
||||
break;
|
||||
case SCC_X86_OPR_RELBR:
|
||||
scc_tree_dump_append(td, "label");
|
||||
scc_tree_dump_append(td, "<relbr>");
|
||||
break;
|
||||
case SCC_X86_OPR_RELOC:
|
||||
switch (op->reloc.target) {
|
||||
case SCC_X86_RELOC_TARGET_BBLOCK:
|
||||
scc_tree_dump_append_fmt(td, "<#BB%d>", op->reloc.bblock_id);
|
||||
break;
|
||||
case SCC_X86_RELOC_TARGET_SYMBOL:
|
||||
scc_tree_dump_append_fmt(td, "<%s>", op->reloc.global_name);
|
||||
break;
|
||||
default:
|
||||
scc_tree_dump_append_fmt(td, "<reloc>");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -75,7 +92,8 @@ scc_x86_operand_value_t scc_x86_lir_val_to_mir_op(scc_x86_64_isel_t *isel,
|
||||
op = scc_x86_op_imm(*(i64 *)&val->data.fimm);
|
||||
break;
|
||||
case SCC_LIR_INSTR_KIND_SYMBOL:
|
||||
op = scc_x86_op_symbol(val->data.symbol);
|
||||
// 默认作为绝对地址立即数(后续可优化为 RIP 相对)
|
||||
op = scc_x86_op_reloc_global_imm(val->data.symbol, 0);
|
||||
break;
|
||||
case SCC_LIR_INSTR_KIND_ARG:
|
||||
Assert(isel->abi_lowering.lower_param);
|
||||
@@ -94,33 +112,41 @@ static scc_x86_operand_value_t new_vreg_temp(scc_x86_64_isel_t *isel) {
|
||||
|
||||
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_kind_t dst_kind = dst.kind;
|
||||
if (dst_kind == SCC_X86_OPR_RELOC) {
|
||||
dst_kind = dst.reloc.kind;
|
||||
}
|
||||
scc_x86_operand_kind_t src_kind = src.kind;
|
||||
if (src_kind == SCC_X86_OPR_RELOC) {
|
||||
src_kind = src.reloc.kind;
|
||||
}
|
||||
|
||||
if (dst.kind == SCC_X86_OPR_REG) {
|
||||
if (src.kind == SCC_X86_OPR_REG) {
|
||||
if (dst_kind == SCC_X86_OPR_REG) {
|
||||
if (src_kind == SCC_X86_OPR_REG) {
|
||||
add_instr_2(isel, SCC_X86_IFORM_MOV_GPRV_GPRV_8B, dst, src);
|
||||
} else if (src.kind == SCC_X86_OPR_IMM) {
|
||||
} else if (src_kind == SCC_X86_OPR_IMM) {
|
||||
add_instr_2(isel,
|
||||
(size == 8) ? SCC_X86_IFORM_MOV_GPRV_IMMZ
|
||||
: SCC_X86_IFORM_MOV_GPRV_IMMV,
|
||||
dst, src);
|
||||
} else if (src.kind == SCC_X86_OPR_IMM && src.imm == 0) {
|
||||
} else if (src_kind == SCC_X86_OPR_IMM && src.imm0 == 0) {
|
||||
// 特殊:符号作为立即数地址
|
||||
add_instr_2(isel, SCC_X86_IFORM_MOV_GPRV_IMMZ, dst, src);
|
||||
} else if (src.kind == SCC_X86_OPR_MEM) {
|
||||
} else if (src_kind == SCC_X86_OPR_MEM) {
|
||||
add_instr_2(isel, SCC_X86_IFORM_MOV_GPRV_MEMV, dst, src);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
} else if (dst.kind == SCC_X86_OPR_MEM) {
|
||||
if (src.kind == SCC_X86_OPR_REG) {
|
||||
} else if (dst_kind == SCC_X86_OPR_MEM) {
|
||||
if (src_kind == SCC_X86_OPR_REG) {
|
||||
add_instr_2(isel, SCC_X86_IFORM_MOV_MEMV_GPRV, dst, src);
|
||||
} else if (src.kind == SCC_X86_OPR_IMM) {
|
||||
} else if (src_kind == SCC_X86_OPR_IMM) {
|
||||
add_instr_2(isel, SCC_X86_IFORM_MOV_MEMV_IMMZ, dst, src);
|
||||
} else if (src.kind == SCC_X86_OPR_IMM) {
|
||||
} else if (src_kind == SCC_X86_OPR_IMM) {
|
||||
scc_x86_operand_value_t temp = new_vreg_temp(isel);
|
||||
add_instr_2(isel, SCC_X86_IFORM_MOV_GPRV_IMMZ, temp, src);
|
||||
add_instr_2(isel, SCC_X86_IFORM_MOV_MEMV_GPRV, dst, temp);
|
||||
} else if (src.kind == SCC_X86_OPR_MEM) {
|
||||
} else if (src_kind == SCC_X86_OPR_MEM) {
|
||||
scc_x86_operand_value_t temp = new_vreg_temp(isel);
|
||||
scc_x86_emit_move(isel, temp, src, size);
|
||||
scc_x86_emit_move(isel, dst, temp, size);
|
||||
@@ -217,16 +243,6 @@ static void emit_binary_op(scc_x86_64_isel_t *isel, scc_lir_op_t op,
|
||||
add_instr_2(isel, iform, dst, src1);
|
||||
}
|
||||
|
||||
static void emit_spill_load(scc_x86_64_isel_t *isel, int vreg, int slot) {
|
||||
scc_x86_operand_value_t dst = scc_x86_op_vreg(vreg);
|
||||
add_instr_2(isel, SCC_X86_IFORM_MOV_GPRV_MEMV, dst, scc_x86_op_slot(slot));
|
||||
}
|
||||
|
||||
static void emit_spill_store(scc_x86_64_isel_t *isel, int vreg, int slot) {
|
||||
scc_x86_operand_value_t src = scc_x86_op_vreg(vreg);
|
||||
add_instr_2(isel, SCC_X86_IFORM_MOV_MEMV_GPRV, scc_x86_op_slot(slot), src);
|
||||
}
|
||||
|
||||
static void sel_mir(scc_x86_64_isel_t *isel, const scc_lir_instr_t *instr) {
|
||||
scc_x86_operand_value_t dst = scc_x86_lir_val_to_mir_op(isel, &instr->to);
|
||||
scc_x86_operand_value_t src0 =
|
||||
@@ -241,17 +257,16 @@ static void sel_mir(scc_x86_64_isel_t *isel, const scc_lir_instr_t *instr) {
|
||||
scc_x86_emit_move(isel, dst, src0, size);
|
||||
break;
|
||||
case SCC_LIR_LOAD:
|
||||
// TODO check valid
|
||||
scc_x86_emit_move(isel, dst, src0, size);
|
||||
break;
|
||||
case SCC_LIR_STORE:
|
||||
// TODO check valid
|
||||
scc_x86_emit_move(isel, src1, src0, size);
|
||||
break;
|
||||
|
||||
case SCC_LIR_STORE_ADDR:
|
||||
TODO();
|
||||
break;
|
||||
|
||||
case SCC_LIR_LEA:
|
||||
case SCC_LIR_LOAD_ADDR:
|
||||
add_instr_2(isel, SCC_X86_IFORM_LEA_GPRV_AGEN, dst, src0);
|
||||
break;
|
||||
@@ -374,9 +389,9 @@ static void sel_mir(scc_x86_64_isel_t *isel, const scc_lir_instr_t *instr) {
|
||||
/* ---- 条件分支 ---- */
|
||||
case SCC_LIR_BR: {
|
||||
scc_x86_operand_value_t true_bb =
|
||||
scc_x86_op_block(instr->metadata.br.true_target);
|
||||
scc_x86_op_reloc_block(instr->metadata.br.true_target, 0);
|
||||
scc_x86_operand_value_t false_bb =
|
||||
scc_x86_op_block(instr->metadata.br.false_target);
|
||||
scc_x86_op_reloc_block(instr->metadata.br.false_target, 0);
|
||||
|
||||
add_instr_2(isel, SCC_X86_IFORM_TEST_GPRV_GPRV, src0, src0);
|
||||
add_instr_1(isel, SCC_X86_IFORM_JNZ_RELBRZ, true_bb);
|
||||
@@ -385,7 +400,7 @@ static void sel_mir(scc_x86_64_isel_t *isel, const scc_lir_instr_t *instr) {
|
||||
|
||||
case SCC_LIR_JMP: {
|
||||
scc_x86_operand_value_t jmp_bb =
|
||||
scc_x86_op_block(instr->metadata.jmp_target);
|
||||
scc_x86_op_reloc_block(instr->metadata.jmp_target, 0);
|
||||
add_instr_1(isel, SCC_X86_IFORM_JMP_RELBRZ, jmp_bb);
|
||||
} break;
|
||||
|
||||
@@ -458,6 +473,7 @@ void scc_isel_x86_64(scc_mir_module_t *mir_module,
|
||||
Assert(func_meta != nullptr);
|
||||
scc_mir_func_meta_init(func_meta);
|
||||
func_meta->vregs_count = SCC_LIR_FUNC_META(func)->vregs_count;
|
||||
func_meta->need_va_args = SCC_LIR_FUNC_META(func)->is_va_arg;
|
||||
func->meta = func_meta;
|
||||
|
||||
isel->func = func;
|
||||
|
||||
@@ -29,8 +29,13 @@ static void frame_alloc_impl(scc_frame_layout_t *ctx,
|
||||
ctx->offset += slot->size;
|
||||
slot->offset = ctx->offset;
|
||||
}
|
||||
op->mem.base = SCC_X86_REG_RSP;
|
||||
op->mem.disp = -slot->offset;
|
||||
*op = scc_x86_op_mem((scc_x86_mem_t){
|
||||
.seg = SCC_X86_REG_INVALID,
|
||||
.base = SCC_X86_REG_RSP,
|
||||
.disp = {.displacement = -slot->offset},
|
||||
.index = SCC_X86_REG_INVALID,
|
||||
.scale = 1,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user