#include "mir/MIR.h" #include #include #include #include "ir/IR.h" #include "utils/Log.h" //#define DEBUG_Lower #ifdef DEBUG_Lower #include #define DEBUG_MSG(msg) std::cerr << "[Lower Debug] " << msg << std::endl #else #define DEBUG_MSG(msg) ((void)0) #endif namespace mir { namespace { using ValueSlotMap = std::unordered_map; static uint32_t FloatToBits(float f) { uint32_t bits; memcpy(&bits, &f, sizeof(bits)); return bits; } // 获取类型大小(字节) int GetTypeSize(const ir::Type* type) { if (!type) return 4; size_t size = type->Size(); return size > 0 ? static_cast(size) : 4; } // 将 IR 整数比较谓词转换为 ARMv8 条件码 CondCode IcmpToCondCode(ir::IcmpInst::Predicate pred) { switch (pred) { case ir::IcmpInst::Predicate::EQ: return CondCode::EQ; case ir::IcmpInst::Predicate::NE: return CondCode::NE; case ir::IcmpInst::Predicate::LT: return CondCode::LT; case ir::IcmpInst::Predicate::GT: return CondCode::GT; case ir::IcmpInst::Predicate::LE: return CondCode::LE; case ir::IcmpInst::Predicate::GE: return CondCode::GE; default: return CondCode::AL; } } // 将 IR 浮点比较谓词转换为 ARMv8 条件码 CondCode FcmpToCondCode(ir::FcmpInst::Predicate pred, bool& isOrdered) { isOrdered = true; switch (pred) { case ir::FcmpInst::Predicate::OEQ: return CondCode::EQ; case ir::FcmpInst::Predicate::ONE: return CondCode::NE; case ir::FcmpInst::Predicate::OLT: return CondCode::LT; case ir::FcmpInst::Predicate::OGT: return CondCode::GT; case ir::FcmpInst::Predicate::OLE: return CondCode::LE; case ir::FcmpInst::Predicate::OGE: return CondCode::GE; case ir::FcmpInst::Predicate::UEQ: isOrdered = false; return CondCode::EQ; case ir::FcmpInst::Predicate::UNE: isOrdered = false; return CondCode::NE; case ir::FcmpInst::Predicate::ULT: isOrdered = false; return CondCode::LT; case ir::FcmpInst::Predicate::UGT: isOrdered = false; return CondCode::GT; case ir::FcmpInst::Predicate::ULE: isOrdered = false; return CondCode::LE; case ir::FcmpInst::Predicate::UGE: isOrdered = false; return CondCode::GE; default: return CondCode::AL; } } // 获取基本块的标签名(用于汇编输出) std::string GetBlockLabel(const ir::BasicBlock* bb) { if (!bb || !bb->GetParent()) { return ".Lunknown"; } // 格式:.L函数名_基本块名 std::string funcName = bb->GetParent()->GetName(); std::string blockName = bb->GetName(); // 如果基本块没有名字,使用地址作为标识 if (blockName.empty()) { blockName = std::to_string(reinterpret_cast(bb)); } return ".L" + funcName + "_" + blockName; } // 获取数组类型的维度信息 static const ir::ArrayType* GetArrayType(const ir::Type* type) { if (type->IsArray()) { return static_cast(type); } return nullptr; } static std::vector GetArrayStrides(const ir::ArrayType* arrayType) { std::vector strides; const std::vector& dims = arrayType->GetDimensions(); int stride = 4; // 元素大小(int/float 是 4 字节) // 从最后一维向前计算步长 for (int i = dims.size() - 1; i >= 0; --i) { strides.insert(strides.begin(), stride); stride *= dims[i]; } return strides; } // 在 Lowering.cpp 中添加辅助函数 const ir::Value* GetOperand(const ir::Instruction& inst, size_t index) { if (index < inst.GetNumOperands()) { return inst.GetOperand(index); } return nullptr; } const ir::BasicBlock* GetBasicBlockOperand(const ir::Instruction& inst, size_t index) { const ir::Value* operand = GetOperand(inst, index); if (operand) { return dynamic_cast(operand); } return nullptr; } void EmitValueToReg(const ir::Value* value, PhysReg target, const ValueSlotMap& slots, MachineBasicBlock& block, MachineFunction& function) { // 处理整数常量 if (value == nullptr) { DEBUG_MSG( "EmitValueToReg called with null value\n"); } // 辅助函数:判断32位立即数是否可用单条 movz/movn 编码 auto isLegalMovImm = [](uint32_t imm) -> bool { // 检查是否可以通过 movz 或 movn 表示(16位立即数,可左移0/16/32/48位) // 对于32位寄存器,只考虑 lsl 0 或 16 if ((imm & 0xFFFF) == imm) return true; // 低16位,lsl #0 if ((imm & 0xFFFF0000) == imm) return true; // 高16位,lsl #16 // 可选:检查 movn 情况(~imm 满足上述条件),为了简单可不做,直接返回 false return false; }; if (auto* constant = dynamic_cast(value)) { uint32_t imm = static_cast(constant->GetValue()); if (isLegalMovImm(imm)) { block.Append(Opcode::MovImm, {Operand::Reg(target), Operand::Imm(static_cast(imm))}); } else { // 分解为 movz (低16位) + movk (高16位) uint16_t low = imm & 0xFFFF; uint16_t high = (imm >> 16) & 0xFFFF; block.Append(Opcode::MovImm, {Operand::Reg(target), Operand::Imm(low)}); // 先加载低16位 if (high != 0) { // 使用 Movk 指令写入高16位 block.Append(Opcode::Movk, {Operand::Reg(target), Operand::Imm(high), Operand::Imm(16)}); } } return; } // 处理浮点常量 if (auto* fconstant = dynamic_cast(value)) { // 检查是否已经为这个常量分配了栈槽 auto it = slots.find(value); int slot; if (it == slots.end()) { DEBUG_MSG("Value not found: " << value->GetName()); // 输出所有 slots 的键名用于调试 for (auto& p : slots) { DEBUG_MSG(" Slot key: " << p.first->GetName()); } // 分配新的栈槽 slot = function.CreateFrameIndex(4); // 将浮点常量存储到栈槽 float fval = fconstant->GetValue(); uint32_t int_val = FloatToBits(fval); // 同样需要对 int_val 进行大立即数分解 if (isLegalMovImm(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::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 (dynamic_cast(value) || dynamic_cast(value)) { // 零常量:直接加载 0 block.Append(Opcode::MovImm, {Operand::Reg(target), Operand::Imm(0)}); return; } // ========== 处理全局变量 ========== if (auto* global = dynamic_cast(value)) { // 如果目标是 32 位寄存器,升级为对应的 64 位寄存器 PhysReg addrTarget = target; if (target >= PhysReg::W0 && target <= PhysReg::W30) { // 映射 Wn → Xn addrTarget = static_cast( static_cast(target) - static_cast(PhysReg::W0) + static_cast(PhysReg::X0)); } // 现在 addrTarget 一定是 64 位寄存器 block.Append(Opcode::Adrp, {Operand::Reg(addrTarget), Operand::Label(global->GetName())}); block.Append(Opcode::AddLabel, {Operand::Reg(addrTarget), Operand::Reg(addrTarget), Operand::Label(global->GetName())}); return; } // ========== 处理从栈槽加载的值 ========== auto it = slots.find(value); if (it == slots.end()) { // 使用值的地址作为调试信息 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) { 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", "找不到值对应的栈槽: " + valueName)); } PhysReg actualTarget = target; const ir::Type* ty = value->GetType().get(); bool isPointer = ty->IsPtrInt32() || ty->IsPtrFloat() || ty->IsPtrInt1() || ty->IsArray(); // 数组类型在地址上下文中视为指针 // 若非指针类型且目标是 64 位寄存器,降级为对应的 32 位寄存器(自动零扩展) if (!isPointer && target >= PhysReg::X0 && target <= PhysReg::X30) { actualTarget = static_cast( static_cast(target) - static_cast(PhysReg::X0) + static_cast(PhysReg::W0)); } block.Append(Opcode::LoadStack, {Operand::Reg(actualTarget), Operand::FrameIndex(it->second)}); } void LowerInstruction(const ir::Instruction& inst, MachineFunction& function, ValueSlotMap& slots, MachineBasicBlock& block, std::unordered_map& blockMap) { //auto& block = function.GetEntry(); DEBUG_MSG("Processing instruction: " << inst.GetName() << " (opcode: " << static_cast(inst.GetOpcode()) << ")"); switch (inst.GetOpcode()) { case ir::Opcode::Alloca: { // alloca 返回一个指针,我们需要为该指针分配一个栈槽(存放地址值) int ptrSlot = function.CreateFrameIndex(8); // 指针占8字节 // 为数组数据分配实际栈空间 int arraySlot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 将数组基地址(sp + arraySlot_offset)加载到 x8 block.Append(Opcode::LoadStackAddr, {Operand::Reg(PhysReg::X8), Operand::FrameIndex(arraySlot)}); // 将地址存储到指针槽 block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::X8), Operand::FrameIndex(ptrSlot)}); // 将 alloca 指令映射到指针槽,后续使用 alloca 值即获得地址 slots.emplace(&inst, ptrSlot); return; } case ir::Opcode::Store: { auto& store = static_cast(inst); const ir::Value* ptr = store.GetPtr(); const ir::Value* val = store.GetValue(); // 处理全局变量作为存储目标 if (auto* global = dynamic_cast(ptr)) { // 生成全局变量地址到 x8 block.Append(Opcode::Adrp, {Operand::Reg(PhysReg::X8), Operand::Label(global->GetName())}); block.Append(Opcode::AddLabel, {Operand::Reg(PhysReg::X8), Operand::Reg(PhysReg::X8), Operand::Label(global->GetName())}); // 加载要存储的值到 w9 EmitValueToReg(val, PhysReg::W9, slots, block, function); // 间接存储:str w9, [x8] block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W9), Operand::Reg(PhysReg::X8)}); return; } auto dstIt = slots.find(ptr); if (dstIt == slots.end()) { // 指针不在 slots 中(例如直接来自函数参数的指针) // 计算指针地址到 x8 EmitValueToReg(ptr, PhysReg::X8, slots, block, function); // 加载要存储的值到 w9 EmitValueToReg(val, PhysReg::W9, slots, block, function); // 使用 StoreStack 的寄存器间接形式(str w9, [x8]) block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W9), Operand::Reg(PhysReg::X8)}); } else { // 指针在 slots 中(alloca 或 gep 的结果),从指针槽加载地址到 x8 block.Append(Opcode::LoadStack, {Operand::Reg(PhysReg::X8), Operand::FrameIndex(dstIt->second)}); // 加载要存储的值到 w9 EmitValueToReg(val, PhysReg::W9, slots, block, function); // 间接存储 block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W9), Operand::Reg(PhysReg::X8)}); } return; } case ir::Opcode::Load: { auto& load = static_cast(inst); const ir::Value* ptr = load.GetPtr(); int dstSlot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 处理全局变量作为加载源 if (auto* global = dynamic_cast(ptr)) { // 生成全局变量地址到 x8 block.Append(Opcode::Adrp, {Operand::Reg(PhysReg::X8), Operand::Label(global->GetName())}); block.Append(Opcode::AddLabel, {Operand::Reg(PhysReg::X8), Operand::Reg(PhysReg::X8), Operand::Label(global->GetName())}); // 间接加载到 w9 block.Append(Opcode::LoadStack, {Operand::Reg(PhysReg::W9), Operand::Reg(PhysReg::X8)}); // 存储结果到栈槽 block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W9), Operand::FrameIndex(dstSlot)}); slots.emplace(&inst, dstSlot); return; } auto srcIt = slots.find(ptr); if (srcIt == slots.end()) { // 指针不在 slots 中,计算地址到 x8 EmitValueToReg(ptr, PhysReg::X8, slots, block, function); // 间接加载到 w9 block.Append(Opcode::LoadStack, {Operand::Reg(PhysReg::W9), Operand::Reg(PhysReg::X8)}); } else { // 从指针槽加载地址到 x8 block.Append(Opcode::LoadStack, {Operand::Reg(PhysReg::X8), Operand::FrameIndex(srcIt->second)}); // 间接加载到 w9 block.Append(Opcode::LoadStack, {Operand::Reg(PhysReg::W9), Operand::Reg(PhysReg::X8)}); } // 将加载的值存入结果槽 block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W9), Operand::FrameIndex(dstSlot)}); slots.emplace(&inst, dstSlot); return; } case ir::Opcode::Add: { auto& bin = static_cast(inst); const ir::Type* lhsTy = bin.GetLhs()->GetType().get(); const ir::Type* rhsTy = bin.GetRhs()->GetType().get(); // 指针判断:指令结果类型是指针,或者任一操作数是指针(指针算术) bool isPointer = (lhsTy->IsPtrInt32() || lhsTy->IsPtrFloat() || lhsTy->IsPtrInt1() || lhsTy->IsArray()) || (rhsTy->IsPtrInt32() || rhsTy->IsPtrFloat() || rhsTy->IsPtrInt1() || rhsTy->IsArray()) || inst.GetType()->IsPtrInt32() || inst.GetType()->IsPtrFloat() || inst.GetType()->IsPtrInt1() || inst.GetType()->IsArray(); int slotSize = isPointer ? 8 : 4; PhysReg lhsReg = isPointer ? PhysReg::X8 : PhysReg::W8; PhysReg rhsReg = isPointer ? PhysReg::X9 : PhysReg::W9; PhysReg dstReg = isPointer ? PhysReg::X8 : PhysReg::W8; int dst_slot = function.CreateFrameIndex(slotSize); // 使用计算出的 slotSize EmitValueToReg(bin.GetLhs(), lhsReg, slots, block, function); EmitValueToReg(bin.GetRhs(), rhsReg, slots, block, function); block.Append(Opcode::AddRR, {Operand::Reg(dstReg), Operand::Reg(lhsReg), Operand::Reg(rhsReg)}); block.Append(Opcode::StoreStack, {Operand::Reg(dstReg), Operand::FrameIndex(dst_slot)}); slots.emplace(&inst, dst_slot); return; } case ir::Opcode::Sub: { auto& bin = static_cast(inst); const ir::Type* lhsTy = bin.GetLhs()->GetType().get(); const ir::Type* rhsTy = bin.GetRhs()->GetType().get(); // 指针判断:指令结果类型是指针,或者任一操作数是指针(指针算术) bool isPointer = (lhsTy->IsPtrInt32() || lhsTy->IsPtrFloat() || lhsTy->IsPtrInt1() || lhsTy->IsArray()) || (rhsTy->IsPtrInt32() || rhsTy->IsPtrFloat() || rhsTy->IsPtrInt1() || rhsTy->IsArray()) || inst.GetType()->IsPtrInt32() || inst.GetType()->IsPtrFloat() || inst.GetType()->IsPtrInt1() || inst.GetType()->IsArray(); int slotSize = isPointer ? 8 : 4; PhysReg lhsReg = isPointer ? PhysReg::X8 : PhysReg::W8; PhysReg rhsReg = isPointer ? PhysReg::X9 : PhysReg::W9; PhysReg dstReg = isPointer ? PhysReg::X8 : PhysReg::W8; int dst_slot = function.CreateFrameIndex(slotSize); // 使用计算出的 slotSize EmitValueToReg(bin.GetLhs(), lhsReg, slots, block, function); EmitValueToReg(bin.GetRhs(), rhsReg, slots, block, function); block.Append(Opcode::SubRR, {Operand::Reg(dstReg), Operand::Reg(lhsReg), Operand::Reg(rhsReg)}); block.Append(Opcode::StoreStack, {Operand::Reg(dstReg), Operand::FrameIndex(dst_slot)}); slots.emplace(&inst, dst_slot); return; } case ir::Opcode::Mul: { auto& bin = static_cast(inst); const ir::Type* ty = inst.GetType().get(); bool isPointer = ty->IsPtrInt32() || ty->IsPtrFloat() || ty->IsPtrInt1(); int slotSize = isPointer ? 8 : 4; PhysReg lhsReg = isPointer ? PhysReg::X8 : PhysReg::W8; PhysReg rhsReg = isPointer ? PhysReg::X9 : PhysReg::W9; PhysReg dstReg = isPointer ? PhysReg::X8 : PhysReg::W8; // 可复用 lhsReg int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 分配结果栈槽 EmitValueToReg(bin.GetLhs(), lhsReg, slots, block, function); EmitValueToReg(bin.GetRhs(), rhsReg, slots, block, function); block.Append(Opcode::MulRR, {Operand::Reg(dstReg), Operand::Reg(lhsReg), Operand::Reg(rhsReg)}); block.Append(Opcode::StoreStack, {Operand::Reg(dstReg), Operand::FrameIndex(dst_slot)}); slots.emplace(&inst, dst_slot); return; } case ir::Opcode::Div: { auto& bin = static_cast(inst); const ir::Type* ty = inst.GetType().get(); bool isPointer = ty->IsPtrInt32() || ty->IsPtrFloat() || ty->IsPtrInt1(); int slotSize = isPointer ? 8 : 4; PhysReg lhsReg = isPointer ? PhysReg::X8 : PhysReg::W8; PhysReg rhsReg = isPointer ? PhysReg::X9 : PhysReg::W9; PhysReg dstReg = isPointer ? PhysReg::X8 : PhysReg::W8; // 可复用 lhsReg int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 分配结果栈槽 EmitValueToReg(bin.GetLhs(), lhsReg, slots, block, function); EmitValueToReg(bin.GetRhs(), rhsReg, slots, block, function); block.Append(Opcode::SDivRR, {Operand::Reg(dstReg), Operand::Reg(lhsReg), Operand::Reg(rhsReg)}); block.Append(Opcode::StoreStack, {Operand::Reg(dstReg), Operand::FrameIndex(dst_slot)}); slots.emplace(&inst, dst_slot); return; } case ir::Opcode::Ret: { auto& ret = static_cast(inst); const ir::Value* retVal = ret.GetValue(); if (retVal != nullptr) { const ir::Type* retType = retVal->GetType().get(); PhysReg retReg = PhysReg::W0; // 默认整数返回值 if (retType->IsFloat()) { retReg = PhysReg::S0; } else if (retType->IsPtrInt32() || retType->IsPtrFloat() || retType->IsPtrInt1()) { retReg = PhysReg::X0; } else { retReg = PhysReg::W0; } EmitValueToReg(retVal, retReg, slots, block, function); } block.Append(Opcode::Ret); return; } case ir::Opcode::FAdd: { auto& bin = static_cast(inst); int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 分配结果栈槽 // 浮点值加载到 S0, S1(使用浮点寄存器) EmitValueToReg(bin.GetLhs(), PhysReg::S0, slots, block, function); EmitValueToReg(bin.GetRhs(), PhysReg::S1, slots, block, function); block.Append(Opcode::FAddRR, {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; } case ir::Opcode::FSub: { auto& bin = static_cast(inst); int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 分配结果栈槽 // 浮点值加载到 S0, S1(使用浮点寄存器) 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; } case ir::Opcode::FMul: { auto& bin = static_cast(inst); int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 分配结果栈槽 // 浮点值加载到 S0, S1(使用浮点寄存器) EmitValueToReg(bin.GetLhs(), PhysReg::S0, slots, block, function); EmitValueToReg(bin.GetRhs(), PhysReg::S1, slots, block, function); block.Append(Opcode::FMulRR, {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; } case ir::Opcode::FDiv: { auto& bin = static_cast(inst); int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 分配结果栈槽 // 浮点值加载到 S0, S1(使用浮点寄存器) EmitValueToReg(bin.GetLhs(), PhysReg::S0, slots, block, function); EmitValueToReg(bin.GetRhs(), PhysReg::S1, slots, block, function); block.Append(Opcode::FDivRR, {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; } // ========== 整数比较指令(修正版)========== case ir::Opcode::Icmp: { auto& icmp = static_cast(inst); int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); EmitValueToReg(icmp.GetLhs(), PhysReg::W8, slots, block, function); EmitValueToReg(icmp.GetRhs(), PhysReg::W9, slots, block, function); block.Append(Opcode::CmpRR, {Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::W9)}); CondCode cc = IcmpToCondCode(icmp.GetPredicate()); // 使用 CSET 模式 block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(1)}); block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W9), Operand::Imm(0)}); std::string true_label = ".L_cset_true_" + std::to_string(reinterpret_cast(&icmp)); std::string end_label = ".L_cset_end_" + std::to_string(reinterpret_cast(&icmp)); 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)}); block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)}); slots.emplace(&inst, dst_slot); return; } // ========== 浮点比较指令 ========== case ir::Opcode::FCmp: { auto& fcmp = static_cast(inst); int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 加载浮点操作数到 s0, s1 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)}); // 简化实现:存储 1 作为结果 block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(1)}); block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)}); slots.emplace(&inst, dst_slot); return; } // ========== 跳转指令(使用标签操作数)========== case ir::Opcode::Br: { 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); 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)}); return; } // ========== 函数调用 ========== case ir::Opcode::Call: { auto& call = static_cast(inst); const ir::Function* callee = call.GetCallee(); const std::string& calleeName = callee->GetName(); // 分配结果栈槽(如果有返回值) int dst_slot = -1; if (!inst.GetType()->IsVoid()) { dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); } // 按照 ARM64 调用约定传递参数 const auto& args = call.GetArgs(); size_t intArgCount = 0; size_t fpArgCount = 0; for (size_t i = 0; i < args.size(); ++i) { const auto* arg = args[i]; const ir::Type* argType = arg->GetType().get(); if (argType->IsFloat()) { // 浮点参数 PhysReg reg = static_cast(static_cast(PhysReg::S0) + fpArgCount); EmitValueToReg(arg, reg, slots, block, function); fpArgCount++; } else if (argType->IsPtrInt32() || argType->IsPtrFloat() || argType->IsPtrInt1()) { // 指针参数 → X 寄存器(占用一个整数参数槽) PhysReg reg = static_cast(static_cast(PhysReg::X0) + intArgCount); EmitValueToReg(arg, reg, slots, block, function); intArgCount++; } else { // 普通整数 → W 寄存器 PhysReg reg = static_cast(static_cast(PhysReg::W0) + intArgCount); EmitValueToReg(arg, reg, slots, block, function); intArgCount++; } } // 生成调用指令 //block.Append(Opcode::Call, {Operand::Imm(0)}); // 实际需要传递函数名 block.Append(Opcode::Call, {Operand::Label(calleeName)}); // 保存返回值 if (dst_slot != -1) { const ir::Type* retType = inst.GetType().get(); PhysReg srcReg = PhysReg::W0; if (retType->IsFloat()) { srcReg = PhysReg::S0; } else if (retType->IsPtrInt32() || retType->IsPtrFloat() || retType->IsPtrInt1()) { srcReg = PhysReg::X0; } else { srcReg = PhysReg::W0; } block.Append(Opcode::StoreStack, {Operand::Reg(srcReg), Operand::FrameIndex(dst_slot)}); slots.emplace(&inst, dst_slot); } return; } // ========== 类型转换指令 ========== case ir::Opcode::ZExt: { auto& zext = static_cast(inst); int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 加载源值到 w8 EmitValueToReg(zext.GetValue(), PhysReg::W8, slots, block, function); // 零扩展:i1 -> i32,直接存储即可(因为 i1 已经是 0 或 1) block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)}); slots.emplace(&inst, dst_slot); return; } case ir::Opcode::SIToFP: { auto& sitofp = static_cast(inst); int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 加载整数到 w8 EmitValueToReg(sitofp.GetValue(), PhysReg::W8, slots, block, function); // 整数转浮点:SCVTF s0, w8 block.Append(Opcode::SIToFP, {Operand::Reg(PhysReg::S0), Operand::Reg(PhysReg::W8)}); block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::S0), Operand::FrameIndex(dst_slot)}); slots.emplace(&inst, dst_slot); return; } case ir::Opcode::FPToSI: { auto& fptosi = static_cast(inst); int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 加载浮点数到 s0 EmitValueToReg(fptosi.GetValue(), PhysReg::S0, slots, block, function); // 浮点转整数:FCVTZS w8, s0 block.Append(Opcode::FPToSI, {Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::S0)}); block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)}); slots.emplace(&inst, dst_slot); return; } case ir::Opcode::GEP: { auto& gep = static_cast(inst); DEBUG_MSG("Processing GEP instruction: " << inst.GetName()); // GEP 返回指针类型,在 ARM64 上指针是 8 字节 int dst_slot = function.CreateFrameIndex(8); // 获取基地址(数组的起始地址) ir::Value* base = gep.GetBase(); const auto& indices = gep.GetIndices(); std::string baseName = base->GetName().empty() ? "unnamed" : base->GetName(); DEBUG_MSG("Base value: " << baseName); DEBUG_MSG("Number of indices: " << indices.size()); // 打印索引值 for (size_t idx_i = 0; idx_i < indices.size(); ++idx_i) { if (auto* const_int = dynamic_cast(indices[idx_i])) { DEBUG_MSG(" Index[" << idx_i << "] = " << const_int->GetValue() << " (constant)"); } else { DEBUG_MSG(" Index[" << idx_i << "] = variable"); } } // 加载基地址到 x8 EmitValueToReg(base, PhysReg::X8, slots, block, function); if (indices.empty()) { DEBUG_MSG("No indices, storing base address directly"); block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::X8), Operand::FrameIndex(dst_slot)}); slots.emplace(&inst, dst_slot); return; } // 获取基地址类型 const ir::Type* baseType = base->GetType().get(); DEBUG_MSG("Base type kind: " << static_cast(baseType->GetKind())); // 关键修改:对于数组指针类型,第一个索引是多余的,应该跳过 size_t start_index = 0; if (baseType->IsPtrInt32() || baseType->IsPtrFloat() || baseType->IsPtrInt1()) { // 对于指针类型,第一个索引是偏移量,不能跳过 DEBUG_MSG("Base is pointer type, using all indices for pointer arithmetic"); start_index = 0; } else if (baseType->IsArray()) { // 对于数组类型(非指针),第一个索引是多余的 // 因为 base 已经是数组本身,不需要再解引用 DEBUG_MSG("Base is array type, skipping first index (array decay)"); start_index = 1; } // 如果基地址是数组类型,需要处理多维数组 if (baseType->IsArray()) { DEBUG_MSG("Base is array type, processing multi-dimensional array"); const ir::ArrayType* arrayType = static_cast(baseType); const std::vector& dims = arrayType->GetDimensions(); DEBUG_MSG("Array dimensions: "); for (size_t i = 0; i < dims.size(); ++i) { DEBUG_MSG(" dim[" << i << "] = " << dims[i]); } // 正确计算每个维度的步长 std::vector strides(dims.size()); int element_size = 4; // 元素大小(int/float 是 4 字节) for (int i = dims.size() - 1; i >= 0; --i) { if (i == static_cast(dims.size()) - 1) { strides[i] = element_size; DEBUG_MSG("strides[" << i << "] = " << strides[i] << " (element size)"); } else { strides[i] = strides[i + 1] * dims[i + 1]; DEBUG_MSG("strides[" << i << "] = " << strides[i+1] << " * " << dims[i+1] << " = " << strides[i]); } } // 计算总偏移,跳过第一个索引 size_t numIndices = indices.size(); size_t effective_indices = numIndices - start_index; if (effective_indices > dims.size()) { DEBUG_MSG("Warning: effective indices (" << effective_indices << ") > dims.size() (" << dims.size() << "), truncating"); effective_indices = dims.size(); } DEBUG_MSG("Using " << effective_indices << " effective indices (starting from " << start_index << ")"); // 加载当前地址到 x9 作为偏移量累加器 block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::X9), Operand::Imm(0)}); // 用于调试的静态偏移计算 int debug_offset = 0; for (size_t i = 0; i < effective_indices; ++i) { size_t idx_pos = start_index + i; int index_value = 0; if (auto* const_int = dynamic_cast(indices[idx_pos])) { index_value = const_int->GetValue(); DEBUG_MSG("Index[" << idx_pos << "] = " << index_value << " (constant)"); debug_offset += index_value * strides[i]; DEBUG_MSG(" Contribution = " << index_value << " * " << strides[i] << " = " << (index_value * strides[i])); DEBUG_MSG(" Running offset = " << debug_offset); } else { DEBUG_MSG("Index[" << idx_pos << "] = variable"); } // 加载当前索引到 x10 EmitValueToReg(indices[idx_pos], PhysReg::X10, slots, block, function); // 乘以步长 block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::X11), Operand::Imm(strides[i])}); block.Append(Opcode::MulRR, {Operand::Reg(PhysReg::X10), Operand::Reg(PhysReg::X10), Operand::Reg(PhysReg::X11)}); // 累加到偏移量 block.Append(Opcode::AddRR, {Operand::Reg(PhysReg::X9), Operand::Reg(PhysReg::X9), Operand::Reg(PhysReg::X10)}); } DEBUG_MSG("Total computed offset = " << debug_offset); // 最终地址 = base + offset block.Append(Opcode::AddRR, {Operand::Reg(PhysReg::X8), Operand::Reg(PhysReg::X8), Operand::Reg(PhysReg::X9)}); // 存储计算出的地址 block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::X8), Operand::FrameIndex(dst_slot)}); slots.emplace(&inst, dst_slot); DEBUG_MSG("Array GEP completed, result stored in slot " << dst_slot); return; } // 其他情况的处理... DEBUG_MSG("Base is other type, using simple handling"); if (indices.size() >= 1) { EmitValueToReg(indices[0], PhysReg::X9, slots, block, function); // 乘以元素大小(默认 4 字节) block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::X10), Operand::Imm(4)}); block.Append(Opcode::MulRR, {Operand::Reg(PhysReg::X9), Operand::Reg(PhysReg::X9), Operand::Reg(PhysReg::X10)}); block.Append(Opcode::AddRR, {Operand::Reg(PhysReg::X8), Operand::Reg(PhysReg::X8), Operand::Reg(PhysReg::X9)}); } block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::X8), Operand::FrameIndex(dst_slot)}); slots.emplace(&inst, dst_slot); DEBUG_MSG("Simple GEP completed"); return; } // 处理 Trunc 指令 case ir::Opcode::Trunc: { auto& inst_ref = static_cast(inst); int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 假设 Trunc 指令有 GetValue() 方法 // 如果没有,需要通过操作数列表获取 const ir::Value* src_val = nullptr; if (inst.GetNumOperands() > 0) { src_val = inst.GetOperand(0); } if (src_val) { EmitValueToReg(src_val, PhysReg::W8, slots, block, function); } block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)}); slots.emplace(&inst, dst_slot); return; } // 处理 Mod 指令 case ir::Opcode::Mod: { int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); // 通过操作数获取左右值 const ir::Value* lhs = nullptr; const ir::Value* rhs = nullptr; if (inst.GetNumOperands() >= 2) { lhs = inst.GetOperand(0); rhs = inst.GetOperand(1); } if (lhs && rhs) { EmitValueToReg(lhs, PhysReg::W8, slots, block, function); EmitValueToReg(rhs, PhysReg::W9, slots, block, function); // a % b = a - (a / b) * b block.Append(Opcode::SDivRR, {Operand::Reg(PhysReg::W10), Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::W9)}); block.Append(Opcode::MulRR, {Operand::Reg(PhysReg::W10), Operand::Reg(PhysReg::W10), Operand::Reg(PhysReg::W9)}); block.Append(Opcode::SubRR, {Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::W10)}); } block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)}); slots.emplace(&inst, dst_slot); return; } // 处理 And 指令 case ir::Opcode::And: { int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); const ir::Value* lhs = nullptr; const ir::Value* rhs = nullptr; if (inst.GetNumOperands() >= 2) { lhs = inst.GetOperand(0); rhs = inst.GetOperand(1); } if (lhs && rhs) { EmitValueToReg(lhs, PhysReg::W8, slots, block, function); EmitValueToReg(rhs, PhysReg::W9, slots, block, function); block.Append(Opcode::AndRR, {Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::W9)}); } block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)}); slots.emplace(&inst, dst_slot); return; } // 处理 Or 指令 case ir::Opcode::Or: { int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); const ir::Value* lhs = nullptr; const ir::Value* rhs = nullptr; if (inst.GetNumOperands() >= 2) { lhs = inst.GetOperand(0); rhs = inst.GetOperand(1); } if (lhs && rhs) { EmitValueToReg(lhs, PhysReg::W8, slots, block, function); EmitValueToReg(rhs, PhysReg::W9, slots, block, function); block.Append(Opcode::OrRR, {Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::W9)}); } block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)}); slots.emplace(&inst, dst_slot); return; } // 处理 Not 指令 case ir::Opcode::Not: { int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); const ir::Value* src_val = nullptr; if (inst.GetNumOperands() > 0) { src_val = inst.GetOperand(0); } if (src_val) { EmitValueToReg(src_val, PhysReg::W8, slots, block, function); // NOT = XOR with -1 block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W9), Operand::Imm(-1)}); block.Append(Opcode::EorRR, {Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::W9)}); } block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)}); slots.emplace(&inst, dst_slot); return; } // 处理 FPExt(浮点扩展) case ir::Opcode::FPExt: { int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); const ir::Value* src_val = nullptr; if (inst.GetNumOperands() > 0) { src_val = inst.GetOperand(0); } if (src_val) { EmitValueToReg(src_val, PhysReg::S0, slots, block, function); } block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::S0), Operand::FrameIndex(dst_slot)}); slots.emplace(&inst, dst_slot); return; } // 处理 FPTrunc(浮点截断) case ir::Opcode::FPTrunc: { int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); const ir::Value* src_val = nullptr; if (inst.GetNumOperands() > 0) { src_val = inst.GetOperand(0); } if (src_val) { EmitValueToReg(src_val, PhysReg::S0, slots, block, function); } block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::S0), Operand::FrameIndex(dst_slot)}); 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())))); } } } // namespace // 辅助函数,将单个 IR 函数转换为 MachineFunction std::unique_ptr LowerFunction(const ir::Function& func) { auto machine_func = std::make_unique(func.GetName()); ValueSlotMap slots; // 存储参数信息,稍后处理 struct ParamInfo { const ir::Value* arg; int slot; bool isFloat; bool isPointer; }; std::vector paramInfos; // 为函数参数分配栈槽 for (const auto& arg : func.GetArguments()) { int slot = machine_func->CreateFrameIndex(GetTypeSize(arg->GetType().get())); slots.emplace(arg.get(), slot); bool isFloat = arg->GetType()->IsFloat(); bool isPointer = arg->GetType()->IsPtrInt32() || arg->GetType()->IsPtrFloat() || arg->GetType()->IsPtrInt1(); paramInfos.push_back({arg.get(), slot, isFloat, isPointer}); } // IR 基本块到 MIR 基本块的映射 std::unordered_map blockMap; // 第一遍:为每个 IR 基本块创建 MIR 基本块 std::string func_name = func.GetName(); for (const auto& bb : func.GetBlocks()) { // 格式: .L函数名_基本块名 auto mirBB = std::make_unique(".L" + func_name + "_" + bb->GetName()); blockMap[bb.get()] = mirBB.get(); machine_func->AddBasicBlock(std::move(mirBB)); } // 在入口基本块的开头添加参数加载指令 if (!func.GetBlocks().empty()) { MachineBasicBlock* entryBB = blockMap[func.GetEntry()]; if (entryBB) { size_t intArgIdx = 0; size_t fpArgIdx = 0; for (const auto& param : paramInfos) { if (param.isFloat) { if (fpArgIdx < 8) { PhysReg reg = static_cast(static_cast(PhysReg::S0) + fpArgIdx); entryBB->Append(Opcode::StoreStack, {Operand::Reg(reg), Operand::FrameIndex(param.slot)}); } fpArgIdx++; } else if (param.isPointer) { if (intArgIdx < 8) { PhysReg reg = static_cast(static_cast(PhysReg::X0) + intArgIdx); entryBB->Append(Opcode::StoreStack, {Operand::Reg(reg), Operand::FrameIndex(param.slot)}); } intArgIdx++; } else { if (intArgIdx < 8) { PhysReg reg = static_cast(static_cast(PhysReg::W0) + intArgIdx); entryBB->Append(Opcode::StoreStack, {Operand::Reg(reg), Operand::FrameIndex(param.slot)}); } intArgIdx++; } } } } // 第二遍:遍历每个基本块,转换指令 for (const auto& bb : func.GetBlocks()) { MachineBasicBlock* mirBB = blockMap[bb.get()]; if (!mirBB) { throw std::runtime_error(FormatError("mir", "找不到基本块对应的 MIR 基本块")); } for (const auto& inst : bb->GetInstructions()) { LowerInstruction(*inst, *machine_func, slots, *mirBB, blockMap); } } return machine_func; } std::unique_ptr LowerToMIR(const ir::Module& module) { DefaultContext(); auto machine_module = std::make_unique(); // 收集全局变量信息 for (const auto& global : module.GetGlobals()) { int size = GetTypeSize(global->GetType().get()); int alignment = global->GetType()->Alignment(); // 简化:假设无显式初始化的全局变量都是零初始化 bool is_zero_init = !global->HasInitializer(); machine_module->AddGlobal(global->GetName(), size, alignment, is_zero_init); } std::vector globals; // 处理全局变量 for (const auto& global : module.GetGlobals()) { // 为全局变量在数据段分配空间 // 这里需要扩展 MachineModule 来支持全局变量 DEBUG_MSG("Global variable: " << global->GetName()); globals.push_back(global.get()); } // 遍历模块中的所有函数 for (const auto& func : module.GetFunctions()) { try { auto machine_func = LowerFunction(*func); machine_module->AddFunction(std::move(machine_func)); } catch (const std::runtime_error& e) { // 记录错误但继续处理其他函数 throw std::runtime_error(FormatError("mir", "转换函数失败: " + func->GetName() + " - " + e.what())); } } if (machine_module->GetFunctions().empty()) { throw std::runtime_error(FormatError("mir", "模块中没有成功转换的函数")); } return machine_module; } } // namespace mir