mirror of https://github.com/PCSX2/pcsx2.git
a few fixes, and half-way done with the vuMicro DIV opcode.
git-svn-id: http://pcsx2-playground.googlecode.com/svn/trunk@24 a6443dda-0b58-4228-96e9-037be469359c
This commit is contained in:
parent
113606ecbf
commit
7e0d5646de
|
@ -1152,14 +1152,14 @@ void vuFloat2(int regd, int regTemp, int XYZW) {
|
||||||
// Clamps infinities to max/min non-infinity number (doesn't use any temp regs)
|
// Clamps infinities to max/min non-infinity number (doesn't use any temp regs)
|
||||||
void vuFloat( int info, int regd, int XYZW) {
|
void vuFloat( int info, int regd, int XYZW) {
|
||||||
if( CHECK_OVERFLOW ) {
|
if( CHECK_OVERFLOW ) {
|
||||||
if ( (XYZW != 0) && (XYZW != 8) && (XYZW != 0xF) ) {
|
/*if ( (XYZW != 0) && (XYZW != 8) && (XYZW != 0xF) ) {
|
||||||
int t1reg = _vuGetTempXMMreg2(info, regd);
|
int t1reg = _vuGetTempXMMreg2(info, regd);
|
||||||
if (t1reg >= 0) {
|
if (t1reg >= 0) {
|
||||||
vuFloat2( regd, t1reg, XYZW );
|
vuFloat2( regd, t1reg, XYZW );
|
||||||
_freeXMMreg( t1reg );
|
_freeXMMreg( t1reg );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
switch (XYZW) {
|
switch (XYZW) {
|
||||||
case 0: // Don't do anything if no vectors are being modified.
|
case 0: // Don't do anything if no vectors are being modified.
|
||||||
break;
|
break;
|
||||||
|
@ -1507,7 +1507,7 @@ void recUpdateFlags(VURegs * VU, int reg, int info)
|
||||||
int t1regBoolean = 0;
|
int t1regBoolean = 0;
|
||||||
if (t1reg == -1) {
|
if (t1reg == -1) {
|
||||||
//SysPrintf( "VU ALLOCATION ERROR: Temp reg can't be allocated!!!!\n" );
|
//SysPrintf( "VU ALLOCATION ERROR: Temp reg can't be allocated!!!!\n" );
|
||||||
t1reg = (reg >= XMMREGS) ? (reg - 1) : (reg + 1);
|
t1reg = (reg == 0) ? (reg + 1) : (reg - 1);
|
||||||
SSE_MOVAPS_XMM_to_M128( (uptr)TEMPXMMData, t1reg );
|
SSE_MOVAPS_XMM_to_M128( (uptr)TEMPXMMData, t1reg );
|
||||||
t1regBoolean = 1;
|
t1regBoolean = 1;
|
||||||
}
|
}
|
||||||
|
@ -3719,10 +3719,12 @@ void recVUMI_CLIP(VURegs *VU, int info)
|
||||||
/******************************/
|
/******************************/
|
||||||
/* VU Lower instructions */
|
/* VU Lower instructions */
|
||||||
/******************************/
|
/******************************/
|
||||||
|
PCSX2_ALIGNED16(u64 DIV_TEMP_XMM[2];)
|
||||||
|
|
||||||
void recVUMI_DIV(VURegs *VU, int info)
|
void recVUMI_DIV(VURegs *VU, int info)
|
||||||
{
|
{
|
||||||
int t1reg;
|
int t1reg;
|
||||||
|
u8* pjmp;
|
||||||
|
|
||||||
if( _Fs_ == 0 ) {
|
if( _Fs_ == 0 ) {
|
||||||
|
|
||||||
|
@ -3751,10 +3753,8 @@ void recVUMI_DIV(VURegs *VU, int info)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( _Fsf_ == 3 ) { // = 1
|
if( _Fsf_ == 3 ) // = 1
|
||||||
// don't use RCPSS (very bad precision)
|
{ // don't use RCPSS (very bad precision)
|
||||||
SSE_MOVSS_M32_to_XMM(EEREC_TEMP, (uptr)&VU->VF[0].UL[3]); // TEMP.x <- 1
|
|
||||||
|
|
||||||
if( _Ftf_ != 0 || (xmmregs[EEREC_T].mode & MODE_WRITE) )
|
if( _Ftf_ != 0 || (xmmregs[EEREC_T].mode & MODE_WRITE) )
|
||||||
{
|
{
|
||||||
if( _Ftf_ )
|
if( _Ftf_ )
|
||||||
|
@ -3765,33 +3765,77 @@ void recVUMI_DIV(VURegs *VU, int info)
|
||||||
{
|
{
|
||||||
_unpackVFSS_xyzw(t1reg, EEREC_T, _Ftf_);
|
_unpackVFSS_xyzw(t1reg, EEREC_T, _Ftf_);
|
||||||
|
|
||||||
|
if (CHECK_EXTRA_OVERFLOW)
|
||||||
|
vuFloat2(t1reg, EEREC_TEMP, 0x8);
|
||||||
|
|
||||||
|
SSE_MOVSS_M32_to_XMM(EEREC_TEMP, (uptr)&VU->VF[0].UL[3]); // TEMP.x <- 1
|
||||||
SSE_DIVSS_XMM_to_XMM(EEREC_TEMP, t1reg);
|
SSE_DIVSS_XMM_to_XMM(EEREC_TEMP, t1reg);
|
||||||
|
|
||||||
_freeXMMreg(t1reg);
|
_freeXMMreg(t1reg);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
_unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, _Ftf_);
|
||||||
|
|
||||||
|
if (CHECK_EXTRA_OVERFLOW)
|
||||||
|
vuFloat2(EEREC_TEMP, EEREC_TEMP, 0x8);
|
||||||
|
|
||||||
|
t1reg = (EEREC_TEMP == 0) ? (EEREC_TEMP + 1) : (EEREC_TEMP - 1);
|
||||||
|
SSE_MOVAPS_XMM_to_M128( (uptr)DIV_TEMP_XMM, t1reg ); // backup data in t1reg to a temp address
|
||||||
|
|
||||||
|
SSE_MOVSS_M32_to_XMM(t1reg, (uptr)&VU->VF[0].UL[3]); // t1reg.x <- 1
|
||||||
|
SSE_DIVSS_XMM_to_XMM(t1reg, EEREC_TEMP); // t1reg = 1 / EEREC_TEMP
|
||||||
|
SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_Q, 0), t1reg); // q <- t1reg
|
||||||
|
|
||||||
|
SSE_MOVAPS_M128_to_XMM( t1reg, (uptr)DIV_TEMP_XMM ); // restore data to t1reg
|
||||||
|
return;
|
||||||
|
/*
|
||||||
SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, (0xe4e4>>(2*_Ftf_))&0xff);
|
SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, (0xe4e4>>(2*_Ftf_))&0xff);
|
||||||
SSE_DIVSS_XMM_to_XMM(EEREC_TEMP, EEREC_T);
|
SSE_DIVSS_XMM_to_XMM(EEREC_TEMP, EEREC_T);
|
||||||
SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, (0xe4e4>>(8-2*_Ftf_))&0xff); // revert
|
SSE_SHUFPS_XMM_to_XMM(EEREC_T, EEREC_T, (0xe4e4>>(8-2*_Ftf_))&0xff); // revert
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (CHECK_EXTRA_OVERFLOW)
|
||||||
|
vuFloat2(EEREC_T, EEREC_TEMP, 0x8);
|
||||||
|
SSE_MOVSS_M32_to_XMM(EEREC_TEMP, (uptr)&VU->VF[0].UL[3]); // TEMP.x <- 1
|
||||||
SSE_DIVSS_XMM_to_XMM(EEREC_TEMP, EEREC_T);
|
SSE_DIVSS_XMM_to_XMM(EEREC_TEMP, EEREC_T);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if (CHECK_EXTRA_OVERFLOW)
|
||||||
|
vuFloat3( (uptr)&VU->VF[_Ft_].UL[_Ftf_] );
|
||||||
|
SSE_MOVSS_M32_to_XMM(EEREC_TEMP, (uptr)&VU->VF[0].UL[3]); // TEMP.x <- 1
|
||||||
SSE_DIVSS_M32_to_XMM(EEREC_TEMP, (uptr)&VU->VF[_Ft_].UL[_Ftf_]);
|
SSE_DIVSS_M32_to_XMM(EEREC_TEMP, (uptr)&VU->VF[_Ft_].UL[_Ftf_]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { // = 0 So result is -MAX/+MAX
|
else { // = 0 So result is -MAX/+MAX
|
||||||
//SysPrintf("FS = 0, FT != 0\n");
|
//SysPrintf("FS = 0, FT != 0\n");
|
||||||
OR32ItoM(VU_VI_ADDR(REG_STATUS_FLAG, 2), 0x410); //Invalid Flag (only when 0/0)
|
|
||||||
SSE_MOVSS_XMM_to_XMM(EEREC_TEMP, EEREC_T);
|
// FT can still be zero here! so we need to check if its zero and set the correct flag.
|
||||||
SSE_ORPS_M128_to_XMM(EEREC_TEMP, (u32)&g_maxvals);
|
|
||||||
|
SSE_XORPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP); // Clear EEREC_TEMP
|
||||||
|
XOR32RtoR( EAX, EAX ); // Clear EAX
|
||||||
|
SSE_CMPEQPS_XMM_to_XMM(EEREC_TEMP, EEREC_T); // Set all F's if each vector is zero
|
||||||
|
|
||||||
|
SSE_MOVMSKPS_XMM_to_R32(EAX, EEREC_TEMP); // Move the sign bits of the previous calculation
|
||||||
|
|
||||||
|
AND32ItoR( EAX, 0x0000000f & ( 1 << _Ftf_ ) ); // Grab "Is Zero" bits from the previous calculation
|
||||||
|
pjmp = JZ8(0); // Skip if none are
|
||||||
|
OR32ItoR(EAX, 0x410); // Set invalid flag they are
|
||||||
|
x86SetJ8(pjmp);
|
||||||
|
|
||||||
|
OR32RtoM( VU_VI_ADDR(REG_STATUS_FLAG, 2), EAX );
|
||||||
|
|
||||||
|
// Now that we've finished the 0/0 flag checking, we can just set Q to +/- Fmax
|
||||||
|
_unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, _Ftf_);
|
||||||
|
|
||||||
|
SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)&VU_Signed_Zero_Mask[0]);
|
||||||
|
SSE_ORPS_M128_to_XMM(EEREC_TEMP, (uptr)&g_maxvals[0]);
|
||||||
SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_Q, 0), EEREC_TEMP);
|
SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_Q, 0), EEREC_TEMP);
|
||||||
//MOV32ItoR(VU_VI_ADDR(REG_Q, 0), 0);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue