Ejemplo n.º 1
0
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);
	}
}
Ejemplo n.º 2
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);
	}
}
Ejemplo n.º 3
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);
	}
}
Ejemplo n.º 4
0
// 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);
	}
}
Ejemplo n.º 5
0
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;
}