diff --git a/Core/MIPS/RiscV/RiscVCompFPU.cpp b/Core/MIPS/RiscV/RiscVCompFPU.cpp index 9d08930848..3be4d1149d 100644 --- a/Core/MIPS/RiscV/RiscVCompFPU.cpp +++ b/Core/MIPS/RiscV/RiscVCompFPU.cpp @@ -220,6 +220,71 @@ void RiscVJit::CompIR_FCompare(IRInst inst) { switch (inst.op) { case IROp::FCmp: + switch (inst.dest) { + case IRFpCompareMode::False: + gpr.SetImm(IRREG_FPCOND, 0); + break; + + case IRFpCompareMode::EitherUnordered: + fpr.MapInIn(inst.src1, inst.src2); + gpr.MapReg(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); + FCLASS(32, SCRATCH1, fpr.R(inst.src1)); + FCLASS(32, SCRATCH2, fpr.R(inst.src2)); + OR(SCRATCH1, SCRATCH1, SCRATCH2); + // NAN is 0x100 or 0x200. + ANDI(SCRATCH1, SCRATCH1, 0x300); + SNEZ(gpr.R(IRREG_FPCOND), SCRATCH1); + break; + + case IRFpCompareMode::EqualOrdered: + fpr.MapInIn(inst.src1, inst.src2); + gpr.MapReg(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); + FEQ(32, gpr.R(IRREG_FPCOND), fpr.R(inst.src1), fpr.R(inst.src2)); + break; + + case IRFpCompareMode::EqualUnordered: + fpr.MapInIn(inst.src1, inst.src2); + gpr.MapReg(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); + FEQ(32, gpr.R(IRREG_FPCOND), fpr.R(inst.src1), fpr.R(inst.src2)); + + // Now let's just OR in the unordered check. + FCLASS(32, SCRATCH1, fpr.R(inst.src1)); + FCLASS(32, SCRATCH2, fpr.R(inst.src2)); + OR(SCRATCH1, SCRATCH1, SCRATCH2); + // NAN is 0x100 or 0x200. + ANDI(SCRATCH1, SCRATCH1, 0x300); + SNEZ(SCRATCH1, SCRATCH1); + OR(gpr.R(IRREG_FPCOND), gpr.R(IRREG_FPCOND), SCRATCH1); + break; + + case IRFpCompareMode::LessEqualOrdered: + fpr.MapInIn(inst.src1, inst.src2); + gpr.MapReg(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); + FLE(32, gpr.R(IRREG_FPCOND), fpr.R(inst.src1), fpr.R(inst.src2)); + break; + + case IRFpCompareMode::LessEqualUnordered: + fpr.MapInIn(inst.src1, inst.src2); + gpr.MapReg(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); + FLT(32, gpr.R(IRREG_FPCOND), fpr.R(inst.src2), fpr.R(inst.src1)); + SEQZ(gpr.R(IRREG_FPCOND), gpr.R(IRREG_FPCOND)); + break; + + case IRFpCompareMode::LessOrdered: + fpr.MapInIn(inst.src1, inst.src2); + gpr.MapReg(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); + FLT(32, gpr.R(IRREG_FPCOND), fpr.R(inst.src1), fpr.R(inst.src2)); + break; + + case IRFpCompareMode::LessUnordered: + fpr.MapInIn(inst.src1, inst.src2); + gpr.MapReg(IRREG_FPCOND, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); + FLE(32, gpr.R(IRREG_FPCOND), fpr.R(inst.src2), fpr.R(inst.src1)); + SEQZ(gpr.R(IRREG_FPCOND), gpr.R(IRREG_FPCOND)); + break; + } + break; + case IROp::FCmovVfpuCC: case IROp::FCmpVfpuBit: case IROp::FCmpVfpuAggregate: diff --git a/Core/MIPS/RiscV/RiscVCompSystem.cpp b/Core/MIPS/RiscV/RiscVCompSystem.cpp index 2413bb55c3..863fbd103d 100644 --- a/Core/MIPS/RiscV/RiscVCompSystem.cpp +++ b/Core/MIPS/RiscV/RiscVCompSystem.cpp @@ -101,7 +101,7 @@ void RiscVJit::CompIR_Transfer(IRInst inst) { break; case IROp::SetCtrlVFPUFReg: - gpr.MapReg(IRREG_VFPU_CTRL_BASE + inst.dest, MIPSMap::NOINIT); + gpr.MapReg(IRREG_VFPU_CTRL_BASE + inst.dest, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); fpr.MapReg(inst.src1); FMV(FMv::X, FMv::W, gpr.R(IRREG_VFPU_CTRL_BASE + inst.dest), fpr.R(inst.src1)); break; @@ -167,7 +167,7 @@ void RiscVJit::CompIR_Transfer(IRInst inst) { break; case IROp::FMovToGPR: - gpr.MapReg(inst.dest, MIPSMap::NOINIT); + gpr.MapReg(inst.dest, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); fpr.MapReg(inst.src1); FMV(FMv::X, FMv::W, gpr.R(inst.dest), fpr.R(inst.src1)); break;