From cc41bb60aef1a6d8d36ec4bfe6aee53ce374147c Mon Sep 17 00:00:00 2001 From: mxr <> Date: Mon, 18 May 2026 23:44:09 +0800 Subject: [PATCH] =?UTF-8?q?feat(mir)=E4=BF=AE=E6=94=B9=E6=B5=AE=E7=82=B9?= =?UTF-8?q?=E6=95=B0=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/verify_asm.sh | 2 +- src/mir/Lowering.cpp | 124 +++++++++++++++++++++++++++++++----------- 2 files changed, 93 insertions(+), 33 deletions(-) diff --git a/scripts/verify_asm.sh b/scripts/verify_asm.sh index f513c6b..c96cb65 100755 --- a/scripts/verify_asm.sh +++ b/scripts/verify_asm.sh @@ -84,7 +84,7 @@ if [[ "$run_exec" == true ]]; then } > "$actual_file" if [[ -f "$expected_file" ]]; then - if diff -u "$expected_file" "$actual_file"; then + if diff -w -u "$expected_file" "$actual_file"; then echo "输出匹配: $expected_file" else echo "输出不匹配: $expected_file" >&2 diff --git a/src/mir/Lowering.cpp b/src/mir/Lowering.cpp index ab5ddd8..c0d6f93 100644 --- a/src/mir/Lowering.cpp +++ b/src/mir/Lowering.cpp @@ -145,6 +145,34 @@ void EmitValueToReg(const ir::Value* value, PhysReg target, if (auto* constant = dynamic_cast(value)) { uint32_t imm = static_cast(constant->GetValue()); + + // 如果目标是浮点寄存器,将 imm 位模式解释为 float 并加载 + if (target >= PhysReg::S0 && target <= PhysReg::S7) { + auto it = slots.find(value); + int slot; + if (it == slots.end()) { + slot = function.CreateFrameIndex(4); + // 将 imm 写入栈槽(与 ConstantFloat 相同方式) + if (isLegalMovImm(imm)) { + block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(static_cast(imm))}); + } else { + uint16_t low = imm & 0xFFFF; + uint16_t high = (imm >> 16) & 0xFFFF; + block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(low)}); + if (high != 0) { + block.Append(Opcode::Movk, {Operand::Reg(PhysReg::W8), Operand::Imm(high), Operand::Imm(16)}); + } + } + block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(slot)}); + const_cast(slots).emplace(value, slot); + } else { + slot = it->second; + } + // 从栈槽加载到浮点目标寄存器 + block.Append(Opcode::LoadStack, {Operand::Reg(target), Operand::FrameIndex(slot)}); + return; + } + if (isLegalMovImm(imm)) { block.Append(Opcode::MovImm, {Operand::Reg(target), Operand::Imm(static_cast(imm))}); @@ -181,16 +209,16 @@ void EmitValueToReg(const ir::Value* value, PhysReg target, // 同样需要对 int_val 进行大立即数分解 if (isLegalMovImm(int_val)) { - block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W17), Operand::Imm(static_cast(int_val))}); + block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(static_cast(int_val))}); } else { uint16_t low = int_val & 0xFFFF; uint16_t high = (int_val >> 16) & 0xFFFF; - block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W17), Operand::Imm(low)}); + block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(low)}); if (high != 0) { - block.Append(Opcode::Movk, {Operand::Reg(PhysReg::W17), Operand::Imm(high), Operand::Imm(16)}); + block.Append(Opcode::Movk, {Operand::Reg(PhysReg::W8), Operand::Imm(high), Operand::Imm(16)}); } } - block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W17), Operand::FrameIndex(slot)}); + block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(slot)}); const_cast(slots).emplace(value, slot); } else { slot = it->second; @@ -204,10 +232,26 @@ void EmitValueToReg(const ir::Value* value, PhysReg target, // 处理零常量 if (dynamic_cast(value) || dynamic_cast(value)) { - // 零常量:直接加载 0 - block.Append(Opcode::MovImm, - {Operand::Reg(target), Operand::Imm(0)}); - return; + // 如果目标是浮点寄存器,必须通过栈槽加载 0.0f 的位模式 + if (target >= PhysReg::S0 && target <= PhysReg::S7) { + auto it = slots.find(value); + int slot; + if (it == slots.end()) { + slot = function.CreateFrameIndex(4); + // 写入 0 + block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(0)}); + block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(slot)}); + const_cast(slots).emplace(value, slot); + } else { + slot = it->second; + } + // 加载到浮点寄存器 + block.Append(Opcode::LoadStack, {Operand::Reg(target), Operand::FrameIndex(slot)}); + return; + } + // 原有的整数/指针零常量处理保持不变 + block.Append(Opcode::MovImm, {Operand::Reg(target), Operand::Imm(0)}); + return; } // ========== 处理全局变量 ========== @@ -415,6 +459,16 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function, case ir::Opcode::Sub: { auto& bin = static_cast(inst); + // 如果两个操作数都是浮点类型,则使用浮点减法 + if (bin.GetLhs()->GetType()->IsFloat() && bin.GetRhs()->GetType()->IsFloat()) { + int dst_slot = function.CreateFrameIndex(4); + EmitValueToReg(bin.GetLhs(), PhysReg::S0, slots, block, function); + EmitValueToReg(bin.GetRhs(), PhysReg::S1, slots, block, function); + block.Append(Opcode::FSubRR, {Operand::Reg(PhysReg::S0), Operand::Reg(PhysReg::S0), Operand::Reg(PhysReg::S1)}); + block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::S0), Operand::FrameIndex(dst_slot)}); + slots.emplace(&inst, dst_slot); + return; + } const ir::Type* lhsTy = bin.GetLhs()->GetType().get(); const ir::Type* rhsTy = bin.GetRhs()->GetType().get(); const ir::Type* resultTy = inst.GetType().get(); @@ -694,37 +748,43 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function, } // ========== 浮点比较指令 ========== case ir::Opcode::FCmp: { - auto& fcmp = static_cast(inst); - int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); + auto& fcmp = static_cast(inst); + int dst_slot = function.CreateFrameIndex(4); // 结果是 i1(4字节) - // 加载浮点操作数到 s0, s1 - EmitValueToReg(fcmp.GetLhs(), PhysReg::S0, slots, block, function); - EmitValueToReg(fcmp.GetRhs(), PhysReg::S1, slots, block, function); + // 1. 加载浮点操作数并比较 + EmitValueToReg(fcmp.GetLhs(), PhysReg::S0, slots, block, function); + EmitValueToReg(fcmp.GetRhs(), PhysReg::S1, slots, block, function); + block.Append(Opcode::FCmpRR, {Operand::Reg(PhysReg::S0), Operand::Reg(PhysReg::S1)}); - // 生成浮点比较指令 - block.Append(Opcode::FCmpRR, {Operand::Reg(PhysReg::S0), Operand::Reg(PhysReg::S1)}); + // 2. 获取有序/无序标志和条件码 + bool isOrdered; + CondCode cc = FcmpToCondCode(fcmp.GetPredicate(), isOrdered); - // 获取条件码(假设仅处理有序比较,无 NaN) - bool isOrdered; - CondCode cc = FcmpToCondCode(fcmp.GetPredicate(), isOrdered); - // 对于无序比较,当前测试用例未涉及,可暂不支持或报错 + // 3. 结果预设为 0 + block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(0)}); - // 使用 CSET 模式 - block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(1)}); - block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W9), Operand::Imm(0)}); + // 4. 生成标签 + std::string set1_label = ".L_fcset_true_" + std::to_string(reinterpret_cast(&fcmp)); + std::string end_label = ".L_fcset_end_" + std::to_string(reinterpret_cast(&fcmp)); - std::string true_label = ".L_fcset_true_" + std::to_string(reinterpret_cast(&fcmp)); - std::string end_label = ".L_fcset_end_" + std::to_string(reinterpret_cast(&fcmp)); + // 5. 处理 NaN 情况 + block.Append(Opcode::BCond, {Operand::Cond(CondCode::VS), Operand::Label(end_label)}); - block.Append(Opcode::BCond, {Operand::Cond(cc), Operand::Label(true_label)}); - block.Append(Opcode::MovReg, {Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::W9)}); - block.Append(Opcode::B, {Operand::Label(end_label)}); - block.Append(Opcode::Label, {Operand::Label(true_label)}); - block.Append(Opcode::Label, {Operand::Label(end_label)}); + // 6. 正常条件跳转 + block.Append(Opcode::BCond, {Operand::Cond(cc), Operand::Label(set1_label)}); - block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)}); - slots.emplace(&inst, dst_slot); - return; + // 7. 无条件到结束 + block.Append(Opcode::B, {Operand::Label(end_label)}); + + // 8. 置 1 标签 + block.Append(Opcode::Label, {Operand::Label(set1_label)}); + block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(1)}); + + // 9. 结束标签并存储结果 + block.Append(Opcode::Label, {Operand::Label(end_label)}); + block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)}); + slots.emplace(&inst, dst_slot); + return; } // ========== 跳转指令(使用标签操作数)========== case ir::Opcode::Br: {