Esempio n. 1
0
void _deleteEEreg(int reg, int flush)
{
	if( !reg ) return;
	if( flush && GPR_IS_CONST1(reg) ) {
		_flushConstReg(reg);
	}
	GPR_DEL_CONST(reg);
	_deleteGPRtoXMMreg(reg, flush ? 0 : 2);
	_deleteMMXreg(MMX_GPR+reg, flush ? 0 : 2);
}
Esempio n. 2
0
void _flushEEreg(int reg)
{
	if (!reg) return;
	if (GPR_IS_CONST1(reg)) {
		_flushConstReg(reg);
		return;
	}
	_deleteGPRtoXMMreg(reg, 1);
	_deleteMMXreg(MMX_GPR + reg, 1);
}
Esempio n. 3
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;
}