Пример #1
0
// rd = rs op rt
void eeFPURecompileCode(R5900FNPTR_INFO xmmcode, R5900FNPTR fpucode, int xmminfo)
{
	int mmregs=-1, mmregt=-1, mmregd=-1, mmregacc=-1;
	int info = PROCESS_EE_XMM;

	if( xmminfo & XMMINFO_READS ) _addNeededFPtoXMMreg(_Fs_);
	if( xmminfo & XMMINFO_READT ) _addNeededFPtoXMMreg(_Ft_);
	if( xmminfo & (XMMINFO_WRITED|XMMINFO_READD) ) _addNeededFPtoXMMreg(_Fd_);
	if( xmminfo & (XMMINFO_WRITEACC|XMMINFO_READACC) ) _addNeededFPACCtoXMMreg();

	if( xmminfo & XMMINFO_READT ) {
		if( g_pCurInstInfo->fpuregs[_Ft_] & EEINST_LASTUSE ) mmregt = _checkXMMreg(XMMTYPE_FPREG, _Ft_, MODE_READ);
		else mmregt = _allocFPtoXMMreg(-1, _Ft_, MODE_READ);
	}

	if( xmminfo & XMMINFO_READS ) {
		if( ( !(xmminfo & XMMINFO_READT) || (mmregt >= 0) ) && (g_pCurInstInfo->fpuregs[_Fs_] & EEINST_LASTUSE) ) {
			mmregs = _checkXMMreg(XMMTYPE_FPREG, _Fs_, MODE_READ);
		}
		else mmregs = _allocFPtoXMMreg(-1, _Fs_, MODE_READ);
	}

	if( mmregs >= 0 ) info |= PROCESS_EE_SETMODES_XMM(mmregs);
	if( mmregt >= 0 ) info |= PROCESS_EE_SETMODET_XMM(mmregt);

	if( xmminfo & XMMINFO_READD ) {
		pxAssert( xmminfo & XMMINFO_WRITED );
		mmregd = _allocFPtoXMMreg(-1, _Fd_, MODE_READ);
	}

	if( xmminfo & XMMINFO_READACC ) {
		if( !(xmminfo&XMMINFO_WRITEACC) && (g_pCurInstInfo->fpuregs[_Ft_] & EEINST_LASTUSE) )
			mmregacc = _checkXMMreg(XMMTYPE_FPACC, 0, MODE_READ);
		else mmregacc = _allocFPACCtoXMMreg(-1, MODE_READ);
	}

	if( xmminfo & XMMINFO_WRITEACC ) {

		// check for last used, if so don't alloc a new XMM reg
		int readacc = MODE_WRITE|((xmminfo&XMMINFO_READACC)?MODE_READ:0);

		mmregacc = _checkXMMreg(XMMTYPE_FPACC, 0, readacc);

		if( mmregacc < 0 ) {
			if( (xmminfo&XMMINFO_READT) && mmregt >= 0 && (FPUINST_LASTUSE(_Ft_) || !FPUINST_ISLIVE(_Ft_)) ) {
				if( FPUINST_ISLIVE(_Ft_) ) {
					_freeXMMreg(mmregt);
					info &= ~PROCESS_EE_MODEWRITET;
				}
				_deleteMMXreg(MMX_FPU+XMMFPU_ACC, 2);
				xmmregs[mmregt].inuse = 1;
				xmmregs[mmregt].reg = 0;
				xmmregs[mmregt].mode = readacc;
				xmmregs[mmregt].type = XMMTYPE_FPACC;
				mmregacc = mmregt;
			}
			else if( (xmminfo&XMMINFO_READS) && mmregs >= 0 && (FPUINST_LASTUSE(_Fs_) || !FPUINST_ISLIVE(_Fs_)) ) {
				if( FPUINST_ISLIVE(_Fs_) ) {
					_freeXMMreg(mmregs);
					info &= ~PROCESS_EE_MODEWRITES;
				}
				_deleteMMXreg(MMX_FPU+XMMFPU_ACC, 2);
				xmmregs[mmregs].inuse = 1;
				xmmregs[mmregs].reg = 0;
				xmmregs[mmregs].mode = readacc;
				xmmregs[mmregs].type = XMMTYPE_FPACC;
				mmregacc = mmregs;
			}
			else mmregacc = _allocFPACCtoXMMreg(-1, readacc);
		}

		xmmregs[mmregacc].mode |= MODE_WRITE;
	}
	else if( xmminfo & XMMINFO_WRITED ) {
		// check for last used, if so don't alloc a new XMM reg
		int readd = MODE_WRITE|((xmminfo&XMMINFO_READD)?MODE_READ:0);
		if( xmminfo&XMMINFO_READD ) mmregd = _allocFPtoXMMreg(-1, _Fd_, readd);
		else mmregd = _checkXMMreg(XMMTYPE_FPREG, _Fd_, readd);

		if( mmregd < 0 ) {
			if( (xmminfo&XMMINFO_READT) && mmregt >= 0 && (FPUINST_LASTUSE(_Ft_) || !FPUINST_ISLIVE(_Ft_)) ) {
				if( FPUINST_ISLIVE(_Ft_) ) {
					_freeXMMreg(mmregt);
					info &= ~PROCESS_EE_MODEWRITET;
				}
				_deleteMMXreg(MMX_FPU+_Fd_, 2);
				xmmregs[mmregt].inuse = 1;
				xmmregs[mmregt].reg = _Fd_;
				xmmregs[mmregt].mode = readd;
				mmregd = mmregt;
			}
			else if( (xmminfo&XMMINFO_READS) && mmregs >= 0 && (FPUINST_LASTUSE(_Fs_) || !FPUINST_ISLIVE(_Fs_)) ) {
				if( FPUINST_ISLIVE(_Fs_) ) {
					_freeXMMreg(mmregs);
					info &= ~PROCESS_EE_MODEWRITES;
				}
				_deleteMMXreg(MMX_FPU+_Fd_, 2);
				xmmregs[mmregs].inuse = 1;
				xmmregs[mmregs].reg = _Fd_;
				xmmregs[mmregs].mode = readd;
				mmregd = mmregs;
			}
			else if( (xmminfo&XMMINFO_READACC) && mmregacc >= 0 && (FPUINST_LASTUSE(XMMFPU_ACC) || !FPUINST_ISLIVE(XMMFPU_ACC)) ) {
				if( FPUINST_ISLIVE(XMMFPU_ACC) )
					_freeXMMreg(mmregacc);
				_deleteMMXreg(MMX_FPU+_Fd_, 2);
				xmmregs[mmregacc].inuse = 1;
				xmmregs[mmregacc].reg = _Fd_;
				xmmregs[mmregacc].mode = readd;
				xmmregs[mmregacc].type = XMMTYPE_FPREG;
				mmregd = mmregacc;
			}
			else mmregd = _allocFPtoXMMreg(-1, _Fd_, readd);
		}
	}

	pxAssert( mmregs >= 0 || mmregt >= 0 || mmregd >= 0 || mmregacc >= 0 );

	if( xmminfo & XMMINFO_WRITED ) {
		pxAssert( mmregd >= 0 );
		info |= PROCESS_EE_SET_D(mmregd);
	}
	if( xmminfo & (XMMINFO_WRITEACC|XMMINFO_READACC) ) {
		if( mmregacc >= 0 ) info |= PROCESS_EE_SET_ACC(mmregacc)|PROCESS_EE_ACC;
		else pxAssert( !(xmminfo&XMMINFO_WRITEACC));
	}

	if( xmminfo & XMMINFO_READS ) {
		if( mmregs >= 0 ) info |= PROCESS_EE_SET_S(mmregs)|PROCESS_EE_S;
	}
	if( xmminfo & XMMINFO_READT ) {
		if( mmregt >= 0 ) info |= PROCESS_EE_SET_T(mmregt)|PROCESS_EE_T;
	}

	// at least one must be in xmm
	if( (xmminfo & (XMMINFO_READS|XMMINFO_READT)) == (XMMINFO_READS|XMMINFO_READT) ) {
		pxAssert( mmregs >= 0 || mmregt >= 0 );
	}

	xmmcode(info);
	_clearNeededXMMregs();
}
Пример #2
0
int _allocCheckFPUtoXMM(EEINST* pinst, int fpureg, int mode)
{
	if( pinst->fpuregs[fpureg] & EEINST_XMM ) return _allocFPtoXMMreg(-1, fpureg, mode);

	return _checkXMMreg(XMMTYPE_FPREG, fpureg, mode);
}