void recMFSA() { int mmreg; if (!_Rd_) return; mmreg = _checkXMMreg(XMMTYPE_GPRREG, _Rd_, MODE_WRITE); if( mmreg >= 0 ) { xMOVL.PS(xRegisterSSE(mmreg), ptr[&cpuRegs.sa]); } else if( (mmreg = _checkMMXreg(MMX_GPR+_Rd_, MODE_WRITE)) >= 0 ) { xMOVDZX(xRegisterMMX(mmreg), ptr[&cpuRegs.sa]); SetMMXstate(); } else { xMOV(eax, ptr[&cpuRegs.sa]); _deleteEEreg(_Rd_, 0); xMOV(ptr[&cpuRegs.GPR.r[_Rd_].UL[0]], eax); xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[1]], 0); } }
void recMFSA( void ) { int mmreg; if (!_Rd_) return; mmreg = _checkXMMreg(XMMTYPE_GPRREG, _Rd_, MODE_WRITE); if( mmreg >= 0 ) { SSE_MOVLPS_M64_to_XMM(mmreg, (uptr)&cpuRegs.sa); } else if( (mmreg = _checkMMXreg(MMX_GPR+_Rd_, MODE_WRITE)) >= 0 ) { MOVDMtoMMX(mmreg, (uptr)&cpuRegs.sa); SetMMXstate(); } else { MOV32MtoR(EAX, (u32)&cpuRegs.sa); _deleteEEreg(_Rd_, 0); MOV32RtoM((uptr)&cpuRegs.GPR.r[_Rd_].UL[0], EAX); MOV32ItoM((uptr)&cpuRegs.GPR.r[_Rd_].UL[1], 0); } }
// SA is 4-bit and contains the amount of bytes to shift void recMTSA() { if( GPR_IS_CONST1(_Rs_) ) { xMOV(ptr32[&cpuRegs.sa], g_cpuConstRegs[_Rs_].UL[0] & 0xf ); } else { int mmreg; if( (mmreg = _checkXMMreg(XMMTYPE_GPRREG, _Rs_, MODE_READ)) >= 0 ) { xMOVSS(ptr[&cpuRegs.sa], xRegisterSSE(mmreg)); } else if( (mmreg = _checkMMXreg(MMX_GPR+_Rs_, MODE_READ)) >= 0 ) { xMOVD(ptr[&cpuRegs.sa], xRegisterMMX(mmreg)); SetMMXstate(); } else { xMOV(eax, ptr[&cpuRegs.GPR.r[_Rs_].UL[0]]); xMOV(ptr[&cpuRegs.sa], eax); } xAND(ptr32[&cpuRegs.sa], 0xf); } }
// SA is 4-bit and contains the amount of bytes to shift void recMTSA( void ) { if( GPR_IS_CONST1(_Rs_) ) { MOV32ItoM((uptr)&cpuRegs.sa, g_cpuConstRegs[_Rs_].UL[0] & 0xf ); } else { int mmreg; if( (mmreg = _checkXMMreg(XMMTYPE_GPRREG, _Rs_, MODE_READ)) >= 0 ) { SSE_MOVSS_XMM_to_M32((uptr)&cpuRegs.sa, mmreg); } else if( (mmreg = _checkMMXreg(MMX_GPR+_Rs_, MODE_READ)) >= 0 ) { MOVDMMXtoM((uptr)&cpuRegs.sa, mmreg); SetMMXstate(); } else { MOV32MtoR(EAX, (uptr)&cpuRegs.GPR.r[_Rs_].UL[0]); MOV32RtoM((uptr)&cpuRegs.sa, EAX); } AND32ItoM((uptr)&cpuRegs.sa, 0xf); } }
int _allocGPRtoXMMreg(int xmmreg, int gprreg, int mode) { int i; for (i=0; (uint)i<iREGCNT_XMM; i++) { if (xmmregs[i].inuse == 0) continue; if (xmmregs[i].type != XMMTYPE_GPRREG) continue; if (xmmregs[i].reg != gprreg) continue; pxAssert( _checkMMXreg(MMX_GPR|gprreg, mode) == -1 ); g_xmmtypes[i] = XMMT_INT; if (!(xmmregs[i].mode & MODE_READ) && (mode & MODE_READ)) { if (gprreg == 0 ) { SSEX_PXOR_XMM_to_XMM(i, i); } else { //pxAssert( !(g_cpuHasConstReg & (1<<gprreg)) || (g_cpuFlushedConstReg & (1<<gprreg)) ); _flushConstReg(gprreg); SSEX_MOVDQA_M128_to_XMM(i, (uptr)&cpuRegs.GPR.r[gprreg].UL[0]); } xmmregs[i].mode |= MODE_READ; } if ((mode & MODE_WRITE) && (gprreg < 32)) { g_cpuHasConstReg &= ~(1<<gprreg); //pxAssert( !(g_cpuHasConstReg & (1<<gprreg)) ); } xmmregs[i].counter = g_xmmAllocCounter++; // update counter xmmregs[i].needed = 1; xmmregs[i].mode|= mode; return i; } // currently only gpr regs are const // fixme - do we really need to execute this both here and in the loop? if ((mode & MODE_WRITE) && gprreg < 32) { //pxAssert( !(g_cpuHasConstReg & (1<<gprreg)) ); g_cpuHasConstReg &= ~(1<<gprreg); } if (xmmreg == -1) xmmreg = _getFreeXMMreg(); g_xmmtypes[xmmreg] = XMMT_INT; xmmregs[xmmreg].inuse = 1; xmmregs[xmmreg].type = XMMTYPE_GPRREG; xmmregs[xmmreg].reg = gprreg; xmmregs[xmmreg].mode = mode; xmmregs[xmmreg].needed = 1; xmmregs[xmmreg].counter = g_xmmAllocCounter++; if (mode & MODE_READ) { if (gprreg == 0 ) { SSEX_PXOR_XMM_to_XMM(xmmreg, xmmreg); } else { // DOX86 int mmxreg; if (mode & MODE_READ) _flushConstReg(gprreg); mmxreg = _checkMMXreg(MMX_GPR+gprreg, 0); if (mmxreg >= 0 ) { // transfer SetMMXstate(); SSE2_MOVQ2DQ_MM_to_XMM(xmmreg, mmxreg); SSE2_PUNPCKLQDQ_XMM_to_XMM(xmmreg, xmmreg); SSE2_PUNPCKHQDQ_M128_to_XMM(xmmreg, (u32)&cpuRegs.GPR.r[gprreg].UL[0]); if (mmxregs[mmxreg].mode & MODE_WRITE ) { // instead of setting to write, just flush to mem if (!(mode & MODE_WRITE)) { SetMMXstate(); MOVQRtoM((u32)&cpuRegs.GPR.r[gprreg].UL[0], mmxreg); } //xmmregs[xmmreg].mode |= MODE_WRITE; } // don't flush mmxregs[mmxreg].inuse = 0; } else SSEX_MOVDQA_M128_to_XMM(xmmreg, (uptr)&cpuRegs.GPR.r[gprreg].UL[0]); } } else _deleteMMXreg(MMX_GPR+gprreg, 0); return xmmreg; }