fix(mir):修复浮点数的错误

develop
cy 3 days ago
parent 8ce783c967
commit f4658ec3fa

@ -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 {

@ -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;

@ -203,24 +203,35 @@ void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& funct
case ir::Opcode::Store: {
auto& store = static_cast<const ir::StoreInst&>(inst);
// 如果指针是 GEP手动生成地址并 store避免额外计算
if (auto* gep = dynamic_cast<const ir::GepInst*>(store.GetPtr())) {
// 值 -> T2
EmitValueToReg(store.GetValue(), PhysReg::T2, slots, block);
// 基址 -> T0 (for_address=true)
if (auto* gep = dynamic_cast<const ir::GepInst*>(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<const ir::GlobalVariable*>(store.GetPtr())) {
@ -240,10 +251,10 @@ void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& funct
case ir::Opcode::Load: {
auto& load = static_cast<const ir::LoadInst&>(inst);
if (auto* gep = dynamic_cast<const ir::GepInst*>(load.GetPtr())) {
// 基址 -> T0
if (auto* gep = dynamic_cast<const ir::GepInst*>(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<MachineFunction> LowerFunctionToMIR(const ir::Function& func) {
slots[arg] = slot;
}
// 第一遍:创建所有 IR 基本块对应的 MIR 基本块
for (const auto& ir_block : func.GetBlocks()) {
GetOrCreateBlock(ir_block.get(), *machine_func);

Loading…
Cancel
Save