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:
@@ -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 {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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 =
|
||||
|
||||
Reference in New Issue
Block a user