Core: Fix up FPU mode register location

This commit is contained in:
zilmar 2023-10-12 14:53:44 +10:30
parent befa57924d
commit 4e71221147
4 changed files with 131 additions and 141 deletions

View File

@ -2039,16 +2039,16 @@ void R4300iOp::COP1_S_ADD()
return;
}
if (CheckFPUInput32(*(float *)_FPR_S[m_Opcode.fs]) || CheckFPUInput32(*(float *)_FPR_S[m_Opcode.ft]))
if (CheckFPUInput32(*(float *)_FPR_S_L[m_Opcode.fs]) || CheckFPUInput32(*(float *)_FPR_UW[m_Opcode.ft]))
{
return;
}
float Result = (*(float *)_FPR_S[m_Opcode.fs] + *(float *)_FPR_S[m_Opcode.ft]);
float Result = (*(float *)_FPR_S_L[m_Opcode.fs] + *(float *)_FPR_UW[m_Opcode.ft]);
if (CheckFPUResult32(Result))
{
return;
}
*(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint32_t *)&Result;
}
void R4300iOp::COP1_S_SUB()
@ -2057,16 +2057,16 @@ void R4300iOp::COP1_S_SUB()
{
return;
}
if (CheckFPUInput32(*(float *)_FPR_S[m_Opcode.fs]) || CheckFPUInput32(*(float *)_FPR_S[m_Opcode.ft]))
if (CheckFPUInput32(*(float *)_FPR_S_L[m_Opcode.fs]) || CheckFPUInput32(*(float *)_FPR_UW[m_Opcode.ft]))
{
return;
}
float Result = (*(float *)_FPR_S[m_Opcode.fs] - *(float *)_FPR_S[m_Opcode.ft]);
float Result = (*(float *)_FPR_S_L[m_Opcode.fs] - *(float *)_FPR_UW[m_Opcode.ft]);
if (CheckFPUResult32(Result))
{
return;
}
*(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint32_t *)&Result;
}
void R4300iOp::COP1_S_MUL()
@ -2076,16 +2076,16 @@ void R4300iOp::COP1_S_MUL()
return;
}
if (CheckFPUInput32(*(float *)_FPR_S[m_Opcode.fs]) || CheckFPUInput32(*(float *)_FPR_S[m_Opcode.ft]))
if (CheckFPUInput32(*(float *)_FPR_S_L[m_Opcode.fs]) || CheckFPUInput32(*(float *)_FPR_UW[m_Opcode.ft]))
{
return;
}
float Result = (*(float *)_FPR_S[m_Opcode.fs] * *(float *)_FPR_S[m_Opcode.ft]);
float Result = (*(float *)_FPR_S_L[m_Opcode.fs] * *(float *)_FPR_UW[m_Opcode.ft]);
if (CheckFPUResult32(Result))
{
return;
}
*(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint32_t *)&Result;
}
void R4300iOp::COP1_S_DIV()
@ -2095,16 +2095,16 @@ void R4300iOp::COP1_S_DIV()
return;
}
if (CheckFPUInput32(*(float *)_FPR_S[m_Opcode.fs]) || CheckFPUInput32(*(float *)_FPR_S[m_Opcode.ft]))
if (CheckFPUInput32(*(float *)_FPR_S_L[m_Opcode.fs]) || CheckFPUInput32(*(float *)_FPR_UW[m_Opcode.ft]))
{
return;
}
float Result = (*(float *)_FPR_S[m_Opcode.fs] / *(float *)_FPR_S[m_Opcode.ft]);
float Result = (*(float *)_FPR_S_L[m_Opcode.fs] / *(float *)_FPR_UW[m_Opcode.ft]);
if (CheckFPUResult32(Result))
{
return;
}
*(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint32_t *)&Result;
}
void R4300iOp::COP1_S_SQRT()
@ -2114,16 +2114,16 @@ void R4300iOp::COP1_S_SQRT()
return;
}
if (CheckFPUInput32(*(float *)_FPR_S[m_Opcode.fs]))
if (CheckFPUInput32(*(float *)_FPR_S_L[m_Opcode.fs]))
{
return;
}
float Result = sqrtf(*(float *)(_FPR_S[m_Opcode.fs]));
float Result = sqrtf(*(float *)(_FPR_S_L[m_Opcode.fs]));
if (CheckFPUResult32(Result))
{
return;
}
*(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint32_t *)&Result;
}
void R4300iOp::COP1_S_ABS()
@ -2133,16 +2133,16 @@ void R4300iOp::COP1_S_ABS()
return;
}
if (CheckFPUInput32(*(float *)_FPR_S[m_Opcode.fs]))
if (CheckFPUInput32(*(float *)_FPR_S_L[m_Opcode.fs]))
{
return;
}
float Result = (float)fabs(*(float *)_FPR_S[m_Opcode.fs]);
float Result = (float)fabs(*(float *)_FPR_S_L[m_Opcode.fs]);
if (CheckFPUResult32(Result))
{
return;
}
*(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint32_t *)&Result;
}
void R4300iOp::COP1_S_MOV()
@ -2151,14 +2151,7 @@ void R4300iOp::COP1_S_MOV()
{
return;
}
switch (((FPStatusReg &)_FPCR[31]).RoundingMode)
{
case FPRoundingMode_RoundToNearest: fesetround(FE_TONEAREST); break;
case FPRoundingMode_RoundTowardZero: fesetround(FE_TOWARDZERO); break;
case FPRoundingMode_RoundTowardPlusInfinity: fesetround(FE_UPWARD); break;
case FPRoundingMode_RoundTowardMinusInfinity: fesetround(FE_DOWNWARD); break;
}
*(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)_FPR_S[m_Opcode.fs];
*_FPR_UDW[m_Opcode.fd] = (*(uint64_t *)_FPR_D[m_Opcode.fs] & 0xFFFFFFFF00000000ll) | *(uint32_t *)_FPR_S_L[m_Opcode.fs];
}
void R4300iOp::COP1_S_NEG()
@ -2168,16 +2161,16 @@ void R4300iOp::COP1_S_NEG()
return;
}
if (CheckFPUInput32(*(float *)_FPR_S[m_Opcode.fs]))
if (CheckFPUInput32(*(float *)_FPR_S_L[m_Opcode.fs]))
{
return;
}
float Result = (*(float *)_FPR_S[m_Opcode.fs] * -1.0f);
float Result = (*(float *)_FPR_S_L[m_Opcode.fs] * -1.0f);
if (CheckFPUResult32(Result))
{
return;
}
*(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint32_t *)&Result;
}
void R4300iOp::COP1_S_ROUND_L()
@ -2187,16 +2180,16 @@ void R4300iOp::COP1_S_ROUND_L()
return;
}
if (CheckFPUInput32Conv(*(float *)_FPR_S[m_Opcode.fs]))
if (CheckFPUInput32Conv(*(float *)_FPR_S_L[m_Opcode.fs]))
{
return;
}
int64_t Result = (int64_t)rint(*(float *)_FPR_S[m_Opcode.fs]);
int64_t Result = (int64_t)rint(*(float *)_FPR_S_L[m_Opcode.fs]);
if (CheckFPUInvalidException())
{
return;
}
*(uint64_t *)_FPR_D[m_Opcode.fd] = *(uint64_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint64_t *)&Result;
}
void R4300iOp::COP1_S_TRUNC_L()
@ -2205,16 +2198,16 @@ void R4300iOp::COP1_S_TRUNC_L()
{
return;
}
if (CheckFPUInput32Conv(*(float *)_FPR_S[m_Opcode.fs]))
if (CheckFPUInput32Conv(*(float *)_FPR_S_L[m_Opcode.fs]))
{
return;
}
int64_t Result = (int64_t)rint(*(float *)_FPR_S[m_Opcode.fs]);
int64_t Result = (int64_t)rint(*(float *)_FPR_S_L[m_Opcode.fs]);
if (CheckFPUInvalidException())
{
return;
}
*(uint64_t *)_FPR_D[m_Opcode.fd] = *(uint64_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint64_t *)&Result;
}
void R4300iOp::COP1_S_CEIL_L()
@ -2223,16 +2216,16 @@ void R4300iOp::COP1_S_CEIL_L()
{
return;
}
if (CheckFPUInput32Conv(*(float *)_FPR_S[m_Opcode.fs]))
if (CheckFPUInput32Conv(*(float *)_FPR_S_L[m_Opcode.fs]))
{
return;
}
int64_t Result = (int64_t)rint(*(float *)_FPR_S[m_Opcode.fs]);
int64_t Result = (int64_t)rint(*(float *)_FPR_S_L[m_Opcode.fs]);
if (CheckFPUInvalidException())
{
return;
}
*(uint64_t *)_FPR_D[m_Opcode.fd] = *(uint64_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint64_t *)&Result;
}
void R4300iOp::COP1_S_FLOOR_L()
@ -2241,16 +2234,16 @@ void R4300iOp::COP1_S_FLOOR_L()
{
return;
}
if (CheckFPUInput32Conv(*(float *)_FPR_S[m_Opcode.fs]))
if (CheckFPUInput32Conv(*(float *)_FPR_S_L[m_Opcode.fs]))
{
return;
}
int64_t Result = (int64_t)rint(*(float *)_FPR_S[m_Opcode.fs]);
int64_t Result = (int64_t)rint(*(float *)_FPR_S_L[m_Opcode.fs]);
if (CheckFPUInvalidException())
{
return;
}
*(uint64_t *)_FPR_D[m_Opcode.fd] = *(uint64_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint64_t *)&Result;
}
void R4300iOp::COP1_S_ROUND_W()
@ -2259,16 +2252,16 @@ void R4300iOp::COP1_S_ROUND_W()
{
return;
}
if (CheckFPUInput32Conv(*(float *)_FPR_S[m_Opcode.fs]))
if (CheckFPUInput32Conv(*(float *)_FPR_S_L[m_Opcode.fs]))
{
return;
}
int32_t Result = (int32_t)rint(*(float *)_FPR_S[m_Opcode.fs]);
int32_t Result = (int32_t)rint(*(float *)_FPR_S_L[m_Opcode.fs]);
if (CheckFPUInvalidException())
{
return;
}
*(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint32_t *)&Result;
}
void R4300iOp::COP1_S_TRUNC_W()
@ -2277,16 +2270,16 @@ void R4300iOp::COP1_S_TRUNC_W()
{
return;
}
if (CheckFPUInput32Conv(*(float *)_FPR_S[m_Opcode.fs]))
if (CheckFPUInput32Conv(*(float *)_FPR_S_L[m_Opcode.fs]))
{
return;
}
int32_t Result = (int32_t)rint(*(float *)_FPR_S[m_Opcode.fs]);
int32_t Result = (int32_t)rint(*(float *)_FPR_S_L[m_Opcode.fs]);
if (CheckFPUInvalidException())
{
return;
}
*(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint32_t *)&Result;
}
void R4300iOp::COP1_S_CEIL_W()
@ -2295,16 +2288,16 @@ void R4300iOp::COP1_S_CEIL_W()
{
return;
}
if (CheckFPUInput32Conv(*(float *)_FPR_S[m_Opcode.fs]))
if (CheckFPUInput32Conv(*(float *)_FPR_S_L[m_Opcode.fs]))
{
return;
}
int32_t Result = (int32_t)rint(*(float *)_FPR_S[m_Opcode.fs]);
int32_t Result = (int32_t)rint(*(float *)_FPR_S_L[m_Opcode.fs]);
if (CheckFPUInvalidException())
{
return;
}
*(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint32_t *)&Result;
}
void R4300iOp::COP1_S_FLOOR_W()
@ -2313,16 +2306,16 @@ void R4300iOp::COP1_S_FLOOR_W()
{
return;
}
if (CheckFPUInput32Conv(*(float *)_FPR_S[m_Opcode.fs]))
if (CheckFPUInput32Conv(*(float *)_FPR_S_L[m_Opcode.fs]))
{
return;
}
int32_t Result = (int32_t)rint(*(float *)_FPR_S[m_Opcode.fs]);
int32_t Result = (int32_t)rint(*(float *)_FPR_S_L[m_Opcode.fs]);
if (CheckFPUInvalidException())
{
return;
}
*(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint32_t *)&Result;
}
void R4300iOp::COP1_S_CVT_D()
@ -2331,16 +2324,16 @@ void R4300iOp::COP1_S_CVT_D()
{
return;
}
if (CheckFPUInput32(*(float *)_FPR_S[m_Opcode.fs]))
if (CheckFPUInput32(*(float *)_FPR_S_L[m_Opcode.fs]))
{
return;
}
double Result = (double)(*(float *)_FPR_S[m_Opcode.fs]);
double Result = (double)(*(float *)_FPR_S_L[m_Opcode.fs]);
if (CheckFPUResult64(Result))
{
return;
}
*(uint64_t *)_FPR_D[m_Opcode.fd] = *(uint64_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint64_t *)&Result;
}
void R4300iOp::COP1_S_CVT_W()
@ -2349,16 +2342,16 @@ void R4300iOp::COP1_S_CVT_W()
{
return;
}
if (CheckFPUInput32Conv(*(float *)_FPR_S[m_Opcode.fs]))
if (CheckFPUInput32Conv(*(float *)_FPR_S_L[m_Opcode.fs]))
{
return;
}
int32_t Result = (int32_t)rint(*(float *)_FPR_S[m_Opcode.fs]);
int32_t Result = (int32_t)rint(*(float *)_FPR_S_L[m_Opcode.fs]);
if (CheckFPUInvalidException())
{
return;
}
*(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint32_t *)&Result;
}
void R4300iOp::COP1_S_CVT_L()
@ -2367,16 +2360,16 @@ void R4300iOp::COP1_S_CVT_L()
{
return;
}
if (CheckFPUInput32Conv(*(float *)_FPR_S[m_Opcode.fs]))
if (CheckFPUInput32Conv(*(float *)_FPR_S_L[m_Opcode.fs]))
{
return;
}
int64_t Result = (int64_t)rint(*(float *)_FPR_S[m_Opcode.fs]);
int64_t Result = (int64_t)rint(*(float *)_FPR_S_L[m_Opcode.fs]);
if (CheckFPUInvalidException())
{
return;
}
*(uint64_t *)_FPR_D[m_Opcode.fd] = *(uint64_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint64_t *)&Result;
}
void R4300iOp::COP1_S_CMP()
@ -2385,8 +2378,8 @@ void R4300iOp::COP1_S_CMP()
{
return;
}
float Temp0 = *(float *)_FPR_S[m_Opcode.fs];
float Temp1 = *(float *)_FPR_S[m_Opcode.ft];
float Temp0 = *(float *)_FPR_S_L[m_Opcode.fs];
float Temp1 = *(float *)_FPR_UW[m_Opcode.ft];
bool less, equal, unorded;
if (_isnan(Temp0) || _isnan(Temp1))
@ -2396,13 +2389,13 @@ void R4300iOp::COP1_S_CMP()
unorded = true;
bool QuietNan = false;
if ((*(uint32_t *)_FPR_S[m_Opcode.fs] >= 0x7FC00000 && *(uint32_t *)_FPR_S[m_Opcode.fs] <= 0x7FFFFFFF) ||
(*(uint32_t *)_FPR_S[m_Opcode.fs] >= 0xFFC00000 && *(uint32_t *)_FPR_S[m_Opcode.fs] <= 0xFFFFFFFF))
if ((*(uint32_t *)_FPR_S_L[m_Opcode.fs] >= 0x7FC00000 && *(uint32_t *)_FPR_S_L[m_Opcode.fs] <= 0x7FFFFFFF) ||
(*(uint32_t *)_FPR_S_L[m_Opcode.fs] >= 0xFFC00000 && *(uint32_t *)_FPR_S_L[m_Opcode.fs] <= 0xFFFFFFFF))
{
QuietNan = true;
}
else if ((*(uint32_t *)_FPR_S[m_Opcode.ft] >= 0x7FC00000 && *(uint32_t *)_FPR_S[m_Opcode.ft] <= 0x7FFFFFFF) ||
(*(uint32_t *)_FPR_S[m_Opcode.ft] >= 0xFFC00000 && *(uint32_t *)_FPR_S[m_Opcode.ft] <= 0xFFFFFFFF))
else if ((*(uint32_t *)_FPR_UW[m_Opcode.ft] >= 0x7FC00000 && *(uint32_t *)_FPR_UW[m_Opcode.ft] <= 0x7FFFFFFF) ||
(*(uint32_t *)_FPR_UW[m_Opcode.ft] >= 0xFFC00000 && *(uint32_t *)_FPR_UW[m_Opcode.ft] <= 0xFFFFFFFF))
{
QuietNan = true;
}
@ -2449,16 +2442,16 @@ void R4300iOp::COP1_D_ADD()
return;
}
if (CheckFPUInput64(*(double *)_FPR_D[m_Opcode.fs]) || CheckFPUInput64(*(double *)_FPR_D[m_Opcode.ft]))
if (CheckFPUInput64(*(double *)_FPR_D[m_Opcode.fs]) || CheckFPUInput64(*(double *)_FPR_UDW[m_Opcode.ft]))
{
return;
}
double Result = (*(double *)_FPR_D[m_Opcode.fs] + *(double *)_FPR_D[m_Opcode.ft]);
double Result = (*(double *)_FPR_D[m_Opcode.fs] + *(double *)_FPR_UDW[m_Opcode.ft]);
if (CheckFPUResult64(Result))
{
return;
}
*(uint64_t *)_FPR_D[m_Opcode.fd] = *(uint64_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint64_t *)&Result;
}
void R4300iOp::COP1_D_SUB()
@ -2468,16 +2461,16 @@ void R4300iOp::COP1_D_SUB()
return;
}
if (CheckFPUInput64(*(double *)_FPR_D[m_Opcode.fs]) || CheckFPUInput64(*(double *)_FPR_D[m_Opcode.ft]))
if (CheckFPUInput64(*(double *)_FPR_D[m_Opcode.fs]) || CheckFPUInput64(*(double *)_FPR_UDW[m_Opcode.ft]))
{
return;
}
double Result = (*(double *)_FPR_D[m_Opcode.fs] - *(double *)_FPR_D[m_Opcode.ft]);
double Result = (*(double *)_FPR_D[m_Opcode.fs] - *(double *)_FPR_UDW[m_Opcode.ft]);
if (CheckFPUResult64(Result))
{
return;
}
*(uint64_t *)_FPR_D[m_Opcode.fd] = *(uint64_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint64_t *)&Result;
}
void R4300iOp::COP1_D_MUL()
@ -2487,16 +2480,16 @@ void R4300iOp::COP1_D_MUL()
return;
}
if (CheckFPUInput64(*(double *)_FPR_D[m_Opcode.fs]) || CheckFPUInput64(*(double *)_FPR_D[m_Opcode.ft]))
if (CheckFPUInput64(*(double *)_FPR_D[m_Opcode.fs]) || CheckFPUInput64(*(double *)_FPR_UDW[m_Opcode.ft]))
{
return;
}
double Result = (*(double *)_FPR_D[m_Opcode.fs] * *(double *)_FPR_D[m_Opcode.ft]);
double Result = (*(double *)_FPR_D[m_Opcode.fs] * *(double *)_FPR_UDW[m_Opcode.ft]);
if (CheckFPUResult64(Result))
{
return;
}
*(uint64_t *)_FPR_D[m_Opcode.fd] = *(uint64_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint64_t *)&Result;
}
void R4300iOp::COP1_D_DIV()
@ -2506,16 +2499,16 @@ void R4300iOp::COP1_D_DIV()
return;
}
if (CheckFPUInput64(*(double *)_FPR_D[m_Opcode.fs]) || CheckFPUInput64(*(double *)_FPR_D[m_Opcode.ft]))
if (CheckFPUInput64(*(double *)_FPR_D[m_Opcode.fs]) || CheckFPUInput64(*(double *)_FPR_UDW[m_Opcode.ft]))
{
return;
}
double Result = (*(double *)_FPR_D[m_Opcode.fs] / *(double *)_FPR_D[m_Opcode.ft]);
double Result = (*(double *)_FPR_D[m_Opcode.fs] / *(double *)_FPR_UDW[m_Opcode.ft]);
if (CheckFPUResult64(Result))
{
return;
}
*(uint64_t *)_FPR_D[m_Opcode.fd] = *(uint64_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint64_t *)&Result;
}
void R4300iOp::COP1_D_SQRT()
@ -2534,7 +2527,7 @@ void R4300iOp::COP1_D_SQRT()
{
return;
}
*(uint64_t *)_FPR_D[m_Opcode.fd] = *(uint64_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint64_t *)&Result;
}
void R4300iOp::COP1_D_ABS()
@ -2553,7 +2546,7 @@ void R4300iOp::COP1_D_ABS()
{
return;
}
*(uint64_t *)_FPR_D[m_Opcode.fd] = *(uint64_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint64_t *)&Result;
}
void R4300iOp::COP1_D_MOV()
@ -2562,14 +2555,7 @@ void R4300iOp::COP1_D_MOV()
{
return;
}
switch (((FPStatusReg &)_FPCR[31]).RoundingMode)
{
case FPRoundingMode_RoundToNearest: fesetround(FE_TONEAREST); break;
case FPRoundingMode_RoundTowardZero: fesetround(FE_TOWARDZERO); break;
case FPRoundingMode_RoundTowardPlusInfinity: fesetround(FE_UPWARD); break;
case FPRoundingMode_RoundTowardMinusInfinity: fesetround(FE_DOWNWARD); break;
}
*(int64_t *)_FPR_D[m_Opcode.fd] = *(int64_t *)_FPR_D[m_Opcode.fs];
*_FPR_UDW[m_Opcode.fd] = *(int64_t *)_FPR_D[m_Opcode.fs];
}
void R4300iOp::COP1_D_NEG()
@ -2588,7 +2574,7 @@ void R4300iOp::COP1_D_NEG()
{
return;
}
*(uint64_t *)_FPR_D[m_Opcode.fd] = *(uint64_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint64_t *)&Result;
}
void R4300iOp::COP1_D_ROUND_L()
@ -2607,7 +2593,7 @@ void R4300iOp::COP1_D_ROUND_L()
{
return;
}
*(uint64_t *)_FPR_D[m_Opcode.fd] = (uint64_t)Result;
*_FPR_UDW[m_Opcode.fd] = (uint64_t)Result;
}
void R4300iOp::COP1_D_TRUNC_L()
@ -2626,7 +2612,7 @@ void R4300iOp::COP1_D_TRUNC_L()
{
return;
}
*(uint64_t *)_FPR_D[m_Opcode.fd] = (uint64_t)Result;
*_FPR_UDW[m_Opcode.fd] = (uint64_t)Result;
}
void R4300iOp::COP1_D_CEIL_L()
@ -2645,7 +2631,7 @@ void R4300iOp::COP1_D_CEIL_L()
{
return;
}
*(uint64_t *)_FPR_D[m_Opcode.fd] = (uint64_t)Result;
*_FPR_UDW[m_Opcode.fd] = (uint64_t)Result;
}
void R4300iOp::COP1_D_FLOOR_L()
@ -2664,7 +2650,7 @@ void R4300iOp::COP1_D_FLOOR_L()
{
return;
}
*(uint64_t *)_FPR_D[m_Opcode.fd] = (uint64_t)Result;
*_FPR_UDW[m_Opcode.fd] = (uint64_t)Result;
}
void R4300iOp::COP1_D_ROUND_W()
@ -2682,7 +2668,7 @@ void R4300iOp::COP1_D_ROUND_W()
{
return;
}
*(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint32_t *)&Result;
}
void R4300iOp::COP1_D_TRUNC_W()
@ -2700,7 +2686,7 @@ void R4300iOp::COP1_D_TRUNC_W()
{
return;
}
*(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint32_t *)&Result;
}
void R4300iOp::COP1_D_CEIL_W()
@ -2718,7 +2704,7 @@ void R4300iOp::COP1_D_CEIL_W()
{
return;
}
*(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint32_t *)&Result;
}
void R4300iOp::COP1_D_FLOOR_W()
@ -2736,7 +2722,7 @@ void R4300iOp::COP1_D_FLOOR_W()
{
return;
}
*(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint32_t *)&Result;
}
void R4300iOp::COP1_D_CVT_S()
@ -2754,7 +2740,7 @@ void R4300iOp::COP1_D_CVT_S()
{
return;
}
*(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint32_t *)&Result;
}
void R4300iOp::COP1_D_CVT_W()
@ -2772,7 +2758,7 @@ void R4300iOp::COP1_D_CVT_W()
{
return;
}
*(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint32_t *)&Result;
}
void R4300iOp::COP1_D_CVT_L()
@ -2791,7 +2777,7 @@ void R4300iOp::COP1_D_CVT_L()
{
return;
}
*(uint64_t *)_FPR_D[m_Opcode.fd] = (uint64_t)Result;
*_FPR_UDW[m_Opcode.fd] = (uint64_t)Result;
}
void R4300iOp::COP1_D_CMP()
@ -2803,7 +2789,7 @@ void R4300iOp::COP1_D_CMP()
MIPS_DWORD Temp0, Temp1;
Temp0.DW = *(int64_t *)_FPR_D[m_Opcode.fs];
Temp1.DW = *(int64_t *)_FPR_D[m_Opcode.ft];
Temp1.DW = *(int64_t *)_FPR_UDW[m_Opcode.ft];
bool less, equal, unorded;
if (_isnan(Temp0.D) || _isnan(Temp1.D))
@ -2818,8 +2804,8 @@ void R4300iOp::COP1_D_CMP()
{
QuietNan = true;
}
else if ((*(uint64_t *)_FPR_D[m_Opcode.ft] >= 0x7FF8000000000000 && *(uint64_t *)_FPR_D[m_Opcode.ft] <= 0x7FFFFFFFFFFFFFFF) ||
(*(uint64_t *)_FPR_D[m_Opcode.ft] >= 0xFFF8000000000000 && *(uint64_t *)_FPR_D[m_Opcode.ft] <= 0xFFFFFFFFFFFFFFFF))
else if ((*(uint64_t *)_FPR_UDW[m_Opcode.ft] >= 0x7FF8000000000000 && *(uint64_t *)_FPR_UDW[m_Opcode.ft] <= 0x7FFFFFFFFFFFFFFF) ||
(*(uint64_t *)_FPR_UDW[m_Opcode.ft] >= 0xFFF8000000000000 && *(uint64_t *)_FPR_UDW[m_Opcode.ft] <= 0xFFFFFFFFFFFFFFFF))
{
QuietNan = true;
}
@ -2866,12 +2852,12 @@ void R4300iOp::COP1_W_CVT_S()
{
return;
}
float Result = (float)*(int32_t *)_FPR_S[m_Opcode.fs];
float Result = (float)*(int32_t *)_FPR_S_L[m_Opcode.fs];
if (CheckFPUResult32(Result))
{
return;
}
*(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint32_t *)&Result;
}
void R4300iOp::COP1_W_CVT_D()
@ -2880,12 +2866,12 @@ void R4300iOp::COP1_W_CVT_D()
{
return;
}
double Result = (double)*(int32_t *)_FPR_S[m_Opcode.fs];
double Result = (double)*(int32_t *)_FPR_S_L[m_Opcode.fs];
if (CheckFPUResult64(Result))
{
return;
}
*(uint64_t *)_FPR_D[m_Opcode.fd] = *(uint64_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint64_t *)&Result;
}
// COP1: L functions
@ -2909,7 +2895,7 @@ void R4300iOp::COP1_L_CVT_S()
{
return;
}
*(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint32_t *)&Result;
}
void R4300iOp::COP1_L_CVT_D()
@ -2931,7 +2917,7 @@ void R4300iOp::COP1_L_CVT_D()
{
return;
}
*(uint64_t *)_FPR_D[m_Opcode.fd] = *(uint64_t *)&Result;
*_FPR_UDW[m_Opcode.fd] = *(uint64_t *)&Result;
}
// COP2 functions

