@@ -745,82 +745,28 @@ void RISCv64ISel::selectNode(DAGNode* node) {
CurMBB - > addInstruction ( std : : move ( instr ) ) ;
break ;
}
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
// }
case Instruction : : kFtoI : { // 浮点 to 整数 (C/C++: 截断 )
// C/C++ 标准要求向零 截断 (truncate), 对应的RISC-V舍入模式是 RTZ (Round Towards Zero).
// fcvt.w.s 指令使用 fcsr 中的 frm 字段来决定舍入模式。
// 我们需要手动设置 frm=1 (RTZ), 执行转换, 然后恢复 frm=0 (RNE, 默认).
auto temp_i_vreg = getNewVReg ( Type : : getIntType ( ) ) ;
auto temp_f_vreg = getNewVReg ( Type : : getFloatType ( ) ) ;
auto cmp_vreg = getNewVReg ( Type : : getIntType ( ) ) ;
// 1. fsrmi x0, 1 (set rounding mode to RTZ)
auto fsrmi1 = std : : make_unique < MachineInstr > ( RVOpcodes : : FSRMI ) ;
fsrmi1 - > addOperand ( std : : make_unique < RegOperand > ( PhysicalReg : : ZERO ) ) ;
fsrmi1 - > addOperand ( std : : make_unique < ImmOperand > ( 1 ) ) ;
CurMBB - > addInstruction ( std : : move ( fsrmi1 ) ) ;
// 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.w.s dest _vreg, src_vreg
auto fcvt = std : : make_unique < MachineInstr > ( RVOpcodes : : FCVT_W_S ) ;
fcvt - > addOperand ( std : : make_unique < RegOperand > ( dest _vreg) ) ;
fcvt - > addOperand ( std : : make_unique < RegOperand > ( src_vreg ) ) ;
CurMBB - > addInstruction ( std : : move ( fcvt ) ) ;
// 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 < Reg Operand> ( 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 ) ) ;
// 3 . fsrmi x0, 0 (restore rounding mode to RNE)
auto fsrmi0 = std : : make_unique < MachineInstr > ( RVOpcodes : : FSRMI ) ;
fsrmi0 - > addOperand ( std : : make_unique < RegOperand > ( PhysicalReg : : ZERO ) ) ;
fsrmi0 - > addOperand ( std : : make_unique < Imm Operand> ( 0 ) ) ;
CurMBB - > addInstruction ( std : : move ( fsrmi0 ) ) ;
break ;
}