|
|
|
|
@ -145,6 +145,34 @@ void EmitValueToReg(const ir::Value* value, PhysReg target,
|
|
|
|
|
|
|
|
|
|
if (auto* constant = dynamic_cast<const ir::ConstantInt*>(value)) {
|
|
|
|
|
uint32_t imm = static_cast<uint32_t>(constant->GetValue());
|
|
|
|
|
|
|
|
|
|
// 如果目标是浮点寄存器,将 imm 位模式解释为 float 并加载
|
|
|
|
|
if (target >= PhysReg::S0 && target <= PhysReg::S7) {
|
|
|
|
|
auto it = slots.find(value);
|
|
|
|
|
int slot;
|
|
|
|
|
if (it == slots.end()) {
|
|
|
|
|
slot = function.CreateFrameIndex(4);
|
|
|
|
|
// 将 imm 写入栈槽(与 ConstantFloat 相同方式)
|
|
|
|
|
if (isLegalMovImm(imm)) {
|
|
|
|
|
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(static_cast<int64_t>(imm))});
|
|
|
|
|
} else {
|
|
|
|
|
uint16_t low = imm & 0xFFFF;
|
|
|
|
|
uint16_t high = (imm >> 16) & 0xFFFF;
|
|
|
|
|
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(low)});
|
|
|
|
|
if (high != 0) {
|
|
|
|
|
block.Append(Opcode::Movk, {Operand::Reg(PhysReg::W8), Operand::Imm(high), Operand::Imm(16)});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(slot)});
|
|
|
|
|
const_cast<ValueSlotMap&>(slots).emplace(value, slot);
|
|
|
|
|
} else {
|
|
|
|
|
slot = it->second;
|
|
|
|
|
}
|
|
|
|
|
// 从栈槽加载到浮点目标寄存器
|
|
|
|
|
block.Append(Opcode::LoadStack, {Operand::Reg(target), Operand::FrameIndex(slot)});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isLegalMovImm(imm)) {
|
|
|
|
|
block.Append(Opcode::MovImm,
|
|
|
|
|
{Operand::Reg(target), Operand::Imm(static_cast<int64_t>(imm))});
|
|
|
|
|
@ -181,16 +209,16 @@ void EmitValueToReg(const ir::Value* value, PhysReg target,
|
|
|
|
|
|
|
|
|
|
// 同样需要对 int_val 进行大立即数分解
|
|
|
|
|
if (isLegalMovImm(int_val)) {
|
|
|
|
|
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W17), Operand::Imm(static_cast<int64_t>(int_val))});
|
|
|
|
|
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), 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::W17), Operand::Imm(low)});
|
|
|
|
|
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(low)});
|
|
|
|
|
if (high != 0) {
|
|
|
|
|
block.Append(Opcode::Movk, {Operand::Reg(PhysReg::W17), Operand::Imm(high), Operand::Imm(16)});
|
|
|
|
|
block.Append(Opcode::Movk, {Operand::Reg(PhysReg::W8), Operand::Imm(high), Operand::Imm(16)});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W17), Operand::FrameIndex(slot)});
|
|
|
|
|
block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(slot)});
|
|
|
|
|
const_cast<ValueSlotMap&>(slots).emplace(value, slot);
|
|
|
|
|
} else {
|
|
|
|
|
slot = it->second;
|
|
|
|
|
@ -204,10 +232,26 @@ void EmitValueToReg(const ir::Value* value, PhysReg target,
|
|
|
|
|
// 处理零常量
|
|
|
|
|
if (dynamic_cast<const ir::ConstantZero*>(value) ||
|
|
|
|
|
dynamic_cast<const ir::ConstantAggregateZero*>(value)) {
|
|
|
|
|
// 零常量:直接加载 0
|
|
|
|
|
block.Append(Opcode::MovImm,
|
|
|
|
|
{Operand::Reg(target), Operand::Imm(0)});
|
|
|
|
|
return;
|
|
|
|
|
// 如果目标是浮点寄存器,必须通过栈槽加载 0.0f 的位模式
|
|
|
|
|
if (target >= PhysReg::S0 && target <= PhysReg::S7) {
|
|
|
|
|
auto it = slots.find(value);
|
|
|
|
|
int slot;
|
|
|
|
|
if (it == slots.end()) {
|
|
|
|
|
slot = function.CreateFrameIndex(4);
|
|
|
|
|
// 写入 0
|
|
|
|
|
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(0)});
|
|
|
|
|
block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(slot)});
|
|
|
|
|
const_cast<ValueSlotMap&>(slots).emplace(value, slot);
|
|
|
|
|
} else {
|
|
|
|
|
slot = it->second;
|
|
|
|
|
}
|
|
|
|
|
// 加载到浮点寄存器
|
|
|
|
|
block.Append(Opcode::LoadStack, {Operand::Reg(target), Operand::FrameIndex(slot)});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// 原有的整数/指针零常量处理保持不变
|
|
|
|
|
block.Append(Opcode::MovImm, {Operand::Reg(target), Operand::Imm(0)});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ========== 处理全局变量 ==========
|
|
|
|
|
@ -415,6 +459,16 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
|
|
|
|
|
|
|
|
|
case ir::Opcode::Sub: {
|
|
|
|
|
auto& bin = static_cast<const ir::BinaryInst&>(inst);
|
|
|
|
|
// 如果两个操作数都是浮点类型,则使用浮点减法
|
|
|
|
|
if (bin.GetLhs()->GetType()->IsFloat() && bin.GetRhs()->GetType()->IsFloat()) {
|
|
|
|
|
int dst_slot = function.CreateFrameIndex(4);
|
|
|
|
|
EmitValueToReg(bin.GetLhs(), PhysReg::S0, slots, block, function);
|
|
|
|
|
EmitValueToReg(bin.GetRhs(), PhysReg::S1, slots, block, function);
|
|
|
|
|
block.Append(Opcode::FSubRR, {Operand::Reg(PhysReg::S0), Operand::Reg(PhysReg::S0), Operand::Reg(PhysReg::S1)});
|
|
|
|
|
block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::S0), Operand::FrameIndex(dst_slot)});
|
|
|
|
|
slots.emplace(&inst, dst_slot);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const ir::Type* lhsTy = bin.GetLhs()->GetType().get();
|
|
|
|
|
const ir::Type* rhsTy = bin.GetRhs()->GetType().get();
|
|
|
|
|
const ir::Type* resultTy = inst.GetType().get();
|
|
|
|
|
@ -694,37 +748,43 @@ 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()));
|
|
|
|
|
auto& fcmp = static_cast<const ir::FcmpInst&>(inst);
|
|
|
|
|
int dst_slot = function.CreateFrameIndex(4); // 结果是 i1(4字节)
|
|
|
|
|
|
|
|
|
|
// 加载浮点操作数到 s0, s1
|
|
|
|
|
EmitValueToReg(fcmp.GetLhs(), PhysReg::S0, slots, block, function);
|
|
|
|
|
EmitValueToReg(fcmp.GetRhs(), PhysReg::S1, slots, block, function);
|
|
|
|
|
// 1. 加载浮点操作数并比较
|
|
|
|
|
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)});
|
|
|
|
|
|
|
|
|
|
// 生成浮点比较指令
|
|
|
|
|
block.Append(Opcode::FCmpRR, {Operand::Reg(PhysReg::S0), Operand::Reg(PhysReg::S1)});
|
|
|
|
|
// 2. 获取有序/无序标志和条件码
|
|
|
|
|
bool isOrdered;
|
|
|
|
|
CondCode cc = FcmpToCondCode(fcmp.GetPredicate(), isOrdered);
|
|
|
|
|
|
|
|
|
|
// 获取条件码(假设仅处理有序比较,无 NaN)
|
|
|
|
|
bool isOrdered;
|
|
|
|
|
CondCode cc = FcmpToCondCode(fcmp.GetPredicate(), isOrdered);
|
|
|
|
|
// 对于无序比较,当前测试用例未涉及,可暂不支持或报错
|
|
|
|
|
// 3. 结果预设为 0
|
|
|
|
|
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(0)});
|
|
|
|
|
|
|
|
|
|
// 使用 CSET 模式
|
|
|
|
|
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(1)});
|
|
|
|
|
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W9), Operand::Imm(0)});
|
|
|
|
|
// 4. 生成标签
|
|
|
|
|
std::string set1_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));
|
|
|
|
|
|
|
|
|
|
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));
|
|
|
|
|
// 5. 处理 NaN 情况
|
|
|
|
|
block.Append(Opcode::BCond, {Operand::Cond(CondCode::VS), Operand::Label(end_label)});
|
|
|
|
|
|
|
|
|
|
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)});
|
|
|
|
|
// 6. 正常条件跳转
|
|
|
|
|
block.Append(Opcode::BCond, {Operand::Cond(cc), Operand::Label(set1_label)});
|
|
|
|
|
|
|
|
|
|
block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst_slot)});
|
|
|
|
|
slots.emplace(&inst, dst_slot);
|
|
|
|
|
return;
|
|
|
|
|
// 7. 无条件到结束
|
|
|
|
|
block.Append(Opcode::B, {Operand::Label(end_label)});
|
|
|
|
|
|
|
|
|
|
// 8. 置 1 标签
|
|
|
|
|
block.Append(Opcode::Label, {Operand::Label(set1_label)});
|
|
|
|
|
block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::W8), Operand::Imm(1)});
|
|
|
|
|
|
|
|
|
|
// 9. 结束标签并存储结果
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
// ========== 跳转指令(使用标签操作数)==========
|
|
|
|
|
case ir::Opcode::Br: {
|
|
|
|
|
|