#include "mir/MIR.h" #include #include #include #include #include #include "ir/IR.h" #include "utils/Log.h" 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; MachineBasicBlock* GetOrCreateBlock(const ir::BasicBlock* ir_block, MachineFunction& function) { auto it = block_map.find(ir_block); if (it != block_map.end()) { return it->second; } std::string name = ir_block->GetName(); if (name.empty()) { name = "block_" + std::to_string(block_map.size()); } auto* block = function.CreateBlock(name); block_map[ir_block] = block; return block; } void EmitValueToReg(const ir::Value* value, PhysReg target, const ValueSlotMap& slots, MachineBasicBlock& block, MachineFunction& function, 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) { // 同类型 → 直接加载,不转换 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)}); } else 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)}); } return; } } // 处理整数常量 if (auto* constant = dynamic_cast(value)) { int64_t val = constant->GetValue(); block.Append(Opcode::MovImm, {Operand::Reg(target), Operand::Imm(static_cast(val))}); return; } // 处理浮点常量 if (auto* fconstant = dynamic_cast(value)) { // 直接使用标准的 double -> float 转换,无需特殊分支 float fval = static_cast(fconstant->GetValue()); uint32_t bits; std::memcpy(&bits, &fval, sizeof(fval)); int32_t imm = static_cast(bits); if (IsFloatReg(target)) { // 通过栈槽加载以保证浮点寄存器符合 NaN‑boxing 要求 int tmp_slot = function.CreateFrameIndex(4); block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::T4), Operand::Imm(imm)}); block.Append(Opcode::Store, {Operand::Reg(PhysReg::T4), Operand::FrameIndex(tmp_slot)}); block.Append(Opcode::LoadFloat, {Operand::Reg(target), Operand::FrameIndex(tmp_slot)}); } else { block.Append(Opcode::MovImm, {Operand::Reg(target), Operand::Imm(imm)}); } return; } // 处理 GEP 指令 if (auto* gep = dynamic_cast(value)) { EmitValueToReg(gep->GetBasePtr(), target, slots, block,function, true); EmitValueToReg(gep->GetIndex(), PhysReg::T1, slots, block,function); block.Append(Opcode::Slli, {Operand::Reg(PhysReg::T1), Operand::Reg(PhysReg::T1), Operand::Imm(2)}); block.Append(Opcode::Add, {Operand::Reg(target), Operand::Reg(target), Operand::Reg(PhysReg::T1)}); return; } // 处理 Alloca 指令 if (auto* alloca = dynamic_cast(value)) { auto it = slots.find(alloca); if (it != slots.end()) { block.Append(Opcode::LoadAddr, {Operand::Reg(target), Operand::FrameIndex(it->second)}); return; } } // 处理全局变量 if (auto* global = dynamic_cast(value)) { block.Append(Opcode::LoadGlobalAddr, {Operand::Reg(target), Operand::Global(global->GetName())}); if (!for_address) { if (global->IsFloat()) { block.Append(Opcode::LoadFloat, {Operand::Reg(target), Operand::Reg(target)}); } else { block.Append(Opcode::LoadGlobal, {Operand::Reg(target), Operand::Reg(target)}); } } return; } // 处理一般栈槽中的值 auto it = slots.find(value); 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)}); } 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; throw std::runtime_error( FormatError("mir", "找不到值对应的栈槽: " + value->GetName())); } void StoreRegToSlot(PhysReg reg, int slot, MachineBasicBlock& block, bool isFloat = false) { if (isFloat) { block.Append(Opcode::StoreFloat, {Operand::Reg(reg), Operand::FrameIndex(slot)}); } else { block.Append(Opcode::Store, {Operand::Reg(reg), Operand::FrameIndex(slot)}); } } // 将 LowerInstruction 重命名为 LowerInstructionToBlock,并添加 MachineBasicBlock 参数 void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& function, ValueSlotMap& slots, MachineBasicBlock& block) { switch (inst.GetOpcode()) { case ir::Opcode::Alloca: { auto& alloca = static_cast(inst); int size = 4; if (alloca.GetNumElements() > 1) { size = alloca.GetNumElements() * 4; } slots.emplace(&inst, function.CreateFrameIndex(size)); return; } case ir::Opcode::Store: { auto& store = static_cast(inst); // 如果指针是 GEP,手动生成地址并 store,避免额外计算 if (auto* gep = dynamic_cast(store.GetPtr())) { // 判断值的类型是否为浮点 bool val_is_float = store.GetValue()->GetType()->IsFloat32(); if (val_is_float) { // 将浮点值加载到 FT0 EmitValueToReg(store.GetValue(), PhysReg::FT0, slots, block, function); } else { // 整数值加载到 T2 EmitValueToReg(store.GetValue(), PhysReg::T2, slots, block, function); } // 计算基址 + 索引*4 EmitValueToReg(gep->GetBasePtr(), PhysReg::T0, slots, block, function, true); auto idx_it = slots.find(gep->GetIndex()); if (idx_it != slots.end()) { block.Append(Opcode::Load, {Operand::Reg(PhysReg::T1), Operand::FrameIndex(idx_it->second)}); } else { EmitValueToReg(gep->GetIndex(), PhysReg::T1, slots, block, function); } block.Append(Opcode::Slli, {Operand::Reg(PhysReg::T1), Operand::Reg(PhysReg::T1), Operand::Imm(2)}); block.Append(Opcode::Add, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T1)}); // 使用正确的间接存储操作码 if (val_is_float) { block.Append(Opcode::StoreIndirectFloat, {Operand::Reg(PhysReg::FT0), Operand::Reg(PhysReg::T0)}); } else { block.Append(Opcode::StoreIndirect, {Operand::Reg(PhysReg::T2), Operand::Reg(PhysReg::T0)}); } return; } if (auto* global = dynamic_cast(store.GetPtr())) { EmitValueToReg(store.GetValue(), PhysReg::T0, slots, block, function); std::string global_name = global->GetName(); block.Append(Opcode::StoreGlobal, {Operand::Reg(PhysReg::T0), Operand::Global(global_name)}); return; } auto dst = slots.find(store.GetPtr()); if (dst != slots.end()) { bool val_is_float = store.GetValue()->GetType()->IsFloat32(); if (val_is_float) { EmitValueToReg(store.GetValue(), PhysReg::FT0, slots, block, function); StoreRegToSlot(PhysReg::FT0, dst->second, block, true); } else { EmitValueToReg(store.GetValue(), PhysReg::T0, slots, block, function); StoreRegToSlot(PhysReg::T0, dst->second, block, false); } return; } throw std::runtime_error(FormatError("mir", "Store: 无法处理的指针类型")); } case ir::Opcode::Load: { auto& load = static_cast(inst); if (auto* gep = dynamic_cast(load.GetPtr())) { // 计算地址到 T0 EmitValueToReg(gep->GetBasePtr(), PhysReg::T0, slots, block, function, true); auto idx_it = slots.find(gep->GetIndex()); if (idx_it != slots.end()) { block.Append(Opcode::Load, {Operand::Reg(PhysReg::T1), Operand::FrameIndex(idx_it->second)}); } else { EmitValueToReg(gep->GetIndex(), PhysReg::T1, slots, block, function); } block.Append(Opcode::Slli, {Operand::Reg(PhysReg::T1), Operand::Reg(PhysReg::T1), Operand::Imm(2)}); block.Append(Opcode::Add, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T1)}); bool load_is_float = load.GetType()->IsFloat32(); int dst_slot = function.CreateFrameIndex(4); if (load_is_float) { // 浮点加载:FT0 = [T0] block.Append(Opcode::LoadIndirectFloat, {Operand::Reg(PhysReg::FT0), Operand::Reg(PhysReg::T0)}); StoreRegToSlot(PhysReg::FT0, dst_slot, block, true); } else { // 整数加载 block.Append(Opcode::LoadIndirect, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T0)}); StoreRegToSlot(PhysReg::T0, dst_slot, block, false); } slots.emplace(&inst, dst_slot); return; } if (dynamic_cast(load.GetPtr())) { EmitValueToReg(load.GetPtr(), PhysReg::T0, slots, block, function, true); block.Append(Opcode::LoadIndirect, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T0)}); int dst_slot = function.CreateFrameIndex(4); StoreRegToSlot(PhysReg::T0, dst_slot, block, false); slots.emplace(&inst, dst_slot); return; } if (auto* global = dynamic_cast(load.GetPtr())) { int dst_slot = function.CreateFrameIndex(4); std::string global_name = global->GetName(); block.Append(Opcode::LoadGlobalAddr, {Operand::Reg(PhysReg::T0), Operand::Global(global_name)}); if (global->IsFloat()) { block.Append(Opcode::LoadFloat, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T0)}); StoreRegToSlot(PhysReg::T0, dst_slot, block, true); } else { block.Append(Opcode::LoadGlobal, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T0)}); StoreRegToSlot(PhysReg::T0, dst_slot, block, false); } slots.emplace(&inst, dst_slot); return; } auto src = slots.find(load.GetPtr()); if (src != slots.end()) { int dst_slot = function.CreateFrameIndex(4); if (load.GetType()->IsFloat32()) { block.Append(Opcode::LoadFloat, {Operand::Reg(PhysReg::FT0), Operand::FrameIndex(src->second)}); StoreRegToSlot(PhysReg::FT0, dst_slot, block, true); } else { block.Append(Opcode::Load, {Operand::Reg(PhysReg::T0), Operand::FrameIndex(src->second)}); StoreRegToSlot(PhysReg::T0, dst_slot, block, false); } slots.emplace(&inst, dst_slot); return; } throw std::runtime_error(FormatError("mir", "Load: 无法处理的指针类型")); } case ir::Opcode::Add: case ir::Opcode::Sub: case ir::Opcode::Mul: case ir::Opcode::Div: 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); 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, function); EmitValueToReg(bin.GetRhs(), PhysReg::FT1, slots, block, function); 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, function); EmitValueToReg(bin.GetRhs(), PhysReg::T1, slots, block, function); 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); } slots.emplace(&inst, dst_slot); return; } case ir::Opcode::Gep: { int dst_slot = function.CreateFrameIndex(); slots.emplace(&inst, dst_slot); return; } case ir::Opcode::Call: { auto& call = static_cast(inst); int numArgs = static_cast(call.GetNumArgs()); int ireg = 0, freg = 0; std::vector> stack_args; // (is_float, value) for (int i = 0; i < numArgs; ++i) { bool arg_is_float = call.GetArg(i)->GetType()->IsFloat32(); if (arg_is_float) { if (freg < 8) { PhysReg fregnum = static_cast(static_cast(PhysReg::FA0) + freg); EmitValueToReg(call.GetArg(i), fregnum, slots, block, function); freg++; } else { stack_args.push_back({true, call.GetArg(i)}); } } else { // integer or pointer if (ireg < 8) { PhysReg iregnum = static_cast(static_cast(PhysReg::A0) + ireg); EmitValueToReg(call.GetArg(i), iregnum, slots, block, function); ireg++; } else { stack_args.push_back({false, call.GetArg(i)}); } } } int stackArgs = static_cast(stack_args.size()); if (stackArgs > 0) { int stackSpace = (stackArgs * 8 + 15) & ~15; // sp -= stackSpace if (stackSpace <= 2047) { block.Append(Opcode::Addi, {Operand::Reg(PhysReg::SP), Operand::Reg(PhysReg::SP), Operand::Imm(-stackSpace)}); } else { block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::T4), Operand::Imm(-stackSpace)}); block.Append(Opcode::Add, {Operand::Reg(PhysReg::SP), Operand::Reg(PhysReg::SP), Operand::Reg(PhysReg::T4)}); } for (int idx = 0; idx < stackArgs; ++idx) { bool is_float = stack_args[idx].first; ir::Value* val = stack_args[idx].second; int offset = idx * 8; // 1. 先加载值 if (is_float) { EmitValueToReg(val, PhysReg::FT0, slots, block, function); } else { EmitValueToReg(val, PhysReg::T0, slots, block, function); } // 2. 再计算栈地址到 T4 if (offset == 0) { block.Append(Opcode::Add, {Operand::Reg(PhysReg::T4), Operand::Reg(PhysReg::SP), Operand::Reg(PhysReg::ZERO)}); } else if (offset <= 2047) { block.Append(Opcode::Addi, {Operand::Reg(PhysReg::T4), Operand::Reg(PhysReg::SP), Operand::Imm(offset)}); } else { block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::T4), Operand::Imm(offset)}); block.Append(Opcode::Add, {Operand::Reg(PhysReg::T4), Operand::Reg(PhysReg::SP), Operand::Reg(PhysReg::T4)}); } // 3. 存储 if (is_float) { block.Append(Opcode::StoreFloat, {Operand::Reg(PhysReg::FT0), Operand::Reg(PhysReg::T4)}); } else { block.Append(Opcode::Store, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T4)}); } } } // 调用目标 std::string func_name = call.GetCalleeName(); block.Append(Opcode::Call, {Operand::Func(func_name)}); // 恢复 sp if (stackArgs > 0) { int stackSpace = (stackArgs * 8 + 15) & ~15; if (stackSpace <= 2047) { block.Append(Opcode::Addi, {Operand::Reg(PhysReg::SP), Operand::Reg(PhysReg::SP), Operand::Imm(stackSpace)}); } else { block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::T4), Operand::Imm(stackSpace)}); block.Append(Opcode::Add, {Operand::Reg(PhysReg::SP), Operand::Reg(PhysReg::SP), Operand::Reg(PhysReg::T4)}); } } // 返回值处理(原有代码保持不变) if (!call.GetType()->IsVoid()) { int dst_slot = function.CreateFrameIndex(); 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; } case ir::Opcode::ICmp: { auto& icmp = static_cast(inst); int dst_slot = function.CreateFrameIndex(); EmitValueToReg(icmp.GetLhs(), PhysReg::T0, slots, block, function); EmitValueToReg(icmp.GetRhs(), PhysReg::T1, slots, block, function); ir::ICmpPredicate pred = icmp.GetPredicate(); switch (pred) { case ir::ICmpPredicate::EQ: block.Append(Opcode::Sub, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T1)}); block.Append(Opcode::Sltiu, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T0), Operand::Imm(1)}); break; case ir::ICmpPredicate::NE: block.Append(Opcode::Sub, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T1)}); block.Append(Opcode::Sltiu, {Operand::Reg(PhysReg::T1), Operand::Reg(PhysReg::T0), Operand::Imm(1)}); block.Append(Opcode::Xori, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T1), Operand::Imm(1)}); break; case ir::ICmpPredicate::SLT: block.Append(Opcode::Slt, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T1)}); break; case ir::ICmpPredicate::SGT: block.Append(Opcode::Slt, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T1), Operand::Reg(PhysReg::T0)}); break; case ir::ICmpPredicate::SGE: // lhs >= rhs 等价于 !(lhs < rhs) block.Append(Opcode::Slt, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T1)}); block.Append(Opcode::Xori, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T0), Operand::Imm(1)}); break; case ir::ICmpPredicate::SLE: // lhs <= rhs 等价于 !(rhs < lhs) block.Append(Opcode::Slt, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T1), Operand::Reg(PhysReg::T0)}); // 注意操作数顺序:rhs < lhs block.Append(Opcode::Xori, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T0), Operand::Imm(1)}); break; } StoreRegToSlot(PhysReg::T0, dst_slot, block); slots.emplace(&inst, dst_slot); return; } case ir::Opcode::ZExt: { auto& zext = static_cast(inst); int dst_slot = function.CreateFrameIndex(4); EmitValueToReg(zext.GetSrc(), PhysReg::T0, slots, block, function); StoreRegToSlot(PhysReg::T0, dst_slot, block); slots.emplace(&inst, dst_slot); return; } case ir::Opcode::FCmp: { auto& fcmp = static_cast(inst); int dst_slot = function.CreateFrameIndex(4); EmitValueToReg(fcmp.GetLhs(), PhysReg::FT0, slots, block, function); EmitValueToReg(fcmp.GetRhs(), PhysReg::FT1, slots, block, function); ir::FCmpPredicate pred = fcmp.GetPredicate(); switch (pred) { case ir::FCmpPredicate::OEQ: block.Append(Opcode::FEq, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::FT0), Operand::Reg(PhysReg::FT1)}); break; case ir::FCmpPredicate::ONE: block.Append(Opcode::FEq, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::FT0), Operand::Reg(PhysReg::FT1)}); block.Append(Opcode::Xori, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T0), Operand::Imm(1)}); break; case ir::FCmpPredicate::OLT: block.Append(Opcode::FLt, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::FT0), Operand::Reg(PhysReg::FT1)}); break; case ir::FCmpPredicate::OGT: block.Append(Opcode::FLt, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::FT1), Operand::Reg(PhysReg::FT0)}); break; case ir::FCmpPredicate::OLE: block.Append(Opcode::FLe, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::FT0), Operand::Reg(PhysReg::FT1)}); break; case ir::FCmpPredicate::OGE: block.Append(Opcode::FLe, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::FT1), Operand::Reg(PhysReg::FT0)}); break; default: block.Append(Opcode::FEq, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::FT0), Operand::Reg(PhysReg::FT1)}); break; } StoreRegToSlot(PhysReg::T0, dst_slot, block); slots.emplace(&inst, dst_slot); return; } case ir::Opcode::SIToFP: { auto& conv = static_cast(inst); int dst_slot = function.CreateFrameIndex(4); // 直接加载源操作数到 T0,不依赖 slots 中是否存在 EmitValueToReg(conv.GetSrc(), PhysReg::T0, slots, block, function); block.Append(Opcode::SIToFP, {Operand::Reg(PhysReg::FT0), Operand::Reg(PhysReg::T0)}); StoreRegToSlot(PhysReg::FT0, dst_slot, block, true); slots.emplace(&inst, dst_slot); return; } case ir::Opcode::FPToSI: { auto& conv = static_cast(inst); int dst_slot = function.CreateFrameIndex(4); // 直接加载源操作数到 FT0,不依赖 slots EmitValueToReg(conv.GetSrc(), PhysReg::FT0, slots, block, function); block.Append(Opcode::FPToSI, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::FT0)}); StoreRegToSlot(PhysReg::T0, dst_slot, block, false); slots.emplace(&inst, dst_slot); return; } case ir::Opcode::Br: { auto& br = static_cast(inst); auto* target = br.GetTarget(); MachineBasicBlock* target_block = GetOrCreateBlock(target, function); block.Append(Opcode::Br, {Operand::Imm64(reinterpret_cast(target_block))}); return; } case ir::Opcode::CondBr: { auto& condbr = static_cast(inst); auto* true_bb = condbr.GetTrueBB(); auto* false_bb = condbr.GetFalseBB(); EmitValueToReg(condbr.GetCond(), PhysReg::T0, slots, block, function); MachineBasicBlock* true_block = GetOrCreateBlock(true_bb, function); MachineBasicBlock* false_block = GetOrCreateBlock(false_bb, function); block.Append(Opcode::CondBr, {Operand::Reg(PhysReg::T0), Operand::Imm64(reinterpret_cast(true_block)), Operand::Imm64(reinterpret_cast(false_block))}); return; } case ir::Opcode::Ret: { auto& ret = static_cast(inst); if (ret.GetValue()) { auto val = ret.GetValue(); if (val->GetType()->IsFloat32()) { EmitValueToReg(val, PhysReg::FA0, slots, block, function); } else { EmitValueToReg(val, PhysReg::A0, slots, block, function); } } else { block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::A0), Operand::Imm(0)}); } block.Append(Opcode::Ret); return; } default: { break; } } } } // namespace std::unique_ptr LowerFunctionToMIR(const ir::Function& func) { block_map.clear(); auto machine_func = std::make_unique(func.GetName()); ValueSlotMap slots; int ireg = 0, freg = 0, stack_idx = 0; for (size_t i = 0; i < func.GetNumArgs(); i++) { ir::Argument* arg = func.GetArgument(i); int size = (arg->GetType()->IsPtrInt32() || arg->GetType()->IsPtrFloat32()) ? 8 : 4; int slot = machine_func->CreateFrameIndex(size); MachineBasicBlock* entry = machine_func->GetEntry(); if (arg->GetType()->IsFloat32()) { if (freg < 8) { PhysReg argReg = static_cast(static_cast(PhysReg::FA0) + freg); entry->Append(Opcode::StoreFloat, {Operand::Reg(argReg), Operand::FrameIndex(slot)}); freg++; } else { entry->Append(Opcode::LoadCallerStackArgFloat, { Operand::Reg(PhysReg::FT0), Operand::FrameIndex(slot), Operand::Imm(stack_idx) }); stack_idx++; } } else { if (ireg < 8) { PhysReg argReg = static_cast(static_cast(PhysReg::A0) + ireg); entry->Append(Opcode::Store, {Operand::Reg(argReg), Operand::FrameIndex(slot)}); ireg++; } else { entry->Append(Opcode::LoadCallerStackArg, { Operand::Reg(PhysReg::T0), Operand::FrameIndex(slot), Operand::Imm(stack_idx) }); stack_idx++; } } slots[arg] = slot; } // 第一遍:创建所有 IR 基本块对应的 MIR 基本块 for (const auto& ir_block : func.GetBlocks()) { GetOrCreateBlock(ir_block.get(), *machine_func); } // 第二遍:遍历所有基本块,降低指令 for (const auto& ir_block : func.GetBlocks()) { MachineBasicBlock* mbb = GetOrCreateBlock(ir_block.get(), *machine_func); for (const auto& inst : ir_block->GetInstructions()) { LowerInstructionToBlock(*inst, *machine_func, slots, *mbb); } } return machine_func; } std::vector> LowerToMIR(const ir::Module& module) { DefaultContext(); // 收集全局变量 g_globalVars.clear(); for (const auto& global : module.GetGlobalVariables()) { GlobalVarInfo info; info.name = global->GetName(); info.isConst = global->IsConst(); info.isArray = global->IsArray(); info.arraySize = global->GetNumElements(); info.isFloat = global->IsFloat(); info.value = 0; info.valueF = 0.0f; if (info.isArray) { if (info.isFloat) { const auto& initVals = global->GetInitValsF(); for (float val : initVals) { info.arrayValuesF.push_back(val); } } else { if (global->HasInitVals()) { const auto& initVals = global->GetInitVals(); for (int val : initVals) { info.arrayValues.push_back(val); } } } } else { if (info.isFloat) { info.valueF = global->GetInitValF(); } else { info.value = global->GetInitVal(); } } g_globalVars.push_back(info); } const auto& functions = module.GetFunctions(); if (functions.empty()) { throw std::runtime_error(FormatError("mir", "模块中没有函数")); } std::vector> result; for (const auto& func : functions) { auto machine_func = LowerFunctionToMIR(*func); result.push_back(std::move(machine_func)); } return result; } } // namespace mir