[backend]将浮点逻辑改为与开发板一致
This commit is contained in:
@ -745,12 +745,83 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
||||
CurMBB->addInstruction(std::move(instr));
|
||||
break;
|
||||
}
|
||||
case Instruction::kFtoI: { // 浮点 to 整数 (使用硬件指令进行向零截断)
|
||||
// 直接生成一条带有 rtz 舍入模式的转换指令
|
||||
auto instr = std::make_unique<MachineInstr>(RVOpcodes::FCVT_W_S_RTZ);
|
||||
instr->addOperand(std::make_unique<RegOperand>(dest_vreg)); // 目标是整数vreg
|
||||
instr->addOperand(std::make_unique<RegOperand>(src_vreg)); // 源是浮点vreg
|
||||
CurMBB->addInstruction(std::move(instr));
|
||||
case Instruction::kFtoI: { // 浮点 to 整数 (带向下取整)
|
||||
// 目标:实现 floor(x) 的效果, C/C++中浮点转整数是截断(truncate)
|
||||
// 对于正数,floor(x) == truncate(x)
|
||||
// RISC-V的 fcvt.w.s 默认是“四舍五入到偶数”
|
||||
// 我们需要手动实现截断逻辑
|
||||
// 逻辑:
|
||||
// temp_i = fcvt.w.s(x) // 四舍五入
|
||||
// temp_f = fcvt.s.w(temp_i) // 转回浮点
|
||||
// if (x < temp_f) { // 如果原数更小,说明被“五入”了
|
||||
// result = temp_i - 1
|
||||
// } else {
|
||||
// result = temp_i
|
||||
// }
|
||||
|
||||
auto temp_i_vreg = getNewVReg(Type::getIntType());
|
||||
auto temp_f_vreg = getNewVReg(Type::getFloatType());
|
||||
auto cmp_vreg = getNewVReg(Type::getIntType());
|
||||
|
||||
// 1. fcvt.w.s temp_i_vreg, src_vreg
|
||||
auto fcvt_w = std::make_unique<MachineInstr>(RVOpcodes::FCVT_W_S);
|
||||
fcvt_w->addOperand(std::make_unique<RegOperand>(temp_i_vreg));
|
||||
fcvt_w->addOperand(std::make_unique<RegOperand>(src_vreg));
|
||||
CurMBB->addInstruction(std::move(fcvt_w));
|
||||
|
||||
// 2. fcvt.s.w temp_f_vreg, temp_i_vreg
|
||||
auto fcvt_s = std::make_unique<MachineInstr>(RVOpcodes::FCVT_S_W);
|
||||
fcvt_s->addOperand(std::make_unique<RegOperand>(temp_f_vreg));
|
||||
fcvt_s->addOperand(std::make_unique<RegOperand>(temp_i_vreg));
|
||||
CurMBB->addInstruction(std::move(fcvt_s));
|
||||
|
||||
// 3. flt.s cmp_vreg, src_vreg, temp_f_vreg
|
||||
auto flt = std::make_unique<MachineInstr>(RVOpcodes::FLT_S);
|
||||
flt->addOperand(std::make_unique<RegOperand>(cmp_vreg));
|
||||
flt->addOperand(std::make_unique<RegOperand>(src_vreg));
|
||||
flt->addOperand(std::make_unique<RegOperand>(temp_f_vreg));
|
||||
CurMBB->addInstruction(std::move(flt));
|
||||
|
||||
// 创建标签
|
||||
int unique_id = this->local_label_counter++;
|
||||
std::string rounded_up_label = MFunc->getName() + "_ftoi_rounded_up_" + std::to_string(unique_id);
|
||||
std::string done_label = MFunc->getName() + "_ftoi_done_" + std::to_string(unique_id);
|
||||
|
||||
// 4. bne cmp_vreg, x0, rounded_up_label
|
||||
auto bne = std::make_unique<MachineInstr>(RVOpcodes::BNE);
|
||||
bne->addOperand(std::make_unique<RegOperand>(cmp_vreg));
|
||||
bne->addOperand(std::make_unique<RegOperand>(PhysicalReg::ZERO));
|
||||
bne->addOperand(std::make_unique<LabelOperand>(rounded_up_label));
|
||||
CurMBB->addInstruction(std::move(bne));
|
||||
|
||||
// 5. else 分支: mv dest_vreg, temp_i_vreg
|
||||
auto mv = std::make_unique<MachineInstr>(RVOpcodes::MV);
|
||||
mv->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
||||
mv->addOperand(std::make_unique<RegOperand>(temp_i_vreg));
|
||||
CurMBB->addInstruction(std::move(mv));
|
||||
|
||||
// 6. j done_label
|
||||
auto j = std::make_unique<MachineInstr>(RVOpcodes::J);
|
||||
j->addOperand(std::make_unique<LabelOperand>(done_label));
|
||||
CurMBB->addInstruction(std::move(j));
|
||||
|
||||
// 7. rounded_up_label:
|
||||
auto label_up = std::make_unique<MachineInstr>(RVOpcodes::LABEL);
|
||||
label_up->addOperand(std::make_unique<LabelOperand>(rounded_up_label));
|
||||
CurMBB->addInstruction(std::move(label_up));
|
||||
|
||||
// 8. addiw dest_vreg, temp_i_vreg, -1
|
||||
auto addi = std::make_unique<MachineInstr>(RVOpcodes::ADDIW);
|
||||
addi->addOperand(std::make_unique<RegOperand>(dest_vreg));
|
||||
addi->addOperand(std::make_unique<RegOperand>(temp_i_vreg));
|
||||
addi->addOperand(std::make_unique<ImmOperand>(-1));
|
||||
CurMBB->addInstruction(std::move(addi));
|
||||
|
||||
// 9. done_label:
|
||||
auto label_done = std::make_unique<MachineInstr>(RVOpcodes::LABEL);
|
||||
label_done->addOperand(std::make_unique<LabelOperand>(done_label));
|
||||
CurMBB->addInstruction(std::move(label_done));
|
||||
|
||||
break;
|
||||
}
|
||||
case Instruction::kFNeg: { // 浮点取负
|
||||
|
||||
Reference in New Issue
Block a user