mirror of https://github.com/PCSX2/pcsx2.git
more recVUMI_FTOI0 changes. should now return proper saturation.
too tired to fix the other FTOI opcodes today. git-svn-id: http://pcsx2-playground.googlecode.com/svn/trunk@413 a6443dda-0b58-4228-96e9-037be469359c
This commit is contained in:
parent
71d9534e3f
commit
0a953edc88
|
@ -3541,9 +3541,7 @@ void recVUMI_NOP( VURegs *VU, int info )
|
|||
static const PCSX2_ALIGNED16(int rec_const_0x8000000[4]) = { 0x80000000, 0x80000000, 0x80000000, 0x80000000 };
|
||||
|
||||
//Saturates for FTOI
|
||||
//NOT Tested yet, it needs 2 temp regs and i have no idea how to use pcsx2's sse reg alloc functions :p
|
||||
//rec_s can be the same as rec_tmp1
|
||||
void recVUMI_FTOI_Saturate(int rec_s,int rec_t,int rec_tmp1,int rec_tmp2)
|
||||
void recVUMI_FTOI_Saturate(int rec_s, int rec_t, int rec_tmp1, int rec_tmp2)
|
||||
{
|
||||
assert(rec_s!=rec_t);
|
||||
assert(rec_tmp1!=rec_t);
|
||||
|
@ -3552,44 +3550,127 @@ void recVUMI_FTOI_Saturate(int rec_s,int rec_t,int rec_tmp1,int rec_tmp2)
|
|||
|
||||
//Duplicate the xor'd sign bit to the whole value
|
||||
//FFFF FFFF for positive, 0 for negative
|
||||
if (rec_tmp1!=rec_s)
|
||||
SSE_MOVAPS_M128_to_XMM(rec_tmp1,rec_s);
|
||||
SSE2_PXOR_M128_to_XMM(rec_tmp1,(uptr)&const_clip[4]);
|
||||
SSE2_PSRAW_I8_to_XMM(rec_tmp1,31);
|
||||
SSE_MOVAPS_XMM_to_XMM(rec_tmp1, rec_s);
|
||||
SSE2_PXOR_M128_to_XMM(rec_tmp1, (uptr)&const_clip[4]);
|
||||
SSE2_PSRAD_I8_to_XMM(rec_tmp1, 31);
|
||||
|
||||
//Create mask: 0 where !=8000 0000
|
||||
SSE_MOVAPS_M128_to_XMM(rec_tmp2,(uptr)&const_clip[4]);
|
||||
SSE2_PCMPEQD_M128_to_XMM(rec_tmp2,rec_t);
|
||||
|
||||
SSE_MOVAPS_XMM_to_XMM(rec_tmp2, rec_t);
|
||||
SSE2_PCMPEQD_M128_to_XMM(rec_tmp2, (uptr)&const_clip[4]);
|
||||
|
||||
//AND the mask w/ the edit values
|
||||
SSE_ANDPS_M128_to_XMM(rec_tmp1,rec_tmp2);
|
||||
SSE_ANDPS_XMM_to_XMM(rec_tmp1, rec_tmp2);
|
||||
|
||||
//if v==8000 0000 && positive -> 8000 0000 + FFFF FFFF -> 7FFF FFFF
|
||||
//if v==8000 0000 && negative -> 8000 0000 + 0 -> 8000 0000
|
||||
//if v!=8000 0000 -> v+0 (masked from the and)
|
||||
|
||||
//Add the values as needed
|
||||
SSE2_PADDD_XMM_to_XMM(rec_t,rec_tmp1);
|
||||
SSE2_PADDD_XMM_to_XMM(rec_t, rec_tmp1);
|
||||
}
|
||||
|
||||
static const PCSX2_ALIGNED16(float rec_float_max_values[4]) = { 0x7FFFFF80, 0x7FFFFF80, 0x7FFFFF80, 0x7FFFFF80 };
|
||||
//static const PCSX2_ALIGNED16(float rec_float_max_values[4]) = { 0x7FFFFF80, 0x7FFFFF80, 0x7FFFFF80, 0x7FFFFF80 };
|
||||
static PCSX2_ALIGNED16(float FTIO_Temp1[4]) = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
|
||||
static PCSX2_ALIGNED16(float FTIO_Temp2[4]) = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
|
||||
|
||||
void recVUMI_FTOI0(VURegs *VU, int info)
|
||||
{
|
||||
int t1reg, t2reg; // Temp XMM regs
|
||||
|
||||
if ( _Ft_ == 0 ) return;
|
||||
|
||||
//SysPrintf("recVUMI_FTOI0()\n");
|
||||
|
||||
if (_X_Y_Z_W != 0xf) {
|
||||
SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP,EEREC_S);
|
||||
SSE_MINPS_M128_to_XMM(EEREC_TEMP,(uptr)&rec_float_max_values[0]); //this is partialy wrong, will return 0x7FFFFF80 instead of 0x7FFFFFFF on saturate
|
||||
SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S);
|
||||
vuFloat( info, EEREC_TEMP, 0xf ); // Clamp Infs and NaNs to pos/neg fmax (NaNs always to positive fmax)
|
||||
SSE2_CVTTPS2DQ_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP);
|
||||
|
||||
t1reg = _vuGetTempXMMreg(info);
|
||||
|
||||
if( t1reg >= 0 ) { // If theres a temp XMM reg available
|
||||
for (t2reg = 0; ( (t2reg == EEREC_S) || (t2reg == EEREC_T) || (t2reg == EEREC_TEMP) ); t2reg++)
|
||||
; // Find unused reg (For second temp reg)
|
||||
SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t2reg); // Backup XMM reg
|
||||
|
||||
recVUMI_FTOI_Saturate(EEREC_S, EEREC_TEMP, t1reg, t2reg); // Saturate if Float->Int conversion returned illegal result
|
||||
|
||||
SSE_MOVAPS_M128_to_XMM(t2reg, (uptr)FTIO_Temp1); // Restore XMM reg
|
||||
_freeXMMreg(t1reg); // Free temp reg
|
||||
}
|
||||
else { // No temp reg available
|
||||
for (t1reg = 0; ( (t1reg == EEREC_S) || (t1reg == EEREC_T) || (t1reg == EEREC_TEMP) ); t1reg++)
|
||||
; // Find unused reg (For first temp reg)
|
||||
SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t1reg); // Backup t1reg XMM reg
|
||||
|
||||
for (t2reg = 0; ( (t2reg == EEREC_S) || (t2reg == EEREC_T) || (t2reg == EEREC_TEMP) || (t2reg == t1reg) ); t2reg++)
|
||||
; // Find unused reg (For second temp reg)
|
||||
SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp2, t2reg); // Backup t2reg XMM reg
|
||||
|
||||
recVUMI_FTOI_Saturate(EEREC_S, EEREC_TEMP, t1reg, t2reg); // Saturate if Float->Int conversion returned illegal result
|
||||
|
||||
SSE_MOVAPS_M128_to_XMM(t1reg, (uptr)FTIO_Temp1); // Restore t1reg XMM reg
|
||||
SSE_MOVAPS_M128_to_XMM(t2reg, (uptr)FTIO_Temp2); // Restore t2reg XMM reg
|
||||
}
|
||||
|
||||
VU_MERGE_REGS(EEREC_T, EEREC_TEMP);
|
||||
}
|
||||
else {
|
||||
if (EEREC_T != EEREC_S)
|
||||
SSE_MOVAPS_XMM_to_XMM(EEREC_T,EEREC_S);
|
||||
if (EEREC_T != EEREC_S) {
|
||||
SSE_MOVAPS_XMM_to_XMM(EEREC_T, EEREC_S);
|
||||
vuFloat( info, EEREC_T, 0xf ); // Clamp Infs and NaNs to pos/neg fmax (NaNs always to positive fmax)
|
||||
SSE2_CVTTPS2DQ_XMM_to_XMM(EEREC_T, EEREC_T);
|
||||
|
||||
SSE_MINPS_M128_to_XMM(EEREC_T,(uptr)&rec_float_max_values[0]); //this is partialy wrong, will return 0x7FFFFF80 instead of 0x7FFFFFFF on saturate
|
||||
SSE2_CVTTPS2DQ_XMM_to_XMM(EEREC_T, EEREC_T);
|
||||
t1reg = _vuGetTempXMMreg(info);
|
||||
|
||||
if( t1reg >= 0 ) { // If theres a temp XMM reg available
|
||||
recVUMI_FTOI_Saturate(EEREC_S, EEREC_T, EEREC_TEMP, t1reg); // Saturate if Float->Int conversion returned illegal result
|
||||
_freeXMMreg(t1reg); // Free temp reg
|
||||
}
|
||||
else { // No temp reg available
|
||||
for (t1reg = 0; ( (t1reg == EEREC_S) || (t1reg == EEREC_T) || (t1reg == EEREC_TEMP) ); t1reg++)
|
||||
; // Find unused reg
|
||||
SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t1reg); // Backup t1reg XMM reg
|
||||
|
||||
recVUMI_FTOI_Saturate(EEREC_S, EEREC_T, EEREC_TEMP, t1reg); // Saturate if Float->Int conversion returned illegal result
|
||||
|
||||
SSE_MOVAPS_M128_to_XMM(t1reg, (uptr)FTIO_Temp1); // Restore t1reg XMM reg
|
||||
}
|
||||
}
|
||||
else {
|
||||
SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S);
|
||||
vuFloat( info, EEREC_TEMP, 0xf ); // Clamp Infs and NaNs to pos/neg fmax (NaNs always to positive fmax)
|
||||
SSE2_CVTTPS2DQ_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP);
|
||||
|
||||
t1reg = _vuGetTempXMMreg(info);
|
||||
|
||||
if( t1reg >= 0 ) { // If theres a temp XMM reg available
|
||||
for (t2reg = 0; ( (t2reg == EEREC_S) || (t2reg == EEREC_T) || (t2reg == EEREC_TEMP) ); t2reg++)
|
||||
; // Find unused reg (For second temp reg)
|
||||
SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t2reg); // Backup XMM reg
|
||||
|
||||
recVUMI_FTOI_Saturate(EEREC_S, EEREC_TEMP, t1reg, t2reg); // Saturate if Float->Int conversion returned illegal result
|
||||
|
||||
SSE_MOVAPS_M128_to_XMM(t2reg, (uptr)FTIO_Temp1); // Restore XMM reg
|
||||
_freeXMMreg(t1reg); // Free temp reg
|
||||
}
|
||||
else { // No temp reg available
|
||||
for (t1reg = 0; ( (t1reg == EEREC_S) || (t1reg == EEREC_T) || (t1reg == EEREC_TEMP) ); t1reg++)
|
||||
; // Find unused reg (For first temp reg)
|
||||
SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp1, t1reg); // Backup t1reg XMM reg
|
||||
|
||||
for (t2reg = 0; ( (t2reg == EEREC_S) || (t2reg == EEREC_T) || (t2reg == EEREC_TEMP) || (t2reg == t1reg) ); t2reg++)
|
||||
; // Find unused reg (For second temp reg)
|
||||
SSE_MOVAPS_XMM_to_M128((uptr)FTIO_Temp2, t2reg); // Backup t2reg XMM reg
|
||||
|
||||
recVUMI_FTOI_Saturate(EEREC_S, EEREC_TEMP, t1reg, t2reg); // Saturate if Float->Int conversion returned illegal result
|
||||
|
||||
SSE_MOVAPS_M128_to_XMM(t1reg, (uptr)FTIO_Temp1); // Restore t1reg XMM reg
|
||||
SSE_MOVAPS_M128_to_XMM(t2reg, (uptr)FTIO_Temp2); // Restore t2reg XMM reg
|
||||
}
|
||||
|
||||
SSE_MOVAPS_XMM_to_XMM(EEREC_T, EEREC_TEMP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3600,7 +3681,8 @@ void recVUMI_FTOIX(VURegs *VU, int addr, int info)
|
|||
if (_X_Y_Z_W != 0xf) {
|
||||
SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S);
|
||||
SSE_MULPS_M128_to_XMM(EEREC_TEMP, addr);
|
||||
SSE_MINPS_M128_to_XMM(EEREC_TEMP,(uptr)&rec_float_max_values[0]); //this is partialy wrong, will return 0x7FFFFF80 instead of 0x7FFFFFFF on saturate
|
||||
//SSE_MINPS_M128_to_XMM(EEREC_TEMP,(uptr)&rec_float_max_values[0]); //this is partialy wrong, will return 0x7FFFFF80 instead of 0x7FFFFFFF on saturate
|
||||
vuFloat( info, EEREC_TEMP, 0xf ); // Clamp Infs and NaNs to pos/neg fmax (NaNs always to positive fmax)
|
||||
SSE2_CVTTPS2DQ_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP);
|
||||
|
||||
VU_MERGE_REGS(EEREC_T, EEREC_TEMP);
|
||||
|
@ -3608,7 +3690,8 @@ void recVUMI_FTOIX(VURegs *VU, int addr, int info)
|
|||
else {
|
||||
if (EEREC_T != EEREC_S) SSE_MOVAPS_XMM_to_XMM(EEREC_T, EEREC_S);
|
||||
SSE_MULPS_M128_to_XMM(EEREC_T, addr);
|
||||
SSE_MINPS_M128_to_XMM(EEREC_T,(uptr)&rec_float_max_values[0]); //this is partialy wrong, will return 0x7FFFFF80 instead of 0x7FFFFFFF on saturate
|
||||
//SSE_MINPS_M128_to_XMM(EEREC_T,(uptr)&rec_float_max_values[0]); //this is partialy wrong, will return 0x7FFFFF80 instead of 0x7FFFFFFF on saturate
|
||||
vuFloat( info, EEREC_T, 0xf ); // Clamp Infs and NaNs to pos/neg fmax (NaNs always to positive fmax)
|
||||
SSE2_CVTTPS2DQ_XMM_to_XMM(EEREC_T, EEREC_T);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue