From 8b4ffdde442e243fd07bfb440c31fcb9ab03db80 Mon Sep 17 00:00:00 2001 From: ftt <> Date: Thu, 9 Apr 2026 22:01:57 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9condbr?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mir/AsmPrinter.cpp | 56 +++++++++++----- src/mir/FrameLowering.cpp | 7 +- src/mir/Lowering.cpp | 136 +++++++++++++++----------------------- 3 files changed, 97 insertions(+), 102 deletions(-) diff --git a/src/mir/AsmPrinter.cpp b/src/mir/AsmPrinter.cpp index 3c6ca93..6d8ca3c 100644 --- a/src/mir/AsmPrinter.cpp +++ b/src/mir/AsmPrinter.cpp @@ -27,8 +27,10 @@ const FrameSlot& GetFrameSlot(const MachineFunction& function, void PrintStackAccess(std::ostream& os, const char* mnemonic, PhysReg reg, int offset) { - os << " " << mnemonic << " " << PhysRegName(reg) << ", [x29, #" << offset - << "]\n"; + //os << " " << mnemonic << " " << PhysRegName(reg) << ", [x29, #" << offset + // << "]\n"; + // 使用 sp 相对寻址 + os << " " << mnemonic << " " << PhysRegName(reg) << ", [sp, #" << offset << "]\n"; } // 打印单个操作数 @@ -59,14 +61,14 @@ void PrintInstruction(std::ostream& os, const MachineInstr& instr, const auto& ops = instr.GetOperands(); switch (instr.GetOpcode()) { - case Opcode::Prologue: - os << " stp x29, x30, [sp, #-16]!\n"; - os << " mov x29, sp\n"; - if (function.GetFrameSize() > 0) { - os << " sub sp, sp, #" << function.GetFrameSize() << "\n"; - } - break; - case Opcode::Epilogue: + case Opcode::Prologue: + os << " stp x29, x30, [sp, #-16]!\n"; + os << " mov x29, sp\n"; + if (function.GetFrameSize() > 0) { + os << " sub sp, sp, #" << function.GetFrameSize() << "\n"; + } + break; + case Opcode::Epilogue: if (function.GetFrameSize() > 0) { os << " add sp, sp, #" << function.GetFrameSize() << "\n"; } @@ -80,14 +82,36 @@ void PrintInstruction(std::ostream& os, const MachineInstr& instr, os << " mov " << PhysRegName(ops.at(0).GetReg()) << ", " << PhysRegName(ops.at(1).GetReg()) << "\n"; break; - case Opcode::LoadStack: { - const auto& slot = GetFrameSlot(function, ops.at(1)); - PrintStackAccess(os, "ldur", ops.at(0).GetReg(), slot.offset); + case Opcode::StoreStack: { + // 检查第二个操作数的类型 + if (ops.size() >= 2 && ops.at(1).GetKind() == Operand::Kind::FrameIndex) { + // 存储到栈槽 + const auto& slot = GetFrameSlot(function, ops.at(1)); + PrintStackAccess(os, "stur", ops.at(0).GetReg(), slot.offset); + } else if (ops.size() >= 2 && ops.at(1).GetKind() == Operand::Kind::Reg) { + // 间接存储:存储到寄存器指向的地址 + // STR W9, [X8] + os << " str " << PhysRegName(ops.at(0).GetReg()) << ", [" + << PhysRegName(ops.at(1).GetReg()) << "]\n"; + } else { + throw std::runtime_error("StoreStack: 无效的操作数类型"); + } break; } - case Opcode::StoreStack: { - const auto& slot = GetFrameSlot(function, ops.at(1)); - PrintStackAccess(os, "stur", ops.at(0).GetReg(), slot.offset); + case Opcode::LoadStack: { + // 检查第二个操作数的类型 + if (ops.size() >= 2 && ops.at(1).GetKind() == Operand::Kind::FrameIndex) { + // 从栈槽加载 + const auto& slot = GetFrameSlot(function, ops.at(1)); + PrintStackAccess(os, "ldur", ops.at(0).GetReg(), slot.offset); + } else if (ops.size() >= 2 && ops.at(1).GetKind() == Operand::Kind::Reg) { + // 间接加载:从寄存器指向的地址加载 + // LDR W9, [X8] + os << " ldr " << PhysRegName(ops.at(0).GetReg()) << ", [" + << PhysRegName(ops.at(1).GetReg()) << "]\n"; + } else { + throw std::runtime_error("LoadStack: 无效的操作数类型"); + } break; } case Opcode::StoreStackPair: diff --git a/src/mir/FrameLowering.cpp b/src/mir/FrameLowering.cpp index 53c256a..b9fa84e 100644 --- a/src/mir/FrameLowering.cpp +++ b/src/mir/FrameLowering.cpp @@ -27,12 +27,14 @@ void RunFrameLowering(MachineFunction& function) { DEBUG_MSG("function RunFrameLowering"); int cursor = 0; for (const auto& slot : function.GetFrameSlots()) { + //cursor += slot.size; + // 使用正偏移,从 sp 开始 + function.GetFrameSlot(slot.index).offset = cursor; cursor += slot.size; if (-cursor < -256) { throw std::runtime_error(FormatError("mir", "暂不支持过大的栈帧")); } } - cursor = 0; for (const auto& slot : function.GetFrameSlots()) { cursor += slot.size; @@ -77,5 +79,4 @@ void RunFrameLowering(MachineModule& module) { } } -} // namespace mir - +} // namespace mir \ No newline at end of file diff --git a/src/mir/Lowering.cpp b/src/mir/Lowering.cpp index 9945c1e..3365385 100644 --- a/src/mir/Lowering.cpp +++ b/src/mir/Lowering.cpp @@ -178,7 +178,7 @@ void EmitValueToReg(const ir::Value* value, PhysReg target, block.Append(Opcode::LoadStack, {Operand::Reg(target), Operand::FrameIndex(it->second)}); return; - } + } // 处理零常量 if (dynamic_cast(value) || dynamic_cast(value)) { @@ -190,13 +190,22 @@ void EmitValueToReg(const ir::Value* value, PhysReg target, auto it = slots.find(value); if (it == slots.end()) { - DEBUG_MSG("Value not found: " << value->GetName()); + // 使用值的地址作为调试信息 + std::string valueName = value->GetName(); + if (valueName.empty()) { + valueName = "(anonymous at " + std::to_string(reinterpret_cast(value)) + ")"; + } + DEBUG_MSG("Value not found: " << valueName); // 输出所有 slots 的键名用于调试 for (auto& p : slots) { - DEBUG_MSG(" Slot key: " << p.first->GetName()); + std::string slotName = p.first->GetName(); + if (slotName.empty()) { + slotName = "(anonymous at " + std::to_string(reinterpret_cast(p.first)) + ")"; + } + DEBUG_MSG(" Slot key: " << slotName); } throw std::runtime_error( - FormatError("mir", "找不到值对应的栈槽: " + value->GetName())); + FormatError("mir", "找不到值对应的栈槽: " + valueName)); } block.Append(Opcode::LoadStack, @@ -222,9 +231,6 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function, if (dst == slots.end()) { //throw std::runtime_error( // FormatError("mir", "暂不支持对非栈变量地址进行写入")); - // 对于非栈变量地址(如 GEP 结果),地址本身在栈槽中 - // 需要先加载地址,然后存储值到该地址 - // 先加载地址到 x8 EmitValueToReg(store.GetPtr(), PhysReg::X8, slots, block, function); // 加载值到 w9 EmitValueToReg(store.GetValue(), PhysReg::W9, slots, block, function); @@ -430,52 +436,40 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function, } // ========== 跳转指令(使用标签操作数)========== case ir::Opcode::Br: { - DEBUG_MSG("Processing Br"); - auto& br = static_cast(inst); - - auto* cond = br.GetCondition(); - DEBUG_MSG("Condition value ptr: " << cond); - DEBUG_MSG("Condition name: " << cond->GetName()); - auto it = slots.find(cond); - if (it == slots.end()) { - DEBUG_MSG("Condition not found in slots!"); - // 输出所有 slots 的键名 - for (auto& p : slots) { - DEBUG_MSG(" Slot key: " << p.first->GetName()); - } - } - - if (br.IsConditional()) { - // 条件跳转: br i1 %cond, label %then, label %else - // 加载条件值到 w8 + DEBUG_MSG("Processing Br"); + auto& br = static_cast(inst); + + if (br.IsConditional()) { + // 条件跳转 + EmitValueToReg(br.GetCondition(), PhysReg::W8, slots, block, function); + block.Append(Opcode::CmpRI, {Operand::Reg(PhysReg::W8), Operand::Imm(0)}); + + std::string trueLabel = GetBlockLabel(br.GetTrueTarget()); + std::string falseLabel = GetBlockLabel(br.GetFalseTarget()); + + block.Append(Opcode::BCond, {Operand::Cond(CondCode::NE), Operand::Label(trueLabel)}); + block.Append(Opcode::B, {Operand::Label(falseLabel)}); + } else { + // 无条件跳转 + std::string targetLabel = GetBlockLabel(br.GetTarget()); + block.Append(Opcode::B, {Operand::Label(targetLabel)}); + } + return; + } + case ir::Opcode::CondBr: { + DEBUG_MSG("Processing CondBr"); + auto& br = static_cast(inst); + + // 条件跳转处理 EmitValueToReg(br.GetCondition(), PhysReg::W8, slots, block, function); - - // 比较条件值是否为 0 block.Append(Opcode::CmpRI, {Operand::Reg(PhysReg::W8), Operand::Imm(0)}); - // 获取目标基本块的标签名 - const ir::BasicBlock* irTrueTarget = br.GetTrueTarget(); - const ir::BasicBlock* irFalseTarget = br.GetFalseTarget(); - - std::string trueLabel = GetBlockLabel(irTrueTarget); - std::string falseLabel = GetBlockLabel(irFalseTarget); + std::string trueLabel = GetBlockLabel(br.GetTrueTarget()); + std::string falseLabel = GetBlockLabel(br.GetFalseTarget()); - // 生成 B.NE true_label block.Append(Opcode::BCond, {Operand::Cond(CondCode::NE), Operand::Label(trueLabel)}); - // 生成 B false_label block.Append(Opcode::B, {Operand::Label(falseLabel)}); - DEBUG_MSG("Generating conditional branch: cond=" << br.GetCondition()->GetName() - << ", true=" << trueLabel << ", false=" << falseLabel); - } else { - // 无条件跳转: br label %target - const ir::BasicBlock* irTarget = br.GetTarget(); - std::string targetLabel = GetBlockLabel(irTarget); - DEBUG_MSG("b: targetLabel is " << GetBlockLabel(irTarget)); - - // 生成 B target_label - block.Append(Opcode::B, {Operand::Label(targetLabel)}); - } - return; + return; } // ========== 函数调用 ========== case ir::Opcode::Call: { @@ -512,8 +506,8 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function, } // 生成调用指令 - block.Append(Opcode::Call, {Operand::Imm(0)}); // 实际需要传递函数名 - + //block.Append(Opcode::Call, {Operand::Imm(0)}); // 实际需要传递函数名 + block.Append(Opcode::Call, {Operand::Label(calleeName)}); // 保存返回值 if (dst_slot != -1) { if (inst.GetType()->IsFloat()) { @@ -820,37 +814,6 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function, slots.emplace(&inst, dst_slot); return; } - // 处理 CondBr 指令 - case ir::Opcode::CondBr: { - // CondBr 通常有两个目标基本块和一个条件 - const ir::Value* condition = nullptr; - const ir::BasicBlock* trueTarget = nullptr; - const ir::BasicBlock* falseTarget = nullptr; - - if (inst.GetNumOperands() >= 3) { - condition = inst.GetOperand(0); - // 操作数1和2应该是 BasicBlock 引用 - // 具体获取方式取决于你的 IR 实现 - if (auto* bb = dynamic_cast(inst.GetOperand(1))) { - trueTarget = bb; - } - if (auto* bb = dynamic_cast(inst.GetOperand(2))) { - falseTarget = bb; - } - } - - if (condition && trueTarget && falseTarget) { - EmitValueToReg(condition, PhysReg::W8, slots, block, function); - block.Append(Opcode::CmpRI, {Operand::Reg(PhysReg::W8), Operand::Imm(0)}); - - std::string trueLabel = GetBlockLabel(trueTarget); - std::string falseLabel = GetBlockLabel(falseTarget); - - block.Append(Opcode::BCond, {Operand::Cond(CondCode::NE), Operand::Label(trueLabel)}); - block.Append(Opcode::B, {Operand::Label(falseLabel)}); - } - return; - } // 处理 FPExt(浮点扩展) case ir::Opcode::FPExt: { int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); @@ -887,9 +850,14 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function, slots.emplace(&inst, dst_slot); return; } + default: + DEBUG_MSG("Unhandled opcode: " << static_cast(inst.GetOpcode()) + << " for instruction: " << inst.GetName()); + throw std::runtime_error(FormatError("mir", "暂不支持该 IR 指令,opcode: " + + std::to_string(static_cast(inst.GetOpcode())))); //throw std::runtime_error(FormatError("mir", "暂不支持该 IR 指令")); - throw std::runtime_error(FormatError("mir", "暂不支持该 IR 指令,opcode: " - + std::to_string(static_cast(inst.GetOpcode())))); + //throw std::runtime_error(FormatError("mir", "暂不支持该 IR 指令,opcode: " + // + std::to_string(static_cast(inst.GetOpcode())))); } } @@ -975,11 +943,13 @@ std::unique_ptr LowerToMIR(const ir::Module& module) { auto machine_module = std::make_unique(); + std::vector globals; // 处理全局变量 for (const auto& global : module.GetGlobals()) { // 为全局变量在数据段分配空间 // 这里需要扩展 MachineModule 来支持全局变量 DEBUG_MSG("Global variable: " << global->GetName()); + globals.push_back(global.get()); } // 遍历模块中的所有函数 @@ -1000,4 +970,4 @@ std::unique_ptr LowerToMIR(const ir::Module& module) { return machine_module; } -} // namespace mir +} // namespace mir \ No newline at end of file