Example #1
0
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;
}
Example #2
0
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);
}
Example #3
0
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;
}