feat(ast): 更新AST dump功能以使用新的树转储接口

- 将头文件中的tree_dump.h替换为scc_tree_dump.h
- 修改函数签名将scc_tree_dump_ctx_t改为scc_tree_dump_t
- 移除过时的宏定义和内联函数实现
- 使用新的scc_tree_dump_* API替代旧的PRINT_*宏
- 简化类型、表达式、语句和声明的转储逻辑
- 统一使用新的树转储接口进行节点和值的输出

feat(ast2ir): 实现逻辑运算符和一元运算符的IR转换

- 添加scc_ast2ir_logical_expr函数处理&&和||运算符
- 实现短路求值逻辑,包含分支控制流
- 添加对一元正号运算符的支持
- 实现取地址和间接寻址运算符
- 添加字符字面量解析支持转义序列

fix(ir): 修复字符串常量构建中的长度计算错误

- 修正数组长度计算从len+1改为len-1
- 调整字符串内容复制逻辑跳过引号边界
- 修正内存分配大小与实际数据长度匹配

refactor(ir): 更新IR转储模块使用统一的树转储接口

- 将IR转储上下文中的tree_dump_ctx_t替换为scc_tree_dump_t
- 更新初始化函数签名以使用新的转储接口类型
This commit is contained in:
zzy
2026-04-03 20:10:51 +08:00
parent 78e7c800ba
commit ca187c78f1
42 changed files with 1264 additions and 1212 deletions

View File

