From 05360d5c7a186cbf5d7d86cb2b98348d00012c5d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 24 Jul 2023 22:58:23 -0700 Subject: [PATCH] riscv: Implement simplest float ops. --- Core/MIPS/IR/IRInterpreter.cpp | 2 ++ Core/MIPS/RiscV/RiscVCompFPU.cpp | 36 ++++++++++++++++++++++++++++- Core/MIPS/RiscV/RiscVCompSystem.cpp | 26 ++++++++++++++++++--- 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/Core/MIPS/IR/IRInterpreter.cpp b/Core/MIPS/IR/IRInterpreter.cpp index 5b858bc1b3..7f576dd4ea 100644 --- a/Core/MIPS/IR/IRInterpreter.cpp +++ b/Core/MIPS/IR/IRInterpreter.cpp @@ -768,9 +768,11 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, int count) { mips->f[inst->dest] = mips->f[inst->src1] / mips->f[inst->src2]; break; case IROp::FMin: + // TODO: This doesn't handle VFPU ordering right. mips->f[inst->dest] = std::min(mips->f[inst->src1], mips->f[inst->src2]); break; case IROp::FMax: + // TODO: This doesn't handle VFPU ordering right. mips->f[inst->dest] = std::max(mips->f[inst->src1], mips->f[inst->src2]); break; diff --git a/Core/MIPS/RiscV/RiscVCompFPU.cpp b/Core/MIPS/RiscV/RiscVCompFPU.cpp index 25d4799a30..f8f1f1cae7 100644 --- a/Core/MIPS/RiscV/RiscVCompFPU.cpp +++ b/Core/MIPS/RiscV/RiscVCompFPU.cpp @@ -39,12 +39,37 @@ void RiscVJit::CompIR_FArith(IRInst inst) { switch (inst.op) { case IROp::FAdd: + fpr.MapDirtyInIn(inst.dest, inst.src1, inst.src2); + FADD(32, fpr.R(inst.dest), fpr.R(inst.src1), fpr.R(inst.src2)); + break; + case IROp::FSub: + fpr.MapDirtyInIn(inst.dest, inst.src1, inst.src2); + FSUB(32, fpr.R(inst.dest), fpr.R(inst.src1), fpr.R(inst.src2)); + break; + case IROp::FMul: + fpr.MapDirtyInIn(inst.dest, inst.src1, inst.src2); + if (inst.src1 != inst.src2) { + CompIR_Generic(inst); + } else { + FMUL(32, fpr.R(inst.dest), fpr.R(inst.src1), fpr.R(inst.src2)); + } + break; + case IROp::FDiv: + fpr.MapDirtyInIn(inst.dest, inst.src1, inst.src2); + FDIV(32, fpr.R(inst.dest), fpr.R(inst.src1), fpr.R(inst.src2)); + break; + case IROp::FSqrt: + fpr.MapDirtyIn(inst.dest, inst.src1); + FSQRT(32, fpr.R(inst.dest), fpr.R(inst.src1)); + break; + case IROp::FNeg: - CompIR_Generic(inst); + fpr.MapDirtyIn(inst.dest, inst.src1); + FNEG(32, fpr.R(inst.dest), fpr.R(inst.src1)); break; default: @@ -59,6 +84,7 @@ void RiscVJit::CompIR_FCondAssign(IRInst inst) { switch (inst.op) { case IROp::FMin: case IROp::FMax: + // TODO: These are tricky, have to handle order correctly. CompIR_Generic(inst); break; @@ -73,7 +99,15 @@ void RiscVJit::CompIR_FAssign(IRInst inst) { switch (inst.op) { case IROp::FMov: + fpr.MapDirtyIn(inst.dest, inst.src1); + FMV(32, fpr.R(inst.dest), fpr.R(inst.src1)); + break; + case IROp::FAbs: + fpr.MapDirtyIn(inst.dest, inst.src1); + FABS(32, fpr.R(inst.dest), fpr.R(inst.src1)); + break; + case IROp::FSign: CompIR_Generic(inst); break; diff --git a/Core/MIPS/RiscV/RiscVCompSystem.cpp b/Core/MIPS/RiscV/RiscVCompSystem.cpp index 10486adf2d..8a8b995f5f 100644 --- a/Core/MIPS/RiscV/RiscVCompSystem.cpp +++ b/Core/MIPS/RiscV/RiscVCompSystem.cpp @@ -50,7 +50,14 @@ void RiscVJit::CompIR_Basic(IRInst inst) { break; case IROp::SetConstF: - CompIR_Generic(inst); + fpr.MapReg(inst.dest, MIPSMap::NOINIT); + if (inst.constant == 0) { + FCVT(FConv::S, FConv::W, fpr.R(inst.dest), R_ZERO); + } else { + // TODO: In the future, could use FLI if it's approved. + LI(SCRATCH1, (int32_t)inst.constant); + FMV(FMv::W, FMv::X, fpr.R(inst.dest), SCRATCH1); + } break; case IROp::Downcount: @@ -93,7 +100,9 @@ void RiscVJit::CompIR_Transfer(IRInst inst) { break; case IROp::SetCtrlVFPUFReg: - CompIR_Generic(inst); + gpr.MapReg(IRREG_VFPU_CTRL_BASE + inst.dest, MIPSMap::NOINIT); + fpr.MapReg(inst.src1); + FMV(FMv::X, FMv::W, gpr.R(IRREG_VFPU_CTRL_BASE + inst.dest), fpr.R(inst.src1)); break; case IROp::FpCondToReg: @@ -113,8 +122,19 @@ void RiscVJit::CompIR_Transfer(IRInst inst) { break; case IROp::FMovFromGPR: + fpr.MapReg(inst.dest, MIPSMap::NOINIT); + if (gpr.IsImm(inst.src1) && gpr.GetImm(inst.src1) == 0) { + FCVT(FConv::S, FConv::W, fpr.R(inst.dest), R_ZERO); + } else { + gpr.MapReg(inst.src1); + FMV(FMv::W, FMv::X, fpr.R(inst.dest), gpr.R(inst.src1)); + } + break; + case IROp::FMovToGPR: - CompIR_Generic(inst); + gpr.MapReg(inst.dest, MIPSMap::NOINIT); + fpr.MapReg(inst.src1); + FMV(FMv::X, FMv::W, gpr.R(inst.dest), fpr.R(inst.src1)); break; default: