mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
riscv: Implement simplest float ops.
This commit is contained in:
parent
bb6fdd0246
commit
05360d5c7a
3 changed files with 60 additions and 4 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Add table
Reference in a new issue