diff --git a/src/mir/Lowering.cpp b/src/mir/Lowering.cpp index 9151f48..9945c1e 100644 --- a/src/mir/Lowering.cpp +++ b/src/mir/Lowering.cpp @@ -105,6 +105,22 @@ static std::vector GetArrayStrides(const ir::ArrayType* arrayType) { 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) { @@ -116,23 +132,52 @@ void EmitValueToReg(const ir::Value* value, PhysReg target, } // 处理浮点常量 if (auto* fconstant = dynamic_cast(value)) { - // 浮点常量需要存储到栈槽,然后加载到寄存器 // 检查是否已经为这个常量分配了栈槽 auto it = slots.find(value); int slot; if (it == slots.end()) { - // 分配新的栈槽 - slot = function.CreateFrameIndex(4); - // 将浮点常量存储到栈槽 - float fval = fconstant->GetValue(); - // 将浮点数作为立即数加载(使用整数表示) - uint32_t int_val = *reinterpret_cast(&fval); - block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(static_cast(int_val))}); - block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(slot)}); - const_cast(slots).emplace(value, slot); + 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); + + // 使用临时寄存器加载常量并存储 + block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(static_cast(int_val))}); + block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(slot)}); + const_cast(slots).emplace(value, slot); } else { - slot = it->second; + slot = it->second; } + + // 从栈槽加载到目标寄存器 + block.Append(Opcode::LoadStack, {Operand::Reg(target), Operand::FrameIndex(slot)}); + return; + } + // 处理全局变量 + if (auto* global = dynamic_cast(value)) { + // 全局变量:需要加载其地址 + // 在 ARM64 中,使用 ADRP + ADD 指令获取全局变量地址 + // 简化版本:先为全局变量分配一个栈槽,然后加载地址到该栈槽 + + // 检查是否已经为这个全局变量分配了栈槽 + auto it = slots.find(value); + if (it == slots.end()) { + // 为全局变量创建栈槽 + const_cast(slots).emplace(value, + const_cast(function).CreateFrameIndex(8)); + it = slots.find(value); + } + + // 从栈槽加载地址到目标寄存器 + block.Append(Opcode::LoadStack, + {Operand::Reg(target), Operand::FrameIndex(it->second)}); + return; } // 处理零常量 if (dynamic_cast(value) || @@ -145,6 +190,11 @@ void EmitValueToReg(const ir::Value* value, PhysReg target, auto it = slots.find(value); if (it == slots.end()) { + DEBUG_MSG("Value not found: " << value->GetName()); + // 输出所有 slots 的键名用于调试 + for (auto& p : slots) { + DEBUG_MSG(" Slot key: " << p.first->GetName()); + } throw std::runtime_error( FormatError("mir", "找不到值对应的栈槽: " + value->GetName())); } @@ -158,6 +208,8 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function, 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: { @@ -333,42 +385,25 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function, auto& icmp = static_cast(inst); int dst_slot = function.CreateFrameIndex(GetTypeSize(inst.GetType().get())); - // 加载左右操作数到 w8, w9 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)}); - - // 使用条件设置指令: CSET W8, cc - // 如果条件成立,W8 = 1;否则 W8 = 0 CondCode cc = IcmpToCondCode(icmp.GetPredicate()); - // 使用 CSET 的替代实现:条件移动 - // MOV W8, #1 - // MOV W9, #0 - // CSEL W8, W8, W9, cc + // 使用 CSET 模式 block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(1)}); block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W9), Operand::Imm(0)}); - // TODO: 需要添加 CSEL 指令,暂时使用条件跳转 - // 创建临时标签 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)); - // 设置条件成立时的值(1) - block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(1)}); - // 条件成立时跳转到 true_label block.Append(Opcode::BCond, {Operand::Cond(cc), Operand::Label(true_label)}); - // 条件不成立:设置 W8 = 0 - block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(0)}); - // 跳转到 end_label + block.Append(Opcode::MovReg, {Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::W9)}); block.Append(Opcode::B, {Operand::Label(end_label)}); - // true_label: 值已经是 1,直接落入 end_label block.Append(Opcode::Label, {Operand::Label(true_label)}); - // end_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); @@ -661,8 +696,199 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function, slots.emplace(&inst, dst_slot); return; } - //throw std::runtime_error(FormatError("mir", "暂不支持该 IR 指令")); - throw std::runtime_error(FormatError("mir", "暂不支持该 IR 指令,opcode: " + // 处理 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; + } + // 处理 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())); + + 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; + } + //throw std::runtime_error(FormatError("mir", "暂不支持该 IR 指令")); + throw std::runtime_error(FormatError("mir", "暂不支持该 IR 指令,opcode: " + std::to_string(static_cast(inst.GetOpcode())))); } } @@ -673,17 +899,21 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function, 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; + }; + std::vector paramInfos; // 为函数参数分配栈槽 for (const auto& arg : func.GetArguments()) { - // 为每个参数分配栈槽 int slot = machine_func->CreateFrameIndex(GetTypeSize(arg->GetType().get())); slots.emplace(arg.get(), slot); - - // 注意:参数的值需要从寄存器加载到栈槽 - // 在 ARM64 调用约定中,前 8 个整数参数在 w0-w7,前 8 个浮点参数在 s0-s7 - // 这里需要生成指令将参数从寄存器存储到栈槽 - // 但 MachineFunction 还没有基本块,所以需要延迟处理 + bool isFloat = arg->GetType()->IsFloat(); + paramInfos.push_back({arg.get(), slot, isFloat}); } // IR 基本块到 MIR 基本块的映射 @@ -702,32 +932,26 @@ std::unique_ptr LowerFunction(const ir::Function& func) { if (!func.GetBlocks().empty()) { MachineBasicBlock* entryBB = blockMap[func.GetEntry()]; if (entryBB) { - // 为每个参数生成从寄存器到栈槽的存储指令 - size_t intArgIdx = 0; - size_t fpArgIdx = 0; - - for (const auto& arg : func.GetArguments()) { - int slot = slots[arg.get()]; - const ir::Type* argType = arg->GetType().get(); + size_t intArgIdx = 0; + size_t fpArgIdx = 0; - if (argType->IsFloat()) { - // 浮点参数从 s0, s1, ... 读取 - if (fpArgIdx < 8) { - PhysReg reg = static_cast(static_cast(PhysReg::S0) + fpArgIdx); - entryBB->Append(Opcode::StoreStack, - {Operand::Reg(reg), Operand::FrameIndex(slot)}); - } - fpArgIdx++; - } else { - // 整数参数从 w0, w1, ... 读取 - if (intArgIdx < 8) { - PhysReg reg = static_cast(static_cast(PhysReg::W0) + intArgIdx); - entryBB->Append(Opcode::StoreStack, - {Operand::Reg(reg), Operand::FrameIndex(slot)}); - } - intArgIdx++; + 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 (intArgIdx < 8) { + PhysReg reg = static_cast(static_cast(PhysReg::W0) + intArgIdx); + entryBB->Append(Opcode::StoreStack, + {Operand::Reg(reg), Operand::FrameIndex(param.slot)}); + } + intArgIdx++; + } } - } } } @@ -750,6 +974,13 @@ std::unique_ptr LowerToMIR(const ir::Module& module) { DefaultContext(); auto machine_module = std::make_unique(); + + // 处理全局变量 + for (const auto& global : module.GetGlobals()) { + // 为全局变量在数据段分配空间 + // 这里需要扩展 MachineModule 来支持全局变量 + DEBUG_MSG("Global variable: " << global->GetName()); + } // 遍历模块中的所有函数 for (const auto& func : module.GetFunctions()) {