diff --git a/include/mir/MIR.h b/include/mir/MIR.h index db3ef89..0ddabc8 100644 --- a/include/mir/MIR.h +++ b/include/mir/MIR.h @@ -100,6 +100,8 @@ enum class Opcode { StoreGlobal, LoadIndirect, // lw rd, 0(rs1) 从寄存器地址加载 StoreIndirect, // sw rs2, 0(rs1) + LoadIndirectFloat, // flw rd, 0(rs1) + StoreIndirectFloat, // fsw rs2, 0(rs1) Call, GEP, LoadAddr, @@ -125,6 +127,7 @@ enum class Opcode { CondBr, Label, LoadCallerStackArg, // 从调用者栈帧加载参数 + LoadCallerStackArgFloat, // 从调用者栈帧加载浮点参数 }; enum class GlobalKind { diff --git a/src/mir/AsmPrinter.cpp b/src/mir/AsmPrinter.cpp index 575169d..5944a24 100644 --- a/src/mir/AsmPrinter.cpp +++ b/src/mir/AsmPrinter.cpp @@ -204,7 +204,7 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) { os << " ld " << PhysRegName(ops[0].GetReg()) << ", " << caller_offset << "(sp)\n"; } else { os << " li t4, " << caller_offset << "\n"; - os << " add t4, sp, t4\n"; + os << " add t4, s0, t4\n"; os << " ld " << PhysRegName(ops[0].GetReg()) << ", 0(t4)\n"; } // 再存入本地槽 @@ -315,7 +315,10 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) { os << " lw " << PhysRegName(ops.at(0).GetReg()) << ", 0(" << PhysRegName(ops.at(1).GetReg()) << ")\n"; break; - + case Opcode::LoadIndirectFloat: + os << " flw " << PhysRegName(ops[0].GetReg()) << ", 0(" + << PhysRegName(ops[1].GetReg()) << ")\n"; + break; case Opcode::Call: { std::string func_name = "memset"; // 默认值 if (!ops.empty() && ops[0].GetKind() == Operand::Kind::Func) { @@ -350,7 +353,10 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) { os << " sw " << PhysRegName(ops.at(0).GetReg()) << ", 0(" << PhysRegName(ops.at(1).GetReg()) << ")\n"; break; - + case Opcode::StoreIndirectFloat: + os << " fsw " << PhysRegName(ops[0].GetReg()) << ", 0(" + << PhysRegName(ops[1].GetReg()) << ")\n"; + break; case Opcode::Ret:{ // 恢复 ra 和 s0 int ra_offset = local_vars; diff --git a/src/mir/Lowering.cpp b/src/mir/Lowering.cpp index d93e3c9..10429f7 100644 --- a/src/mir/Lowering.cpp +++ b/src/mir/Lowering.cpp @@ -203,24 +203,35 @@ void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& funct case ir::Opcode::Store: { auto& store = static_cast(inst); // 如果指针是 GEP,手动生成地址并 store,避免额外计算 - if (auto* gep = dynamic_cast(store.GetPtr())) { - // 值 -> T2 - EmitValueToReg(store.GetValue(), PhysReg::T2, slots, block); - // 基址 -> T0 (for_address=true) + 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); + } else { + // 整数值加载到 T2 + EmitValueToReg(store.GetValue(), PhysReg::T2, slots, block); + } + + // 计算基址 + 索引*4 EmitValueToReg(gep->GetBasePtr(), PhysReg::T0, slots, block, 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); } - // 左移2位 -> 乘4 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)}); - // store - block.Append(Opcode::StoreIndirect, {Operand::Reg(PhysReg::T2), Operand::Reg(PhysReg::T0)}); + + // 使用正确的间接存储操作码 + 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())) { @@ -240,10 +251,10 @@ void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& funct case ir::Opcode::Load: { auto& load = static_cast(inst); - if (auto* gep = dynamic_cast(load.GetPtr())) { - // 基址 -> T0 + if (auto* gep = dynamic_cast(load.GetPtr())) { + // 计算地址到 T0 EmitValueToReg(gep->GetBasePtr(), PhysReg::T0, slots, block, true); - // 索引 -> T1 + 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)}); @@ -252,10 +263,19 @@ void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& funct } 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)}); - // load 到 T0,然后存储到新槽 - block.Append(Opcode::LoadIndirect, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T0)}); + + bool load_is_float = load.GetType()->IsFloat32(); int dst_slot = function.CreateFrameIndex(4); - StoreRegToSlot(PhysReg::T0, dst_slot, block, false); + + 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; } @@ -692,7 +712,7 @@ std::unique_ptr LowerFunctionToMIR(const ir::Function& func) { slots[arg] = slot; } - + // 第一遍:创建所有 IR 基本块对应的 MIR 基本块 for (const auto& ir_block : func.GetBlocks()) { GetOrCreateBlock(ir_block.get(), *machine_func);