From 45c59e0b653f7a1dd888b7d533ceb7291de13aff Mon Sep 17 00:00:00 2001 From: zzy <2450266535@qq.com> Date: Sun, 15 Mar 2026 15:44:50 +0800 Subject: [PATCH] =?UTF-8?q?feat(ast2ir):=20=E6=B7=BB=E5=8A=A0AST=E5=88=B0I?= =?UTF-8?q?R=E8=BD=AC=E6=8D=A2=E5=8A=9F=E8=83=BD=E5=B9=B6=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E7=B1=BB=E5=9E=8BABI=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加了ast2ir库用于将AST转换为IR中间表示 - 实现了Windows x64 ABI类型定义文件 - 完善了IR库中的类型定义,添加了无符号整数类型和操作符枚举 - 更新了IR转储功能以支持新的节点类型 - 在主程序中集成了AST到IR的转换流程 - 修改了PE目标文件生成功能以修正节区标志 - 更新了向量实现的日志和错误处理机制 fix(ir): 修复IR库中的操作符枚举和类型处理问题 - 修复了IR操作符枚举的命名空间问题,统一使用SCC_IR前缀 - 添加了无符号整数类型的哈希和比较支持 - 修正了常量整数节点的打印函数调用 - 更新了各种IR节点的转储输出格式 - 删除了测试文件中的冗余代码 refactor: 重构项目依赖配置和构建设置 - 启用了ast2ir和ir库的依赖配置 - 添加了def文件到.gitignore中 - 重命名了部分测试文件 --- .gitignore | 3 + cbuild.toml | 4 +- libs/ast2ir/cbuild.toml | 5 +- libs/ast2ir/include/abi/win_x64_type_abi.h | 141 ++++++++++++++++++ libs/ast2ir/include/scc_ast2ir.h | 6 +- libs/ast2ir/include/scc_type_abi.h | 14 ++ libs/ast2ir/src/ast2ir.c | 82 +++++----- libs/ast2ir/tests/test_ast2ir_unit.c | 0 libs/ir/include/ir_def.h | 86 +++++++---- libs/ir/src/ir_base.c | 2 +- libs/ir/src/ir_builtin.c | 2 +- libs/ir/src/ir_ctx.c | 12 +- libs/ir/src/ir_dump.c | 54 ++++--- libs/ir/tests/test_ir.c | 10 -- .../tests/test_.c => ir/tests/test_ir_unit.c} | 0 libs/target/pe/src/main.c | 3 +- libs/target/pe/src/scc_pe_idata.c | 2 +- runtime/scc_core/include/scc_core_vec.h | 5 +- src/main.c | 39 +++-- 19 files changed, 339 insertions(+), 131 deletions(-) create mode 100644 libs/ast2ir/include/abi/win_x64_type_abi.h create mode 100644 libs/ast2ir/include/scc_type_abi.h create mode 100644 libs/ast2ir/tests/test_ast2ir_unit.c delete mode 100644 libs/ir/tests/test_ir.c rename libs/{ast2ir/tests/test_.c => ir/tests/test_ir_unit.c} (100%) diff --git a/.gitignore b/.gitignore index ac73a47..7a02213 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,6 @@ external/ # dot file and svg file *.dot *.svg + +# dll def or other definition file +*.def diff --git a/cbuild.toml b/cbuild.toml index 0c30497..97e77c0 100644 --- a/cbuild.toml +++ b/cbuild.toml @@ -8,6 +8,6 @@ dependencies = [ { name = "pproc", path = "./libs/pproc" }, { name = "parser", path = "./libs/parser" }, { name = "ast", path = "./libs/ast" }, - # { name = "ast2ir", path = "./libs/ast2ir" }, - # { name = "ir", path = "./libs/ir" }, + { name = "ast2ir", path = "./libs/ast2ir" }, + { name = "ir", path = "./libs/ir" }, ] diff --git a/libs/ast2ir/cbuild.toml b/libs/ast2ir/cbuild.toml index 2fc8343..7e7e21e 100644 --- a/libs/ast2ir/cbuild.toml +++ b/libs/ast2ir/cbuild.toml @@ -4,6 +4,9 @@ version = "0.1.0" authors = [] description = "" -# dependencies = [] +dependencies = [ + { name = "scc_ast", path = "../ast" }, + { name = "scc_ir", path = "../ir" }, +] # features = {} # default_features = [] diff --git a/libs/ast2ir/include/abi/win_x64_type_abi.h b/libs/ast2ir/include/abi/win_x64_type_abi.h new file mode 100644 index 0000000..0753182 --- /dev/null +++ b/libs/ast2ir/include/abi/win_x64_type_abi.h @@ -0,0 +1,141 @@ +#ifndef __SCC_WIN_X64_TYPE_ABI_H__ +#define __SCC_WIN_X64_TYPE_ABI_H__ + +#include "../scc_type_abi.h" + +/** + * @brief Windows x64 ABI Type + * @details + * https://learn.microsoft.com/zh-cn/cpp/build/x64-software-conventions?view=msvc-180 + */ +static const scc_type_abi_t scc_win_x64_type_abi[] = { + { + .ast_type = SCC_AST_BUILTIN_TYPE_UNKNOWN, + .ir_type = SCC_IR_TYPE_UNKNOWN, + .size = 0, + .alignment = 0, + }, + { + .ast_type = SCC_AST_BUILTIN_TYPE_VOID, + .ir_type = SCC_IR_TYPE_VOID, + .size = 0, + .alignment = 0, + }, + { + .ast_type = SCC_AST_BUILTIN_TYPE_BOOL, + .ir_type = SCC_IR_TYPE_U8, + .size = 1, + .alignment = 1, + }, + { + .ast_type = SCC_AST_BUILTIN_TYPE_CHAR, + .ir_type = SCC_IR_TYPE_I8, + .size = 1, + .alignment = 1, + }, + { + .ast_type = SCC_AST_BUILTIN_TYPE_SIGNED_CHAR, + .ir_type = SCC_IR_TYPE_I8, + .size = 1, + .alignment = 1, + }, + { + .ast_type = SCC_AST_BUILTIN_TYPE_UNSIGNED_CHAR, + .ir_type = SCC_IR_TYPE_U8, + .size = 1, + .alignment = 1, + }, + { + .ast_type = SCC_AST_BUILTIN_TYPE_SHORT, + .ir_type = SCC_IR_TYPE_I16, + .size = 2, + .alignment = 2, + }, + { + .ast_type = SCC_AST_BUILTIN_TYPE_SIGNED_SHORT, + .ir_type = SCC_IR_TYPE_I16, + .size = 2, + .alignment = 2, + }, + { + .ast_type = SCC_AST_BUILTIN_TYPE_UNSIGNED_SHORT, + .ir_type = SCC_IR_TYPE_U16, + .size = 2, + .alignment = 2, + }, + { + .ast_type = SCC_AST_BUILTIN_TYPE_INT, + .ir_type = SCC_IR_TYPE_I32, + .size = 4, + .alignment = 4, + }, + { + .ast_type = SCC_AST_BUILTIN_TYPE_SIGNED_INT, + .ir_type = SCC_IR_TYPE_I32, + .size = 4, + .alignment = 4, + }, + { + .ast_type = SCC_AST_BUILTIN_TYPE_UNSIGNED_INT, + .ir_type = SCC_IR_TYPE_U32, + .size = 4, + .alignment = 4, + }, + { + .ast_type = SCC_AST_BUILTIN_TYPE_LONG, + .ir_type = SCC_IR_TYPE_I32, + .size = 4, + .alignment = 4, + }, + { + .ast_type = SCC_AST_BUILTIN_TYPE_SIGNED_LONG, + .ir_type = SCC_IR_TYPE_I32, + .size = 4, + .alignment = 4, + }, + { + .ast_type = SCC_AST_BUILTIN_TYPE_UNSIGNED_LONG, + .ir_type = SCC_IR_TYPE_U32, + .size = 4, + .alignment = 4, + }, + { + .ast_type = SCC_AST_BUILTIN_TYPE_LONG_LONG, + .ir_type = SCC_IR_TYPE_I64, + .size = 8, + .alignment = 8, + }, + { + .ast_type = SCC_AST_BUILTIN_TYPE_SIGNED_LONG_LONG, + .ir_type = SCC_IR_TYPE_I64, + .size = 8, + .alignment = 8, + }, + { + .ast_type = SCC_AST_BUILTIN_TYPE_UNSIGNED_LONG_LONG, + .ir_type = SCC_IR_TYPE_I64, + .size = 8, + .alignment = 8, + }, + { + .ast_type = SCC_AST_BUILTIN_TYPE_FLOAT, + .ir_type = SCC_IR_TYPE_F32, + .size = 4, + .alignment = 4, + }, + { + .ast_type = SCC_AST_BUILTIN_TYPE_DOUBLE, + .ir_type = SCC_IR_TYPE_F64, + .size = 8, + .alignment = 8, + }, + { + // NULL + .ast_type = SCC_AST_BUILTIN_TYPE_UNKNOWN, + .ir_type = SCC_IR_TYPE_UNKNOWN, + .size = 0, + .alignment = 0, + }, +}; + +#endif /* __SCC_WIN_X64_TYPE_ABI_H__ */ diff --git a/libs/ast2ir/include/scc_ast2ir.h b/libs/ast2ir/include/scc_ast2ir.h index f8c211a..11de474 100644 --- a/libs/ast2ir/include/scc_ast2ir.h +++ b/libs/ast2ir/include/scc_ast2ir.h @@ -1,10 +1,12 @@ #ifndef __SCC_AST2IR_H__ #define __SCC_AST2IR_H__ -#include +#include "scc_type_abi.h" #include #include -void scc_ast2ir(scc_ast_translation_unit_t *tu, scc_ir_builder_t *builder); +void scc_ast2ir_translation_unit(scc_ir_builder_t *builder, + scc_ast_translation_unit_t *tu, + const scc_type_abi_t *abi); #endif /* __SCC_AST2IR_H__ */ diff --git a/libs/ast2ir/include/scc_type_abi.h b/libs/ast2ir/include/scc_type_abi.h new file mode 100644 index 0000000..24f2162 --- /dev/null +++ b/libs/ast2ir/include/scc_type_abi.h @@ -0,0 +1,14 @@ +#ifndef __SCC_TYPE_ABI_H__ +#define __SCC_TYPE_ABI_H__ + +#include +#include + +typedef struct { + scc_ast_builtin_type_t ast_type; + scc_ir_type_tag_t ir_type; + usize size; + usize alignment; +} scc_type_abi_t; + +#endif /* __SCC_TYPE_ABI_H__ */ diff --git a/libs/ast2ir/src/ast2ir.c b/libs/ast2ir/src/ast2ir.c index 7e92679..3dfc3f0 100644 --- a/libs/ast2ir/src/ast2ir.c +++ b/libs/ast2ir/src/ast2ir.c @@ -66,9 +66,11 @@ static scc_ir_type_ref_t ast_type_to_ir_type(scc_ir_builder_t *ctx, scc_ir_type_ref_vec_t params; scc_vec_init(params); scc_vec_foreach(ast_type->function.param_types, i) { - scc_ast_type_t *param_type = + scc_ast_decl_t *decl_param = scc_vec_at(ast_type->function.param_types, i); - scc_ir_type_ref_t tmp_type = ast_type_to_ir_type(ctx, param_type); + Assert(decl_param->base.type == SCC_AST_DECL_PARAM); + scc_ir_type_ref_t tmp_type = + ast_type_to_ir_type(ctx, decl_param->param.type); scc_vec_push(params, tmp_type); } ir_type.data.function.params = params; @@ -99,7 +101,8 @@ static scc_ir_node_ref_t ast_expr_to_ir(scc_ir_builder_t *ctx, } case SCC_AST_EXPR_INT_LITERAL: { - return scc_ir_ctx_get_i32_const(&ctx->ctx, expr->literal.value.i); + // TODO parse i32 value + return scc_ir_ctx_get_i32_const(&ctx->ctx, 0); } case SCC_AST_EXPR_BINARY: { @@ -112,22 +115,22 @@ static scc_ir_node_ref_t ast_expr_to_ir(scc_ir_builder_t *ctx, scc_ir_op_type_t op; switch (expr->binary.op) { /* clang-format off */ - case SCC_AST_OP_ADD: op = IR_OP_ADD; break; - case SCC_AST_OP_SUB: op = IR_OP_SUB; break; - case SCC_AST_OP_MUL: op = IR_OP_MUL; break; - case SCC_AST_OP_DIV: op = IR_OP_DIV; break; - case SCC_AST_OP_MOD: op = IR_OP_MOD; break; - case SCC_AST_OP_LOGICAL_AND: op = IR_OP_AND; break; - case SCC_AST_OP_LOGICAL_OR: op = IR_OP_OR; break; - case SCC_AST_OP_BITWISE_XOR: op = IR_OP_XOR; break; - case SCC_AST_OP_LEFT_SHIFT: op = IR_OP_SHL; break; - case SCC_AST_OP_RIGHT_SHIFT: op = IR_OP_SHR; break; - case SCC_AST_OP_EQUAL: op = IR_OP_EQ; break; - case SCC_AST_OP_NOT_EQUAL: op = IR_OP_NEQ; break; - case SCC_AST_OP_LESS: op = IR_OP_LT; break; - case SCC_AST_OP_LESS_EQUAL: op = IR_OP_LE; break; - case SCC_AST_OP_GREATER: op = IR_OP_GT; break; - case SCC_AST_OP_GREATER_EQUAL: op = IR_OP_GE; break; + case SCC_AST_OP_ADD: op = SCC_IR_OP_ADD; break; + case SCC_AST_OP_SUB: op = SCC_IR_OP_SUB; break; + case SCC_AST_OP_MUL: op = SCC_IR_OP_MUL; break; + case SCC_AST_OP_DIV: op = SCC_IR_OP_DIV; break; + case SCC_AST_OP_MOD: op = SCC_IR_OP_MOD; break; + case SCC_AST_OP_LOGICAL_AND: op = SCC_IR_OP_AND; break; + case SCC_AST_OP_LOGICAL_OR: op = SCC_IR_OP_OR; break; + case SCC_AST_OP_BITWISE_XOR: op = SCC_IR_OP_XOR; break; + case SCC_AST_OP_LEFT_SHIFT: op = SCC_IR_OP_SHL; break; + case SCC_AST_OP_RIGHT_SHIFT: op = SCC_IR_OP_SHR; break; + case SCC_AST_OP_EQUAL: op = SCC_IR_OP_EQ; break; + case SCC_AST_OP_NOT_EQUAL: op = SCC_IR_OP_NEQ; break; + case SCC_AST_OP_LESS: op = SCC_IR_OP_LT; break; + case SCC_AST_OP_LESS_EQUAL: op = SCC_IR_OP_LE; break; + case SCC_AST_OP_GREATER: op = SCC_IR_OP_GT; break; + case SCC_AST_OP_GREATER_EQUAL: op = SCC_IR_OP_GE; break; case SCC_AST_OP_ASSIGN: { // 赋值表达式:存储右值到左值位置 return scc_ir_builder_store(ctx, lhs, rhs); @@ -138,7 +141,7 @@ static scc_ir_node_ref_t ast_expr_to_ir(scc_ir_builder_t *ctx, /* clang-format on */ default: LOG_WARN("Unsupported binary operator: %d", expr->binary.op); - op = IR_OP_ADD; // 默认 + op = SCC_IR_OP_ADD; // 默认 } // 创建操作节点 @@ -151,20 +154,21 @@ static scc_ir_node_ref_t ast_expr_to_ir(scc_ir_builder_t *ctx, // 映射一元操作符 switch (expr->unary.op) { - case SCC_TOK_SUB: + case SCC_AST_OP_SUB: // 负号 // 实现为0 - operand - return scc_ir_builder_binop(ctx, IR_OP_SUB, + return scc_ir_builder_binop(ctx, SCC_IR_OP_SUB, scc_ir_ctx_get_builtin_zero(&ctx->ctx), operand); - case SCC_TOK_BIT_NOT: + case SCC_AST_OP_BITWISE_NOT: // 按位取反 - return scc_ir_builder_binop(ctx, IR_OP_NOT, operand, 0); - case SCC_TOK_NOT: + return scc_ir_builder_binop(ctx, SCC_IR_OP_NOT, operand, 0); + case SCC_AST_OP_LOGICAL_NOT: // 逻辑非 // 实现为与0比较 - return scc_ir_builder_binop( - ctx, IR_OP_EQ, scc_ir_ctx_get_builtin_zero(&ctx->ctx), operand); + return scc_ir_builder_binop(ctx, SCC_IR_OP_EQ, + scc_ir_ctx_get_builtin_zero(&ctx->ctx), + operand); default: LOG_WARN("Unsupported unary operator: %d", expr->unary.op); return 0; @@ -450,9 +454,9 @@ static void ast_stmt_to_ir(scc_ir_builder_t *ctx, scc_ast_stmt_t *stmt) { // ast_stmt_to_ir(ctx, stmt->for_stmt.body); // // 执行迭代表达式(如果存在) - // if (stmt->for_stmt.iter) { + // if (stmt->for_stmt.incr) { // scc_ir_node_t dummy_node; - // ast_expr_to_ir(ctx, stmt->for_stmt.iter, &dummy_node); + // ast_expr_to_ir(ctx, stmt->for_stmt.incr, &dummy_node); // } // // 跳转回条件块 @@ -497,7 +501,7 @@ static void ast_decl_to_ir(scc_ir_builder_t *ctx, scc_ast_decl_t *decl) { // 创建分配节点 scc_ir_node_ref_t alloc_val_node = - scc_ir_builder_alloca(ctx, ir_type, decl->var.name); + scc_ir_builder_alloca(ctx, ir_type, decl->name); // 如果有初始化表达式 if (!decl->var.init) { @@ -518,7 +522,7 @@ static void ast_decl_to_ir(scc_ir_builder_t *ctx, scc_ast_decl_t *decl) { case SCC_AST_DECL_FUNC: { // TODO params name scc_ir_type_ref_t func_type = ast_type_to_ir_type(ctx, decl->func.type); - scc_ir_builder_begin_func(ctx, decl->func.name, func_type, null); + scc_ir_builder_begin_func(ctx, decl->name, func_type, null); // 处理函数体(如果有) if (decl->func.body) { scc_ir_builder_begin_bblock(ctx, "entry"); @@ -535,17 +539,21 @@ static void ast_decl_to_ir(scc_ir_builder_t *ctx, scc_ast_decl_t *decl) { } } -// 主转换函数:将AST翻译单元转换为IR程序 -void scc_ast2ir(scc_ast_translation_unit_t *tu, scc_ir_builder_t *builder) { +/** + * @brief 将AST的翻译单元转换为IR + * @warning 需要初始化builder且保证tu合法 + * + * @param builder + * @param tu + */ +void scc_ast2ir_translation_unit(scc_ir_builder_t *builder, + scc_ast_translation_unit_t *tu, + const scc_type_abi_t *abi) { if (tu == null || builder == null) { LOG_ERROR("Invalid argument"); return; } - // 初始化上下文 - scc_ir_builder_init(builder); - - // 转换所有声明 scc_vec_foreach(tu->declarations, i) { scc_ast_decl_t *decl = scc_vec_at(tu->declarations, i); ast_decl_to_ir(builder, decl); diff --git a/libs/ast2ir/tests/test_ast2ir_unit.c b/libs/ast2ir/tests/test_ast2ir_unit.c new file mode 100644 index 0000000..e69de29 diff --git a/libs/ir/include/ir_def.h b/libs/ir/include/ir_def.h index 5d0aa6e..aae1d0a 100644 --- a/libs/ir/include/ir_def.h +++ b/libs/ir/include/ir_def.h @@ -23,17 +23,26 @@ typedef ir_handle_t scc_ir_func_ref_t; typedef SCC_VEC(scc_ir_func_ref_t) scc_ir_func_ref_vec_t; typedef enum scc_ir_type_tag { + SCC_IR_TYPE_UNKNOWN, SCC_IR_TYPE_VOID, - SCC_IR_TYPE_I1, + SCC_IR_TYPE_I8, SCC_IR_TYPE_I16, SCC_IR_TYPE_I32, SCC_IR_TYPE_I64, SCC_IR_TYPE_I128, + + SCC_IR_TYPE_U8, + SCC_IR_TYPE_U16, + SCC_IR_TYPE_U32, + SCC_IR_TYPE_U64, + SCC_IR_TYPE_U128, + SCC_IR_TYPE_F16, SCC_IR_TYPE_F32, SCC_IR_TYPE_F64, SCC_IR_TYPE_F128, + SCC_IR_TYPE_PTR, SCC_IR_TYPE_ARRAY, SCC_IR_TYPE_FUNC, @@ -76,56 +85,61 @@ struct scc_ir_func { typedef enum scc_ir_node_tag { SCC_IR_NODE_NULL, SCC_IR_NODE_CONST_INT, - SCC_IR_NODE_ALLOC, - SCC_IR_NODE_LOAD, - SCC_IR_NODE_STORE, - SCC_IR_NODE_GET_PTR, - SCC_IR_NODE_OP, - SCC_IR_NODE_BRANCH, - SCC_IR_NODE_JUMP, - SCC_IR_NODE_CALL, - SCC_IR_NODE_RET, + SCC_IR_NODE_CONV, ///< 类型转换 + SCC_IR_NODE_FUNC_ARG_REF, ///< 函数参数引用 + SCC_IR_NODE_BLOCK_ARG_REF, ///< 基本块参数引用 + SCC_IR_NODE_ALLOC, ///< 分配内存(stack) + SCC_IR_NODE_GLOBAL_ALLOC, ///< 全局分配(bss) + SCC_IR_NODE_LOAD, ///< 加载数据 + SCC_IR_NODE_STORE, ///< 存储数据 + SCC_IR_NODE_GET_PTR, ///< 获取指针 + SCC_IR_NODE_GET_ELEM_PTR, ///< 获取元素指针(used by array) + SCC_IR_NODE_OP, ///< 二元运算 + SCC_IR_NODE_BRANCH, ///< 有条件分支 + SCC_IR_NODE_JUMP, ///< 无条件跳转 + SCC_IR_NODE_CALL, ///< 调用函数 + SCC_IR_NODE_RET, ///< 函数返回 } scc_ir_node_tag_t; typedef enum { /// Empty op for init or nop - IR_OP_EMPTY, + SCC_IR_OP_EMPTY, /// Not equal to. - IR_OP_NEQ, + SCC_IR_OP_NEQ, /// Equal to. - IR_OP_EQ, + SCC_IR_OP_EQ, /// Greater than. - IR_OP_GT, + SCC_IR_OP_GT, /// Less than. - IR_OP_LT, + SCC_IR_OP_LT, /// Greater than or equal to. - IR_OP_GE, + SCC_IR_OP_GE, /// Less than or equal to. - IR_OP_LE, + SCC_IR_OP_LE, /// Addition. - IR_OP_ADD, + SCC_IR_OP_ADD, /// Subtraction. - IR_OP_SUB, + SCC_IR_OP_SUB, /// Multiplication. - IR_OP_MUL, + SCC_IR_OP_MUL, /// Division. - IR_OP_DIV, + SCC_IR_OP_DIV, /// Modulo. - IR_OP_MOD, + SCC_IR_OP_MOD, /// Bitwise AND. - IR_OP_AND, + SCC_IR_OP_AND, /// Bitwise OR. - IR_OP_OR, + SCC_IR_OP_OR, /// Bitwise XOR. - IR_OP_XOR, + SCC_IR_OP_XOR, /// Bitwise NOT. - IR_OP_NOT, + SCC_IR_OP_NOT, /// Shift left logical. - IR_OP_SHL, + SCC_IR_OP_SHL, /// Shift right logical. - IR_OP_SHR, + SCC_IR_OP_SHR, /// Shift right arithmetic. - IR_OP_SAR, + SCC_IR_OP_SAR, } scc_ir_op_type_t; struct scc_ir_node { @@ -151,9 +165,17 @@ struct scc_ir_node { u8 uint_any[16]; } const_uint; // aggregate; - // func_arg_ref; - // block_arg_ref; - // global_alloc; + struct { + usize idx; + } arg_ref; + struct { + scc_ir_node_ref_vec_t elements; + } global_alloc; + struct { + scc_ir_node_ref_t operand; + scc_ir_type_ref_t target_type; // 目标类型 + enum { CONV_SEXT, CONV_ZEXT, CONV_TRUNC } conv_type; + } conv; struct { scc_ir_node_ref_t target; } load; diff --git a/libs/ir/src/ir_base.c b/libs/ir/src/ir_base.c index 88bec41..8b6ab06 100644 --- a/libs/ir/src/ir_base.c +++ b/libs/ir/src/ir_base.c @@ -70,7 +70,7 @@ void scc_ir_node_init(scc_ir_node_t *in, const char *name, in->data.get_ptr.index = 0; break; case SCC_IR_NODE_OP: - in->data.op.op = IR_OP_EMPTY; + in->data.op.op = SCC_IR_OP_EMPTY; in->data.op.lhs = 0; in->data.op.rhs = 0; break; diff --git a/libs/ir/src/ir_builtin.c b/libs/ir/src/ir_builtin.c index e822335..d6344fc 100644 --- a/libs/ir/src/ir_builtin.c +++ b/libs/ir/src/ir_builtin.c @@ -7,4 +7,4 @@ scc_ir_type_t scc_ir_builtin_i32 = { scc_ir_node_t scc_ir_builtin_zero = { .tag = SCC_IR_NODE_CONST_INT, .data.const_int.int_any = {0}, -}; \ No newline at end of file +}; diff --git a/libs/ir/src/ir_ctx.c b/libs/ir/src/ir_ctx.c index b67ed9e..788910e 100644 --- a/libs/ir/src/ir_ctx.c +++ b/libs/ir/src/ir_ctx.c @@ -22,7 +22,11 @@ static u32 hash_type(const scc_ir_type_t *key) { switch (key->tag) { case SCC_IR_TYPE_VOID: - case SCC_IR_TYPE_I1: + case SCC_IR_TYPE_U8: + case SCC_IR_TYPE_U16: + case SCC_IR_TYPE_U32: + case SCC_IR_TYPE_U64: + case SCC_IR_TYPE_U128: case SCC_IR_TYPE_I8: case SCC_IR_TYPE_I16: case SCC_IR_TYPE_I32: @@ -70,7 +74,11 @@ static int cmp_type(const scc_ir_type_t *key1, const scc_ir_type_t *key2) { switch (key1->tag) { case SCC_IR_TYPE_VOID: - case SCC_IR_TYPE_I1: + case SCC_IR_TYPE_U8: + case SCC_IR_TYPE_U16: + case SCC_IR_TYPE_U32: + case SCC_IR_TYPE_U64: + case SCC_IR_TYPE_U128: case SCC_IR_TYPE_I8: case SCC_IR_TYPE_I16: case SCC_IR_TYPE_I32: diff --git a/libs/ir/src/ir_dump.c b/libs/ir/src/ir_dump.c index 13e0f8a..69d88f8 100644 --- a/libs/ir/src/ir_dump.c +++ b/libs/ir/src/ir_dump.c @@ -31,13 +31,16 @@ static const char *get_node_type_str(scc_ir_node_tag_t tag) { // 获取操作符字符串 static const char *get_op_str(scc_ir_op_type_t op) { static const char *ops[] = { - [IR_OP_EMPTY] = "empty", [IR_OP_NEQ] = "!=", [IR_OP_EQ] = "==", - [IR_OP_GT] = ">", [IR_OP_LT] = "<", [IR_OP_GE] = ">=", - [IR_OP_LE] = "<=", [IR_OP_ADD] = "+", [IR_OP_SUB] = "-", - [IR_OP_MUL] = "*", [IR_OP_DIV] = "/", [IR_OP_MOD] = "%", - [IR_OP_AND] = "&", [IR_OP_OR] = "|", [IR_OP_XOR] = "^", - [IR_OP_NOT] = "~", [IR_OP_SHL] = "<<", [IR_OP_SHR] = ">>", - [IR_OP_SAR] = ">>a", // Arithmetic shift right + [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 }; if (op >= 0 && op < sizeof(ops) / sizeof(ops[0]) && ops[op] != NULL) { @@ -49,7 +52,9 @@ static const char *get_op_str(scc_ir_op_type_t op) { // 获取类型标签字符串 static const char *get_type_tag_str(scc_ir_type_tag_t tag) { static const char *type_tags[] = { - [SCC_IR_TYPE_VOID] = "void", [SCC_IR_TYPE_I1] = "i1", + [SCC_IR_TYPE_VOID] = "void", [SCC_IR_TYPE_U8] = "u8", + [SCC_IR_TYPE_U16] = "u16", [SCC_IR_TYPE_U32] = "u32", + [SCC_IR_TYPE_U64] = "u64", [SCC_IR_TYPE_U128] = "u128", [SCC_IR_TYPE_I8] = "i8", [SCC_IR_TYPE_I16] = "i16", [SCC_IR_TYPE_I32] = "i32", [SCC_IR_TYPE_I64] = "i64", [SCC_IR_TYPE_I128] = "i128", [SCC_IR_TYPE_F16] = "f16", @@ -82,7 +87,7 @@ static void dump_const_int_node(scc_ir_dump_ctx_t *ctx, const scc_ir_node_t *node) { scc_tree_dump_push_level(ctx->dump_ctx, true); scc_tree_print_indent(ctx->dump_ctx); - scc_printf("%d\n", node->data.const_int.int32); + scc_tree_dump_printf(ctx->dump_ctx, "%d\n", node->data.const_int.int32); scc_tree_dump_pop_level(ctx->dump_ctx); } @@ -189,13 +194,14 @@ static void dump_jump_node(scc_ir_dump_ctx_t *ctx, const scc_ir_node_t *node) { scc_ir_bblock_t *target_bblock = scc_ir_ctx_get_bblock(ctx->ir_ctx, node->data.jump.target_bblock); if (target_bblock) { - scc_printf("to '%s'", target_bblock->label ? target_bblock->label - : ""); + scc_tree_dump_printf(ctx->dump_ctx, "to '%s'", + target_bblock->label ? target_bblock->label + : ""); } else { - scc_printf("to invalid block"); + scc_tree_dump_printf(ctx->dump_ctx, "to invalid block"); } } else { - scc_printf("to NULL"); + scc_tree_dump_printf(ctx->dump_ctx, "to NULL"); } } @@ -206,16 +212,17 @@ static void dump_call_node(scc_ir_dump_ctx_t *ctx, const scc_ir_node_t *node) { scc_ir_func_t *callee = scc_ir_ctx_get_func(ctx->ir_ctx, node->data.call.callee); if (callee) { - scc_printf("func='%s'", callee->name ? callee->name : ""); + scc_tree_dump_printf(ctx->dump_ctx, "func='%s'", + callee->name ? callee->name : ""); } else { - scc_printf("func="); + scc_tree_dump_printf(ctx->dump_ctx, "func="); } } else { - scc_printf("func=NULL"); + scc_tree_dump_printf(ctx->dump_ctx, "func=NULL"); } if (scc_vec_size(node->data.call.args) > 0) { - scc_printf("\n"); + scc_tree_dump_printf(ctx->dump_ctx, "\n"); } // 输出参数 @@ -261,14 +268,14 @@ void scc_ir_dump_node(scc_ir_dump_ctx_t *ctx, scc_ir_node_ref_t node_ref) { } if (node->type) { - scc_printf(" : "); + scc_tree_dump_printf(ctx->dump_ctx, " : "); scc_ir_type_t *type = scc_ir_ctx_get_type(ctx->ir_ctx, node->type); if (type) { PRINT_VALUE(ctx->dump_ctx, "%s", get_type_tag_str(type->tag)); } } - scc_printf("\n"); + scc_tree_dump_printf(ctx->dump_ctx, "\n"); // 根据节点类型输出特定信息 switch (node->tag) { @@ -305,7 +312,7 @@ void scc_ir_dump_node(scc_ir_dump_ctx_t *ctx, scc_ir_node_ref_t node_ref) { break; default: PRINT_QUOTED_VALUE(ctx->dump_ctx, "unknown"); - scc_printf("tag(%d)", node->tag); + scc_tree_dump_printf(ctx->dump_ctx, "tag(%d)", node->tag); break; } } @@ -325,7 +332,7 @@ void scc_ir_dump_type(scc_ir_dump_ctx_t *ctx, scc_ir_type_ref_t type_ref) { scc_tree_print_indent(ctx->dump_ctx); PRINT_NODE(ctx->dump_ctx, "Type: "); PRINT_QUOTED_VALUE(ctx->dump_ctx, get_type_tag_str(type->tag)); - scc_printf("\n"); + scc_tree_dump_printf(ctx->dump_ctx, "\n"); // 递归转储子类型 switch (type->tag) { @@ -398,7 +405,7 @@ void scc_ir_dump_bblock(scc_ir_dump_ctx_t *ctx, PRINT_NODE(ctx->dump_ctx, "BasicBlock: "); PRINT_QUOTED_VALUE(ctx->dump_ctx, bblock->label ? bblock->label : ""); - scc_printf("\n"); + scc_tree_dump_printf(ctx->dump_ctx, "\n"); // 转储基本块中的指令 for (usize i = 0; i < scc_vec_size(bblock->instrs); i++) { @@ -422,7 +429,7 @@ void scc_ir_dump_func(scc_ir_dump_ctx_t *ctx, scc_ir_func_ref_t func_ref) { scc_tree_print_indent(ctx->dump_ctx); PRINT_NODE(ctx->dump_ctx, "Function: "); PRINT_QUOTED_VALUE(ctx->dump_ctx, func->name ? func->name : ""); - scc_printf("\n"); + scc_tree_dump_printf(ctx->dump_ctx, "\n"); // 输出函数类型 if (func->type) { @@ -546,6 +553,7 @@ void scc_ir_dump_type_linear(scc_ir_dump_ctx_t *ctx, } else { PRINT_TYPE(ctx->dump_ctx, ")"); } + break; default: LOG_ERROR("invalid type tag"); break; diff --git a/libs/ir/tests/test_ir.c b/libs/ir/tests/test_ir.c deleted file mode 100644 index 1616237..0000000 --- a/libs/ir/tests/test_ir.c +++ /dev/null @@ -1,10 +0,0 @@ -#include - -void test_example() { - printf("Test passed!\n"); -} - -int main() { - test_example(); - return 0; -} diff --git a/libs/ast2ir/tests/test_.c b/libs/ir/tests/test_ir_unit.c similarity index 100% rename from libs/ast2ir/tests/test_.c rename to libs/ir/tests/test_ir_unit.c diff --git a/libs/target/pe/src/main.c b/libs/target/pe/src/main.c index b11bf4a..763b362 100644 --- a/libs/target/pe/src/main.c +++ b/libs/target/pe/src/main.c @@ -47,7 +47,7 @@ int main() { u32 idata_size = scc_pe_reserve_idata(&idata_builder); scc_pe_section_range idata_range = scc_pe_reserve_section_header( &builder, (BYTE *)".idata\0", - IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | + IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE, idata_size, idata_size); scc_vec_at(builder.image_data_directory_vec, IMAGE_DIRECTORY_ENTRY_IMPORT) = @@ -97,6 +97,5 @@ int main() { scc_pe_write_section(&builder, &idata_range, scc_vec_unsafe_get_data(idata_buffer), scc_vec_size(idata_buffer)); - scc_pe_dump_to_file(&builder, "hello_world.exe"); } diff --git a/libs/target/pe/src/scc_pe_idata.c b/libs/target/pe/src/scc_pe_idata.c index 7927213..34df2cb 100644 --- a/libs/target/pe/src/scc_pe_idata.c +++ b/libs/target/pe/src/scc_pe_idata.c @@ -32,8 +32,8 @@ static void scc_winpe_hnt_builder_push(scc_winpe_hnt_builder_t *builder, scc_hashtable_set(&builder->str_map, name, (void *)(u64)builder->data.size); /// FIXME WARNING需要转换为little endian - scc_vec_push(builder->data, hint >> 8); scc_vec_push(builder->data, hint & 0xff); + scc_vec_push(builder->data, hint >> 8); while (*name) { scc_vec_push(builder->data, *name); diff --git a/runtime/scc_core/include/scc_core_vec.h b/runtime/scc_core/include/scc_core_vec.h index 13c628e..fa38c63 100644 --- a/runtime/scc_core/include/scc_core_vec.h +++ b/runtime/scc_core/include/scc_core_vec.h @@ -9,9 +9,10 @@ #define __SCC_CORE_VEC_H__ #ifndef __SCC_CORE_VEC_USE_STD__ +#include "scc_core_log.h" + #include "scc_core_impl.h" #include "scc_core_type.h" - #define __scc_vec_realloc scc_realloc #define __scc_vec_free scc_free #else @@ -27,7 +28,7 @@ typedef size_t usize; #define LOG_FATAL(...) \ do { \ printf(__VA_ARGS__); \ - exit(1); \ + abort(); \ } while (0) #endif diff --git a/src/main.c b/src/main.c index e70eb6e..96ddb9d 100644 --- a/src/main.c +++ b/src/main.c @@ -3,9 +3,9 @@ #include #include +#include +#include #include -// #include -// #include typedef struct { const char *input_file; @@ -332,20 +332,29 @@ sstream_drop: return 0; } - // scc_ir_builder_t ir_builder; - // scc_ast2ir(translation_unit, &ir_builder); + scc_ir_builder_t ir_builder; + scc_ir_builder_init(&ir_builder); +#include + scc_ast2ir_translation_unit(&ir_builder, translation_unit, + scc_win_x64_type_abi); - // if (config.emit_ir) { - // scc_ir_dump_ctx_t ir_dump_ctx; - // scc_tree_dump_ctx_t tree_dump; // 仅为 ir dump 辅助 - // scc_tree_dump_ctx_init(&tree_dump, true); - // scc_ir_dump_ctx_init(&ir_dump_ctx, &tree_dump, &ir_builder.cprog, - // &ir_builder.ctx); - // // scc_ir_dump_cprog(&ir_dump_ctx); - // scc_ir_dump_cprog_linear(&ir_dump_ctx); - // scc_tree_dump_ctx_drop(&tree_dump); - // return 0; - // } + if (config.emit_ir) { + scc_ir_dump_ctx_t ir_dump_ctx; + scc_tree_dump_ctx_t tree_dump; + if (fp == null) { + scc_tree_dump_ctx_init(&tree_dump, true, (void *)scc_fprintf, + (void *)scc_stdout); + } else { + scc_tree_dump_ctx_init(&tree_dump, false, (void *)scc_fprintf, + (void *)fp); + } + scc_ir_dump_ctx_init(&ir_dump_ctx, &tree_dump, &ir_builder.cprog, + &ir_builder.ctx); + // scc_ir_dump_cprog(&ir_dump_ctx); + scc_ir_dump_cprog_linear(&ir_dump_ctx); + scc_tree_dump_ctx_drop(&tree_dump); + return 0; + } scc_printf("output exe at %s\n", config.output_file); return 0;