@@ -8,11 +8,12 @@
typedef enum {
SCC_REG_KIND_UNDEF,
SCC_REG_KIND_FUNC_ARG,
SCC_REG_KIND_GPR, ///< 通用寄存器(整数)
SCC_REG_KIND_FPR, ///< 浮点数寄存器
SCC_REG_KIND_STACK, ///< 栈
SCC_REG_KIND_IMM, ///< 整数立即数
SCC_REG_KIND_IMM_FP, ///< 浮点数常量
SCC_REG_KIND_GPR, ///< 通用寄存器(整数)
SCC_REG_KIND_FPR, ///< 浮点数寄存器
SCC_REG_KIND_STACK, ///< 栈
SCC_REG_KIND_STACK_ADDR, ///< 栈地址(如 alloc 节点)
SCC_REG_KIND_IMM, ///< 整数立即数
SCC_REG_KIND_IMM_FP, ///< 浮点数常量
} scc_reg_kind_t;
typedef struct {

View File

@@ -5,6 +5,24 @@
#define GET_MODULE(ctx) (&(ctx->cprog->module))
static int scc_type_width(scc_ir_type_t *type) {
/* clang-format off */
switch (type->tag) {
case SCC_IR_TYPE_i8: case SCC_IR_TYPE_u8: return 1;
case SCC_IR_TYPE_i16: case SCC_IR_TYPE_u16: return 2;
case SCC_IR_TYPE_i32: case SCC_IR_TYPE_u32: return 4;
case SCC_IR_TYPE_i64: case SCC_IR_TYPE_u64: return 8;
case SCC_IR_TYPE_PTR: return 8;
default: return 8; // 默认64位
}
/* clang-format on */
}
static bool scc_type_is_signed(scc_ir_type_t *type) {
return (type->tag == SCC_IR_TYPE_i8 || type->tag == SCC_IR_TYPE_i16 ||
type->tag == SCC_IR_TYPE_i32 || type->tag == SCC_IR_TYPE_i64);
}
static void parse_location(scc_ir2mcode_ctx_t *ctx, scc_reg_loc_t *loc,
scc_ir_value_ref_t node_ref) {
Assert(ctx != null && loc != null);
@@ -40,11 +58,12 @@ static void parse_location(scc_ir2mcode_ctx_t *ctx, scc_reg_loc_t *loc,
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;
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_ALLOC:
default:
idx = (usize)scc_hashtable_get(ctx->noderef2regloc,
(void *)(usize)node_ref);
@@ -72,6 +91,12 @@ static void load_value_to_reg(scc_mcode_t *mcode, scc_reg_loc_t *loc, int reg) {
case SCC_REG_KIND_IMM:
scc_mcode_amd64_mov_r64_imm64(mcode, reg, loc->idx); // 或 imm32
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);
break;
default:
LOG_FATAL("unsupported location");
}
@@ -93,6 +118,12 @@ static void store_value_from_reg(scc_mcode_t *mcode, scc_reg_loc_t *loc,
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");
break;
@@ -123,8 +154,9 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
///< ABI
break;
case SCC_IR_VALUE_TAG_BLOCK_ARG_REF: ///< 基本块参数引用
case SCC_IR_VALUE_TAG_ALLOC: ///< 分配内存(stack)
case SCC_IR_VALUE_TAG_GLOBAL_ALLOC: ///< 全局分配(bss)
break;
case SCC_IR_VALUE_TAG_ALLOC: ///< 分配内存(stack)
case SCC_IR_VALUE_TAG_GLOBAL_ALLOC: ///< 全局分配(bss
break;
///< 加载数据
case SCC_IR_VALUE_TAG_LOAD: {
@@ -133,18 +165,79 @@ static void parse_value(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->sect_mcode, &from, SCC_AMD64_RAX);
load_value_to_reg(&ctx->sect_mcode, &from, SCC_AMD64_RCX);
// 获取基类型宽度
scc_ir_type_t *ptr_type = scc_ir_module_get_type_by_value(
GET_MODULE(ctx), node->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_type_width(base_type);
bool is_signed = scc_type_is_signed(base_type);
// 间接加载到 RAX
if (width == 1) {
if (is_signed)
scc_mcode_amd64_movsx_r64_m8(&ctx->sect_mcode, SCC_AMD64_RAX,
SCC_AMD64_RCX);
else
scc_mcode_amd64_movzx_r64_m8(&ctx->sect_mcode, SCC_AMD64_RAX,
SCC_AMD64_RCX);
} else if (width == 2) {
if (is_signed)
scc_mcode_amd64_movsx_r64_m16(&ctx->sect_mcode, SCC_AMD64_RAX,
SCC_AMD64_RCX);
else
scc_mcode_amd64_movzx_r64_m16(&ctx->sect_mcode, SCC_AMD64_RAX,
SCC_AMD64_RCX);
} else if (width == 4) {
if (is_signed)
scc_mcode_amd64_movsx_r64_m32(&ctx->sect_mcode, SCC_AMD64_RAX,
SCC_AMD64_RCX);
else
scc_mcode_amd64_mov_r32_m32(
&ctx->sect_mcode, SCC_AMD64_RAX,
SCC_AMD64_RCX); // 32位加载自动清零高位
} else { // 8
scc_mcode_amd64_mov_r64_m64(&ctx->sect_mcode, SCC_AMD64_RAX,
SCC_AMD64_RCX);
}
// 存储结果
store_value_from_reg(&ctx->sect_mcode, &to, SCC_AMD64_RAX);
break;
}
///< 存储数据
///< 存储数据
case SCC_IR_VALUE_TAG_STORE: {
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->sect_mcode, &from, SCC_AMD64_RAX);
store_value_from_reg(&ctx->sect_mcode, &to, SCC_AMD64_RAX);
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);
// 将值加载到 RAX
load_value_to_reg(&ctx->sect_mcode, &val_loc, SCC_AMD64_RAX);
// 将目标地址加载到 RCX
load_value_to_reg(&ctx->sect_mcode, &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);
scc_ir_type_t *base_type = scc_ir_module_get_type(
GET_MODULE(ctx), ptr_type->data.pointer.base);
int width = scc_type_width(base_type);
// 根据宽度生成存储指令
if (width == 1) {
scc_mcode_amd64_mov_m8_r8(&ctx->sect_mcode, SCC_AMD64_RCX,
SCC_AMD64_RAX);
} else if (width == 2) {
scc_mcode_amd64_mov_m16_r16(&ctx->sect_mcode, SCC_AMD64_RCX,
SCC_AMD64_RAX);
} else if (width == 4) {
scc_mcode_amd64_mov_m32_r32(&ctx->sect_mcode, SCC_AMD64_RCX,
SCC_AMD64_RAX);
} else { // width == 8
scc_mcode_amd64_mov_m64_r64(&ctx->sect_mcode, SCC_AMD64_RCX,
SCC_AMD64_RAX);
}
break;
}
///< 获取指针
@@ -189,6 +282,9 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
// 将右操作数加载到 RCX
load_value_to_reg(&ctx->sect_mcode, &loc_rhs, SCC_AMD64_RCX);
switch (node->data.op.op) {
case SCC_IR_OP_EMPTY:
Panic("unsupported empty op");
break;
case SCC_IR_OP_ADD:
scc_mcode_amd64_add_r64_r64(&ctx->sect_mcode, SCC_AMD64_RAX,
SCC_AMD64_RCX);
@@ -200,16 +296,30 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
case SCC_IR_OP_MUL:
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] = ">",
// [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_DIV:
case SCC_IR_OP_MOD:
TODO();
break;
case SCC_IR_OP_AND:
scc_mcode_amd64_and_r64_r64(&ctx->sect_mcode, SCC_AMD64_RAX,
SCC_AMD64_RCX);
break;
case SCC_IR_OP_OR:
scc_mcode_amd64_or_r64_r64(&ctx->sect_mcode, SCC_AMD64_RAX,
SCC_AMD64_RCX);
break;
case SCC_IR_OP_XOR:
scc_mcode_amd64_xor_r64_r64(&ctx->sect_mcode, SCC_AMD64_RAX,
SCC_AMD64_RCX);
break;
case SCC_IR_OP_NOT:
scc_mcode_amd64_not_r64(&ctx->sect_mcode, SCC_AMD64_RAX);
break;
case SCC_IR_OP_SHL:
case SCC_IR_OP_SHR:
case SCC_IR_OP_SAR:
TODO();
break;
case SCC_IR_OP_NEQ:
scc_mcode_amd64_cmp_r64_r64(&ctx->sect_mcode, SCC_AMD64_RAX,
SCC_AMD64_RCX);
@@ -329,7 +439,12 @@ static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
return;
}
scc_mcode_amd64_call_rel32(&ctx->sect_mcode, 0);
// FIXME hack func value
if (scc_vec_size(func->bblocks)) {
scc_mcode_amd64_call_rel32(&ctx->sect_mcode, 0);
} else {
scc_mcode_amd64_call_mem_rip_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(

View File

@@ -49,8 +49,7 @@ scc_hashtable_t *scc_reg_alloc_with_stack(scc_reg_alloc_t *ctx,
case SCC_IR_VALUE_TAG_LOAD:
case SCC_IR_VALUE_TAG_OP:
case SCC_IR_VALUE_TAG_GET_PTR:
case SCC_IR_VALUE_TAG_GET_ELEM_PTR:
case SCC_IR_VALUE_TAG_ALLOC: {
case SCC_IR_VALUE_TAG_GET_ELEM_PTR: {
loc.kind = SCC_REG_KIND_STACK;
loc.idx = ctx->alloc_stack_size;
@@ -61,6 +60,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_VALUE_TAG_ALLOC: {
// 为 alloc 分配栈偏移,但不作为普通值存储
loc.kind =
SCC_REG_KIND_STACK_ADDR; // 实际不需要存储到 reg_loc_vec
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;
}
case SCC_IR_VALUE_TAG_CALL: {
// 处理返回值
scc_ir_type_t *func_type =