View File

@ -224,7 +224,10 @@ MIPS_DWORD * CSystemRegisters::_FPR = nullptr;
uint64_t * CSystemRegisters::_CP0 = nullptr;
MIPS_DWORD * CSystemRegisters::_RegHI = nullptr;
MIPS_DWORD * CSystemRegisters::_RegLO = nullptr;
uint32_t ** CSystemRegisters::_FPR_UW = nullptr;
uint64_t ** CSystemRegisters::_FPR_UDW = nullptr;
float ** CSystemRegisters::_FPR_S;
float ** CSystemRegisters::_FPR_S_L;
double ** CSystemRegisters::_FPR_D;
uint32_t * CSystemRegisters::_FPCR = nullptr;
uint32_t * CSystemRegisters::_LLBit = nullptr;
@ -537,7 +540,10 @@ void CRegisters::SetAsCurrentSystem()
_CP0 = m_CP0;
_RegHI = &m_HI;
_RegLO = &m_LO;
_FPR_UW = m_FPR_UW;
_FPR_UDW = m_FPR_UDW;
_FPR_S = m_FPR_S;
_FPR_S_L = m_FPR_S_L;
_FPR_D = m_FPR_D;
_FPCR = m_FPCR;
_LLBit = &m_LLBit;
@ -755,22 +761,14 @@ void CRegisters::DoAddressError(uint64_t BadVaddr, bool FromRead)
void CRegisters::FixFpuLocations()
{
if (STATUS_REGISTER.FR == 0)
for (uint8_t i = 0; i < 32; i++)
{
for (int count = 0; count < 32; count++)
{
m_FPR_S[count] = &m_FPR[count & ~1].F[count & 1];
m_FPR_D[count] = &m_FPR[count & ~1].D;
}
}
else
{
for (int count = 0; count < 32; count++)
{
m_FPR_S[count] = &m_FPR[count].F[0];
m_FPR_D[count] = &m_FPR[count].D;
}
}
m_FPR_UW[i] = &m_FPR[i].UW[0];
m_FPR_UDW[i] = &m_FPR[i].UDW;
m_FPR_S[i] = STATUS_REGISTER.FR == 0 ? &m_FPR[i & ~1].F[i & 1] : &m_FPR[i].F[0];
m_FPR_S_L[i] = STATUS_REGISTER.FR == 0 ? &m_FPR[i & ~1].F[0] : &m_FPR[i].F[0];
m_FPR_D[i] = STATUS_REGISTER.FR == 0 ? &m_FPR[i & ~1].D : &m_FPR[i].D;
}
}
bool CRegisters::DoIntrException()

