static bool fnmsubs(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.frC]); a.mulsd(a.xmm0, a.xmm1); a.movq(a.xmm1, a.ppcfpr[instr.frB]); a.subsd(a.xmm0, a.xmm1); a.mov(a.zax, UINT64_C(0x8000000000000000)); a.movq(a.xmm1, a.zax); a.pxor(a.xmm0, a.xmm1); a.cvtsd2ss(a.xmm1, a.xmm0); a.cvtss2sd(a.xmm0, a.xmm1); a.movq(a.ppcfpr[instr.frD], a.xmm0); return true; }
static void negateXmmSd(PPCEmuAssembler& a, const PPCEmuAssembler::XmmRegister& reg) { auto maskGp = a.allocGpTmp(); auto maskXmm = a.allocXmmTmp(); a.mov(maskGp, UINT64_C(0x8000000000000000)); a.movq(maskXmm, maskGp); a.pxor(reg, maskXmm); }
static bool fsel(PPCEmuAssembler& a, Instruction instr) { auto dst = a.loadRegisterWrite(a.fprps[instr.frD]); auto srcB = a.loadRegisterRead(a.fprps[instr.frB]); auto srcC = a.loadRegisterRead(a.fprps[instr.frC]); auto tmp = a.allocXmmTmp(); a.pxor(tmp, tmp); constexpr auto NLE_US = 6; a.cmpsd(tmp, a.loadRegisterRead(a.fprps[instr.frA]), NLE_US); auto tmp2 = a.allocXmmTmp(); a.movapd(tmp2, tmp); a.pand(tmp, srcB); a.pandn(tmp2, srcC); a.por(tmp2, tmp); a.movsd(dst, tmp2); return true; }