refactor(ast2ir): 更新IR构建器接口并重构类型映射
- 将IR构建器初始化函数修改为接受cprog参数 - 添加scc_ast2ir_ctx_drop函数用于资源清理 - 更新类型标识符命名规范,从大写改为小写形式 - 替换scc_ir_ctx_get_*函数调用为scc_ir_module_get_*函数 - 移除对ir_builtin.h的依赖,改用ir_builder.h中的构建器函数 - 为整数常量创建添加专门的构建器辅助函数 fix(ir): 重构IR上下文和模块管理结构 - 将原有的scc_ir_cprog_ctx_t拆分为scc_ir_module_t和scc_ir_ctx_t - 添加scc_ir_module_t结构用于统一管理IR对象存储 - 更新IR类型枚举名称格式,从SCC_IR_TYPE_XXX改为SCC_IR_TYPE_xxx - 添加整数、无符号整数和浮点数常量联合体定义 - 移除ir_base.h和ir_builtin.h头文件,整合到scc_ir.h中 feat(ir_builder): 添加类型构建器函数和常量创建功能 - 为各种基础类型添加scc_ir_builder_type_*内联函数 - 实现scc_ir_builder_const_int函数用于创建整数常量 - 修改构建器初始化函数签名以接受cprog参数 - 更新构建器内部结构,使用指向cprog的指针而非嵌入式结构
This commit is contained in:
@@ -29,7 +29,7 @@ typedef scc_hashtable_t *(*scc_reg_alloc_func_t)(
|
||||
);
|
||||
|
||||
typedef struct scc_reg_alloc {
|
||||
scc_ir_cprog_ctx_t *ir_ctx; ///< IR上下文
|
||||
scc_ir_module_t *ir_module; ///< IR存储节点
|
||||
scc_hashtable_t node_ref2reg_loc; ///< 输出结果哈希表
|
||||
scc_reg_loc_vec_t reg_loc_vec;
|
||||
int gpr_caller_saved; ///< 函数可以随意修改,调用者如果在意需自行保护.
|
||||
@@ -41,7 +41,7 @@ typedef struct scc_reg_alloc {
|
||||
#define scc_reg_alloc(ctx, func) ((ctx)->reg_alloc_func(ctx, func))
|
||||
|
||||
void scc_reg_alloc_init(scc_reg_alloc_t *ctx, scc_reg_alloc_func_t func,
|
||||
scc_ir_cprog_ctx_t *ir_ctx);
|
||||
scc_ir_module_t *ir_module);
|
||||
scc_hashtable_t *scc_reg_alloc_with_stack(scc_reg_alloc_t *ctx,
|
||||
scc_ir_func_t *func);
|
||||
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
#include <scc_ir.h>
|
||||
#include <scc_mcode.h>
|
||||
#include <sccf_builder.h>
|
||||
|
||||
typedef struct {
|
||||
scc_ir_cprog_t *cprog;
|
||||
scc_ir_cprog_ctx_t *ir_ctx;
|
||||
scc_mcode_t mcode;
|
||||
sccf_builder_t builder;
|
||||
sccf_builder_t *builder;
|
||||
scc_mcode_t sect_mcode;
|
||||
sccf_sect_data_t sect_data;
|
||||
|
||||
// FIXME
|
||||
usize stack_size;
|
||||
@@ -21,7 +22,9 @@ typedef struct {
|
||||
// amd64
|
||||
|
||||
void scc_ir2mcode_init(scc_ir2mcode_ctx_t *ctx, scc_ir_cprog_t *cprog,
|
||||
scc_ir_cprog_ctx_t *ir_ctx, scc_mcode_arch_t arch);
|
||||
sccf_builder_t *builder, scc_mcode_arch_t arch);
|
||||
void scc_ir2mcode_drop(scc_ir2mcode_ctx_t *ctx);
|
||||
|
||||
void scc_ir2mcode(scc_ir2mcode_ctx_t *ctx);
|
||||
|
||||
#endif /* __SCC_IR2MCODE_H__ */
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
#include <reg_alloc.h>
|
||||
#include <scc_ir2mcode.h>
|
||||
|
||||
#define GET_MODULE(ctx) (&(ctx->cprog->module))
|
||||
|
||||
static void parse_location(scc_ir2mcode_ctx_t *ctx, scc_reg_loc_t *loc,
|
||||
scc_ir_node_ref_t node_ref) {
|
||||
Assert(ctx != null && loc != null);
|
||||
scc_ir_node_t *node = scc_ir_ctx_get_node(ctx->ir_ctx, node_ref);
|
||||
scc_ir_node_t *node = scc_ir_module_get_node(GET_MODULE(ctx), node_ref);
|
||||
if (node == null) {
|
||||
LOG_FATAL("invalid node ref");
|
||||
UNREACHABLE();
|
||||
@@ -15,9 +17,10 @@ static void parse_location(scc_ir2mcode_ctx_t *ctx, scc_reg_loc_t *loc,
|
||||
usize idx = 0;
|
||||
switch (node->tag) {
|
||||
case SCC_IR_NODE_CONST_INT:
|
||||
scc_ir_type_t *type = scc_ir_ctx_get_type(ctx->ir_ctx, node->type);
|
||||
scc_ir_type_t *type =
|
||||
scc_ir_module_get_type(GET_MODULE(ctx), node->type);
|
||||
Assert(type != 0);
|
||||
Assert(type->tag == SCC_IR_TYPE_U32 || type->tag == SCC_IR_TYPE_I32);
|
||||
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,
|
||||
@@ -28,7 +31,8 @@ static void parse_location(scc_ir2mcode_ctx_t *ctx, scc_reg_loc_t *loc,
|
||||
TODO();
|
||||
break;
|
||||
case SCC_IR_NODE_FUNC_ARG_REF: {
|
||||
scc_ir_type_t *type = scc_ir_ctx_get_type(ctx->ir_ctx, node->type);
|
||||
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;
|
||||
@@ -101,7 +105,7 @@ typedef SCC_VEC(patch_t) patch_vec_t;
|
||||
|
||||
static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
patch_vec_t *patches) {
|
||||
scc_ir_node_t *node = scc_ir_ctx_get_node(ctx->ir_ctx, node_ref);
|
||||
scc_ir_node_t *node = scc_ir_module_get_node(GET_MODULE(ctx), node_ref);
|
||||
if (node == null) {
|
||||
LOG_ERROR("invalid node ref");
|
||||
return;
|
||||
@@ -126,8 +130,8 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
scc_reg_loc_t to;
|
||||
parse_location(ctx, &from, node->data.load.target);
|
||||
parse_location(ctx, &to, node_ref);
|
||||
load_value_to_reg(&ctx->mcode, &from, SCC_AMD64_RAX);
|
||||
store_value_from_reg(&ctx->mcode, &to, SCC_AMD64_RAX);
|
||||
load_value_to_reg(&ctx->sect_mcode, &from, SCC_AMD64_RAX);
|
||||
store_value_from_reg(&ctx->sect_mcode, &to, SCC_AMD64_RAX);
|
||||
break;
|
||||
}
|
||||
case SCC_IR_NODE_STORE: ///< 存储数据
|
||||
@@ -136,8 +140,8 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
scc_reg_loc_t to;
|
||||
parse_location(ctx, &from, node->data.store.value);
|
||||
parse_location(ctx, &to, node->data.store.target);
|
||||
load_value_to_reg(&ctx->mcode, &from, SCC_AMD64_RAX);
|
||||
store_value_from_reg(&ctx->mcode, &to, SCC_AMD64_RAX);
|
||||
load_value_to_reg(&ctx->sect_mcode, &from, SCC_AMD64_RAX);
|
||||
store_value_from_reg(&ctx->sect_mcode, &to, SCC_AMD64_RAX);
|
||||
break;
|
||||
}
|
||||
case SCC_IR_NODE_GET_PTR: ///< 获取指针
|
||||
@@ -153,20 +157,20 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
parse_location(ctx, &loc_res, node_ref);
|
||||
|
||||
// 将左操作数加载到 RAX(临时结果寄存器)
|
||||
load_value_to_reg(&ctx->mcode, &loc_lhs, SCC_AMD64_RAX);
|
||||
load_value_to_reg(&ctx->sect_mcode, &loc_lhs, SCC_AMD64_RAX);
|
||||
// 将右操作数加载到 RCX
|
||||
load_value_to_reg(&ctx->mcode, &loc_rhs, SCC_AMD64_RCX);
|
||||
load_value_to_reg(&ctx->sect_mcode, &loc_rhs, SCC_AMD64_RCX);
|
||||
switch (node->data.op.op) {
|
||||
case SCC_IR_OP_ADD:
|
||||
scc_mcode_amd64_add_r64_r64(&ctx->mcode, SCC_AMD64_RAX,
|
||||
scc_mcode_amd64_add_r64_r64(&ctx->sect_mcode, SCC_AMD64_RAX,
|
||||
SCC_AMD64_RCX);
|
||||
break;
|
||||
case SCC_IR_OP_SUB:
|
||||
scc_mcode_amd64_sub_r64_r64(&ctx->mcode, SCC_AMD64_RAX,
|
||||
scc_mcode_amd64_sub_r64_r64(&ctx->sect_mcode, SCC_AMD64_RAX,
|
||||
SCC_AMD64_RCX);
|
||||
break;
|
||||
case SCC_IR_OP_MUL:
|
||||
scc_mcode_amd64_mul_r64(&ctx->mcode, SCC_AMD64_RCX);
|
||||
scc_mcode_amd64_mul_r64(&ctx->sect_mcode, SCC_AMD64_RCX);
|
||||
break;
|
||||
// [SCC_IR_OP_EMPTY] = "empty", [SCC_IR_OP_NEQ] = "!=",
|
||||
// [SCC_IR_OP_EQ] = "==", [SCC_IR_OP_GT] = ">",
|
||||
@@ -179,51 +183,51 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
// [SCC_IR_OP_SHL] = "<<", [SCC_IR_OP_SHR] = ">>",
|
||||
// [SCC_IR_OP_SAR] = ">>a", // Arithmetic shift right
|
||||
case SCC_IR_OP_NEQ:
|
||||
scc_mcode_amd64_cmp_r64_r64(&ctx->mcode, SCC_AMD64_RAX,
|
||||
scc_mcode_amd64_cmp_r64_r64(&ctx->sect_mcode, SCC_AMD64_RAX,
|
||||
SCC_AMD64_RCX);
|
||||
scc_mcode_amd64_setcc_r8(&ctx->mcode, SCC_AMD64_COND_NE,
|
||||
scc_mcode_amd64_setcc_r8(&ctx->sect_mcode, SCC_AMD64_COND_NE,
|
||||
SCC_AMD64_RAX);
|
||||
scc_mcode_amd64_movzx_r64_r8(&ctx->mcode, SCC_AMD64_RAX,
|
||||
scc_mcode_amd64_movzx_r64_r8(&ctx->sect_mcode, SCC_AMD64_RAX,
|
||||
SCC_AMD64_RAX);
|
||||
break;
|
||||
case SCC_IR_OP_EQ:
|
||||
scc_mcode_amd64_cmp_r64_r64(&ctx->mcode, SCC_AMD64_RAX,
|
||||
scc_mcode_amd64_cmp_r64_r64(&ctx->sect_mcode, SCC_AMD64_RAX,
|
||||
SCC_AMD64_RCX);
|
||||
scc_mcode_amd64_setcc_r8(&ctx->mcode, SCC_AMD64_COND_E,
|
||||
scc_mcode_amd64_setcc_r8(&ctx->sect_mcode, SCC_AMD64_COND_E,
|
||||
SCC_AMD64_RAX);
|
||||
scc_mcode_amd64_movzx_r64_r8(&ctx->mcode, SCC_AMD64_RAX,
|
||||
scc_mcode_amd64_movzx_r64_r8(&ctx->sect_mcode, SCC_AMD64_RAX,
|
||||
SCC_AMD64_RAX);
|
||||
break;
|
||||
case SCC_IR_OP_GT:
|
||||
scc_mcode_amd64_cmp_r64_r64(&ctx->mcode, SCC_AMD64_RAX,
|
||||
scc_mcode_amd64_cmp_r64_r64(&ctx->sect_mcode, SCC_AMD64_RAX,
|
||||
SCC_AMD64_RCX);
|
||||
scc_mcode_amd64_setcc_r8(&ctx->mcode, SCC_AMD64_COND_G,
|
||||
scc_mcode_amd64_setcc_r8(&ctx->sect_mcode, SCC_AMD64_COND_G,
|
||||
SCC_AMD64_RAX);
|
||||
scc_mcode_amd64_movzx_r64_r8(&ctx->mcode, SCC_AMD64_RAX,
|
||||
scc_mcode_amd64_movzx_r64_r8(&ctx->sect_mcode, SCC_AMD64_RAX,
|
||||
SCC_AMD64_RAX);
|
||||
break;
|
||||
case SCC_IR_OP_LT:
|
||||
scc_mcode_amd64_cmp_r64_r64(&ctx->mcode, SCC_AMD64_RAX,
|
||||
scc_mcode_amd64_cmp_r64_r64(&ctx->sect_mcode, SCC_AMD64_RAX,
|
||||
SCC_AMD64_RCX);
|
||||
scc_mcode_amd64_setcc_r8(&ctx->mcode, SCC_AMD64_COND_L,
|
||||
scc_mcode_amd64_setcc_r8(&ctx->sect_mcode, SCC_AMD64_COND_L,
|
||||
SCC_AMD64_RAX);
|
||||
scc_mcode_amd64_movzx_r64_r8(&ctx->mcode, SCC_AMD64_RAX,
|
||||
scc_mcode_amd64_movzx_r64_r8(&ctx->sect_mcode, SCC_AMD64_RAX,
|
||||
SCC_AMD64_RAX);
|
||||
break;
|
||||
case SCC_IR_OP_GE:
|
||||
scc_mcode_amd64_cmp_r64_r64(&ctx->mcode, SCC_AMD64_RAX,
|
||||
scc_mcode_amd64_cmp_r64_r64(&ctx->sect_mcode, SCC_AMD64_RAX,
|
||||
SCC_AMD64_RCX);
|
||||
scc_mcode_amd64_setcc_r8(&ctx->mcode, SCC_AMD64_COND_GE,
|
||||
scc_mcode_amd64_setcc_r8(&ctx->sect_mcode, SCC_AMD64_COND_GE,
|
||||
SCC_AMD64_RAX);
|
||||
scc_mcode_amd64_movzx_r64_r8(&ctx->mcode, SCC_AMD64_RAX,
|
||||
scc_mcode_amd64_movzx_r64_r8(&ctx->sect_mcode, SCC_AMD64_RAX,
|
||||
SCC_AMD64_RAX);
|
||||
break;
|
||||
case SCC_IR_OP_LE:
|
||||
scc_mcode_amd64_cmp_r64_r64(&ctx->mcode, SCC_AMD64_RAX,
|
||||
scc_mcode_amd64_cmp_r64_r64(&ctx->sect_mcode, SCC_AMD64_RAX,
|
||||
SCC_AMD64_RCX);
|
||||
scc_mcode_amd64_setcc_r8(&ctx->mcode, SCC_AMD64_COND_LE,
|
||||
scc_mcode_amd64_setcc_r8(&ctx->sect_mcode, SCC_AMD64_COND_LE,
|
||||
SCC_AMD64_RAX);
|
||||
scc_mcode_amd64_movzx_r64_r8(&ctx->mcode, SCC_AMD64_RAX,
|
||||
scc_mcode_amd64_movzx_r64_r8(&ctx->sect_mcode, SCC_AMD64_RAX,
|
||||
SCC_AMD64_RAX);
|
||||
break;
|
||||
default:
|
||||
@@ -231,7 +235,7 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
break;
|
||||
}
|
||||
// 将 RAX 中的结果存储到 res 位置
|
||||
store_value_from_reg(&ctx->mcode, &loc_res, SCC_AMD64_RAX);
|
||||
store_value_from_reg(&ctx->sect_mcode, &loc_res, SCC_AMD64_RAX);
|
||||
break;
|
||||
}
|
||||
///< 有条件分支
|
||||
@@ -239,16 +243,16 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
scc_reg_loc_t loc;
|
||||
parse_location(ctx, &loc, node->data.branch.cond);
|
||||
// (void)loc;
|
||||
load_value_to_reg(&ctx->mcode, &loc, SCC_AMD64_RAX);
|
||||
scc_mcode_amd64_cmp_r64_imm32(&ctx->mcode, SCC_AMD64_RAX, 0);
|
||||
load_value_to_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RAX);
|
||||
scc_mcode_amd64_cmp_r64_imm32(&ctx->sect_mcode, SCC_AMD64_RAX, 0);
|
||||
|
||||
scc_mcode_amd64_jcc_rel32(&ctx->mcode, SCC_AMD64_COND_NE, 0);
|
||||
patch_t patch_true = {.pos = scc_vec_size(ctx->mcode.mcode),
|
||||
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};
|
||||
scc_vec_push(*patches, patch_true);
|
||||
scc_mcode_amd64_jmp_rel32(&ctx->mcode, 0);
|
||||
patch_t patch_false = {.pos = scc_vec_size(ctx->mcode.mcode),
|
||||
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};
|
||||
scc_vec_push(*patches, patch_false);
|
||||
@@ -256,8 +260,8 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
}
|
||||
///< 无条件跳转
|
||||
case SCC_IR_NODE_JUMP: {
|
||||
scc_mcode_amd64_jmp_rel32(&ctx->mcode, 0);
|
||||
usize pos = scc_vec_size(ctx->mcode.mcode);
|
||||
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};
|
||||
scc_vec_push(*patches, patch);
|
||||
@@ -277,13 +281,13 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
scc_vec_foreach(node->data.call.args, i) {
|
||||
parse_location(ctx, &loc, scc_vec_at(node->data.call.args, i));
|
||||
if (i == 0) {
|
||||
load_value_to_reg(&ctx->mcode, &loc, SCC_AMD64_RCX);
|
||||
load_value_to_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RCX);
|
||||
} else if (i == 1) {
|
||||
load_value_to_reg(&ctx->mcode, &loc, SCC_AMD64_RDX);
|
||||
load_value_to_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RDX);
|
||||
} else if (i == 2) {
|
||||
load_value_to_reg(&ctx->mcode, &loc, SCC_AMD64_R8);
|
||||
load_value_to_reg(&ctx->sect_mcode, &loc, SCC_AMD64_R8);
|
||||
} else if (i == 3) {
|
||||
load_value_to_reg(&ctx->mcode, &loc, SCC_AMD64_R9);
|
||||
load_value_to_reg(&ctx->sect_mcode, &loc, SCC_AMD64_R9);
|
||||
} else {
|
||||
LOG_FATAL("not support more than 4 args");
|
||||
}
|
||||
@@ -291,32 +295,33 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
}
|
||||
|
||||
scc_ir_func_t *func =
|
||||
scc_ir_ctx_get_func(ctx->ir_ctx, node->data.call.callee);
|
||||
scc_ir_module_get_func(GET_MODULE(ctx), node->data.call.callee);
|
||||
if (!func) {
|
||||
LOG_ERROR("invalid function reference");
|
||||
return;
|
||||
}
|
||||
|
||||
scc_mcode_amd64_call_rel32(&ctx->mcode, 0);
|
||||
usize sym_idx = sccf_builder_get_symbol_idx(&ctx->builder, func->name);
|
||||
scc_mcode_amd64_call_rel32(&ctx->sect_mcode, 0);
|
||||
usize sym_idx = sccf_builder_get_symbol_idx(ctx->builder, func->name);
|
||||
Assert(sym_idx != 0);
|
||||
sccf_builder_add_reloc(&ctx->builder,
|
||||
(sccf_reloc_t){
|
||||
.reloc_type = SCCF_RELOC_TYPE_REL,
|
||||
.offset = scc_vec_size(ctx->mcode.mcode) - 4,
|
||||
.addend = 4,
|
||||
.sect_type = SCCF_SECT_CODE,
|
||||
.sym_idx = sym_idx,
|
||||
});
|
||||
sccf_builder_add_reloc(
|
||||
ctx->builder, (sccf_reloc_t){
|
||||
.reloc_type = SCCF_RELOC_TYPE_REL,
|
||||
.offset = scc_vec_size(ctx->sect_mcode.mcode) - 4,
|
||||
.addend = 4,
|
||||
.sect_type = SCCF_SECT_CODE,
|
||||
.sym_idx = sym_idx,
|
||||
});
|
||||
|
||||
// 处理返回值
|
||||
scc_ir_type_t *func_type = scc_ir_ctx_get_type(ctx->ir_ctx, func->type);
|
||||
scc_ir_type_t *func_type =
|
||||
scc_ir_module_get_type(GET_MODULE(ctx), func->type);
|
||||
Assert(func_type);
|
||||
scc_ir_type_t *ret_type =
|
||||
scc_ir_ctx_get_type(ctx->ir_ctx, func_type->data.function.ret_type);
|
||||
if (ret_type && ret_type->tag != SCC_IR_TYPE_VOID) {
|
||||
scc_ir_type_t *ret_type = scc_ir_module_get_type(
|
||||
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->mcode, &loc, SCC_AMD64_RAX);
|
||||
store_value_from_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RAX);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -325,11 +330,11 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
if (node->data.ret.ret_val) {
|
||||
scc_reg_loc_t loc;
|
||||
parse_location(ctx, &loc, node->data.ret.ret_val);
|
||||
load_value_to_reg(&ctx->mcode, &loc, SCC_AMD64_RAX);
|
||||
load_value_to_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RAX);
|
||||
}
|
||||
scc_mcode_amd64_add_rsp_imm32(&ctx->mcode, ctx->stack_size);
|
||||
scc_mcode_amd64_pop_r64(&ctx->mcode, SCC_AMD64_RBP);
|
||||
scc_mcode_amd64_ret(&ctx->mcode);
|
||||
scc_mcode_amd64_add_rsp_imm32(&ctx->sect_mcode, ctx->stack_size);
|
||||
scc_mcode_amd64_pop_r64(&ctx->sect_mcode, SCC_AMD64_RBP);
|
||||
scc_mcode_amd64_ret(&ctx->sect_mcode);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -374,24 +379,24 @@ static void parse_function(scc_ir2mcode_ctx_t *ctx, scc_ir_func_t *func) {
|
||||
patch_vec_t patches;
|
||||
scc_vec_init(patches);
|
||||
|
||||
scc_mcode_amd64_push_r64(&ctx->mcode, SCC_AMD64_RBP);
|
||||
scc_mcode_amd64_sub_rsp_imm32(&ctx->mcode, ctx->stack_size);
|
||||
scc_mcode_amd64_lea_r64_m64_disp32(&ctx->mcode, SCC_AMD64_RBP,
|
||||
scc_mcode_amd64_push_r64(&ctx->sect_mcode, SCC_AMD64_RBP);
|
||||
scc_mcode_amd64_sub_rsp_imm32(&ctx->sect_mcode, ctx->stack_size);
|
||||
scc_mcode_amd64_lea_r64_m64_disp32(&ctx->sect_mcode, SCC_AMD64_RBP,
|
||||
SCC_AMD64_RSP, ctx->stack_size);
|
||||
scc_reg_loc_t loc;
|
||||
scc_vec_foreach(func->params, i) {
|
||||
// scc_ir_node_t *param =
|
||||
// scc_ir_ctx_get_node(ctx->ir_ctx, );
|
||||
// scc_ir_module_get_node(GET_MODULE(ctx), );
|
||||
scc_ir_node_ref_t node_ref = scc_vec_at(func->params, i);
|
||||
parse_location(ctx, &loc, node_ref);
|
||||
if (i == 0) {
|
||||
store_value_from_reg(&ctx->mcode, &loc, SCC_AMD64_RCX);
|
||||
store_value_from_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RCX);
|
||||
} else if (i == 1) {
|
||||
store_value_from_reg(&ctx->mcode, &loc, SCC_AMD64_RDX);
|
||||
store_value_from_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RDX);
|
||||
} else if (i == 2) {
|
||||
store_value_from_reg(&ctx->mcode, &loc, SCC_AMD64_R8);
|
||||
store_value_from_reg(&ctx->sect_mcode, &loc, SCC_AMD64_R8);
|
||||
} else if (i == 3) {
|
||||
store_value_from_reg(&ctx->mcode, &loc, SCC_AMD64_R9);
|
||||
store_value_from_reg(&ctx->sect_mcode, &loc, SCC_AMD64_R9);
|
||||
} else {
|
||||
LOG_FATAL("not support more than 4 args");
|
||||
}
|
||||
@@ -401,19 +406,19 @@ static void parse_function(scc_ir2mcode_ctx_t *ctx, scc_ir_func_t *func) {
|
||||
for (usize i = 0; i < scc_vec_size(func->bblocks); i++) {
|
||||
scc_ir_bblock_ref_t bblock_ref = scc_vec_at(func->bblocks, i);
|
||||
scc_ir_bblock_t *bblock =
|
||||
scc_ir_ctx_get_bblock(ctx->ir_ctx, bblock_ref);
|
||||
scc_ir_module_get_bblock(GET_MODULE(ctx), bblock_ref);
|
||||
|
||||
if (bblock == null) {
|
||||
LOG_FATAL("<invalid block>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
bblock_offsets[i] = scc_vec_size(ctx->mcode.mcode);
|
||||
bblock_offsets[i] = scc_vec_size(ctx->sect_mcode.mcode);
|
||||
parse_bblock(ctx, bblock, &patches);
|
||||
}
|
||||
|
||||
// 回填所有跳转偏移
|
||||
u8 *buf = scc_vec_unsafe_get_data(ctx->mcode.mcode);
|
||||
u8 *buf = scc_vec_unsafe_get_data(ctx->sect_mcode.mcode);
|
||||
scc_vec_foreach(patches, idx) {
|
||||
patch_t *p = &scc_vec_at(patches, idx);
|
||||
usize target_id =
|
||||
@@ -430,11 +435,12 @@ 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, ctx->ir_ctx);
|
||||
scc_reg_alloc_init(&ctx->reg_alloc, scc_reg_alloc_with_stack,
|
||||
GET_MODULE(ctx));
|
||||
|
||||
scc_vec_foreach(ctx->cprog->func_decls, i) {
|
||||
scc_ir_node_ref_t func_ref = scc_vec_at(ctx->cprog->func_decls, i);
|
||||
scc_ir_func_t *func = scc_ir_ctx_get_func(ctx->ir_ctx, func_ref);
|
||||
scc_ir_func_t *func = scc_ir_module_get_func(GET_MODULE(ctx), func_ref);
|
||||
if (!func) {
|
||||
LOG_ERROR("invalid function reference");
|
||||
return;
|
||||
@@ -460,40 +466,31 @@ void scc_ir2amd64(scc_ir2mcode_ctx_t *ctx) {
|
||||
.sccf_sym_vis = SCCF_SYM_VIS_DEFAULT,
|
||||
};
|
||||
}
|
||||
usize sym_idx =
|
||||
sccf_builder_add_symbol(&ctx->builder, func->name, &sym);
|
||||
usize sym_idx = sccf_builder_add_symbol(ctx->builder, func->name, &sym);
|
||||
Assert(sym_idx != 0);
|
||||
}
|
||||
|
||||
scc_vec_foreach(ctx->cprog->func_defs, i) {
|
||||
scc_ir_node_ref_t func_ref = scc_vec_at(ctx->cprog->func_defs, i);
|
||||
scc_ir_func_t *func = scc_ir_ctx_get_func(ctx->ir_ctx, func_ref);
|
||||
scc_ir_func_t *func = scc_ir_module_get_func(GET_MODULE(ctx), func_ref);
|
||||
if (!func) {
|
||||
LOG_ERROR("invalid function reference");
|
||||
return;
|
||||
}
|
||||
sccf_sym_t *sym =
|
||||
sccf_builder_get_symbol_unsafe(&ctx->builder, func->name);
|
||||
sccf_builder_get_symbol_unsafe(ctx->builder, func->name);
|
||||
Assert(sym != null);
|
||||
sym->sccf_sect_offset = scc_vec_size(ctx->mcode.mcode);
|
||||
sym->sccf_sect_offset = scc_vec_size(ctx->sect_mcode.mcode);
|
||||
parse_function(ctx, func);
|
||||
}
|
||||
sccf_sect_data_t text_section;
|
||||
scc_vec_unsafe_from_buffer(text_section,
|
||||
scc_vec_unsafe_get_data(ctx->mcode.mcode),
|
||||
scc_vec_size(ctx->mcode.mcode));
|
||||
sccf_builder_add_text_section(&ctx->builder, &text_section);
|
||||
sccf_sect_data_t data_section;
|
||||
scc_vec_init(data_section);
|
||||
sccf_builder_add_data_section(&ctx->builder, &data_section);
|
||||
|
||||
u8 *buf = scc_vec_unsafe_get_data(ctx->mcode.mcode);
|
||||
scc_vec_foreach(ctx->builder.relocs, i) {
|
||||
sccf_reloc_t *reloc = &scc_vec_at(ctx->builder.relocs, i);
|
||||
u8 *buf = scc_vec_unsafe_get_data(ctx->sect_mcode.mcode);
|
||||
scc_vec_foreach(ctx->builder->relocs, i) {
|
||||
sccf_reloc_t *reloc = &scc_vec_at(ctx->builder->relocs, i);
|
||||
if (reloc->sym_idx == 0) {
|
||||
Panic("relocate to an invalid symbol");
|
||||
}
|
||||
sccf_sym_t *sym = &scc_vec_at(ctx->builder.symtab, reloc->sym_idx);
|
||||
sccf_sym_t *sym = &scc_vec_at(ctx->builder->symtab, reloc->sym_idx);
|
||||
if (sym->sccf_sym_type != SCCF_SYM_TYPE_EXTERN) {
|
||||
Assert(reloc->reloc_type == SCCF_RELOC_TYPE_REL);
|
||||
|
||||
@@ -508,6 +505,15 @@ void scc_ir2amd64(scc_ir2mcode_ctx_t *ctx) {
|
||||
reloc->reloc_type = SCCF_RELOC_TYPE_EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
sccf_sect_data_t text_section;
|
||||
scc_vec_unsafe_from_buffer(text_section,
|
||||
scc_vec_unsafe_get_data(ctx->sect_mcode.mcode),
|
||||
scc_vec_size(ctx->sect_mcode.mcode));
|
||||
sccf_builder_add_text_section(ctx->builder, &text_section);
|
||||
sccf_sect_data_t data_section;
|
||||
scc_vec_init(data_section);
|
||||
sccf_builder_add_data_section(ctx->builder, &data_section);
|
||||
// FIXME
|
||||
ctx->builder.entry_symbol_name = "main";
|
||||
ctx->builder->entry_symbol_name = "main";
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@ int equal_func(const void *key1, const void *key2) {
|
||||
}
|
||||
|
||||
void scc_reg_alloc_init(scc_reg_alloc_t *ctx, scc_reg_alloc_func_t func,
|
||||
scc_ir_cprog_ctx_t *ir_ctx) {
|
||||
scc_ir_module_t *ir_module) {
|
||||
ctx->gpr_caller_saved = 0;
|
||||
ctx->gpr_callee_saved = 0;
|
||||
ctx->ir_ctx = ir_ctx;
|
||||
ctx->ir_module = ir_module;
|
||||
ctx->reg_alloc_func = func;
|
||||
|
||||
ctx->alloc_stack_size = 0;
|
||||
@@ -37,16 +37,18 @@ scc_hashtable_t *scc_reg_alloc_with_stack(scc_reg_alloc_t *ctx,
|
||||
scc_vec_foreach(func->bblocks, i) {
|
||||
scc_ir_bblock_ref_t bblock_ref = scc_vec_at(func->bblocks, i);
|
||||
scc_ir_bblock_t *bblock =
|
||||
scc_ir_ctx_get_bblock(ctx->ir_ctx, bblock_ref);
|
||||
scc_ir_module_get_bblock(ctx->ir_module, bblock_ref);
|
||||
Assert(bblock != null);
|
||||
scc_vec_foreach(bblock->instrs, j) {
|
||||
scc_ir_node_ref_t node_ref = scc_vec_at(bblock->instrs, j);
|
||||
scc_ir_node_t *node = scc_ir_ctx_get_node(ctx->ir_ctx, node_ref);
|
||||
scc_ir_node_t *node =
|
||||
scc_ir_module_get_node(ctx->ir_module, node_ref);
|
||||
Assert(node != null);
|
||||
loc.kind = SCC_REG_KIND_UNDEF;
|
||||
switch (node->tag) {
|
||||
case SCC_IR_NODE_LOAD:
|
||||
case SCC_IR_NODE_OP:
|
||||
|
||||
case SCC_IR_NODE_ALLOC: {
|
||||
loc.kind = SCC_REG_KIND_STACK;
|
||||
loc.idx = ctx->alloc_stack_size;
|
||||
@@ -61,11 +63,11 @@ scc_hashtable_t *scc_reg_alloc_with_stack(scc_reg_alloc_t *ctx,
|
||||
case SCC_IR_NODE_CALL: {
|
||||
// 处理返回值
|
||||
scc_ir_type_t *func_type =
|
||||
scc_ir_ctx_get_type(ctx->ir_ctx, func->type);
|
||||
scc_ir_module_get_type(ctx->ir_module, func->type);
|
||||
Assert(func_type);
|
||||
scc_ir_type_t *ret_type = scc_ir_ctx_get_type(
|
||||
ctx->ir_ctx, func_type->data.function.ret_type);
|
||||
if (ret_type && ret_type->tag != SCC_IR_TYPE_VOID) {
|
||||
scc_ir_type_t *ret_type = scc_ir_module_get_type(
|
||||
ctx->ir_module, func_type->data.function.ret_type);
|
||||
if (ret_type && ret_type->tag != SCC_IR_TYPE_void) {
|
||||
loc.kind = SCC_REG_KIND_STACK;
|
||||
loc.idx = ctx->alloc_stack_size;
|
||||
ctx->alloc_stack_size += 8;
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
#include <scc_ir2mcode.h>
|
||||
|
||||
void scc_ir2mcode_init(scc_ir2mcode_ctx_t *ctx, scc_ir_cprog_t *cprog,
|
||||
scc_ir_cprog_ctx_t *ir_ctx, scc_mcode_arch_t arch) {
|
||||
sccf_builder_t *builder, scc_mcode_arch_t arch) {
|
||||
ctx->cprog = cprog;
|
||||
ctx->ir_ctx = ir_ctx;
|
||||
scc_mcode_init(&ctx->mcode, arch);
|
||||
sccf_builder_init(&ctx->builder);
|
||||
ctx->builder = builder;
|
||||
scc_mcode_init(&ctx->sect_mcode, arch);
|
||||
scc_vec_init(ctx->sect_data);
|
||||
sccf_builder_init(ctx->builder);
|
||||
}
|
||||
|
||||
void scc_ir2mcode_drop(scc_ir2mcode_ctx_t *ctx) {}
|
||||
|
||||
void scc_ir2amd64(scc_ir2mcode_ctx_t *ctx);
|
||||
|
||||
void scc_ir2mcode(scc_ir2mcode_ctx_t *ctx) { scc_ir2amd64(ctx); }
|
||||
|
||||
@@ -31,15 +31,20 @@ void test_example(const char *input, cbool need_sema, const char *name) {
|
||||
|
||||
scc_ast2ir_ctx_t ast2ir_ctx;
|
||||
#include <abi/win_x64_type_abi.h>
|
||||
scc_ast2ir_ctx_init(&ast2ir_ctx, scc_win_x64_type_abi);
|
||||
scc_ir_cprog_t cprog;
|
||||
scc_ir_cprog_init(&cprog);
|
||||
scc_ast2ir_ctx_init(&ast2ir_ctx, scc_win_x64_type_abi, &cprog);
|
||||
scc_ast2ir_translation_unit(&ast2ir_ctx, tu);
|
||||
scc_ast2ir_ctx_drop(&ast2ir_ctx);
|
||||
|
||||
scc_ir2mcode_ctx_t mcode_ctx;
|
||||
scc_ir2mcode_init(&mcode_ctx, &ast2ir_ctx.builder.cprog,
|
||||
&ast2ir_ctx.builder.ctx, SCC_MCODE_ARCH_AMD64);
|
||||
scc_ir2mcode(&mcode_ctx);
|
||||
scc_ir2mcode_ctx_t ir2mcode_ctx;
|
||||
sccf_builder_t sccf_builder;
|
||||
scc_ir2mcode_init(&ir2mcode_ctx, &cprog, &sccf_builder,
|
||||
SCC_MCODE_ARCH_AMD64);
|
||||
scc_ir2mcode(&ir2mcode_ctx);
|
||||
scc_ir2mcode_drop(&ir2mcode_ctx);
|
||||
|
||||
const sccf_t *sccf = sccf_builder_to_sccf(&mcode_ctx.builder);
|
||||
const sccf_t *sccf = sccf_builder_to_sccf(&sccf_builder);
|
||||
scc_pe_builder_t pe_builder;
|
||||
sccf2pe(&pe_builder, sccf);
|
||||
|
||||
@@ -82,6 +87,24 @@ int main() {
|
||||
"int main(void) {\n"
|
||||
" return add(1, 2);\n"
|
||||
"}\n",
|
||||
true, "10_call.exe");
|
||||
true, "10_main.exe");
|
||||
test_example("int factorial(int);\n"
|
||||
"\n"
|
||||
"int main() {\n"
|
||||
" int num = 5;\n"
|
||||
" int result = factorial(num);\n"
|
||||
" // printf(\"%d\", result);\n"
|
||||
" return result;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"int factorial(int num) {\n"
|
||||
" if (num == 0) {\n"
|
||||
" return 1;\n"
|
||||
" } else {\n"
|
||||
" return num * factorial(num - 1);\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
true, "11_recursion.exe");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user