(mir)修复寄存器重用冲突错误和浮点比较逻辑

mxr 3 weeks ago
parent d0ecc5c2e9
commit fdeb3fc66e

@ -177,16 +177,16 @@ void EmitValueToReg(const ir::Value* value, PhysReg target,
// 同样需要对 int_val 进行大立即数分解
if (isLegalMovImm(int_val)) {
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(static_cast<int64_t>(int_val))});
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W17), Operand::Imm(static_cast<int64_t>(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)});
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W17), Operand::Imm(low)});
if (high != 0) {
block.Append(Opcode::Movk, {Operand::Reg(PhysReg::W8), Operand::Imm(high), Operand::Imm(16)});
block.Append(Opcode::Movk, {Operand::Reg(PhysReg::W17), Operand::Imm(high), Operand::Imm(16)});
}
}
block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(slot)});
block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W17), Operand::FrameIndex(slot)});
const_cast<ValueSlotMap&>(slots).emplace(value, slot);
} else {
slot = it->second;
@ -551,18 +551,33 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
case ir::Opcode::FCmp: {
auto& fcmp = static_cast<const ir::FcmpInst&>(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 作为结果
// 获取条件码(假设仅处理有序比较,无 NaN
bool isOrdered;
CondCode cc = FcmpToCondCode(fcmp.GetPredicate(), isOrdered);
// 对于无序比较,当前测试用例未涉及,可暂不支持或报错
// 使用 CSET 模式
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(1)});
block.Append(Opcode::StoreStack,
{Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W9), Operand::Imm(0)});
std::string true_label = ".L_fcset_true_" + std::to_string(reinterpret_cast<uintptr_t>(&fcmp));
std::string end_label = ".L_fcset_end_" + std::to_string(reinterpret_cast<uintptr_t>(&fcmp));
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;
}

Loading…
Cancel
Save