feat(ir2mcode): 实现AMD64代码生成器支持控制流和函数调用
- 实现了条件分支、无条件跳转和函数调用的机器码生成 - 添加了跳转目标地址回填机制,处理条件分支和跳转指令的偏移量 - 改进了寄存器分配逻辑,支持函数调用返回值的处理 - 重构了位置解析函数,从返回指针改为传入引用参数 fix(ast2ir): 移除无用的注释代码 - 删除了关于一元操作符映射的注释代码 test: 更新测试框架和测试用例 - 修改测试框架以支持新的可执行文件输出格式 - 添加了条件分支、循环和函数调用的测试用例 - 使用TOML配置文件管理期望的返回值 - 替换标准库头文件为自定义头文件以减少依赖
This commit is contained in:
@@ -234,7 +234,6 @@ scc_ir_node_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
|
||||
// SCC_AST_OP_PREFIX_DECREMENT, // -- (前缀)
|
||||
// SCC_AST_OP_POSTFIX_INCREMENT, // ++ (后缀)
|
||||
// SCC_AST_OP_POSTFIX_DECREMENT, // -- (后缀)
|
||||
// 映射一元操作符
|
||||
switch (expr->unary.op) {
|
||||
case SCC_AST_OP_UNARY_MINUS:
|
||||
// 负号
|
||||
|
||||
@@ -3,12 +3,14 @@
|
||||
#include <reg_alloc.h>
|
||||
#include <scc_ir2mcode.h>
|
||||
|
||||
static scc_reg_loc_t *parse_location(scc_ir2mcode_ctx_t *ctx,
|
||||
scc_ir_bblock_ref_t node_ref) {
|
||||
static void parse_location(scc_ir2mcode_ctx_t *ctx, scc_reg_loc_t *loc,
|
||||
scc_ir_bblock_ref_t node_ref) {
|
||||
Assert(ctx != null && loc != null);
|
||||
scc_ir_node_t *node = scc_ir_ctx_get_node(ctx->ir_ctx, node_ref);
|
||||
if (node == null) {
|
||||
LOG_FATAL("invalid node ref");
|
||||
return null;
|
||||
UNREACHABLE();
|
||||
return;
|
||||
}
|
||||
usize idx = 0;
|
||||
switch (node->tag) {
|
||||
@@ -16,11 +18,11 @@ static scc_reg_loc_t *parse_location(scc_ir2mcode_ctx_t *ctx,
|
||||
scc_ir_type_t *type = scc_ir_ctx_get_type(ctx->ir_ctx, node->type);
|
||||
Assert(type != 0);
|
||||
Assert(type->tag == SCC_IR_TYPE_U32 || type->tag == SCC_IR_TYPE_I32);
|
||||
scc_reg_loc_t loc = {.kind = SCC_REG_KIND_IMM,
|
||||
.idx = (usize)node->data.const_int.int32};
|
||||
scc_vec_push(ctx->reg_alloc.reg_loc_vec, loc);
|
||||
idx = scc_vec_size(ctx->reg_alloc.reg_loc_vec);
|
||||
break;
|
||||
*loc = (scc_reg_loc_t){
|
||||
.kind = SCC_REG_KIND_IMM,
|
||||
.idx = (usize)node->data.const_int.int32,
|
||||
};
|
||||
return;
|
||||
case SCC_IR_NODE_CONST_UINT:
|
||||
case SCC_IR_NODE_CONST_FLOAT:
|
||||
TODO();
|
||||
@@ -32,7 +34,7 @@ static scc_reg_loc_t *parse_location(scc_ir2mcode_ctx_t *ctx,
|
||||
}
|
||||
|
||||
Assert(idx > 0 && idx <= scc_vec_size(ctx->reg_alloc.reg_loc_vec));
|
||||
return &scc_vec_at(ctx->reg_alloc.reg_loc_vec, idx - 1);
|
||||
*loc = scc_vec_at(ctx->reg_alloc.reg_loc_vec, idx - 1);
|
||||
}
|
||||
|
||||
static void load_value_to_reg(scc_mcode_t *mcode, scc_reg_loc_t *loc, int reg) {
|
||||
@@ -77,8 +79,15 @@ static void store_value_from_reg(scc_mcode_t *mcode, scc_reg_loc_t *loc,
|
||||
}
|
||||
}
|
||||
|
||||
// 临时存储待修补条目
|
||||
typedef struct {
|
||||
usize pos;
|
||||
usize target_bb_ref;
|
||||
} patch_t;
|
||||
typedef SCC_VEC(patch_t) patch_vec_t;
|
||||
|
||||
static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
int idx) {
|
||||
patch_vec_t *patches) {
|
||||
scc_ir_node_t *node = scc_ir_ctx_get_node(ctx->ir_ctx, node_ref);
|
||||
if (node == null) {
|
||||
LOG_ERROR("invalid node ref");
|
||||
@@ -97,32 +106,39 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
case SCC_IR_NODE_LOAD: ///< 加载数据
|
||||
{
|
||||
// node->data.load.target
|
||||
scc_reg_loc_t *from = parse_location(ctx, node->data.load.target);
|
||||
scc_reg_loc_t *to = parse_location(ctx, node_ref);
|
||||
load_value_to_reg(&ctx->mcode, from, SCC_AMD64_RAX);
|
||||
store_value_from_reg(&ctx->mcode, to, SCC_AMD64_RAX);
|
||||
scc_reg_loc_t from;
|
||||
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);
|
||||
break;
|
||||
}
|
||||
case SCC_IR_NODE_STORE: ///< 存储数据
|
||||
{
|
||||
scc_reg_loc_t *from = parse_location(ctx, node->data.store.value);
|
||||
scc_reg_loc_t *to = parse_location(ctx, node->data.store.target);
|
||||
load_value_to_reg(&ctx->mcode, from, SCC_AMD64_RAX);
|
||||
store_value_from_reg(&ctx->mcode, to, SCC_AMD64_RAX);
|
||||
scc_reg_loc_t from;
|
||||
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);
|
||||
break;
|
||||
}
|
||||
case SCC_IR_NODE_GET_PTR: ///< 获取指针
|
||||
case SCC_IR_NODE_GET_ELEM_PTR: ///< 获取元素指针(used by array)
|
||||
TODO();
|
||||
case SCC_IR_NODE_OP: ///< 二元运算
|
||||
scc_reg_loc_t *loc_lhs = parse_location(ctx, node->data.op.lhs);
|
||||
scc_reg_loc_t *loc_rhs = parse_location(ctx, node->data.op.rhs);
|
||||
scc_reg_loc_t *loc_res = parse_location(ctx, node_ref);
|
||||
scc_reg_loc_t loc_lhs;
|
||||
parse_location(ctx, &loc_lhs, node->data.op.lhs);
|
||||
scc_reg_loc_t loc_rhs;
|
||||
parse_location(ctx, &loc_rhs, node->data.op.rhs);
|
||||
scc_reg_loc_t loc_res;
|
||||
parse_location(ctx, &loc_res, node_ref);
|
||||
|
||||
// 将左操作数加载到 RAX(临时结果寄存器)
|
||||
load_value_to_reg(&ctx->mcode, loc_lhs, SCC_AMD64_RAX);
|
||||
load_value_to_reg(&ctx->mcode, &loc_lhs, SCC_AMD64_RAX);
|
||||
// 将右操作数加载到 RCX
|
||||
load_value_to_reg(&ctx->mcode, loc_rhs, SCC_AMD64_RCX);
|
||||
load_value_to_reg(&ctx->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,
|
||||
@@ -135,59 +151,195 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
|
||||
case SCC_IR_OP_MUL:
|
||||
scc_mcode_amd64_mul_r64(&ctx->mcode, SCC_AMD64_RCX);
|
||||
break;
|
||||
// [SCC_IR_OP_EMPTY] = "empty", [SCC_IR_OP_NEQ] = "!=",
|
||||
// [SCC_IR_OP_EQ] = "==", [SCC_IR_OP_GT] = ">",
|
||||
// [SCC_IR_OP_LT] = "<", [SCC_IR_OP_GE] = ">=",
|
||||
// [SCC_IR_OP_LE] = "<=", [SCC_IR_OP_ADD] = "+",
|
||||
// [SCC_IR_OP_SUB] = "-", [SCC_IR_OP_MUL] = "*",
|
||||
// [SCC_IR_OP_DIV] = "/", [SCC_IR_OP_MOD] = "%",
|
||||
// [SCC_IR_OP_AND] = "&", [SCC_IR_OP_OR] = "|",
|
||||
// [SCC_IR_OP_XOR] = "^", [SCC_IR_OP_NOT] = "~",
|
||||
// [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_AMD64_RCX);
|
||||
scc_mcode_amd64_setcc_r8(&ctx->mcode, SCC_AMD64_COND_NE,
|
||||
SCC_AMD64_RAX);
|
||||
scc_mcode_amd64_movzx_r64_r8(&ctx->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_AMD64_RCX);
|
||||
scc_mcode_amd64_setcc_r8(&ctx->mcode, SCC_AMD64_COND_E,
|
||||
SCC_AMD64_RAX);
|
||||
scc_mcode_amd64_movzx_r64_r8(&ctx->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_AMD64_RCX);
|
||||
scc_mcode_amd64_setcc_r8(&ctx->mcode, SCC_AMD64_COND_G,
|
||||
SCC_AMD64_RAX);
|
||||
scc_mcode_amd64_movzx_r64_r8(&ctx->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_AMD64_RCX);
|
||||
scc_mcode_amd64_setcc_r8(&ctx->mcode, SCC_AMD64_COND_L,
|
||||
SCC_AMD64_RAX);
|
||||
scc_mcode_amd64_movzx_r64_r8(&ctx->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_AMD64_RCX);
|
||||
scc_mcode_amd64_setcc_r8(&ctx->mcode, SCC_AMD64_COND_GE,
|
||||
SCC_AMD64_RAX);
|
||||
scc_mcode_amd64_movzx_r64_r8(&ctx->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_AMD64_RCX);
|
||||
scc_mcode_amd64_setcc_r8(&ctx->mcode, SCC_AMD64_COND_LE,
|
||||
SCC_AMD64_RAX);
|
||||
scc_mcode_amd64_movzx_r64_r8(&ctx->mcode, SCC_AMD64_RAX,
|
||||
SCC_AMD64_RAX);
|
||||
break;
|
||||
default:
|
||||
LOG_FATAL("unknown op: %d", node->data.op.op);
|
||||
break;
|
||||
}
|
||||
// 将 RAX 中的结果存储到 res 位置
|
||||
store_value_from_reg(&ctx->mcode, loc_res, SCC_AMD64_RAX);
|
||||
// [SCC_IR_OP_EMPTY] = "empty", [SCC_IR_OP_NEQ] = "!=",
|
||||
// [SCC_IR_OP_EQ] = "==", [SCC_IR_OP_GT] = ">",
|
||||
// [SCC_IR_OP_LT] = "<", [SCC_IR_OP_GE] = ">=",
|
||||
// [SCC_IR_OP_LE] = "<=", [SCC_IR_OP_ADD] = "+",
|
||||
// [SCC_IR_OP_SUB] = "-", [SCC_IR_OP_MUL] = "*",
|
||||
// [SCC_IR_OP_DIV] = "/", [SCC_IR_OP_MOD] = "%",
|
||||
// [SCC_IR_OP_AND] = "&", [SCC_IR_OP_OR] = "|",
|
||||
// [SCC_IR_OP_XOR] = "^", [SCC_IR_OP_NOT] = "~",
|
||||
// [SCC_IR_OP_SHL] = "<<", [SCC_IR_OP_SHR] = ">>",
|
||||
// [SCC_IR_OP_SAR] = ">>a", // Arithmetic shift right
|
||||
store_value_from_reg(&ctx->mcode, &loc_res, SCC_AMD64_RAX);
|
||||
break;
|
||||
case SCC_IR_NODE_BRANCH: ///< 有条件分支
|
||||
case SCC_IR_NODE_JUMP: ///< 无条件跳转
|
||||
case SCC_IR_NODE_CALL: ///< 调用函数
|
||||
LOG_FATAL("Unsupported node type: %d", node->tag);
|
||||
///< 有条件分支
|
||||
case SCC_IR_NODE_BRANCH: {
|
||||
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);
|
||||
|
||||
scc_mcode_amd64_jcc_rel32(&ctx->mcode, SCC_AMD64_COND_NE, 0);
|
||||
patch_t patch_true = {.pos = scc_vec_size(ctx->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),
|
||||
.target_bb_ref =
|
||||
(usize)node->data.branch.false_bblock};
|
||||
scc_vec_push(*patches, patch_false);
|
||||
break;
|
||||
case SCC_IR_NODE_RET: ///< 函数返回
|
||||
}
|
||||
///< 无条件跳转
|
||||
case SCC_IR_NODE_JUMP: {
|
||||
scc_mcode_amd64_jmp_rel32(&ctx->mcode, 0);
|
||||
usize pos = scc_vec_size(ctx->mcode.mcode);
|
||||
patch_t patch = {.pos = pos,
|
||||
.target_bb_ref = (usize)node->data.jump.target_bblock};
|
||||
scc_vec_push(*patches, patch);
|
||||
break;
|
||||
}
|
||||
///< 调用函数
|
||||
case SCC_IR_NODE_CALL: {
|
||||
scc_reg_loc_t loc;
|
||||
/*
|
||||
ABI
|
||||
RAX 不稳定的 返回值寄存器
|
||||
RCX 不稳定的 第一个整型自变量
|
||||
RDX 不稳定的 第二个整型自变量
|
||||
R8 不稳定的 第三个整型自变量
|
||||
R9 不稳定的 第四个整型自变量
|
||||
*/
|
||||
scc_vec_foreach(node->data.call.args, i) {
|
||||
parse_location(ctx, &loc, node->data.branch.cond);
|
||||
if (i == 0) {
|
||||
load_value_to_reg(&ctx->mcode, &loc, SCC_AMD64_RCX);
|
||||
} else if (i == 1) {
|
||||
load_value_to_reg(&ctx->mcode, &loc, SCC_AMD64_RDX);
|
||||
} else if (i == 2) {
|
||||
load_value_to_reg(&ctx->mcode, &loc, SCC_AMD64_R8);
|
||||
} else if (i == 3) {
|
||||
load_value_to_reg(&ctx->mcode, &loc, SCC_AMD64_R9);
|
||||
} else {
|
||||
LOG_FATAL("not support more than 4 args");
|
||||
}
|
||||
// scc_mcode_amd64_push_r64();
|
||||
}
|
||||
|
||||
scc_ir_func_t *func =
|
||||
scc_ir_ctx_get_func(ctx->ir_ctx, node->data.call.callee);
|
||||
if (!func) {
|
||||
LOG_ERROR("invalid function reference");
|
||||
return;
|
||||
}
|
||||
|
||||
scc_mcode_amd64_call_rel32(&ctx->mcode, 0);
|
||||
|
||||
// 处理返回值
|
||||
scc_ir_type_t *ret_type = scc_ir_ctx_get_type(ctx->ir_ctx, node->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);
|
||||
}
|
||||
break;
|
||||
}
|
||||
///< 函数返回
|
||||
case SCC_IR_NODE_RET: {
|
||||
if (node->data.ret.ret_val) {
|
||||
scc_reg_loc_t *loc = parse_location(ctx, node->data.ret.ret_val);
|
||||
load_value_to_reg(&ctx->mcode, loc, SCC_AMD64_RAX);
|
||||
scc_reg_loc_t loc;
|
||||
parse_location(ctx, &loc, node->data.ret.ret_val);
|
||||
load_value_to_reg(&ctx->mcode, &loc, SCC_AMD64_RAX);
|
||||
}
|
||||
scc_mcode_amd64_mov_r64_r64(&ctx->mcode, SCC_AMD64_RSP, SCC_AMD64_RBP);
|
||||
scc_mcode_amd64_pop_r64(&ctx->mcode, SCC_AMD64_RBP);
|
||||
scc_mcode_amd64_ret(&ctx->mcode);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void parse_bblock(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_t *bblock) {
|
||||
static void parse_bblock(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_t *bblock,
|
||||
patch_vec_t *patches) {
|
||||
|
||||
// 打印基本块中的每条指令
|
||||
for (usize i = 0; i < scc_vec_size(bblock->instrs); i++) {
|
||||
scc_ir_node_ref_t node_ref = scc_vec_at(bblock->instrs, i);
|
||||
parse_node(ctx, node_ref, i);
|
||||
parse_node(ctx, node_ref, patches);
|
||||
}
|
||||
}
|
||||
|
||||
static void parse_function(scc_ir2mcode_ctx_t *ctx, scc_ir_func_t *func) {
|
||||
scc_hashtable_t bblock2offset;
|
||||
static u32 hash_func(const void *key) { return (u32)(usize)key; }
|
||||
static int equal_func(const void *key1, const void *key2) {
|
||||
return (usize)key1 - (usize)key2;
|
||||
}
|
||||
|
||||
static void parse_function(scc_ir2mcode_ctx_t *ctx, scc_ir_func_t *func) {
|
||||
ctx->noderef2regloc = scc_reg_alloc(&ctx->reg_alloc, func);
|
||||
// 对齐到 16 字节
|
||||
usize stack_size = (ctx->reg_alloc.alloc_stack_size + 15) & ~15;
|
||||
|
||||
usize bblock_cnt = scc_vec_size(func->bblocks);
|
||||
usize *bblock_offsets = scc_calloc(bblock_cnt, sizeof(usize));
|
||||
// 建立 bblock_ref -> id 的映射
|
||||
scc_hashtable_t ref2id;
|
||||
scc_hashtable_init(&ref2id, hash_func, equal_func);
|
||||
for (usize i = 0; i < bblock_cnt; i++) {
|
||||
scc_ir_bblock_ref_t ref = scc_vec_at(func->bblocks, i);
|
||||
scc_hashtable_set(&ref2id, (void *)(usize)ref, (void *)i);
|
||||
}
|
||||
|
||||
patch_vec_t patches;
|
||||
scc_vec_init(patches);
|
||||
|
||||
scc_mcode_amd64_push_r64(&ctx->mcode, SCC_AMD64_RBP);
|
||||
scc_mcode_amd64_mov_r64_r64(&ctx->mcode, SCC_AMD64_RBP, SCC_AMD64_RSP);
|
||||
scc_mcode_amd64_sub_rsp_imm32(&ctx->mcode, stack_size);
|
||||
@@ -201,8 +353,30 @@ static void parse_function(scc_ir2mcode_ctx_t *ctx, scc_ir_func_t *func) {
|
||||
LOG_FATAL("<invalid block>\n");
|
||||
return;
|
||||
}
|
||||
parse_bblock(ctx, bblock);
|
||||
|
||||
bblock_offsets[i] = scc_vec_size(ctx->mcode.mcode);
|
||||
parse_bblock(ctx, bblock, &patches);
|
||||
}
|
||||
|
||||
// 回填所有跳转偏移
|
||||
u8 *buf = scc_vec_unsafe_get_data(ctx->mcode.mcode);
|
||||
scc_vec_foreach(patches, idx) {
|
||||
patch_t *p = &scc_vec_at(patches, idx);
|
||||
usize target_id =
|
||||
(usize)scc_hashtable_get(&ref2id, (void *)(usize)p->target_bb_ref);
|
||||
usize target_off = bblock_offsets[target_id];
|
||||
usize next_off = p->pos;
|
||||
i32 rel = (i32)(target_off - next_off);
|
||||
// 写入到指令的偏移字段(小端)
|
||||
*(u32 *)(&buf[p->pos - 4]) = rel;
|
||||
// buf[p->pos + 1] = (u8)(rel >> 0);
|
||||
// buf[p->pos + 2] = (u8)(rel >> 8);
|
||||
// buf[p->pos + 3] = (u8)(rel >> 16);
|
||||
// buf[p->pos + 4] = (u8)(rel >> 24);
|
||||
}
|
||||
scc_free(bblock_offsets);
|
||||
scc_vec_free(patches);
|
||||
scc_hashtable_drop(&ref2id);
|
||||
}
|
||||
|
||||
void scc_ir2amd64(scc_ir2mcode_ctx_t *ctx) {
|
||||
|
||||
@@ -50,6 +50,20 @@ scc_hashtable_t *scc_reg_alloc_with_stack(scc_reg_alloc_t *ctx,
|
||||
(void *)scc_vec_size(ctx->reg_loc_vec));
|
||||
break;
|
||||
}
|
||||
case SCC_IR_NODE_CALL: {
|
||||
scc_ir_type_t *ret_type =
|
||||
scc_ir_ctx_get_type(ctx->ir_ctx, node->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;
|
||||
scc_vec_push(ctx->reg_loc_vec, loc);
|
||||
scc_hashtable_set(&ctx->node_ref2reg_loc,
|
||||
(void *)(usize)node_ref,
|
||||
(void *)scc_vec_size(ctx->reg_loc_vec));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void test_example(const char *input, cbool need_sema) {
|
||||
void test_example(const char *input, cbool need_sema, const char *name) {
|
||||
int res = 0;
|
||||
scc_sstream_t mem_stream;
|
||||
res = scc_sstream_init_by_buffer(&mem_stream, input, scc_strlen(input),
|
||||
@@ -42,7 +42,10 @@ void test_example(const char *input, cbool need_sema) {
|
||||
const sccf_t *sccf = sccf_builder_to_sccf(&mcode_ctx.builder);
|
||||
scc_pe_builder_t pe_builder;
|
||||
sccf2pe(&pe_builder, sccf);
|
||||
scc_pe_dump_to_file(&pe_builder, __FILE__ "/../../test.exe");
|
||||
|
||||
char fname[1024] = {0};
|
||||
scc_snprintf(fname, sizeof(fname), "%s%s%s", __FILE__, "/../../", name);
|
||||
scc_pe_dump_to_file(&pe_builder, fname);
|
||||
}
|
||||
|
||||
int main() {
|
||||
@@ -54,6 +57,31 @@ int main() {
|
||||
" a = a - b + 1;\n"
|
||||
" return a;\n"
|
||||
"}\n",
|
||||
true);
|
||||
true, "02_decl_expr.exe");
|
||||
test_example("int main(void) {\n"
|
||||
" int a;\n"
|
||||
" a = 1;\n"
|
||||
" if (a) {\n"
|
||||
" a = 1;\n"
|
||||
" } else {\n"
|
||||
" a = 2;\n"
|
||||
" }\n"
|
||||
" return a;\n"
|
||||
"}\n",
|
||||
true, "04_if.exe");
|
||||
test_example("int main() {\n"
|
||||
" int i = 0;\n"
|
||||
" while (i < 10) i = i + 1;\n"
|
||||
" return i;\n"
|
||||
"}\n",
|
||||
true, "07_while.exe");
|
||||
test_example("int add(int a, int b) {\n"
|
||||
" return a + b;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"int main(void) {\n"
|
||||
" return add(1, 2);\n"
|
||||
"}\n",
|
||||
true, "10_call.exe");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user