View File

@ -427,7 +427,10 @@ protected:
static uint64_t * _CP0;
static MIPS_DWORD * _RegHI;
static MIPS_DWORD * _RegLO;
static uint32_t ** _FPR_UW;
static uint64_t ** _FPR_UDW;
static float ** _FPR_S;
static float ** _FPR_S_L;
static double ** _FPR_D;
static uint32_t * _FPCR;
static uint32_t * _LLBit;
@ -521,7 +524,10 @@ public:
// Floating point registers/information
uint32_t m_FPCR[32];
MIPS_DWORD m_FPR[32];
uint32_t * m_FPR_UW[32];
uint64_t * m_FPR_UDW[32];
float * m_FPR_S[32];
float * m_FPR_S_L[32];
double * m_FPR_D[32];
// Memory-mapped N64 registers

View File

@ -4002,7 +4002,7 @@ void CX86RecompilerOps::LWC1()
LW_KnownAddress(TempReg1, Address);
asmjit::x86::Gp TempReg2 = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false);
m_Assembler.MoveVariableToX86reg(TempReg2, &m_Reg.m_FPR_S[m_Opcode.ft], stdstr_f("_FPR_S[%d]", m_Opcode.ft).c_str());
m_Assembler.MoveVariableToX86reg(TempReg2, &m_Reg.m_FPR_S[m_Opcode.ft], stdstr_f("m_FPR_S[%d]", m_Opcode.ft).c_str());
m_Assembler.mov(asmjit::x86::dword_ptr(TempReg2), TempReg1);
return;
}
@ -4010,7 +4010,7 @@ void CX86RecompilerOps::LWC1()
asmjit::x86::Gp ValueReg = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false);
CompileLoadMemoryValue(x86Reg_Unknown, ValueReg, x86Reg_Unknown, 32, false);
asmjit::x86::Gp FPR_SPtr = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false);
m_Assembler.MoveVariableToX86reg(FPR_SPtr, &m_Reg.m_FPR_S[m_Opcode.ft], stdstr_f("_FPR_S[%d]", m_Opcode.ft).c_str());
m_Assembler.MoveVariableToX86reg(FPR_SPtr, &m_Reg.m_FPR_S[m_Opcode.ft], stdstr_f("m_FPR_S[%d]", m_Opcode.ft).c_str());
m_Assembler.mov(asmjit::x86::dword_ptr(FPR_SPtr), ValueReg);
}
@ -4036,7 +4036,7 @@ void CX86RecompilerOps::LDC1()
m_Assembler.mov(asmjit::x86::dword_ptr(TempReg2), TempReg1);
LW_KnownAddress(TempReg1, Address + 4);
m_Assembler.MoveVariableToX86reg(TempReg2, &m_Reg.m_FPR_D[m_Opcode.ft], stdstr_f("_FPR_S[%d]", m_Opcode.ft).c_str());
m_Assembler.MoveVariableToX86reg(TempReg2, &m_Reg.m_FPR_D[m_Opcode.ft], stdstr_f("m_FPR_S[%d]", m_Opcode.ft).c_str());
m_Assembler.mov(asmjit::x86::dword_ptr(TempReg2), TempReg1);
}
else
@ -4123,7 +4123,7 @@ void CX86RecompilerOps::SWC1()
m_RegWorkingSet.UnMap_FPR(m_Opcode.ft, true);
asmjit::x86::Gp TempReg1 = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false);
m_Assembler.MoveVariableToX86reg(TempReg1, &m_Reg.m_FPR_S[m_Opcode.ft], stdstr_f("_FPR_S[%d]", m_Opcode.ft).c_str());
m_Assembler.MoveVariableToX86reg(TempReg1, &m_Reg.m_FPR_S[m_Opcode.ft], stdstr_f("m_FPR_S[%d]", m_Opcode.ft).c_str());
m_Assembler.mov(TempReg1, asmjit::x86::dword_ptr(TempReg1));
SW_Register(TempReg1, Address);
return;
@ -4131,7 +4131,7 @@ void CX86RecompilerOps::SWC1()
PreWriteInstruction();
m_RegWorkingSet.UnMap_FPR(m_Opcode.ft, true);
asmjit::x86::Gp ValueReg = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false);
m_Assembler.MoveVariableToX86reg(ValueReg, &m_Reg.m_FPR_S[m_Opcode.ft], stdstr_f("_FPR_S[%d]", m_Opcode.ft).c_str());
m_Assembler.MoveVariableToX86reg(ValueReg, &m_Reg.m_FPR_S[m_Opcode.ft], stdstr_f("m_FPR_S[%d]", m_Opcode.ft).c_str());
m_Assembler.mov(ValueReg, asmjit::x86::dword_ptr(ValueReg));
CompileStoreMemoryValue(x86Reg_Unknown, ValueReg, x86Reg_Unknown, 0, 32);
@ -7466,7 +7466,7 @@ void CX86RecompilerOps::COP1_MF()
m_RegWorkingSet.UnMap_FPR(m_Opcode.fs, true);
m_RegWorkingSet.Map_GPR_32bit(m_Opcode.rt, true, -1);
asmjit::x86::Gp TempReg = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false);
m_Assembler.MoveVariableToX86reg(TempReg, (uint8_t *)&m_Reg.m_FPR_S[m_Opcode.fs], stdstr_f("_FPR_S[%d]", m_Opcode.fs).c_str());
m_Assembler.MoveVariableToX86reg(TempReg, (uint8_t *)&m_Reg.m_FPR_S[m_Opcode.fs], stdstr_f("m_FPR_S[%d]", m_Opcode.fs).c_str());
m_Assembler.mov(m_RegWorkingSet.GetMipsRegMapLo(m_Opcode.rt), asmjit::x86::dword_ptr(TempReg));
}
@ -7511,7 +7511,7 @@ void CX86RecompilerOps::COP1_MT()
}
m_RegWorkingSet.UnMap_FPR(m_Opcode.fs, true);
asmjit::x86::Gp TempReg = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false);
m_Assembler.MoveVariableToX86reg(TempReg, (uint8_t *)&m_Reg.m_FPR_S[m_Opcode.fs], stdstr_f("_FPR_S[%d]", m_Opcode.fs).c_str());
m_Assembler.MoveVariableToX86reg(TempReg, (uint8_t *)&m_Reg.m_FPR_S[m_Opcode.fs], stdstr_f("m_FPR_S[%d]", m_Opcode.fs).c_str());
if (m_RegWorkingSet.IsConst(m_Opcode.rt))
{
@ -7647,7 +7647,7 @@ void CX86RecompilerOps::COP1_S_ADD()
{
m_RegWorkingSet.UnMap_FPR(Reg2, true);
asmjit::x86::Gp TempReg = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false);
m_Assembler.MoveVariableToX86reg(TempReg, (uint8_t *)&m_Reg.m_FPR_S[Reg2], stdstr_f("_FPR_S[%d]", Reg2).c_str());
m_Assembler.MoveVariableToX86reg(TempReg, (uint8_t *)&m_Reg.m_FPR_S[Reg2], stdstr_f("m_FPR_S[%d]", Reg2).c_str());
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fd, CRegInfo::FPU_Float);
m_Assembler.fadd(asmjit::x86::dword_ptr(TempReg));
}
@ -7693,7 +7693,7 @@ void CX86RecompilerOps::COP1_S_SUB()
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float);
asmjit::x86::Gp TempReg = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false);
m_Assembler.MoveVariableToX86reg(TempReg, (uint8_t *)&m_Reg.m_FPR_S[m_Opcode.ft], stdstr_f("_FPR_S[%d]", m_Opcode.ft).c_str());
m_Assembler.MoveVariableToX86reg(TempReg, (uint8_t *)&m_Reg.m_FPR_S[m_Opcode.ft], stdstr_f("m_FPR_S[%d]", m_Opcode.ft).c_str());
m_Assembler.fsub(asmjit::x86::dword_ptr(TempReg));
}
else
@ -7709,7 +7709,7 @@ void CX86RecompilerOps::COP1_S_SUB()
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fd, CRegInfo::FPU_Float);
asmjit::x86::Gp TempReg = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false);
m_Assembler.MoveVariableToX86reg(TempReg, (uint8_t *)&m_Reg.m_FPR_S[Reg2], stdstr_f("_FPR_S[%d]", Reg2).c_str());
m_Assembler.MoveVariableToX86reg(TempReg, (uint8_t *)&m_Reg.m_FPR_S[Reg2], stdstr_f("m_FPR_S[%d]", Reg2).c_str());
m_Assembler.fsub(asmjit::x86::dword_ptr(TempReg));
}
}
@ -7760,7 +7760,7 @@ void CX86RecompilerOps::COP1_S_MUL()
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fd, CRegInfo::FPU_Float);
asmjit::x86::Gp TempReg = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false);
m_Assembler.MoveVariableToX86reg(TempReg, (uint8_t *)&m_Reg.m_FPR_S[Reg2], stdstr_f("_FPR_S[%d]", Reg2).c_str());
m_Assembler.MoveVariableToX86reg(TempReg, (uint8_t *)&m_Reg.m_FPR_S[Reg2], stdstr_f("m_FPR_S[%d]", Reg2).c_str());
m_Assembler.fmul(asmjit::x86::dword_ptr(TempReg));
}
m_RegWorkingSet.UnMap_FPR(m_Opcode.fd, true);
@ -7781,7 +7781,7 @@ void CX86RecompilerOps::COP1_S_DIV()
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float);
asmjit::x86::Gp TempReg = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false);
m_Assembler.MoveVariableToX86reg(TempReg, (uint8_t *)&m_Reg.m_FPR_S[m_Opcode.ft], stdstr_f("_FPR_S[%d]", m_Opcode.ft).c_str());
m_Assembler.MoveVariableToX86reg(TempReg, (uint8_t *)&m_Reg.m_FPR_S[m_Opcode.ft], stdstr_f("m_FPR_S[%d]", m_Opcode.ft).c_str());
m_Assembler.fdiv(asmjit::x86::dword_ptr(TempReg));
}
else
@ -7797,7 +7797,7 @@ void CX86RecompilerOps::COP1_S_DIV()
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fd, CRegInfo::FPU_Float);
asmjit::x86::Gp TempReg = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false);
m_Assembler.MoveVariableToX86reg(TempReg, (uint8_t *)&m_Reg.m_FPR_S[Reg2], stdstr_f("_FPR_S[%d]", Reg2).c_str());
m_Assembler.MoveVariableToX86reg(TempReg, (uint8_t *)&m_Reg.m_FPR_S[Reg2], stdstr_f("m_FPR_S[%d]", Reg2).c_str());
m_Assembler.fdiv(asmjit::x86::dword_ptr(TempReg));
}
}
@ -7987,7 +7987,7 @@ void CX86RecompilerOps::COP1_S_CMP()
m_RegWorkingSet.Load_FPR_ToTop(Reg1, Reg1, CRegInfo::FPU_Float);
asmjit::x86::Gp TempReg = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false);
m_Assembler.MoveVariableToX86reg(TempReg, (uint8_t *)&m_Reg.m_FPR_S[Reg2], stdstr_f("_FPR_S[%d]", Reg2).c_str());
m_Assembler.MoveVariableToX86reg(TempReg, (uint8_t *)&m_Reg.m_FPR_S[Reg2], stdstr_f("m_FPR_S[%d]", Reg2).c_str());
m_Assembler.fcom(asmjit::x86::dword_ptr(TempReg));
}
m_Assembler.AndConstToVariable(&m_Reg.m_FPCR[31], "_FPCR[31]", (uint32_t)~FPCSR_C);
@ -8646,7 +8646,7 @@ void CX86RecompilerOps::CompileCheckFPUResult32(int32_t DestReg)
}
m_Assembler.MoveVariableToX86reg(TempReg, &m_TempValue32, "TempValue32");
asmjit::x86::Gp TempRegFPR_S = ExitRegSet.Map_TempReg(x86Reg_Unknown, -1, false, false);
m_Assembler.MoveVariableToX86reg(TempRegFPR_S, &m_Reg.m_FPR_S[DestReg], stdstr_f("_FPR_S[%d]", DestReg).c_str());
m_Assembler.MoveVariableToX86reg(TempRegFPR_S, &m_Reg.m_FPR_S[DestReg], stdstr_f("m_FPR_S[%d]", DestReg).c_str());
m_Assembler.mov(asmjit::x86::dword_ptr(TempRegFPR_S), TempReg);
ExitRegSet.SetBlockCycleCount(ExitRegSet.GetBlockCycleCount() + g_System->CountPerOp());
CompileExit(m_CompilePC + 4, m_CompilePC + 4, ExitRegSet, ExitReason_Normal, false, &CX86Ops::JmpLabel);