feat(ir2mcode): 添加帧分配器框架和Windows 64位实现
添加了frame_alloc.h头文件定义帧分配器操作接口,实现了Windows 64位 平台的帧分配器实现,包括槽位分配、偏移计算和栈帧布局管理功能。 BREAKING CHANGE: 移除了旧的frame_manager.h接口,采用新的frame_alloc_ops_t 抽象接口。 fix(ast2ir): 修复字符串字面量表达式返回值问题 修复了AST到IR转换过程中字符串字面量表达式的处理,确保正确返回 创建的常量字符串值引用而非直接跳出。 fix(ir): 修复内置memcpy函数参数验证和类型比较逻辑 在IR构建器中为builtin_memcpy函数添加参数空指针检查,在类型比较 函数中添加未知类型的边界条件处理,增强系统稳定性。 refactor(ir2mcode): 重构寄存器分配器接口以支持帧分配器集成 修改寄存器分配器接口以接受帧分配器参数,统一节点到位置的映射表 命名,并提供便捷的栈大小和偏移获取接口。
This commit is contained in:
@@ -14,23 +14,51 @@ static bool scc_type_is_signed(scc_ir_type_t *type) {
|
||||
static void parse_location(scc_ir2mcode_ctx_t *ctx, scc_reg_loc_t *loc,
|
||||
scc_ir_value_ref_t node_ref) {
|
||||
Assert(ctx != nullptr && loc != nullptr);
|
||||
scc_ir_value_t *node = scc_ir_module_get_value(GET_MODULE(ctx), node_ref);
|
||||
if (node == nullptr) {
|
||||
LOG_FATAL("invalid node ref");
|
||||
scc_ir_value_t *value = scc_ir_module_get_value(GET_MODULE(ctx), node_ref);
|
||||
if (value == nullptr) {
|
||||
LOG_FATAL("invalid value ref");
|
||||
UNREACHABLE();
|
||||
return;
|
||||
}
|
||||
usize idx = 0;
|
||||
switch (node->tag) {
|
||||
switch (value->tag) {
|
||||
case SCC_IR_VALUE_TAG_CONST_INT:
|
||||
scc_ir_type_t *type =
|
||||
scc_ir_module_get_type(GET_MODULE(ctx), node->type);
|
||||
scc_ir_module_get_type(GET_MODULE(ctx), value->type);
|
||||
Assert(type != 0);
|
||||
Assert(type->tag == SCC_IR_TYPE_u32 || type->tag == SCC_IR_TYPE_i32);
|
||||
*loc = (scc_reg_loc_t){
|
||||
.kind = SCC_REG_KIND_IMM,
|
||||
.idx = (usize)node->data.const_int.int32,
|
||||
};
|
||||
switch (type->tag) {
|
||||
case SCC_IR_TYPE_u8:
|
||||
case SCC_IR_TYPE_i8:
|
||||
*loc = (scc_reg_loc_t){
|
||||
.kind = SCC_REG_KIND_IMM,
|
||||
.data.data = (usize)value->data.const_int.int8,
|
||||
};
|
||||
break;
|
||||
case SCC_IR_TYPE_u16:
|
||||
case SCC_IR_TYPE_i16:
|
||||
*loc = (scc_reg_loc_t){
|
||||
.kind = SCC_REG_KIND_IMM,
|
||||
.data.data = (usize)value->data.const_int.int16,
|
||||
};
|
||||
break;
|
||||
case SCC_IR_TYPE_u32:
|
||||
case SCC_IR_TYPE_i32:
|
||||
*loc = (scc_reg_loc_t){
|
||||
.kind = SCC_REG_KIND_IMM,
|
||||
.data.data = (usize)value->data.const_int.int32,
|
||||
};
|
||||
break;
|
||||
case SCC_IR_TYPE_u64:
|
||||
case SCC_IR_TYPE_i64:
|
||||
*loc = (scc_reg_loc_t){
|
||||
.kind = SCC_REG_KIND_IMM,
|
||||
.data.data = (usize)value->data.const_int.int64,
|
||||
};
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
case SCC_IR_VALUE_TAG_CONST_UINT:
|
||||
case SCC_IR_VALUE_TAG_CONST_FLOAT:
|
||||
@@ -39,18 +67,7 @@ static void parse_location(scc_ir2mcode_ctx_t *ctx, scc_reg_loc_t *loc,
|
||||
case SCC_IR_VALUE_TAG_GLOBAL_ALLOC:
|
||||
TODO();
|
||||
break;
|
||||
case SCC_IR_VALUE_TAG_FUNC_ARG_REF: {
|
||||
scc_ir_type_t *type =
|
||||
scc_ir_module_get_type(GET_MODULE(ctx), node->type);
|
||||
Assert(type != 0);
|
||||
scc_reg_loc_t arg_loc;
|
||||
// arg_loc.kind = SCC_REG_KIND_FUNC_ARG;
|
||||
// arg_loc.idx = node->data.arg_ref.idx;
|
||||
arg_loc.kind = SCC_REG_KIND_STACK_ADDR;
|
||||
arg_loc.idx = 8 * node->data.arg_ref.idx;
|
||||
*loc = arg_loc;
|
||||
return;
|
||||
}
|
||||
case SCC_IR_VALUE_TAG_FUNC_ARG_REF:
|
||||
case SCC_IR_VALUE_TAG_ALLOC:
|
||||
default:
|
||||
idx = (usize)scc_hashtable_get(ctx->noderef2regloc,
|
||||
@@ -58,62 +75,65 @@ static void parse_location(scc_ir2mcode_ctx_t *ctx, scc_reg_loc_t *loc,
|
||||
break;
|
||||
}
|
||||
|
||||
Assert(idx > 0 && idx <= scc_vec_size(ctx->reg_alloc.reg_loc_vec));
|
||||
*loc = scc_vec_at(ctx->reg_alloc.reg_loc_vec, idx - 1);
|
||||
Assert(idx > 0 && idx <= scc_vec_size(ctx->reg_alloc.loc_vec));
|
||||
*loc = scc_vec_at(ctx->reg_alloc.loc_vec, idx - 1);
|
||||
}
|
||||
|
||||
static void load_value_to_reg(scc_mcode_t *mcode, scc_reg_loc_t *loc, int reg) {
|
||||
static void load_value_to_reg(scc_ir2mcode_ctx_t *ctx, scc_reg_loc_t *loc,
|
||||
int reg) {
|
||||
scc_mcode_t *mcode = &ctx->sect_mcode;
|
||||
switch (loc->kind) {
|
||||
case SCC_REG_KIND_GPR:
|
||||
if (loc->idx != reg) {
|
||||
scc_mcode_amd64_mov_r64_r64(mcode, reg, loc->idx);
|
||||
if (loc->data.gpr_idx != reg) {
|
||||
scc_mcode_amd64_mov_r64_r64(mcode, reg, loc->data.gpr_idx);
|
||||
} else {
|
||||
TODO();
|
||||
}
|
||||
break;
|
||||
case SCC_REG_KIND_STACK:
|
||||
// FIXME -8 for rdp
|
||||
scc_mcode_amd64_mov_r64_m64_disp32(mcode, reg, SCC_AMD64_RBP,
|
||||
-loc->idx - 8);
|
||||
break;
|
||||
case SCC_REG_KIND_IMM:
|
||||
scc_mcode_amd64_mov_r64_imm64(mcode, reg, loc->idx); // 或 imm32
|
||||
scc_mcode_amd64_mov_r64_m64_disp32(
|
||||
mcode, reg, SCC_AMD64_RBP,
|
||||
scc_reg_stack_offset(&ctx->reg_alloc, loc));
|
||||
break;
|
||||
case SCC_REG_KIND_STACK_ADDR:
|
||||
// 将栈地址加载到寄存器(取地址)
|
||||
// FIXME -8 for rdp
|
||||
scc_mcode_amd64_lea_r64_m64_disp32(mcode, reg, SCC_AMD64_RBP,
|
||||
-loc->idx - 8);
|
||||
scc_mcode_amd64_lea_r64_m64_disp32(
|
||||
mcode, reg, SCC_AMD64_RBP,
|
||||
scc_reg_stack_offset(&ctx->reg_alloc, loc));
|
||||
break;
|
||||
case SCC_REG_KIND_IMM:
|
||||
scc_mcode_amd64_mov_r64_imm64(mcode, reg, loc->data.data); // 或 imm32
|
||||
break;
|
||||
default:
|
||||
LOG_FATAL("unsupported location");
|
||||
}
|
||||
}
|
||||
|
||||
static void store_value_from_reg(scc_mcode_t *mcode, scc_reg_loc_t *loc,
|
||||
static void store_value_from_reg(scc_ir2mcode_ctx_t *ctx, scc_reg_loc_t *loc,
|
||||
int reg) {
|
||||
scc_mcode_t *mcode = &ctx->sect_mcode;
|
||||
switch (loc->kind) {
|
||||
case SCC_REG_KIND_GPR:
|
||||
if (loc->idx != reg) {
|
||||
scc_mcode_amd64_mov_r64_r64(mcode, loc->idx, reg);
|
||||
if (loc->data.gpr_idx != reg) {
|
||||
scc_mcode_amd64_mov_r64_r64(mcode, loc->data.gpr_idx, reg);
|
||||
}
|
||||
break;
|
||||
case SCC_REG_KIND_STACK:
|
||||
// FIXME -8 for rdp
|
||||
scc_mcode_amd64_mov_m64_disp32_r64(mcode, SCC_AMD64_RBP, -loc->idx - 8,
|
||||
reg);
|
||||
scc_mcode_amd64_mov_m64_disp32_r64(
|
||||
mcode, SCC_AMD64_RBP, scc_reg_stack_offset(&ctx->reg_alloc, loc),
|
||||
reg);
|
||||
break;
|
||||
case SCC_REG_KIND_STACK_ADDR:
|
||||
// 将寄存器的值存储到栈地址
|
||||
scc_mcode_amd64_mov_m64_disp32_r64(
|
||||
mcode, SCC_AMD64_RBP, scc_reg_stack_offset(&ctx->reg_alloc, loc),
|
||||
reg);
|
||||
break;
|
||||
case SCC_REG_KIND_IMM:
|
||||
LOG_FATAL("cannot store to immediate");
|
||||
break;
|
||||
case SCC_REG_KIND_STACK_ADDR:
|
||||
// 将寄存器的值存储到栈地址
|
||||
// FIXME -8 for rdp
|
||||
scc_mcode_amd64_mov_m64_disp32_r64(mcode, SCC_AMD64_RBP, -loc->idx - 8,
|
||||
reg);
|
||||
break;
|
||||
default:
|
||||
LOG_FATAL("unsupported location");
|
||||
Panic("unsupported location %d", loc->kind);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -127,15 +147,49 @@ typedef SCC_VEC(patch_t) patch_vec_t;
|
||||
|
||||
static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
patch_vec_t *patches) {
|
||||
scc_ir_value_t *node = scc_ir_module_get_value(GET_MODULE(ctx), node_ref);
|
||||
if (node == nullptr) {
|
||||
LOG_ERROR("invalid node ref");
|
||||
scc_ir_value_t *value = scc_ir_module_get_value(GET_MODULE(ctx), node_ref);
|
||||
if (value == nullptr) {
|
||||
LOG_ERROR("invalid value ref");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (node->tag) {
|
||||
switch (value->tag) {
|
||||
case SCC_IR_VALUE_TAG_BUILTIN: {
|
||||
scc_ir_builtin_t *builtin = &value->data.builtin;
|
||||
switch (builtin->tag) {
|
||||
case SCC_IR_BUILTIN_TAG_MEMCPY: {
|
||||
// 1. 获取操作数的位置
|
||||
scc_reg_loc_t dest_loc, src_loc, size_loc;
|
||||
parse_location(ctx, &dest_loc, builtin->func.memcpy.dest);
|
||||
parse_location(ctx, &src_loc, builtin->func.memcpy.src);
|
||||
scc_ir_value_t *const_value = scc_ir_module_get_value(
|
||||
GET_MODULE(ctx), builtin->func.memcpy.size);
|
||||
Assert(const_value->tag == SCC_IR_VALUE_TAG_CONST_INT);
|
||||
size_loc.kind = SCC_REG_KIND_IMM;
|
||||
size_loc.data.data = const_value->data.const_int.int64;
|
||||
|
||||
// 2. 将 dest 地址加载到 RDI(rep movsb 目标)
|
||||
load_value_to_reg(ctx, &dest_loc, SCC_AMD64_RDI);
|
||||
// 3. 将 src 地址加载到 RSI
|
||||
load_value_to_reg(ctx, &src_loc, SCC_AMD64_RSI);
|
||||
// 4. 将长度加载到 RCX
|
||||
load_value_to_reg(ctx, &size_loc, SCC_AMD64_RCX);
|
||||
|
||||
// 5. 如果长度可能为 0,可以跳过,但 rep movsb 处理 0
|
||||
// 也没问题,只是多一次指令。 生成 rep movsb 指令(字节复制)
|
||||
// 需要使用 REX.W 前缀保证 64 位操作,但 rep movsb 本身不需要 REX.W
|
||||
// 为了复制字节,使用 rep movsb (0xF3 0xA4)
|
||||
scc_mcode_add_u8(&ctx->sect_mcode, 0xF3); // rep prefix
|
||||
scc_mcode_add_u8(&ctx->sect_mcode, 0xA4); // movsb
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Panic("unsupported builtin");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SCC_IR_VALUE_TAG_CONV: ///< 类型转换
|
||||
LOG_FATAL("Unsupported node type: %d", node->tag);
|
||||
LOG_FATAL("Unsupported value type: %d", value->tag);
|
||||
break;
|
||||
///< 函数参数引用
|
||||
case SCC_IR_VALUE_TAG_FUNC_ARG_REF:
|
||||
@@ -148,16 +202,16 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
break;
|
||||
///< 加载数据
|
||||
case SCC_IR_VALUE_TAG_LOAD: {
|
||||
// node->data.load.target
|
||||
// value->data.load.target
|
||||
scc_reg_loc_t from;
|
||||
scc_reg_loc_t to;
|
||||
parse_location(ctx, &from, node->data.load.target);
|
||||
parse_location(ctx, &from, value->data.load.target);
|
||||
parse_location(ctx, &to, node_ref);
|
||||
|
||||
load_value_to_reg(&ctx->sect_mcode, &from, SCC_AMD64_RCX);
|
||||
load_value_to_reg(ctx, &from, SCC_AMD64_RCX);
|
||||
// 获取基类型宽度
|
||||
scc_ir_type_t *ptr_type = scc_ir_module_get_type_by_value(
|
||||
GET_MODULE(ctx), node->data.load.target);
|
||||
GET_MODULE(ctx), value->data.load.target);
|
||||
scc_ir_type_t *base_type = scc_ir_module_get_type(
|
||||
GET_MODULE(ctx), ptr_type->data.pointer.base);
|
||||
int width = scc_ir2mcode_type_width(GET_MODULE(ctx), base_type);
|
||||
@@ -195,23 +249,23 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
SCC_AMD64_RCX);
|
||||
}
|
||||
// 存储结果
|
||||
store_value_from_reg(&ctx->sect_mcode, &to, SCC_AMD64_RAX);
|
||||
store_value_from_reg(ctx, &to, SCC_AMD64_RAX);
|
||||
break;
|
||||
}
|
||||
///< 存储数据
|
||||
case SCC_IR_VALUE_TAG_STORE: {
|
||||
scc_reg_loc_t val_loc, addr_loc;
|
||||
parse_location(ctx, &val_loc, node->data.store.value);
|
||||
parse_location(ctx, &addr_loc, node->data.store.target);
|
||||
parse_location(ctx, &val_loc, value->data.store.value);
|
||||
parse_location(ctx, &addr_loc, value->data.store.target);
|
||||
|
||||
// 将值加载到 RAX
|
||||
load_value_to_reg(&ctx->sect_mcode, &val_loc, SCC_AMD64_RAX);
|
||||
load_value_to_reg(ctx, &val_loc, SCC_AMD64_RAX);
|
||||
// 将目标地址加载到 RCX
|
||||
load_value_to_reg(&ctx->sect_mcode, &addr_loc, SCC_AMD64_RCX);
|
||||
load_value_to_reg(ctx, &addr_loc, SCC_AMD64_RCX);
|
||||
|
||||
// 获取目标指针的基类型宽度
|
||||
scc_ir_type_t *ptr_type = scc_ir_module_get_type_by_value(
|
||||
GET_MODULE(ctx), node->data.store.target);
|
||||
GET_MODULE(ctx), value->data.store.target);
|
||||
scc_ir_type_t *base_type = scc_ir_module_get_type(
|
||||
GET_MODULE(ctx), ptr_type->data.pointer.base);
|
||||
int width = scc_ir2mcode_type_width(GET_MODULE(ctx), base_type);
|
||||
@@ -238,7 +292,7 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
parse_location(ctx, &loc_res, node_ref);
|
||||
|
||||
scc_ir_value_t *src_addr = scc_ir_module_get_value(
|
||||
GET_MODULE(ctx), node->data.get_ptr.src_addr);
|
||||
GET_MODULE(ctx), value->data.get_ptr.src_addr);
|
||||
Assert(src_addr != nullptr);
|
||||
|
||||
if (src_addr->tag == SCC_IR_VALUE_TAG_GLOBAL_ALLOC) {
|
||||
@@ -254,25 +308,24 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
.reloc_type = SCCF_RELOC_TYPE_REL,
|
||||
.offset = scc_vec_size(ctx->sect_mcode.mcode) - 4,
|
||||
.addend = 4,
|
||||
.sect_type = SCCF_SECT_DATA,
|
||||
.sect_type = SCCF_SECT_CODE,
|
||||
.sym_idx = sym_idx,
|
||||
});
|
||||
} else if (src_addr->tag == SCC_IR_VALUE_TAG_ALLOC) {
|
||||
// 栈上变量:地址为 rbp - offset
|
||||
scc_reg_loc_t src_loc;
|
||||
parse_location(ctx, &src_loc, node->data.get_ptr.src_addr);
|
||||
// src_loc.kind 应为 SCC_REG_KIND_STACK_ADDR,idx 是虚拟偏移(正数)
|
||||
scc_mcode_amd64_lea_r64_m64_disp32(&ctx->sect_mcode, SCC_AMD64_RAX,
|
||||
SCC_AMD64_RBP, -src_loc.idx - 8);
|
||||
parse_location(ctx, &src_loc, value->data.get_ptr.src_addr);
|
||||
src_loc.kind = SCC_REG_KIND_STACK_ADDR;
|
||||
load_value_to_reg(ctx, &src_loc, SCC_AMD64_RAX);
|
||||
} else {
|
||||
// 其他情况(如链式 getptr):源地址值已经存储在某个位置,直接加载到
|
||||
// RAX
|
||||
scc_reg_loc_t src_loc;
|
||||
parse_location(ctx, &src_loc, node->data.get_ptr.src_addr);
|
||||
load_value_to_reg(&ctx->sect_mcode, &src_loc, SCC_AMD64_RAX);
|
||||
parse_location(ctx, &src_loc, value->data.get_ptr.src_addr);
|
||||
load_value_to_reg(ctx, &src_loc, SCC_AMD64_RAX);
|
||||
}
|
||||
|
||||
store_value_from_reg(&ctx->sect_mcode, &loc_res, SCC_AMD64_RAX);
|
||||
store_value_from_reg(ctx, &loc_res, SCC_AMD64_RAX);
|
||||
break;
|
||||
}
|
||||
case SCC_IR_VALUE_TAG_GET_ELEM_PTR: ///< 获取元素指针(used by array)
|
||||
@@ -280,17 +333,17 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
///< 二元运算
|
||||
case SCC_IR_VALUE_TAG_OP: {
|
||||
scc_reg_loc_t loc_lhs;
|
||||
parse_location(ctx, &loc_lhs, node->data.op.lhs);
|
||||
parse_location(ctx, &loc_lhs, value->data.op.lhs);
|
||||
scc_reg_loc_t loc_rhs;
|
||||
parse_location(ctx, &loc_rhs, node->data.op.rhs);
|
||||
parse_location(ctx, &loc_rhs, value->data.op.rhs);
|
||||
scc_reg_loc_t loc_res;
|
||||
parse_location(ctx, &loc_res, node_ref);
|
||||
|
||||
// 将左操作数加载到 RAX(临时结果寄存器)
|
||||
load_value_to_reg(&ctx->sect_mcode, &loc_lhs, SCC_AMD64_RAX);
|
||||
load_value_to_reg(ctx, &loc_lhs, SCC_AMD64_RAX);
|
||||
// 将右操作数加载到 RCX
|
||||
load_value_to_reg(&ctx->sect_mcode, &loc_rhs, SCC_AMD64_RCX);
|
||||
switch (node->data.op.op) {
|
||||
load_value_to_reg(ctx, &loc_rhs, SCC_AMD64_RCX);
|
||||
switch (value->data.op.op) {
|
||||
case SCC_IR_OP_EMPTY:
|
||||
Panic("unsupported empty op");
|
||||
break;
|
||||
@@ -378,30 +431,30 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
SCC_AMD64_RAX);
|
||||
break;
|
||||
default:
|
||||
LOG_FATAL("unknown op: %d", node->data.op.op);
|
||||
LOG_FATAL("unknown op: %d", value->data.op.op);
|
||||
break;
|
||||
}
|
||||
// 将 RAX 中的结果存储到 res 位置
|
||||
store_value_from_reg(&ctx->sect_mcode, &loc_res, SCC_AMD64_RAX);
|
||||
store_value_from_reg(ctx, &loc_res, SCC_AMD64_RAX);
|
||||
break;
|
||||
}
|
||||
///< 有条件分支
|
||||
case SCC_IR_VALUE_TAG_BRANCH: {
|
||||
scc_reg_loc_t loc;
|
||||
parse_location(ctx, &loc, node->data.branch.cond);
|
||||
parse_location(ctx, &loc, value->data.branch.cond);
|
||||
// (void)loc;
|
||||
load_value_to_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RAX);
|
||||
load_value_to_reg(ctx, &loc, SCC_AMD64_RAX);
|
||||
scc_mcode_amd64_cmp_r64_imm32(&ctx->sect_mcode, SCC_AMD64_RAX, 0);
|
||||
|
||||
scc_mcode_amd64_jcc_rel32(&ctx->sect_mcode, SCC_AMD64_COND_NE, 0);
|
||||
patch_t patch_true = {.pos = scc_vec_size(ctx->sect_mcode.mcode),
|
||||
.target_bb_ref =
|
||||
(usize)node->data.branch.true_bblock};
|
||||
(usize)value->data.branch.true_bblock};
|
||||
scc_vec_push(*patches, patch_true);
|
||||
scc_mcode_amd64_jmp_rel32(&ctx->sect_mcode, 0);
|
||||
patch_t patch_false = {.pos = scc_vec_size(ctx->sect_mcode.mcode),
|
||||
.target_bb_ref =
|
||||
(usize)node->data.branch.false_bblock};
|
||||
(usize)value->data.branch.false_bblock};
|
||||
scc_vec_push(*patches, patch_false);
|
||||
break;
|
||||
}
|
||||
@@ -409,8 +462,8 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
case SCC_IR_VALUE_TAG_JUMP: {
|
||||
scc_mcode_amd64_jmp_rel32(&ctx->sect_mcode, 0);
|
||||
usize pos = scc_vec_size(ctx->sect_mcode.mcode);
|
||||
patch_t patch = {.pos = pos,
|
||||
.target_bb_ref = (usize)node->data.jump.target_bblock};
|
||||
patch_t patch = {
|
||||
.pos = pos, .target_bb_ref = (usize)value->data.jump.target_bblock};
|
||||
scc_vec_push(*patches, patch);
|
||||
break;
|
||||
}
|
||||
@@ -425,16 +478,16 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
R8 不稳定的 第三个整型自变量
|
||||
R9 不稳定的 第四个整型自变量
|
||||
*/
|
||||
scc_vec_foreach(node->data.call.args, i) {
|
||||
parse_location(ctx, &loc, scc_vec_at(node->data.call.args, i));
|
||||
scc_vec_foreach(value->data.call.args, i) {
|
||||
parse_location(ctx, &loc, scc_vec_at(value->data.call.args, i));
|
||||
if (i == 0) {
|
||||
load_value_to_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RCX);
|
||||
load_value_to_reg(ctx, &loc, SCC_AMD64_RCX);
|
||||
} else if (i == 1) {
|
||||
load_value_to_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RDX);
|
||||
load_value_to_reg(ctx, &loc, SCC_AMD64_RDX);
|
||||
} else if (i == 2) {
|
||||
load_value_to_reg(&ctx->sect_mcode, &loc, SCC_AMD64_R8);
|
||||
load_value_to_reg(ctx, &loc, SCC_AMD64_R8);
|
||||
} else if (i == 3) {
|
||||
load_value_to_reg(&ctx->sect_mcode, &loc, SCC_AMD64_R9);
|
||||
load_value_to_reg(ctx, &loc, SCC_AMD64_R9);
|
||||
} else {
|
||||
LOG_FATAL("not support more than 4 args");
|
||||
}
|
||||
@@ -442,7 +495,7 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
}
|
||||
|
||||
scc_ir_func_t *func =
|
||||
scc_ir_module_get_func(GET_MODULE(ctx), node->data.call.callee);
|
||||
scc_ir_module_get_func(GET_MODULE(ctx), value->data.call.callee);
|
||||
if (!func) {
|
||||
LOG_ERROR("invalid function reference");
|
||||
return;
|
||||
@@ -473,16 +526,16 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
GET_MODULE(ctx), func_type->data.function.ret_type);
|
||||
if (ret_type && ret_type->tag != SCC_IR_TYPE_void) {
|
||||
parse_location(ctx, &loc, node_ref);
|
||||
store_value_from_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RAX);
|
||||
store_value_from_reg(ctx, &loc, SCC_AMD64_RAX);
|
||||
}
|
||||
break;
|
||||
}
|
||||
///< 函数返回
|
||||
case SCC_IR_VALUE_TAG_RET: {
|
||||
if (node->data.ret.ret_val) {
|
||||
if (value->data.ret.ret_val) {
|
||||
scc_reg_loc_t loc;
|
||||
parse_location(ctx, &loc, node->data.ret.ret_val);
|
||||
load_value_to_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RAX);
|
||||
parse_location(ctx, &loc, value->data.ret.ret_val);
|
||||
load_value_to_reg(ctx, &loc, SCC_AMD64_RAX);
|
||||
}
|
||||
scc_mcode_amd64_add_rsp_imm32(&ctx->sect_mcode, ctx->stack_size);
|
||||
scc_mcode_amd64_pop_r64(&ctx->sect_mcode, SCC_AMD64_RBP);
|
||||
@@ -490,7 +543,7 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG_FATAL("unknown node type: %d", node->tag);
|
||||
LOG_FATAL("unknown value type: %d", value->tag);
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
@@ -511,14 +564,13 @@ static int equal_func(const void *key1, const void *key2) {
|
||||
return (usize)key1 - (usize)key2;
|
||||
}
|
||||
|
||||
const scc_frame_alloc_ops_t *scc_frame_alloc_win64_ops(void);
|
||||
static void parse_function(scc_ir2mcode_ctx_t *ctx, scc_ir_func_t *func) {
|
||||
// FIXME using API instead
|
||||
ctx->reg_alloc.init_stack_size = 8;
|
||||
ctx->noderef2regloc = scc_reg_alloc(&ctx->reg_alloc, func);
|
||||
// 对齐到 16 字节
|
||||
// FIXME
|
||||
ctx->stack_size += 8; ///< for rbp
|
||||
ctx->stack_size = (ctx->reg_alloc.alloc_stack_size + 15) & ~15;
|
||||
// FIXME using other
|
||||
ctx->noderef2regloc =
|
||||
scc_reg_alloc_run(&ctx->reg_alloc, func, scc_frame_alloc_win64_ops());
|
||||
ctx->stack_size = scc_reg_stack_size(&ctx->reg_alloc);
|
||||
Assert(ctx->noderef2regloc);
|
||||
|
||||
usize bblock_cnt = scc_vec_size(func->bblocks);
|
||||
usize *bblock_offsets = scc_calloc(bblock_cnt, sizeof(usize));
|
||||
@@ -544,13 +596,13 @@ static void parse_function(scc_ir2mcode_ctx_t *ctx, scc_ir_func_t *func) {
|
||||
scc_ir_value_ref_t node_ref = scc_vec_at(func->params, i);
|
||||
parse_location(ctx, &loc, node_ref);
|
||||
if (i == 0) {
|
||||
store_value_from_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RCX);
|
||||
store_value_from_reg(ctx, &loc, SCC_AMD64_RCX);
|
||||
} else if (i == 1) {
|
||||
store_value_from_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RDX);
|
||||
store_value_from_reg(ctx, &loc, SCC_AMD64_RDX);
|
||||
} else if (i == 2) {
|
||||
store_value_from_reg(&ctx->sect_mcode, &loc, SCC_AMD64_R8);
|
||||
store_value_from_reg(ctx, &loc, SCC_AMD64_R8);
|
||||
} else if (i == 3) {
|
||||
store_value_from_reg(&ctx->sect_mcode, &loc, SCC_AMD64_R9);
|
||||
store_value_from_reg(ctx, &loc, SCC_AMD64_R9);
|
||||
} else {
|
||||
LOG_FATAL("not support more than 4 args");
|
||||
}
|
||||
@@ -589,11 +641,9 @@ static void parse_function(scc_ir2mcode_ctx_t *ctx, scc_ir_func_t *func) {
|
||||
}
|
||||
|
||||
void scc_ir2amd64(scc_ir2mcode_ctx_t *ctx) {
|
||||
scc_reg_alloc_init(&ctx->reg_alloc, scc_reg_alloc_with_stack,
|
||||
scc_reg_alloc_init(&ctx->reg_alloc, scc_reg_alloc_strategy_pure_stack,
|
||||
GET_MODULE(ctx));
|
||||
|
||||
sccf_sect_data_t data_section;
|
||||
scc_vec_init(data_section);
|
||||
scc_vec_foreach(ctx->cprog->global_vals, i) {
|
||||
scc_ir_value_t *galloc = scc_ir_module_get_value(
|
||||
GET_MODULE(ctx), scc_vec_at(ctx->cprog->global_vals, i));
|
||||
@@ -612,7 +662,7 @@ void scc_ir2amd64(scc_ir2mcode_ctx_t *ctx) {
|
||||
.sccf_sym_vis = SCCF_SYM_VIS_DEFAULT,
|
||||
};
|
||||
scc_vec_foreach(value->data.const_array.elements, j) {
|
||||
scc_vec_push(data_section,
|
||||
scc_vec_push(ctx->sect_data,
|
||||
scc_vec_at(value->data.const_array.elements, j));
|
||||
}
|
||||
usize sym_idx =
|
||||
@@ -695,7 +745,7 @@ void scc_ir2amd64(scc_ir2mcode_ctx_t *ctx) {
|
||||
scc_vec_size(ctx->sect_mcode.mcode));
|
||||
sccf_builder_add_text_section(ctx->builder, &text_section);
|
||||
|
||||
sccf_builder_add_data_section(ctx->builder, &data_section);
|
||||
// FIXME
|
||||
sccf_builder_add_data_section(ctx->builder, &ctx->sect_data);
|
||||
// FIXME maybe _entry and add crt
|
||||
ctx->builder->entry_symbol_name = "main";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user