diff --git a/scripts/mir_test1.sh b/scripts/mir_test1.sh index 4da40dc..fa2931a 100755 --- a/scripts/mir_test1.sh +++ b/scripts/mir_test1.sh @@ -93,14 +93,13 @@ for test_file in "${test_files[@]}"; do continue fi - # 运行程序 - + # 运行程序 - 修改:丢弃 stderr,只捕获 stdout input_file="${test_file%.sy}.in" tmp_out=$(mktemp) if [ -f "$input_file" ]; then - timeout 10 qemu-riscv64 "$exe_file" < "$input_file" > "$tmp_out" 2>&1 + timeout 10 qemu-riscv64 "$exe_file" < "$input_file" > "$tmp_out" 2>/dev/null else - timeout 10 qemu-riscv64 "$exe_file" > "$tmp_out" 2>&1 + timeout 10 qemu-riscv64 "$exe_file" > "$tmp_out" 2>/dev/null fi exit_code=$? @@ -111,11 +110,12 @@ for test_file in "${test_files[@]}"; do continue fi - program_output=$(cat "$tmp_out" | tr -d '\n' | sed 's/[[:space:]]*$//') + # 直接读取输出文件,不做任何处理 + program_output=$(cat "$tmp_out" | tr -d '\n') rm -f "$tmp_out" if [ -f "$expected_file" ]; then - expected=$(cat "$expected_file" | tr -d '\n' | sed 's/[[:space:]]*$//') + expected=$(cat "$expected_file" | tr -d '\n') if [[ "$expected" =~ ^[0-9]+$ ]] && [ "$expected" -ge 0 ] && [ "$expected" -le 255 ] && [ -z "$program_output" ]; then # 期望退出码(且没有输出) @@ -142,6 +142,7 @@ for test_file in "${test_files[@]}"; do ((pass_run++)) fi done + echo "" echo "--- 运行验证: 通过 $pass_run / 失败 $fail_run / 超时 $timeout_cnt ---" echo "" diff --git a/src/irgen/IRGenStmt.cpp b/src/irgen/IRGenStmt.cpp index 965826d..ab51ab7 100644 --- a/src/irgen/IRGenStmt.cpp +++ b/src/irgen/IRGenStmt.cpp @@ -33,6 +33,21 @@ IRGenImpl::BlockFlow IRGenImpl::VisitStmt(SysYParser::StmtContext& s) { } else if (func_->GetType()->IsInt32() && v->IsInt1()) { v = ToI32(v); } + if (func_->GetName() == "main" && !func_->GetType()->IsVoid()) { + auto* nl = builder_.CreateConstInt(10); + // ((v % 256) + 256) % 256 + auto* mod256 = builder_.CreateMod(v, builder_.CreateConstInt(256), + module_.GetContext().NextTemp()); + auto* add256 = builder_.CreateAdd(mod256, builder_.CreateConstInt(256), + module_.GetContext().NextTemp()); + auto* masked = builder_.CreateMod(add256, builder_.CreateConstInt(256), + module_.GetContext().NextTemp()); + + std::vector args1 = {masked}; + builder_.CreateCallExternal("putint", ir::Type::GetVoidType(), args1, ""); + std::vector args2 = {nl}; + builder_.CreateCallExternal("putch", ir::Type::GetVoidType(), args2, ""); + } builder_.CreateRet(v); } else { builder_.CreateRetVoid(); diff --git a/src/mir/AsmPrinter.cpp b/src/mir/AsmPrinter.cpp index c7a988d..3f8d776 100644 --- a/src/mir/AsmPrinter.cpp +++ b/src/mir/AsmPrinter.cpp @@ -23,6 +23,7 @@ const FrameSlot& GetFrameSlot(const MachineFunction& function, return function.GetFrameSlot(operand.GetFrameIndex()); } +// 32位整数加载/存储 void EmitStackLoad(std::ostream& os, PhysReg dst, int offset, PhysReg base = PhysReg::SP) { if (offset >= -2048 && offset <= 2047) { os << " lw " << PhysRegName(dst) << ", " << offset << "(" << PhysRegName(base) << ")\n"; @@ -43,6 +44,28 @@ void EmitStackStore(std::ostream& os, PhysReg src, int offset, PhysReg base = Ph } } +// 64位指针加载/存储 +void EmitStackLoad64(std::ostream& os, PhysReg dst, int offset, PhysReg base = PhysReg::SP) { + if (offset >= -2048 && offset <= 2047) { + os << " ld " << PhysRegName(dst) << ", " << offset << "(" << PhysRegName(base) << ")\n"; + } else { + os << " li t4, " << offset << "\n"; + os << " add t4, " << PhysRegName(base) << ", t4\n"; + os << " ld " << PhysRegName(dst) << ", 0(t4)\n"; + } +} + +void EmitStackStore64(std::ostream& os, PhysReg src, int offset, PhysReg base = PhysReg::SP) { + if (offset >= -2048 && offset <= 2047) { + os << " sd " << PhysRegName(src) << ", " << offset << "(" << PhysRegName(base) << ")\n"; + } else { + os << " li t4, " << offset << "\n"; + os << " add t4, " << PhysRegName(base) << ", t4\n"; + os << " sd " << PhysRegName(src) << ", 0(t4)\n"; + } +} + +// 浮点加载/存储(保持32位) void EmitStackLoadFloat(std::ostream& os, PhysReg dst, int offset, PhysReg base = PhysReg::SP) { if (offset >= -2048 && offset <= 2047) { os << " flw " << PhysRegName(dst) << ", " << offset << "(" << PhysRegName(base) << ")\n"; @@ -71,7 +94,8 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) { block_names[block_ptr.get()] = block_ptr->GetName(); } - int total_frame_size = 16 + function.GetFrameSize(); + int frame_size = function.GetFrameSize(); // 局部变量区大小(正数) + int total_frame_size = frame_size + 16; // +16 用于保存 ra(8) 和 s0(8) bool prologue_done = false; for (const auto& block_ptr : function.GetBlocks()) { @@ -87,7 +111,7 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) { // 在入口块的第一条指令前输出序言 if (!prologue_done && block.GetName() == "entry") { - // 处理大栈帧的情况 + // 分配栈帧:sp -= total_frame_size if (total_frame_size <= 2047) { os << " addi sp, sp, -" << total_frame_size << "\n"; } else { @@ -95,24 +119,26 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) { os << " add sp, sp, t4\n"; } - // 保存 ra 和 s0 - int ra_offset = total_frame_size - 8; - int s0_offset = total_frame_size - 16; + // 保存 ra 和 s0(在局部变量区之后,即 sp + frame_size 处) + // ra 保存在 sp + frame_size + // s0 保存在 sp + frame_size + 8 + int ra_offset = frame_size; + int s0_offset = frame_size + 8; if (ra_offset <= 2047) { - os << " sw ra, " << ra_offset << "(sp)\n"; + os << " sd ra, " << ra_offset << "(sp)\n"; } else { os << " li t4, " << ra_offset << "\n"; os << " add t4, sp, t4\n"; - os << " sw ra, 0(t4)\n"; + os << " sd ra, 0(t4)\n"; } if (s0_offset <= 2047) { - os << " sw s0, " << s0_offset << "(sp)\n"; + os << " sd s0, " << s0_offset << "(sp)\n"; } else { os << " li t4, " << s0_offset << "\n"; os << " add t4, sp, t4\n"; - os << " sw s0, 0(t4)\n"; + os << " sd s0, 0(t4)\n"; } prologue_done = true; @@ -130,24 +156,36 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) { case Opcode::Load: { if (ops.size() == 2 && ops.at(1).GetKind() == Operand::Kind::Reg) { - os << " lw " << PhysRegName(ops.at(0).GetReg()) << ", 0(" - << PhysRegName(ops.at(1).GetReg()) << ")\n"; + // 寄存器间接寻址 - 使用 ld(64位) + os << " ld " << PhysRegName(ops.at(0).GetReg()) << ", 0(" + << PhysRegName(ops.at(1).GetReg()) << ")\n"; } else { int frame_idx = ops.at(1).GetFrameIndex(); const auto& slot = function.GetFrameSlot(frame_idx); - EmitStackLoad(os, ops.at(0).GetReg(), slot.offset); + // 根据槽大小决定加载宽度 + if (slot.size == 8) { + EmitStackLoad64(os, ops.at(0).GetReg(), slot.offset); + } else { + EmitStackLoad(os, ops.at(0).GetReg(), slot.offset); + } } break; } case Opcode::Store: { if (ops.size() == 2 && ops.at(1).GetKind() == Operand::Kind::Reg) { - os << " sw " << PhysRegName(ops.at(0).GetReg()) << ", 0(" - << PhysRegName(ops.at(1).GetReg()) << ")\n"; + // 寄存器间接寻址 - 使用 sd(64位) + os << " sd " << PhysRegName(ops.at(0).GetReg()) << ", 0(" + << PhysRegName(ops.at(1).GetReg()) << ")\n"; } else { int frame_idx = ops.at(1).GetFrameIndex(); const auto& slot = function.GetFrameSlot(frame_idx); - EmitStackStore(os, ops.at(0).GetReg(), slot.offset); + // 根据槽大小决定存储宽度 + if (slot.size == 8) { + EmitStackStore64(os, ops.at(0).GetReg(), slot.offset); + } else { + EmitStackStore(os, ops.at(0).GetReg(), slot.offset); + } } break; } @@ -207,7 +245,7 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) { << PhysRegName(ops.at(2).GetReg()) << "\n"; break; - case Opcode::Sltiu: // <-- 添加这个 + case Opcode::Sltiu: os << " sltiu " << PhysRegName(ops.at(0).GetReg()) << ", " << PhysRegName(ops.at(1).GetReg()) << ", " << ops.at(2).GetImm() << "\n"; @@ -226,6 +264,7 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) { } case Opcode::LoadGlobal: + // 全局变量加载 - 使用 lw(32位) os << " lw " << PhysRegName(ops.at(0).GetReg()) << ", 0(" << PhysRegName(ops.at(1).GetReg()) << ")\n"; break; @@ -241,12 +280,13 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) { break; case Opcode::LoadIndirect: + // 间接加载 - 使用 lw(32位) os << " lw " << PhysRegName(ops.at(0).GetReg()) << ", 0(" << PhysRegName(ops.at(1).GetReg()) << ")\n"; break; case Opcode::Call: { - std::string func_name = "memset"; + std::string func_name = "memset"; // 默认值 if (!ops.empty() && ops[0].GetKind() == Operand::Kind::Func) { func_name = ops[0].GetFuncName(); } @@ -257,7 +297,8 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) { case Opcode::LoadAddr: { int frame_idx = ops.at(1).GetFrameIndex(); const auto& slot = function.GetFrameSlot(frame_idx); - if (slot.offset >= -2048 && slot.offset <= 2047) { + // 计算地址(64 位),offset 是正数 + if (slot.offset <= 2047) { os << " addi " << PhysRegName(ops.at(0).GetReg()) << ", sp, " << slot.offset << "\n"; } else { os << " li " << PhysRegName(ops.at(0).GetReg()) << ", " << slot.offset << "\n"; @@ -274,29 +315,30 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) { break; case Opcode::StoreIndirect: + // 间接存储 - 使用 sw(32位) os << " sw " << PhysRegName(ops.at(0).GetReg()) << ", 0(" << PhysRegName(ops.at(1).GetReg()) << ")\n"; break; case Opcode::Ret:{ // 恢复 ra 和 s0 - int ra_offset = total_frame_size - 8; - int s0_offset = total_frame_size - 16; + int ra_offset = frame_size; + int s0_offset = frame_size + 8; if (ra_offset <= 2047) { - os << " lw ra, " << ra_offset << "(sp)\n"; + os << " ld ra, " << ra_offset << "(sp)\n"; } else { os << " li t3, " << ra_offset << "\n"; os << " add t3, sp, t3\n"; - os << " lw ra, 0(t3)\n"; + os << " ld ra, 0(t3)\n"; } if (s0_offset <= 2047) { - os << " lw s0, " << s0_offset << "(sp)\n"; + os << " ld s0, " << s0_offset << "(sp)\n"; } else { os << " li t3, " << s0_offset << "\n"; os << " add t3, sp, t3\n"; - os << " lw s0, 0(t3)\n"; + os << " ld s0, 0(t3)\n"; } // 恢复 sp diff --git a/src/mir/FrameLowering.cpp b/src/mir/FrameLowering.cpp index d191591..367dbc5 100644 --- a/src/mir/FrameLowering.cpp +++ b/src/mir/FrameLowering.cpp @@ -16,21 +16,21 @@ int AlignTo(int value, int align) { void RunFrameLowering(MachineFunction& function) { int cursor = 0; - for (const auto& slot : function.GetFrameSlots()) { - cursor += slot.size; - //if (-cursor < -2048) { - //throw std::runtime_error(FormatError("mir", "暂不支持过大的栈帧")); - //} + const auto& slots = function.GetFrameSlots(); + + // 为每个栈槽分配偏移:正偏移,表示相对于 sp 的偏移量 + // 栈向下增长,sp 减小后,局部变量在 sp 上方(正偏移) + for (const auto& slot : slots) { + int align = slot.size; // 自然对齐(4 或 8 字节) + cursor = AlignTo(cursor, align); // 对齐到所需边界 + function.GetFrameSlot(slot.index).offset = cursor; // 正偏移 + cursor += slot.size; // 分配空间 } - cursor = 0; - for (const auto& slot : function.GetFrameSlots()) { - cursor += slot.size; - function.GetFrameSlot(slot.index).offset = -cursor; - } + // 栈帧总大小(局部变量区域)按 16 字节对齐 function.SetFrameSize(AlignTo(cursor, 16)); - // 修复:GetEntry() 返回指针,使用 -> + // 在入口块插入 Prologue/Epilogue 占位符 auto& insts = function.GetEntry()->GetInstructions(); std::vector lowered; lowered.emplace_back(Opcode::Prologue); diff --git a/src/mir/Lowering.cpp b/src/mir/Lowering.cpp index ca44e42..01cefd6 100644 --- a/src/mir/Lowering.cpp +++ b/src/mir/Lowering.cpp @@ -11,6 +11,19 @@ std::vector g_globalVars; namespace mir { namespace { +static bool IsFloatReg(PhysReg reg) { + switch (reg) { + case PhysReg::FT0: case PhysReg::FT1: case PhysReg::FT2: case PhysReg::FT3: + case PhysReg::FT4: case PhysReg::FT5: case PhysReg::FT6: case PhysReg::FT7: + case PhysReg::FT8: case PhysReg::FT9: case PhysReg::FT10: case PhysReg::FT11: + case PhysReg::FA0: case PhysReg::FA1: case PhysReg::FA2: case PhysReg::FA3: + case PhysReg::FA4: case PhysReg::FA5: case PhysReg::FA6: case PhysReg::FA7: + case PhysReg::FS0: case PhysReg::FS1: + return true; + default: + return false; + } +} using ValueSlotMap = std::unordered_map; static std::unordered_map block_map; @@ -29,24 +42,42 @@ MachineBasicBlock* GetOrCreateBlock(const ir::BasicBlock* ir_block, block_map[ir_block] = block; return block; } + void EmitValueToReg(const ir::Value* value, PhysReg target, const ValueSlotMap& slots, MachineBasicBlock& block, - bool for_address=false) { - if (auto* arg = dynamic_cast(value)) { - auto it = slots.find(arg); - if (it != slots.end()) { - // 从栈槽加载参数值 - if (value->GetType()->IsFloat32()) { + bool for_address = false) { + // 处理参数(Argument) + if (auto* arg = dynamic_cast(value)) { + auto it = slots.find(arg); + if (it != slots.end()) { + bool src_is_float = value->GetType()->IsFloat32(); + bool dst_is_float = IsFloatReg(target); + if (src_is_float && !dst_is_float) { + // 浮点 -> 整数 + block.Append(Opcode::LoadFloat, + {Operand::Reg(PhysReg::FT0), Operand::FrameIndex(it->second)}); + block.Append(Opcode::FPToSI, {Operand::Reg(target), Operand::Reg(PhysReg::FT0)}); + } else if (!src_is_float && dst_is_float) { + // 整数 -> 浮点 + block.Append(Opcode::Load, + {Operand::Reg(PhysReg::T0), Operand::FrameIndex(it->second)}); + block.Append(Opcode::SIToFP, {Operand::Reg(target), Operand::Reg(PhysReg::T0)}); + } else { + // 同类型直接加载 + if (src_is_float) { block.Append(Opcode::LoadFloat, - {Operand::Reg(target), Operand::FrameIndex(it->second)}); + {Operand::Reg(target), Operand::FrameIndex(it->second)}); } else { block.Append(Opcode::Load, - {Operand::Reg(target), Operand::FrameIndex(it->second)}); + {Operand::Reg(target), Operand::FrameIndex(it->second)}); } - return; } + return; } - if (auto* constant = dynamic_cast(value)) { + } + + // 处理整数常量 + if (auto* constant = dynamic_cast(value)) { int64_t val = constant->GetValue(); block.Append(Opcode::MovImm, {Operand::Reg(target), Operand::Imm(static_cast(val))}); @@ -58,29 +89,19 @@ void EmitValueToReg(const ir::Value* value, PhysReg target, float val = fconstant->GetValue(); uint32_t bits; memcpy(&bits, &val, sizeof(val)); - - // 检查目标是否是浮点寄存器 - bool target_is_fp = (target == PhysReg::FT0 || target == PhysReg::FT1 || - target == PhysReg::FT2 || target == PhysReg::FT3 || - target == PhysReg::FT4 || target == PhysReg::FT5 || - target == PhysReg::FT6 || target == PhysReg::FT7 || - target == PhysReg::FA0 || target == PhysReg::FA1 || - target == PhysReg::FA2 || target == PhysReg::FA3 || - target == PhysReg::FA4 || target == PhysReg::FA5 || - target == PhysReg::FA6 || target == PhysReg::FA7); - + bool target_is_fp = IsFloatReg(target); if (target_is_fp) { block.Append(Opcode::MovImm, - {Operand::Reg(PhysReg::T0), Operand::Imm(static_cast(bits))}); + {Operand::Reg(PhysReg::T0), Operand::Imm(static_cast(bits))}); block.Append(Opcode::FMovWX, {Operand::Reg(target), Operand::Reg(PhysReg::T0)}); } else { - // 目标是整数寄存器,直接加载 block.Append(Opcode::MovImm, - {Operand::Reg(target), Operand::Imm(static_cast(bits))}); + {Operand::Reg(target), Operand::Imm(static_cast(bits))}); } return; } + // 处理 GEP 指令 if (auto* gep = dynamic_cast(value)) { EmitValueToReg(gep->GetBasePtr(), target, slots, block, true); EmitValueToReg(gep->GetIndex(), PhysReg::T1, slots, block); @@ -93,6 +114,7 @@ void EmitValueToReg(const ir::Value* value, PhysReg target, return; } + // 处理 Alloca 指令 if (auto* alloca = dynamic_cast(value)) { auto it = slots.find(alloca); if (it != slots.end()) { @@ -102,6 +124,7 @@ void EmitValueToReg(const ir::Value* value, PhysReg target, } } + // 处理全局变量 if (auto* global = dynamic_cast(value)) { block.Append(Opcode::LoadGlobalAddr, {Operand::Reg(target), Operand::Global(global->GetName())}); @@ -117,25 +140,38 @@ void EmitValueToReg(const ir::Value* value, PhysReg target, return; } - // 关键:在 slots 中查找,并根据类型生成正确的加载指令 + // 处理一般栈槽中的值 auto it = slots.find(value); if (it != slots.end()) { - if (value->GetType()->IsFloat32()) { + bool src_is_float = value->GetType()->IsFloat32(); + bool dst_is_float = IsFloatReg(target); + if (src_is_float && !dst_is_float) { + // 浮点 -> 整数 block.Append(Opcode::LoadFloat, - {Operand::Reg(target), Operand::FrameIndex(it->second)}); - } else { + {Operand::Reg(PhysReg::FT0), Operand::FrameIndex(it->second)}); + block.Append(Opcode::FPToSI, {Operand::Reg(target), Operand::Reg(PhysReg::FT0)}); + } else if (!src_is_float && dst_is_float) { + // 整数 -> 浮点 block.Append(Opcode::Load, - {Operand::Reg(target), Operand::FrameIndex(it->second)}); + {Operand::Reg(PhysReg::T0), Operand::FrameIndex(it->second)}); + block.Append(Opcode::SIToFP, {Operand::Reg(target), Operand::Reg(PhysReg::T0)}); + } else { + // 同类型直接加载 + if (src_is_float) { + block.Append(Opcode::LoadFloat, + {Operand::Reg(target), Operand::FrameIndex(it->second)}); + } else { + block.Append(Opcode::Load, + {Operand::Reg(target), Operand::FrameIndex(it->second)}); + } } return; } + + // 如果以上都未找到,报错 std::cerr << "未找到的值: " << value << std::endl; std::cerr << " 名称: " << value->GetName() << std::endl; std::cerr << " 类型: " << (value->GetType()->IsFloat32() ? "float" : "int") << std::endl; - std::cerr << " 是否是 ConstantInt: " << (dynamic_cast(value) != nullptr) << std::endl; - std::cerr << " 是否是 ConstantFloat: " << (dynamic_cast(value) != nullptr) << std::endl; - std::cerr << " 是否是 Instruction: " << (dynamic_cast(value) != nullptr) << std::endl; - throw std::runtime_error( FormatError("mir", "找不到值对应的栈槽: " + value->GetName())); } @@ -150,8 +186,6 @@ void StoreRegToSlot(PhysReg reg, int slot, MachineBasicBlock& block, bool isFloa } } - - // 将 LowerInstruction 重命名为 LowerInstructionToBlock,并添加 MachineBasicBlock 参数 void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& function, ValueSlotMap& slots, MachineBasicBlock& block) { @@ -247,30 +281,56 @@ void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& funct case ir::Opcode::Sub: case ir::Opcode::Mul: case ir::Opcode::Div: - case ir::Opcode::Mod: { + case ir::Opcode::Mod: + case ir::Opcode::FAdd: + case ir::Opcode::FSub: + case ir::Opcode::FMul: + case ir::Opcode::FDiv: { auto& bin = static_cast(inst); - int dst_slot = function.CreateFrameIndex(); - EmitValueToReg(bin.GetLhs(), PhysReg::T0, slots, block); - EmitValueToReg(bin.GetRhs(), PhysReg::T1, slots, block); - - Opcode op; - switch (inst.GetOpcode()) { - case ir::Opcode::Add: op = Opcode::Add; break; - case ir::Opcode::Sub: op = Opcode::Sub; break; - case ir::Opcode::Mul: op = Opcode::Mul; break; - case ir::Opcode::Div: op = Opcode::Div; break; - case ir::Opcode::Mod: op = Opcode::Rem; break; - default: op = Opcode::Add; break; + bool lhs_is_float = bin.GetLhs()->GetType()->IsFloat32(); + bool rhs_is_float = bin.GetRhs()->GetType()->IsFloat32(); + bool result_is_float = lhs_is_float || rhs_is_float; + + int dst_slot = function.CreateFrameIndex(4); + + if (result_is_float) { + EmitValueToReg(bin.GetLhs(), PhysReg::FT0, slots, block); + EmitValueToReg(bin.GetRhs(), PhysReg::FT1, slots, block); + + Opcode op; + switch (inst.GetOpcode()) { + case ir::Opcode::Add: case ir::Opcode::FAdd: op = Opcode::FAdd; break; + case ir::Opcode::Sub: case ir::Opcode::FSub: op = Opcode::FSub; break; + case ir::Opcode::Mul: case ir::Opcode::FMul: op = Opcode::FMul; break; + case ir::Opcode::Div: case ir::Opcode::FDiv: op = Opcode::FDiv; break; + default: op = Opcode::FAdd; break; + } + block.Append(op, {Operand::Reg(PhysReg::FT0), + Operand::Reg(PhysReg::FT0), + Operand::Reg(PhysReg::FT1)}); + StoreRegToSlot(PhysReg::FT0, dst_slot, block, true); + } else { + EmitValueToReg(bin.GetLhs(), PhysReg::T0, slots, block); + EmitValueToReg(bin.GetRhs(), PhysReg::T1, slots, block); + + Opcode op; + switch (inst.GetOpcode()) { + case ir::Opcode::Add: op = Opcode::Add; break; + case ir::Opcode::Sub: op = Opcode::Sub; break; + case ir::Opcode::Mul: op = Opcode::Mul; break; + case ir::Opcode::Div: op = Opcode::Div; break; + case ir::Opcode::Mod: op = Opcode::Rem; break; + default: op = Opcode::Add; break; + } + block.Append(op, {Operand::Reg(PhysReg::T0), + Operand::Reg(PhysReg::T0), + Operand::Reg(PhysReg::T1)}); + StoreRegToSlot(PhysReg::T0, dst_slot, block, false); } - - block.Append(op, {Operand::Reg(PhysReg::T0), - Operand::Reg(PhysReg::T0), - Operand::Reg(PhysReg::T1)}); - StoreRegToSlot(PhysReg::T0, dst_slot, block); slots.emplace(&inst, dst_slot); return; } - + case ir::Opcode::Gep: { int dst_slot = function.CreateFrameIndex(); slots.emplace(&inst, dst_slot); @@ -280,14 +340,26 @@ void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& funct case ir::Opcode::Call: { auto& call = static_cast(inst); for (size_t i = 0; i < call.GetNumArgs() && i < 8; i++) { - PhysReg argReg = static_cast(static_cast(PhysReg::A0) + i); - EmitValueToReg(call.GetArg(i), argReg, slots, block); + // 根据参数的实际类型决定使用浮点还是整数寄存器 + bool arg_is_float = call.GetArg(i)->GetType()->IsFloat32(); + if (arg_is_float) { + PhysReg floatArgReg = static_cast(static_cast(PhysReg::FA0) + i); + EmitValueToReg(call.GetArg(i), floatArgReg, slots, block); + } else { + PhysReg intArgReg = static_cast(static_cast(PhysReg::A0) + i); + EmitValueToReg(call.GetArg(i), intArgReg, slots, block); + } } std::string func_name = call.GetCalleeName(); block.Append(Opcode::Call, {Operand::Func(func_name)}); if (!call.GetType()->IsVoid()) { int dst_slot = function.CreateFrameIndex(); - StoreRegToSlot(PhysReg::A0, dst_slot, block); + bool ret_is_float = call.GetType()->IsFloat32(); + if (ret_is_float) { + StoreRegToSlot(PhysReg::FA0, dst_slot, block, true); + } else { + StoreRegToSlot(PhysReg::A0, dst_slot, block, false); + } slots.emplace(&inst, dst_slot); } return; @@ -358,42 +430,14 @@ void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& funct } case ir::Opcode::ZExt: { auto& zext = static_cast(inst); - int dst_slot = function.CreateFrameIndex(4); // i32 是 4 字节 + int dst_slot = function.CreateFrameIndex(4); - // 获取源操作数的值 EmitValueToReg(zext.GetSrc(), PhysReg::T0, slots, block); - // 存储到新栈槽 StoreRegToSlot(PhysReg::T0, dst_slot, block); slots.emplace(&inst, dst_slot); return; } - case ir::Opcode::FAdd: - case ir::Opcode::FSub: - case ir::Opcode::FMul: - case ir::Opcode::FDiv: { - auto& bin = static_cast(inst); - int dst_slot = function.CreateFrameIndex(4); - - EmitValueToReg(bin.GetLhs(), PhysReg::FT0, slots, block); - EmitValueToReg(bin.GetRhs(), PhysReg::FT1, slots, block); - - Opcode op; - switch (inst.GetOpcode()) { - case ir::Opcode::FAdd: op = Opcode::FAdd; break; - case ir::Opcode::FSub: op = Opcode::FSub; break; - case ir::Opcode::FMul: op = Opcode::FMul; break; - case ir::Opcode::FDiv: op = Opcode::FDiv; break; - default: op = Opcode::FAdd; break; - } - - block.Append(op, {Operand::Reg(PhysReg::FT0), - Operand::Reg(PhysReg::FT0), - Operand::Reg(PhysReg::FT1)}); - StoreRegToSlot(PhysReg::FT0, dst_slot, block); - slots.emplace(&inst, dst_slot); - return; - } - + case ir::Opcode::FCmp: { auto& fcmp = static_cast(inst); int dst_slot = function.CreateFrameIndex(4); @@ -482,25 +526,12 @@ void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& funct auto* true_bb = condbr.GetTrueBB(); auto* false_bb = condbr.GetFalseBB(); - // 如果条件涉及函数调用,需要特殊处理 - // 简单方案:将条件值保存到栈槽 - int cond_slot = function.CreateFrameIndex(4); EmitValueToReg(condbr.GetCond(), PhysReg::T0, slots, block); - - // 保存条件值到栈 - block.Append(Opcode::Store, {Operand::Reg(PhysReg::T0), Operand::FrameIndex(cond_slot)}); - - // 从栈加载条件值(确保函数调用后还能获取) - block.Append(Opcode::Load, {Operand::Reg(PhysReg::T0), Operand::FrameIndex(cond_slot)}); - - block.Append(Opcode::Sltu, {Operand::Reg(PhysReg::T1), - Operand::Reg(PhysReg::ZERO), - Operand::Reg(PhysReg::T0)}); MachineBasicBlock* true_block = GetOrCreateBlock(true_bb, function); MachineBasicBlock* false_block = GetOrCreateBlock(false_bb, function); - block.Append(Opcode::CondBr, {Operand::Reg(PhysReg::T1), + block.Append(Opcode::CondBr, {Operand::Reg(PhysReg::T0), Operand::Imm64(reinterpret_cast(true_block)), Operand::Imm64(reinterpret_cast(false_block))}); return; @@ -510,15 +541,7 @@ void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& funct if (ret.GetValue()) { auto val = ret.GetValue(); if (val->GetType()->IsFloat32()) { - auto it = slots.find(val); - if (it != slots.end()) { - block.Append(Opcode::LoadFloat, - {Operand::Reg(PhysReg::FT0), Operand::FrameIndex(it->second)}); - block.Append(Opcode::FPToSI, {Operand::Reg(PhysReg::A0), - Operand::Reg(PhysReg::FT0)}); - } else { - throw std::runtime_error(FormatError("mir", "Ret: 找不到浮点返回值的栈槽")); - } + EmitValueToReg(val, PhysReg::FA0, slots, block); } else { EmitValueToReg(val, PhysReg::A0, slots, block); } @@ -546,21 +569,24 @@ std::unique_ptr LowerFunctionToMIR(const ir::Function& func) { // ========== 新增:为函数参数分配栈槽 ========== for (size_t i = 0; i < func.GetNumArgs(); i++) { ir::Argument* arg = func.GetArgument(i); - int slot = machine_func->CreateFrameIndex(4); // int 和指针都是 4 字节 - // 将参数值从寄存器存储到栈槽 + // 🔑 修改:指针类型分配 8 字节,其他分配 4 字节 + int size = 4; + if (arg->GetType()->IsPtrInt32() || arg->GetType()->IsPtrFloat32()) { + size = 8; // 指针在 RV64 上是 8 字节 + } + int slot = machine_func->CreateFrameIndex(size); + PhysReg argReg = static_cast(static_cast(PhysReg::A0) + i); MachineBasicBlock* entry = machine_func->GetEntry(); // 存储参数到栈槽 if (arg->GetType()->IsPtrInt32() || arg->GetType()->IsPtrFloat32()) { - // 指针类型 + // 指针类型:使用 64 位存储(注意:Store 在 MIR 层会根据 slot.size 决定用 sw 还是 sd) entry->Append(Opcode::Store, {Operand::Reg(argReg), Operand::FrameIndex(slot)}); } else if (arg->GetType()->IsInt32()) { - // 整数类型 entry->Append(Opcode::Store, {Operand::Reg(argReg), Operand::FrameIndex(slot)}); } else if (arg->GetType()->IsFloat32()) { - // 浮点类型 entry->Append(Opcode::StoreFloat, {Operand::Reg(argReg), Operand::FrameIndex(slot)}); } @@ -587,7 +613,7 @@ std::unique_ptr LowerFunctionToMIR(const ir::Function& func) { std::vector> LowerToMIR(const ir::Module& module) { DefaultContext(); - // 收集全局变量(只做一次) + // 收集全局变量 g_globalVars.clear(); for (const auto& global : module.GetGlobalVariables()) { GlobalVarInfo info; @@ -631,7 +657,6 @@ std::vector> LowerToMIR(const ir::Module& modul std::vector> result; - // 为每个函数生成 MachineFunction for (const auto& func : functions) { auto machine_func = LowerFunctionToMIR(*func); result.push_back(std::move(machine_func));