static bool fpArithGeneric(PPCEmuAssembler& a, Instruction instr) { if (instr.rc) { return jit_fallback(a, instr); } // FPSCR, FPRF supposed to be updated here... auto tmpSrcA = a.allocXmmTmp(a.loadRegisterRead(a.fprps[instr.frA])); switch (op) { case FPAdd: { auto srcB = a.loadRegisterRead(a.fprps[instr.frB]); a.addsd(tmpSrcA, srcB); break; } case FPSub: { auto srcB = a.loadRegisterRead(a.fprps[instr.frB]); a.subsd(tmpSrcA, srcB); break; } case FPMul: { auto tmpSrcC = a.allocXmmTmp(a.loadRegisterRead(a.fprps[instr.frC])); if (ShouldRound) { // PPC has this weird behaviour with fmuls where it truncates the // RHS operator to 24-bits of mantissa before multiplying... roundTo24BitSd(a, tmpSrcC); } a.mulsd(tmpSrcA, tmpSrcC); break; } case FPDiv: { auto srcB = a.loadRegisterRead(a.fprps[instr.frB]); a.divsd(tmpSrcA, srcB); break; } } if (ShouldRound) { roundToSingleSd(a, tmpSrcA, tmpSrcA); auto dst = a.loadRegisterWrite(a.fprps[instr.frD]); a.movddup(dst, tmpSrcA); } else { auto dst = a.loadRegisterReadWrite(a.fprps[instr.frD]); a.movsd(dst, tmpSrcA); } return true; }
static bool fdiv(PPCEmuAssembler& a, Instruction instr) { if (instr.rc) { return jit_fallback(a, instr); } // FPSCR, FPRF supposed to be updated here... a.movq(a.xmm0, a.ppcfpr[instr.frA]); a.movq(a.xmm1, a.ppcfpr[instr.frB]); a.divsd(a.xmm0, a.xmm1); a.movq(a.ppcfpr[instr.frD], a.xmm0); return true; }