Core: fix up how recompiler handles rounding
This commit is contained in:
parent
a80860605d
commit
6884c8d2c9
|
@ -1887,7 +1887,7 @@ void R4300iOp::COP0_CO_ERET()
|
|||
// COP1 functions
|
||||
void R4300iOp::CPO1_UNIMPLEMENTED_OP()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -1954,7 +1954,7 @@ void R4300iOp::COP1_CT()
|
|||
|
||||
void R4300iOp::COP1_BCF()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -1971,7 +1971,7 @@ void R4300iOp::COP1_BCF()
|
|||
|
||||
void R4300iOp::COP1_BCT()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -1988,7 +1988,7 @@ void R4300iOp::COP1_BCT()
|
|||
|
||||
void R4300iOp::COP1_BCFL()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2006,7 +2006,7 @@ void R4300iOp::COP1_BCFL()
|
|||
|
||||
void R4300iOp::COP1_BCTL()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2025,7 +2025,7 @@ void R4300iOp::COP1_BCTL()
|
|||
// COP1: S functions
|
||||
void R4300iOp::COP1_S_ADD()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2044,7 +2044,7 @@ void R4300iOp::COP1_S_ADD()
|
|||
|
||||
void R4300iOp::COP1_S_SUB()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2062,7 +2062,7 @@ void R4300iOp::COP1_S_SUB()
|
|||
|
||||
void R4300iOp::COP1_S_MUL()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2081,7 +2081,7 @@ void R4300iOp::COP1_S_MUL()
|
|||
|
||||
void R4300iOp::COP1_S_DIV()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2100,7 +2100,7 @@ void R4300iOp::COP1_S_DIV()
|
|||
|
||||
void R4300iOp::COP1_S_SQRT()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2119,7 +2119,7 @@ void R4300iOp::COP1_S_SQRT()
|
|||
|
||||
void R4300iOp::COP1_S_ABS()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2142,13 +2142,19 @@ void R4300iOp::COP1_S_MOV()
|
|||
{
|
||||
return;
|
||||
}
|
||||
fesetround(*_RoundingModel);
|
||||
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];
|
||||
}
|
||||
|
||||
void R4300iOp::COP1_S_NEG()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2167,7 +2173,7 @@ void R4300iOp::COP1_S_NEG()
|
|||
|
||||
void R4300iOp::COP1_S_ROUND_L()
|
||||
{
|
||||
if (InitFpuOperation(FE_TONEAREST))
|
||||
if (InitFpuOperation(FPRoundingMode_RoundToNearest))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2186,7 +2192,7 @@ void R4300iOp::COP1_S_ROUND_L()
|
|||
|
||||
void R4300iOp::COP1_S_TRUNC_L()
|
||||
{
|
||||
if (InitFpuOperation(FE_TOWARDZERO))
|
||||
if (InitFpuOperation(FPRoundingMode_RoundTowardZero))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2204,7 +2210,7 @@ void R4300iOp::COP1_S_TRUNC_L()
|
|||
|
||||
void R4300iOp::COP1_S_CEIL_L()
|
||||
{
|
||||
if (InitFpuOperation(FE_UPWARD))
|
||||
if (InitFpuOperation(FPRoundingMode_RoundTowardPlusInfinity))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2222,7 +2228,7 @@ void R4300iOp::COP1_S_CEIL_L()
|
|||
|
||||
void R4300iOp::COP1_S_FLOOR_L()
|
||||
{
|
||||
if (InitFpuOperation(FE_DOWNWARD))
|
||||
if (InitFpuOperation(FPRoundingMode_RoundTowardMinusInfinity))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2240,7 +2246,7 @@ void R4300iOp::COP1_S_FLOOR_L()
|
|||
|
||||
void R4300iOp::COP1_S_ROUND_W()
|
||||
{
|
||||
if (InitFpuOperation(FE_TONEAREST))
|
||||
if (InitFpuOperation(FPRoundingMode_RoundToNearest))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2258,7 +2264,7 @@ void R4300iOp::COP1_S_ROUND_W()
|
|||
|
||||
void R4300iOp::COP1_S_TRUNC_W()
|
||||
{
|
||||
if (InitFpuOperation(FE_TOWARDZERO))
|
||||
if (InitFpuOperation(FPRoundingMode_RoundTowardZero))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2276,7 +2282,7 @@ void R4300iOp::COP1_S_TRUNC_W()
|
|||
|
||||
void R4300iOp::COP1_S_CEIL_W()
|
||||
{
|
||||
if (InitFpuOperation(FE_UPWARD))
|
||||
if (InitFpuOperation(FPRoundingMode_RoundTowardPlusInfinity))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2294,7 +2300,7 @@ void R4300iOp::COP1_S_CEIL_W()
|
|||
|
||||
void R4300iOp::COP1_S_FLOOR_W()
|
||||
{
|
||||
if (InitFpuOperation(FE_DOWNWARD))
|
||||
if (InitFpuOperation(FPRoundingMode_RoundTowardMinusInfinity))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2312,7 +2318,7 @@ void R4300iOp::COP1_S_FLOOR_W()
|
|||
|
||||
void R4300iOp::COP1_S_CVT_D()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2330,7 +2336,7 @@ void R4300iOp::COP1_S_CVT_D()
|
|||
|
||||
void R4300iOp::COP1_S_CVT_W()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2348,7 +2354,7 @@ void R4300iOp::COP1_S_CVT_W()
|
|||
|
||||
void R4300iOp::COP1_S_CVT_L()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2366,7 +2372,7 @@ void R4300iOp::COP1_S_CVT_L()
|
|||
|
||||
void R4300iOp::COP1_S_CMP()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2429,7 +2435,7 @@ void R4300iOp::COP1_S_CMP()
|
|||
// COP1: D functions
|
||||
void R4300iOp::COP1_D_ADD()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2448,7 +2454,7 @@ void R4300iOp::COP1_D_ADD()
|
|||
|
||||
void R4300iOp::COP1_D_SUB()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2467,7 +2473,7 @@ void R4300iOp::COP1_D_SUB()
|
|||
|
||||
void R4300iOp::COP1_D_MUL()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2486,7 +2492,7 @@ void R4300iOp::COP1_D_MUL()
|
|||
|
||||
void R4300iOp::COP1_D_DIV()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2505,7 +2511,7 @@ void R4300iOp::COP1_D_DIV()
|
|||
|
||||
void R4300iOp::COP1_D_SQRT()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2524,7 +2530,7 @@ void R4300iOp::COP1_D_SQRT()
|
|||
|
||||
void R4300iOp::COP1_D_ABS()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2547,13 +2553,19 @@ void R4300iOp::COP1_D_MOV()
|
|||
{
|
||||
return;
|
||||
}
|
||||
fesetround(*_RoundingModel);
|
||||
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];
|
||||
}
|
||||
|
||||
void R4300iOp::COP1_D_NEG()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2572,7 +2584,7 @@ void R4300iOp::COP1_D_NEG()
|
|||
|
||||
void R4300iOp::COP1_D_ROUND_L()
|
||||
{
|
||||
if (InitFpuOperation(FE_TONEAREST))
|
||||
if (InitFpuOperation(FPRoundingMode_RoundToNearest))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2591,7 +2603,7 @@ void R4300iOp::COP1_D_ROUND_L()
|
|||
|
||||
void R4300iOp::COP1_D_TRUNC_L()
|
||||
{
|
||||
if (InitFpuOperation(FE_TOWARDZERO))
|
||||
if (InitFpuOperation(FPRoundingMode_RoundTowardZero))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2610,7 +2622,7 @@ void R4300iOp::COP1_D_TRUNC_L()
|
|||
|
||||
void R4300iOp::COP1_D_CEIL_L()
|
||||
{
|
||||
if (InitFpuOperation(FE_UPWARD))
|
||||
if (InitFpuOperation(FPRoundingMode_RoundTowardPlusInfinity))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2629,7 +2641,7 @@ void R4300iOp::COP1_D_CEIL_L()
|
|||
|
||||
void R4300iOp::COP1_D_FLOOR_L()
|
||||
{
|
||||
if (InitFpuOperation(FE_DOWNWARD))
|
||||
if (InitFpuOperation(FPRoundingMode_RoundTowardMinusInfinity))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2648,7 +2660,7 @@ void R4300iOp::COP1_D_FLOOR_L()
|
|||
|
||||
void R4300iOp::COP1_D_ROUND_W()
|
||||
{
|
||||
if (InitFpuOperation(FE_TONEAREST))
|
||||
if (InitFpuOperation(FPRoundingMode_RoundToNearest))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2666,7 +2678,7 @@ void R4300iOp::COP1_D_ROUND_W()
|
|||
|
||||
void R4300iOp::COP1_D_TRUNC_W()
|
||||
{
|
||||
if (InitFpuOperation(FE_TOWARDZERO))
|
||||
if (InitFpuOperation(FPRoundingMode_RoundTowardZero))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2684,7 +2696,7 @@ void R4300iOp::COP1_D_TRUNC_W()
|
|||
|
||||
void R4300iOp::COP1_D_CEIL_W()
|
||||
{
|
||||
if (InitFpuOperation(FE_UPWARD))
|
||||
if (InitFpuOperation(FPRoundingMode_RoundTowardPlusInfinity))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2702,7 +2714,7 @@ void R4300iOp::COP1_D_CEIL_W()
|
|||
|
||||
void R4300iOp::COP1_D_FLOOR_W()
|
||||
{
|
||||
if (InitFpuOperation(FE_DOWNWARD))
|
||||
if (InitFpuOperation(FPRoundingMode_RoundTowardMinusInfinity))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2720,7 +2732,7 @@ void R4300iOp::COP1_D_FLOOR_W()
|
|||
|
||||
void R4300iOp::COP1_D_CVT_S()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2738,7 +2750,7 @@ void R4300iOp::COP1_D_CVT_S()
|
|||
|
||||
void R4300iOp::COP1_D_CVT_W()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2756,7 +2768,7 @@ void R4300iOp::COP1_D_CVT_W()
|
|||
|
||||
void R4300iOp::COP1_D_CVT_L()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2775,7 +2787,7 @@ void R4300iOp::COP1_D_CVT_L()
|
|||
|
||||
void R4300iOp::COP1_D_CMP()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2841,7 +2853,7 @@ void R4300iOp::COP1_D_CMP()
|
|||
// COP1: W functions
|
||||
void R4300iOp::COP1_W_CVT_S()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2855,7 +2867,7 @@ void R4300iOp::COP1_W_CVT_S()
|
|||
|
||||
void R4300iOp::COP1_W_CVT_D()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2871,7 +2883,7 @@ void R4300iOp::COP1_W_CVT_D()
|
|||
|
||||
void R4300iOp::COP1_L_CVT_S()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2893,7 +2905,7 @@ void R4300iOp::COP1_L_CVT_S()
|
|||
|
||||
void R4300iOp::COP1_L_CVT_D()
|
||||
{
|
||||
if (InitFpuOperation(*_RoundingModel))
|
||||
if (InitFpuOperation(((FPStatusReg &)_FPCR[31]).RoundingMode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -3218,16 +3230,16 @@ bool R4300iOp::CheckFPUResult32(float & Result)
|
|||
StatusReg.Cause.Inexact = 1;
|
||||
StatusReg.Flags.Inexact = 1;
|
||||
|
||||
switch (*_RoundingModel)
|
||||
switch (StatusReg.RoundingMode)
|
||||
{
|
||||
case FE_TONEAREST:
|
||||
case FE_TOWARDZERO:
|
||||
case FPRoundingMode_RoundToNearest:
|
||||
case FPRoundingMode_RoundTowardZero:
|
||||
Result = Result >= 0.0f ? 0.0f : -0.0f;
|
||||
break;
|
||||
case FE_UPWARD:
|
||||
case FPRoundingMode_RoundTowardPlusInfinity:
|
||||
Result = Result >= 0.0f ? 1.175494351e-38F : -0.0f;
|
||||
break;
|
||||
case FE_DOWNWARD:
|
||||
case FPRoundingMode_RoundTowardMinusInfinity:
|
||||
Result = Result >= 0.0f ? 0.0f : -1.175494351e-38F;
|
||||
break;
|
||||
}
|
||||
|
@ -3274,16 +3286,16 @@ bool R4300iOp::CheckFPUResult64(double & Result)
|
|||
StatusReg.Cause.Inexact = 1;
|
||||
StatusReg.Flags.Inexact = 1;
|
||||
|
||||
switch (*_RoundingModel)
|
||||
switch (StatusReg.RoundingMode)
|
||||
{
|
||||
case FE_TONEAREST:
|
||||
case FE_TOWARDZERO:
|
||||
case FPRoundingMode_RoundToNearest:
|
||||
case FPRoundingMode_RoundTowardZero:
|
||||
Result = Result >= 0.0 ? 0.0 : -0.0;
|
||||
break;
|
||||
case FE_UPWARD:
|
||||
case FPRoundingMode_RoundTowardPlusInfinity:
|
||||
Result = Result >= 0.0 ? 2.2250738585072014e-308 : -0.0;
|
||||
break;
|
||||
case FE_DOWNWARD:
|
||||
case FPRoundingMode_RoundTowardMinusInfinity:
|
||||
Result = Result >= 0.0 ? 0.0 : -2.2250738585072014e-308;
|
||||
break;
|
||||
}
|
||||
|
@ -3339,13 +3351,20 @@ bool R4300iOp::CheckFPUInvalidException(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool R4300iOp::InitFpuOperation(int RoundingModel)
|
||||
bool R4300iOp::InitFpuOperation(FPRoundingMode RoundingModel)
|
||||
{
|
||||
if (TestCop1UsableException())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
_FPCR[31] &= ~0x0003F000;
|
||||
switch (RoundingModel)
|
||||
{
|
||||
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;
|
||||
}
|
||||
fesetround(RoundingModel);
|
||||
feclearexcept(FE_ALL_EXCEPT);
|
||||
return false;
|
||||
|
|
|
@ -272,7 +272,7 @@ protected:
|
|||
static bool CheckFPUResult64(double & Result);
|
||||
static bool CheckFPUException(void);
|
||||
static bool CheckFPUInvalidException(void);
|
||||
static bool InitFpuOperation(int RoundingModel);
|
||||
static bool InitFpuOperation(FPRoundingMode RoundingModel);
|
||||
static bool SetFPUException(void);
|
||||
|
||||
static const uint32_t SWL_MASK[4], SWR_MASK[4], LWL_MASK[4], LWR_MASK[4];
|
||||
|
|
|
@ -226,7 +226,6 @@ float ** CSystemRegisters::_FPR_S;
|
|||
double ** CSystemRegisters::_FPR_D;
|
||||
uint32_t * CSystemRegisters::_FPCR = nullptr;
|
||||
uint32_t * CSystemRegisters::_LLBit = nullptr;
|
||||
int32_t * CSystemRegisters::_RoundingModel = nullptr;
|
||||
|
||||
CP0registers::CP0registers(uint64_t * _CP0) :
|
||||
INDEX_REGISTER(_CP0[0]),
|
||||
|
@ -295,8 +294,6 @@ void CRegisters::Reset()
|
|||
m_CP2Latch = 0;
|
||||
m_HI.DW = 0;
|
||||
m_LO.DW = 0;
|
||||
m_RoundingModel = FE_TONEAREST;
|
||||
|
||||
m_LLBit = 0;
|
||||
|
||||
// Reset system registers
|
||||
|
@ -330,7 +327,6 @@ void CRegisters::SetAsCurrentSystem()
|
|||
_FPR_D = m_FPR_D;
|
||||
_FPCR = m_FPCR;
|
||||
_LLBit = &m_LLBit;
|
||||
_RoundingModel = &m_RoundingModel;
|
||||
}
|
||||
|
||||
uint64_t CRegisters::Cop0_MF(COP0Reg Reg)
|
||||
|
@ -469,13 +465,6 @@ void CRegisters::Cop1_CT(uint32_t Reg, uint32_t Value)
|
|||
{
|
||||
FPStatusReg & StatusReg = (FPStatusReg &)_FPCR[31];
|
||||
StatusReg.Value = (Value & 0x183FFFF);
|
||||
switch (StatusReg.RoundingMode)
|
||||
{
|
||||
case 0: *_RoundingModel = FE_TONEAREST; break;
|
||||
case 1: *_RoundingModel = FE_TOWARDZERO; break;
|
||||
case 2: *_RoundingModel = FE_UPWARD; break;
|
||||
case 3: *_RoundingModel = FE_DOWNWARD; break;
|
||||
}
|
||||
|
||||
if (((StatusReg.Cause.Inexact & StatusReg.Enable.Inexact) != 0) ||
|
||||
((StatusReg.Cause.Underflow & StatusReg.Enable.Underflow) != 0) ||
|
||||
|
|
|
@ -62,13 +62,21 @@ union COP0XContext
|
|||
};
|
||||
};
|
||||
|
||||
enum FPRoundingMode : unsigned
|
||||
{
|
||||
FPRoundingMode_RoundToNearest = 0,
|
||||
FPRoundingMode_RoundTowardZero = 1,
|
||||
FPRoundingMode_RoundTowardPlusInfinity = 2,
|
||||
FPRoundingMode_RoundTowardMinusInfinity = 3,
|
||||
};
|
||||
|
||||
union FPStatusReg
|
||||
{
|
||||
uint32_t Value;
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned RoundingMode : 2;
|
||||
FPRoundingMode RoundingMode : 2;
|
||||
unsigned : 22;
|
||||
unsigned FlushSubnormals : 1;
|
||||
unsigned : 7;
|
||||
|
@ -341,7 +349,6 @@ protected:
|
|||
static double ** _FPR_D;
|
||||
static uint32_t * _FPCR;
|
||||
static uint32_t * _LLBit;
|
||||
static int32_t * _RoundingModel;
|
||||
};
|
||||
|
||||
class CN64System;
|
||||
|
@ -430,7 +437,6 @@ public:
|
|||
|
||||
// Floating point registers/information
|
||||
uint32_t m_FPCR[32];
|
||||
int32_t m_RoundingModel;
|
||||
MIPS_DWORD m_FPR[32];
|
||||
float * m_FPR_S[32];
|
||||
double * m_FPR_D[32];
|
||||
|
|
|
@ -1511,10 +1511,6 @@ void CN64System::SyncCPU(CN64System * const SecondCPU)
|
|||
{
|
||||
ErrorFound = true;
|
||||
}
|
||||
if (m_Reg.m_RoundingModel != SecondCPU->m_Reg.m_RoundingModel)
|
||||
{
|
||||
ErrorFound = true;
|
||||
}
|
||||
|
||||
for (int i = 0, n = sizeof(m_Reg.m_Mips_Interface) / sizeof(m_Reg.m_Mips_Interface[0]); i < n; i++)
|
||||
{
|
||||
|
@ -1669,10 +1665,6 @@ void CN64System::DumpSyncErrors(CN64System * SecondCPU)
|
|||
}
|
||||
m_TLB.RecordDifference(Error, SecondCPU->m_TLB);
|
||||
m_SystemTimer.RecordDifference(Error, SecondCPU->m_SystemTimer);
|
||||
if (m_Reg.m_RoundingModel != SecondCPU->m_Reg.m_RoundingModel)
|
||||
{
|
||||
Error.LogF("RoundingModel: %X %X\r\n", m_Reg.m_RoundingModel, SecondCPU->m_Reg.m_RoundingModel);
|
||||
}
|
||||
if (bFastSP() && m_Recomp)
|
||||
{
|
||||
uint32_t StackPointer = (m_Reg.m_GPR[29].W[0] & 0x1FFFFFFF);
|
||||
|
@ -1759,8 +1751,6 @@ void CN64System::DumpSyncErrors(CN64System * SecondCPU)
|
|||
count < 10 ? 7 : 6, " ", *(m_Reg.m_FPR_D[count]), *(SecondCPU->m_Reg.m_FPR_D[count]));
|
||||
}
|
||||
Error.Log("\r\n");
|
||||
Error.LogF("Rounding model, 0x%08X, 0x%08X\r\n", m_Reg.m_RoundingModel, SecondCPU->m_Reg.m_RoundingModel);
|
||||
Error.Log("\r\n");
|
||||
for (count = 0; count < 32; count++)
|
||||
{
|
||||
Error.LogF("CP0[%s],%*s0x%08X, 0x%08X\r\n", CRegName::Cop0[count],
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <fenv.h>
|
||||
#include <stdio.h>
|
||||
|
||||
uint32_t CX86RecompilerOps::m_RoundingModeValue = 0;
|
||||
uint32_t CX86RecompilerOps::m_TempValue32 = 0;
|
||||
uint64_t CX86RecompilerOps::m_TempValue64 = 0;
|
||||
uint32_t CX86RecompilerOps::m_BranchCompare = 0;
|
||||
|
@ -7438,10 +7439,10 @@ void CX86RecompilerOps::ChangeDefaultRoundingModel()
|
|||
{
|
||||
switch ((g_Reg->m_FPCR[31] & 3))
|
||||
{
|
||||
case 0: g_Reg->m_RoundingModel = FE_TONEAREST; break;
|
||||
case 1: g_Reg->m_RoundingModel = FE_TOWARDZERO; break;
|
||||
case 2: g_Reg->m_RoundingModel = FE_UPWARD; break;
|
||||
case 3: g_Reg->m_RoundingModel = FE_DOWNWARD; break;
|
||||
case 0: m_RoundingModeValue = 0x0000; break;
|
||||
case 1: m_RoundingModeValue = 0x0C00; break;
|
||||
case 2: m_RoundingModeValue = 0x0800; break;
|
||||
case 3: m_RoundingModeValue = 0x0400; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8480,6 +8481,7 @@ void CX86RecompilerOps::CompileCop1Test()
|
|||
return;
|
||||
}
|
||||
|
||||
m_Assembler.finit();
|
||||
m_Assembler.TestVariable(&g_Reg->STATUS_REGISTER, "STATUS_REGISTER", STATUS_CU1);
|
||||
CRegInfo ExitRegSet = m_RegWorkingSet;
|
||||
ExitRegSet.SetBlockCycleCount(ExitRegSet.GetBlockCycleCount() + g_System->CountPerOp());
|
||||
|
|
|
@ -23,6 +23,8 @@ class CX86RecompilerOps :
|
|||
protected CLogSettings,
|
||||
private CGameSettings
|
||||
{
|
||||
friend CX86RegInfo;
|
||||
|
||||
public:
|
||||
CX86RecompilerOps(CMipsMemoryVM & MMU, CRegisters & Reg, CCodeBlock & CodeBlock);
|
||||
~CX86RecompilerOps();
|
||||
|
@ -288,6 +290,7 @@ private:
|
|||
CX86RegInfo m_RegWorkingSet;
|
||||
CRegInfo m_RegBeforeDelay;
|
||||
bool m_EffectDelaySlot;
|
||||
static uint32_t m_RoundingModeValue;
|
||||
static uint32_t m_TempValue32;
|
||||
static uint64_t m_TempValue64;
|
||||
static uint32_t m_BranchCompare;
|
||||
|
|
|
@ -290,26 +290,8 @@ void CX86RegInfo::FixRoundModel(FPU_ROUND RoundMethod)
|
|||
|
||||
if (RoundMethod == RoundDefault)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
static const unsigned int msRound[4] =
|
||||
{
|
||||
0x00000000, //_RC_NEAR
|
||||
0x00000300, //_RC_CHOP
|
||||
0x00000200, //_RC_UP
|
||||
0x00000100, //_RC_DOWN
|
||||
};
|
||||
|
||||
asmjit::x86::Gp RoundReg = Map_TempReg(x86Reg_Unknown, -1, false, false);
|
||||
m_Assembler.MoveVariableToX86reg(RoundReg, &g_Reg->m_RoundingModel, "m_RoundingModel");
|
||||
m_Assembler.MoveVariableDispToX86Reg(RoundReg, (void *)&msRound[0], "msRound", RoundReg, CX86Ops::Multip_x4);
|
||||
|
||||
m_Assembler.shl(RoundReg, 2);
|
||||
m_Assembler.or_(reg, RoundReg);
|
||||
#else
|
||||
asmjit::x86::Gp RoundReg = Map_TempReg(x86Reg_Unknown, -1, false, false);
|
||||
m_Assembler.MoveVariableToX86reg(RoundReg, _RoundingModel, "_RoundingModel");
|
||||
m_Assembler.or_(reg, RoundReg);
|
||||
#endif
|
||||
m_Assembler.OrVariableToX86Reg(reg, &CX86RecompilerOps::m_RoundingModeValue, "m_RoundingModeValue");
|
||||
SetX86Protected(GetIndexFromX86Reg(RoundReg), false);
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue