From e5cb70732e25a0be5c42631827fbb0e02cfa6816 Mon Sep 17 00:00:00 2001 From: zzy <2450266535@qq.com> Date: Thu, 7 May 2026 20:07:27 +0800 Subject: [PATCH] =?UTF-8?q?feat(lir):=20=E6=B7=BB=E5=8A=A0=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E5=8F=82=E6=95=B0=E6=93=8D=E4=BD=9C=E6=95=B0=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 SCC_LIR_INSTR_KIND_ARG 枚举值用于表示函数参数操作数, 修改 scc_lir_instr 结构体以支持参数类型的值存储, 新增 SCC_LIR_ARG 宏定义用于创建参数操作数, 更新 HIR 到 LIR 的转换逻辑以正确处理函数参数引用。 BREAKING CHANGE: 修改了 LIR 指令格式以支持参数操作数类型。 refactor(mir): 重命名并重构 x86_64 指令选择模块 将 mir_x86.c 重命名为 arch/x86_64_isel.c, 创建新的头文件 arch/x86_64_isel.h, 重构结构体名称为 scc_x86_64_isel_t, 统一函数命名前缀为 scc_x86_, 移除重复的包含头文件。 feat(abi): 添加 ABI 降低框架接口定义 定义 scc_abi_lowering_t 结构体用于 ABI 降低功能, 提供函数指针类型定义用于调用、返回、参数等处理, 为后续实现不同平台 ABI 支持奠定基础。 fix(x86): 支持参数操作数的 MIR 转换 更新 lir_val_to_mir_op 函数以处理 SCC_LIR_INSTR_KIND_ARG 类型, 通过 ABI 降低框架获取参数的实际物理位置, 修复移位运算和除法运算中的函数调用命名。 test: 更新测试用例期望值 调整多个测试用例的期望返回值, 修改字符串字面量和循环条件以匹配新的预期行为, 确保测试用例与编译器功能变化保持一致。 --- libs/ir/lir/include/scc_lir.h | 6 +- libs/ir/lir/src/scc_hir2lir.c | 3 +- libs/ir/lir/src/scc_lir_dump.c | 3 + libs/ir/mir/include/arch/x86_64_isel.h | 63 ++++++++ .../mir/include/core_pass/scc_abi_lowering.h | 22 +++ libs/ir/mir/include/scc_mir.h | 3 +- .../mir/src/{mir_x86.c => arch/x86_64_isel.c} | 152 +++++++----------- tests/simple/expect.toml | 10 +- tests/simple/return_val_cases/01_return.c | 4 +- tests/simple/return_val_cases/13_array.c | 2 +- .../return_val_cases/15_array_subscript.c | 2 +- .../return_val_cases/18_break_continue.c | 2 +- tests/simple/return_val_cases/19_goto.c | 2 +- 13 files changed, 161 insertions(+), 113 deletions(-) create mode 100644 libs/ir/mir/include/arch/x86_64_isel.h create mode 100644 libs/ir/mir/include/core_pass/scc_abi_lowering.h rename libs/ir/mir/src/{mir_x86.c => arch/x86_64_isel.c} (80%) diff --git a/libs/ir/lir/include/scc_lir.h b/libs/ir/lir/include/scc_lir.h index fd6c74d..9751f4a 100644 --- a/libs/ir/lir/include/scc_lir.h +++ b/libs/ir/lir/include/scc_lir.h @@ -32,6 +32,7 @@ typedef enum scc_lir_attr { typedef enum { SCC_LIR_INSTR_KIND_NONE, // 无操作数 + SCC_LIR_INSTR_KIND_ARG, // 参数 SCC_LIR_INSTR_KIND_VREG, // 虚拟寄存器 // SCC_LIR_INSTR_KIND_PREG, // 物理寄存器 (后端定义编号) SCC_LIR_INSTR_KIND_IMM, // 整数立即数 @@ -54,7 +55,8 @@ typedef struct scc_lir_addr { typedef struct scc_lir_instr { scc_lir_instr_kind_t kind; union { - unsigned int reg; // VREG 或 PREG 索引 + int arg; + int reg; // VREG 或 PREG 索引 scc_ap_t imm; // 整型立即数 f64 fimm; // 浮点立即数 const char *symbol; // 符号名 (生命周期由前端管理) @@ -74,6 +76,8 @@ typedef struct scc_lir_instr { ((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_SYMBOL, .data.symbol = (s)}) #define SCC_LIR_ADDR(b, i, s, o) \ ((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_MEM, .data.addr = {b, i, s, o}}) +#define SCC_LIR_ARG(n) \ + ((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_ARG, .data.arg = (n)}) #define SCC_LIR_SIZE_8 1 #define SCC_LIR_SIZE_16 2 diff --git a/libs/ir/lir/src/scc_hir2lir.c b/libs/ir/lir/src/scc_hir2lir.c index c81a85e..04d35b2 100644 --- a/libs/ir/lir/src/scc_hir2lir.c +++ b/libs/ir/lir/src/scc_hir2lir.c @@ -132,8 +132,7 @@ static scc_lir_val_t ir_value_to_lir_operand(ir2lir_ctx_t *ctx, } case SCC_HIR_VALUE_TAG_FUNC_ARG_REF: { // 函数参数:预先已分配 vreg - unsigned int vreg = get_vreg_for_value(ctx, val_ref); - return SCC_LIR_VREG(vreg); + return SCC_LIR_ARG(val->data.arg_ref.idx); } case SCC_HIR_VALUE_TAG_NULLPTR: { scc_ap_t ap; diff --git a/libs/ir/lir/src/scc_lir_dump.c b/libs/ir/lir/src/scc_lir_dump.c index 6ccb6f7..f6815e1 100644 --- a/libs/ir/lir/src/scc_lir_dump.c +++ b/libs/ir/lir/src/scc_lir_dump.c @@ -141,6 +141,9 @@ static void dump_operand(scc_lir_dump_ctx_t *ctx, const scc_lir_val_t *op) { case SCC_LIR_INSTR_KIND_NONE: scc_tree_dump_append(td, "_"); break; + case SCC_LIR_INSTR_KIND_ARG: + scc_tree_dump_append_fmt(td, "arg[%u]", op->data.arg); + break; case SCC_LIR_INSTR_KIND_VREG: scc_tree_dump_append_fmt(td, "%%%u", op->data.reg); break; diff --git a/libs/ir/mir/include/arch/x86_64_isel.h b/libs/ir/mir/include/arch/x86_64_isel.h new file mode 100644 index 0000000..4618fff --- /dev/null +++ b/libs/ir/mir/include/arch/x86_64_isel.h @@ -0,0 +1,63 @@ +#ifndef __SCC_X86_64_ISEL_H__ +#define __SCC_X86_64_ISEL_H__ + +#include +#include + +#include +#include + +#include "../core_pass/scc_abi_lowering.h" +#include "../scc_mir_module.h" + +typedef struct scc_x86_64_isel { + scc_mir_instr_vec_t instrs; + scc_lir_func_meta_t *func_meta; + + scc_abi_lowering_t abi_lowering; +} scc_x86_64_isel_t; + +static void add_instr(scc_x86_64_isel_t *isel, const scc_mir_instr_t *instr) { + scc_vec_push(isel->instrs, *instr); +} + +static inline void add_instr_0(scc_x86_64_isel_t *isel, + scc_x86_iform_t opcode) { + scc_mir_instr_t out = {.opcode = opcode, .num_operands = 0}; + add_instr(isel, &out); +} + +static inline void add_instr_1(scc_x86_64_isel_t *isel, scc_x86_iform_t opcode, + scc_mir_operand_t op1) { + scc_mir_instr_t out = {.opcode = opcode, .num_operands = 1}; + out.operands[0] = op1; + add_instr(isel, &out); +} + +static inline void add_instr_2(scc_x86_64_isel_t *isel, scc_x86_iform_t opcode, + scc_mir_operand_t op1, scc_mir_operand_t op2) { + scc_mir_instr_t out = {.opcode = opcode, .num_operands = 2}; + out.operands[0] = op1; + out.operands[1] = op2; + add_instr(isel, &out); +} + +static inline scc_mir_operand_t reg_operand(scc_x86_reg_t reg) { + return (scc_mir_operand_t){.kind = SCC_MIR_OP_PREG, .preg = reg}; +} + +// Utils + +void scc_x86_emit_move(scc_x86_64_isel_t *isel, scc_mir_operand_t dst, + scc_mir_operand_t src, u8 size); +scc_mir_operand_t scc_x86_lir_val_to_mir_op(scc_x86_64_isel_t *isel, + const scc_lir_val_t *val); +static inline void emit_call(scc_x86_64_isel_t *isel, const char *callee) { + scc_mir_operand_t sym = {.kind = SCC_MIR_OP_SYMBOL, .symbol = callee}; + add_instr_1(isel, SCC_X86_IFORM_CALL_NEAR_GPRV, sym); +} +static inline void emit_ret(scc_x86_64_isel_t *isel) { + add_instr_0(isel, SCC_X86_IFORM_RET_NEAR); +} + +#endif /* __SCC_X86_64_ISEL_H__ */ diff --git a/libs/ir/mir/include/core_pass/scc_abi_lowering.h b/libs/ir/mir/include/core_pass/scc_abi_lowering.h new file mode 100644 index 0000000..c78d804 --- /dev/null +++ b/libs/ir/mir/include/core_pass/scc_abi_lowering.h @@ -0,0 +1,22 @@ +#ifndef __SCC_ABI_LOWERING_H__ +#define __SCC_ABI_LOWERING_H__ + +#include "../scc_mir_module.h" +#include + +typedef void (*scc_abi_lower_fn)(void *user_data, const scc_lir_instr_t *instr); +typedef scc_mir_operand_t (*scc_abi_lower_param_fn)(void *userdata, + const scc_lir_val_t *val); + +typedef struct scc_abi_lowering { + scc_abi_lower_fn lower_call; + scc_abi_lower_fn lower_ret; + scc_abi_lower_param_fn lower_param; + // TODO va_list + scc_abi_lower_fn lower_va_start; + scc_abi_lower_fn lower_va_arg; + scc_abi_lower_fn lower_va_end; + scc_abi_lower_fn lower_va_copy; +} scc_abi_lowering_t; + +#endif /* __SCC_ABI_LOWERING_H__ */ diff --git a/libs/ir/mir/include/scc_mir.h b/libs/ir/mir/include/scc_mir.h index b2c604e..cccdae7 100644 --- a/libs/ir/mir/include/scc_mir.h +++ b/libs/ir/mir/include/scc_mir.h @@ -3,8 +3,7 @@ #ifndef __SCC_MIR_H__ #define __SCC_MIR_H__ -#include // 复用 VREG 概念和一些基础类型 -// #include "scc_target_desc.h" // 目标架构描述(寄存器文件、指令编码) +#include typedef enum { SCC_MIR_OP_NONE, diff --git a/libs/ir/mir/src/mir_x86.c b/libs/ir/mir/src/arch/x86_64_isel.c similarity index 80% rename from libs/ir/mir/src/mir_x86.c rename to libs/ir/mir/src/arch/x86_64_isel.c index 5b005a0..a911a3b 100644 --- a/libs/ir/mir/src/mir_x86.c +++ b/libs/ir/mir/src/arch/x86_64_isel.c @@ -1,6 +1,4 @@ -#include -#include -#include +#include #include #include @@ -44,35 +42,9 @@ void scc_x86_instr_dump(scc_tree_dump_t *td, const scc_mir_instr_t *instr) { } } -typedef struct x86_isel { - scc_mir_instr_vec_t instrs; - scc_lir_func_meta_t *func_meta; -} x86_isel_t; - -static void add_instr(x86_isel_t *isel, const scc_mir_instr_t *instr) { - scc_vec_push(isel->instrs, *instr); -} - -static inline void add_instr_0(x86_isel_t *isel, scc_x86_iform_t opcode) { - scc_mir_instr_t out = {.opcode = opcode, .num_operands = 0}; - add_instr(isel, &out); -} -static inline void add_instr_1(x86_isel_t *isel, scc_x86_iform_t opcode, - scc_mir_operand_t op1) { - scc_mir_instr_t out = {.opcode = opcode, .num_operands = 1}; - out.operands[0] = op1; - add_instr(isel, &out); -} -static inline void add_instr_2(x86_isel_t *isel, scc_x86_iform_t opcode, - scc_mir_operand_t op1, scc_mir_operand_t op2) { - scc_mir_instr_t out = {.opcode = opcode, .num_operands = 2}; - out.operands[0] = op1; - out.operands[1] = op2; - add_instr(isel, &out); -} - // 将 LIR 值转换为 MIR 操作数 -static scc_mir_operand_t lir_val_to_mir_op(const scc_lir_val_t *val) { +scc_mir_operand_t scc_x86_lir_val_to_mir_op(scc_x86_64_isel_t *isel, + const scc_lir_val_t *val) { scc_mir_operand_t op = {0}; switch (val->kind) { case SCC_LIR_INSTR_KIND_NONE: @@ -96,6 +68,10 @@ static scc_mir_operand_t lir_val_to_mir_op(const scc_lir_val_t *val) { op.kind = SCC_MIR_OP_SYMBOL; op.symbol = val->data.symbol; break; + case SCC_LIR_INSTR_KIND_ARG: + Assert(isel->abi_lowering.lower_param); + op = isel->abi_lowering.lower_param(isel, val); + break; default: UNREACHABLE(); } @@ -103,13 +79,13 @@ static scc_mir_operand_t lir_val_to_mir_op(const scc_lir_val_t *val) { } // 虚拟临时寄存器分配(简单递增) -static scc_mir_operand_t new_vreg_temp(x86_isel_t *isel) { +static scc_mir_operand_t new_vreg_temp(scc_x86_64_isel_t *isel) { return (scc_mir_operand_t){.kind = SCC_MIR_OP_VREG, .vreg = isel->func_meta->vregs_count++}; } -static void emit_move(x86_isel_t *isel, scc_mir_operand_t dst, - scc_mir_operand_t src, u8 size) { +void scc_x86_emit_move(scc_x86_64_isel_t *isel, scc_mir_operand_t dst, + scc_mir_operand_t src, u8 size) { if (dst.kind == SCC_MIR_OP_VREG || dst.kind == SCC_MIR_OP_PREG) { if (src.kind == SCC_MIR_OP_VREG || src.kind == SCC_MIR_OP_PREG) { add_instr_2(isel, SCC_X86_IFORM_MOV_GPRV_GPRV_89, dst, src); @@ -136,8 +112,8 @@ static void emit_move(x86_isel_t *isel, scc_mir_operand_t dst, add_instr_2(isel, SCC_X86_IFORM_MOV_MEMV_GPRV, dst, temp); } else if (src.kind == SCC_MIR_OP_MEM) { scc_mir_operand_t temp = new_vreg_temp(isel); - emit_move(isel, temp, src, size); - emit_move(isel, dst, temp, size); + scc_x86_emit_move(isel, temp, src, size); + scc_x86_emit_move(isel, dst, temp, size); } else { UNREACHABLE(); } @@ -146,7 +122,7 @@ static void emit_move(x86_isel_t *isel, scc_mir_operand_t dst, } } -static void emit_compare(x86_isel_t *isel, scc_mir_operand_t op0, +static void emit_compare(scc_x86_64_isel_t *isel, scc_mir_operand_t op0, scc_mir_operand_t op1, u8 size) { // cmp op0, op1 (注意 x86 是 cmp a, b 即 a - b) if (op0.kind == SCC_MIR_OP_VREG && op1.kind == SCC_MIR_OP_IMM) { @@ -186,25 +162,16 @@ static scc_x86_iform_t cond_to_setcc(scc_lir_cond_t cond) { } } -static void emit_ret(x86_isel_t *isel, scc_lir_val_t ret_val) { - if (ret_val.kind != SCC_LIR_INSTR_KIND_NONE) { - scc_mir_operand_t rax = {.kind = SCC_MIR_OP_PREG, - .preg = SCC_X86_REG_RAX}; - emit_move(isel, rax, lir_val_to_mir_op(&ret_val), 8); - } - add_instr_0(isel, SCC_X86_IFORM_RET_NEAR); -} - -static void emit_copy_if_needed(x86_isel_t *isel, scc_mir_operand_t dst, +static void emit_copy_if_needed(scc_x86_64_isel_t *isel, scc_mir_operand_t dst, scc_mir_operand_t src0, u8 size) { if (dst.kind == SCC_MIR_OP_VREG && src0.kind == SCC_MIR_OP_VREG && dst.vreg == src0.vreg) { return; } - emit_move(isel, dst, src0, size); + scc_x86_emit_move(isel, dst, src0, size); } -static void emit_binary_op(x86_isel_t *isel, scc_lir_op_t op, +static void emit_binary_op(scc_x86_64_isel_t *isel, scc_lir_op_t op, scc_mir_operand_t dst, scc_mir_operand_t src0, scc_mir_operand_t src1, u8 size) { emit_copy_if_needed(isel, dst, src0, size); @@ -242,44 +209,34 @@ static scc_mir_operand_t stack_slot_op(int offset) { return (scc_mir_operand_t){.kind = SCC_MIR_OP_MEM, .stack_slot = offset}; } -static void emit_spill_load(x86_isel_t *isel, int vreg, int offset) { +static void emit_spill_load(scc_x86_64_isel_t *isel, int vreg, int offset) { scc_mir_operand_t dst = {.kind = SCC_MIR_OP_VREG, .vreg = vreg}; add_instr_2(isel, SCC_X86_IFORM_MOV_GPRV_MEMV, dst, stack_slot_op(offset)); } -static void emit_spill_store(x86_isel_t *isel, int vreg, int offset) { +static void emit_spill_store(scc_x86_64_isel_t *isel, int vreg, int offset) { scc_mir_operand_t src = {.kind = SCC_MIR_OP_VREG, .vreg = vreg}; add_instr_2(isel, SCC_X86_IFORM_MOV_MEMV_GPRV, stack_slot_op(offset), src); } -static void emit_call(x86_isel_t *isel, const char *callee, - scc_mir_operand_t ret_reg) { - scc_mir_operand_t sym = {.kind = SCC_MIR_OP_SYMBOL, .symbol = callee}; - add_instr_1(isel, SCC_X86_IFORM_CALL_NEAR_GPRV, sym); - if (ret_reg.kind == SCC_MIR_OP_VREG) { - scc_mir_operand_t rax = {.kind = SCC_MIR_OP_PREG, - .preg = SCC_X86_REG_RAX}; - emit_move(isel, ret_reg, rax, 8); - } -} - -static void emit_alloca(x86_isel_t *isel, scc_mir_operand_t dst, i64 size) { +static void emit_alloca(scc_x86_64_isel_t *isel, scc_mir_operand_t dst, + i64 size) { scc_mir_operand_t imm = {.kind = SCC_MIR_OP_IMM, .imm = size}; scc_mir_operand_t rsp = {.kind = SCC_MIR_OP_PREG, .preg = SCC_X86_REG_RSP}; add_instr_2(isel, SCC_X86_IFORM_SUB_GPRV_IMMZ, rsp, imm); - emit_move(isel, dst, rsp, 8); + scc_x86_emit_move(isel, dst, rsp, 8); } -static void sel_mir(x86_isel_t *isel, const scc_lir_instr_t *instr) { - scc_mir_operand_t dst = lir_val_to_mir_op(&instr->to); - scc_mir_operand_t src0 = lir_val_to_mir_op(&instr->arg0); - scc_mir_operand_t src1 = lir_val_to_mir_op(&instr->arg1); +static void sel_mir(scc_x86_64_isel_t *isel, const scc_lir_instr_t *instr) { + scc_mir_operand_t dst = scc_x86_lir_val_to_mir_op(isel, &instr->to); + scc_mir_operand_t src0 = scc_x86_lir_val_to_mir_op(isel, &instr->arg0); + scc_mir_operand_t src1 = scc_x86_lir_val_to_mir_op(isel, &instr->arg1); u8 size = instr->size; switch (instr->op) { /* ---- 数据移动 ---- */ case SCC_LIR_MOV: - emit_move(isel, dst, src0, size); + scc_x86_emit_move(isel, dst, src0, size); break; case SCC_LIR_LOAD: @@ -326,7 +283,7 @@ static void sel_mir(x86_isel_t *isel, const scc_lir_instr_t *instr) { case SCC_LIR_SHL: case SCC_LIR_SHR: - case SCC_LIR_SAR: + case SCC_LIR_SAR: { // 双地址:dst = dst op count emit_copy_if_needed(isel, dst, src0, size); @@ -350,7 +307,7 @@ static void sel_mir(x86_isel_t *isel, const scc_lir_instr_t *instr) { // 移位量在 CL(需要先 mov cl, src1) scc_mir_operand_t cl = {.kind = SCC_MIR_OP_PREG, .preg = SCC_X86_REG_CL}; - emit_move(isel, cl, src1, 1); // CL 是 8 位 + scc_x86_emit_move(isel, cl, src1, 1); // CL 是 8 位 scc_x86_iform_t iform; switch (instr->op) { case SCC_LIR_SHL: @@ -367,7 +324,7 @@ static void sel_mir(x86_isel_t *isel, const scc_lir_instr_t *instr) { } add_instr_2(isel, iform, dst, cl); } - break; + } break; /* ---- 除法与取模 ---- */ case SCC_LIR_DIV_S: @@ -379,7 +336,7 @@ static void sel_mir(x86_isel_t *isel, const scc_lir_instr_t *instr) { scc_mir_operand_t rdx = {.kind = SCC_MIR_OP_PREG, .preg = SCC_X86_REG_RDX}; - emit_move(isel, rax, src0, size); + scc_x86_emit_move(isel, rax, src0, size); if (instr->op == SCC_LIR_DIV_S || instr->op == SCC_LIR_REM_S) { // 有符号扩展:cqo / cdq(根据 size 选择,这里简化为 64 位 cqo) @@ -387,7 +344,7 @@ static void sel_mir(x86_isel_t *isel, const scc_lir_instr_t *instr) { } else { // 无符号:xor edx, edx scc_mir_operand_t zero = {.kind = SCC_MIR_OP_IMM, .imm = 0}; - emit_move(isel, rdx, zero, size); + scc_x86_emit_move(isel, rdx, zero, size); } scc_x86_iform_t div_if = @@ -398,11 +355,10 @@ static void sel_mir(x86_isel_t *isel, const scc_lir_instr_t *instr) { // 结果:商在 RAX,余数在 RDX if (instr->op == SCC_LIR_REM_S || instr->op == SCC_LIR_REM_U) - emit_move(isel, dst, rdx, size); + scc_x86_emit_move(isel, dst, rdx, size); else - emit_move(isel, dst, rax, size); - break; - } + scc_x86_emit_move(isel, dst, rax, size); + } break; /* ---- 比较指令 ---- */ case SCC_LIR_CMP: { @@ -424,8 +380,7 @@ static void sel_mir(x86_isel_t *isel, const scc_lir_instr_t *instr) { scc_mir_operand_t one = {.kind = SCC_MIR_OP_IMM, .imm = 1}; add_instr_2(isel, SCC_X86_IFORM_AND_GPRV_IMMZ, dst, one); } - break; - } + } break; /* ---- 条件分支 ---- */ case SCC_LIR_BR: { @@ -444,29 +399,20 @@ static void sel_mir(x86_isel_t *isel, const scc_lir_instr_t *instr) { add_instr_1(isel, SCC_X86_IFORM_JNZ_RELBRZ, true_bb); // jmp false add_instr_1(isel, SCC_X86_IFORM_JMP_RELBRZ, false_bb); - break; - } + } break; - case SCC_LIR_JMP: + case SCC_LIR_JMP: { add_instr_1( isel, SCC_X86_IFORM_JMP_RELBRZ, (scc_mir_operand_t){.kind = SCC_MIR_OP_BLOCK, .block_id = instr->metadata.jmp_target}); - break; - - /* ---- 调用与返回 ---- */ - case SCC_LIR_CALL: - emit_call(isel, instr->metadata.call.callee, dst); - break; - case SCC_LIR_RET: - emit_ret(isel, instr->metadata.ret_val); - break; + } break; /* ---- 栈分配 ---- */ case SCC_LIR_ALLOCA: // emit_alloca(isel, dst, instr->metadata.alloca.size_bytes); add_instr_2(isel, (scc_x86_iform_t)SCC_MIR_PSUEDO_ALLOCA, - lir_val_to_mir_op(&instr->to), + scc_x86_lir_val_to_mir_op(isel, &instr->to), (scc_mir_operand_t){ .kind = SCC_MIR_OP_IMM, .imm = instr->size, @@ -477,15 +423,29 @@ static void sel_mir(x86_isel_t *isel, const scc_lir_instr_t *instr) { case SCC_LIR_NOP: break; - default: + /* ---- 调用与返回 ---- */ + case SCC_LIR_CALL: { + Assert(isel->abi_lowering.lower_call); + isel->abi_lowering.lower_call(isel, instr); + } break; + case SCC_LIR_RET: { + Assert(isel->abi_lowering.lower_ret); + isel->abi_lowering.lower_ret(isel, instr); + } break; + default: { UNREACHABLE(); - break; + } break; } } static void sel_func(const scc_lir_module_t *lir_module, const scc_lir_func_t *func) { - x86_isel_t isel; + scc_x86_64_isel_t isel; + + void scc_win_pc_x64_abi_lowering(scc_abi_lowering_t * abi_lowering); + // TODO target got real abi_lowering + isel.abi_lowering = (scc_abi_lowering_t){0}; + scc_win_pc_x64_abi_lowering(&isel.abi_lowering); isel.func_meta = SCC_LIR_FUNC_META(func); scc_vec_foreach(func->bblocks, i) { diff --git a/tests/simple/expect.toml b/tests/simple/expect.toml index 27528f8..bdca9dd 100644 --- a/tests/simple/expect.toml +++ b/tests/simple/expect.toml @@ -2,7 +2,7 @@ # windows powershell: echo $LASTEXITCODE # nushell: echo $env.LAST_EXIT_CODE # bash: echo $? -"./return_val_cases/01_return.c" = 65536 +"./return_val_cases/01_return.c" = 255 "./return_val_cases/02_decl_expr.c" = 1 "./return_val_cases/03_decl_init.c" = 11 "./return_val_cases/04_if.c" = 1 @@ -14,12 +14,12 @@ "./return_val_cases/10_main.c" = 3 "./return_val_cases/11_recursive.c" = 120 "./return_val_cases/12_logic.c" = 10 -"./return_val_cases/13_array.c" = 1198 +"./return_val_cases/13_array.c" = 209 "./return_val_cases/14_pointer.c" = 2 -"./return_val_cases/15_array_subscript.c" = 1198 +"./return_val_cases/15_array_subscript.c" = 209 "./return_val_cases/16_enum.c" = 5 "./return_val_cases/17_more_arg.c" = 45 -"./return_val_cases/18_break_continue.c" = 676 -"./return_val_cases/19_goto.c" = 676 +"./return_val_cases/18_break_continue.c" = 219 +"./return_val_cases/19_goto.c" = 219 [stdout_val_cases] "./stdout_val_cases/01_include.c" = "Hello World!\n" diff --git a/tests/simple/return_val_cases/01_return.c b/tests/simple/return_val_cases/01_return.c index 9fd5dff..591f216 100644 --- a/tests/simple/return_val_cases/01_return.c +++ b/tests/simple/return_val_cases/01_return.c @@ -1,3 +1 @@ -int main() { - return 65536; -} +int main() { return 255; } diff --git a/tests/simple/return_val_cases/13_array.c b/tests/simple/return_val_cases/13_array.c index 4d007b8..2a84156 100644 --- a/tests/simple/return_val_cases/13_array.c +++ b/tests/simple/return_val_cases/13_array.c @@ -1,5 +1,5 @@ int main(void) { - char buff[] = "hello buffer"; + char buff[] = "hi"; int res = 0; for (char *ptr = buff; *ptr != 0; ptr += 1) { res += *ptr; diff --git a/tests/simple/return_val_cases/15_array_subscript.c b/tests/simple/return_val_cases/15_array_subscript.c index 8a1205b..461a203 100644 --- a/tests/simple/return_val_cases/15_array_subscript.c +++ b/tests/simple/return_val_cases/15_array_subscript.c @@ -1,5 +1,5 @@ int main(void) { - char buff[] = "hello buffer"; + char buff[] = "hi"; int res = 0; for (int i = 0; buff[i] != 0; i += 1) { res += buff[i]; diff --git a/tests/simple/return_val_cases/18_break_continue.c b/tests/simple/return_val_cases/18_break_continue.c index c82f901..5066171 100644 --- a/tests/simple/return_val_cases/18_break_continue.c +++ b/tests/simple/return_val_cases/18_break_continue.c @@ -3,7 +3,7 @@ int main(void) { char buff[] = "hello buffer"; int res = 0; for (int i = 0; buff[i] != 0; i += 1) { - if (i < 2) + if (i <= 6) continue; if (i > 8) break; diff --git a/tests/simple/return_val_cases/19_goto.c b/tests/simple/return_val_cases/19_goto.c index d918c24..b50831e 100644 --- a/tests/simple/return_val_cases/19_goto.c +++ b/tests/simple/return_val_cases/19_goto.c @@ -2,7 +2,7 @@ int main(void) { char buff[] = "hello buffer"; int res = 0; for (int i = 0; buff[i] != 0; i += 1) { - if (i < 2) + if (i <= 6) goto the_continue; if (i > 8) goto the_break;