Core: Convert TEST_COP1_USABLE_EXCEPTION from a macro to a function

This commit is contained in:
zilmar 2023-01-30 11:40:03 +10:30
parent f802b18cdc
commit 7affd514c0
2 changed files with 245 additions and 67 deletions

View File

@ -51,15 +51,6 @@ const int32_t R4300iOp::SWR_SHIFT[4] = {24, 16, 8, 0};
const int32_t R4300iOp::LWL_SHIFT[4] = {0, 8, 16, 24}; const int32_t R4300iOp::LWL_SHIFT[4] = {0, 8, 16, 24};
const int32_t R4300iOp::LWR_SHIFT[4] = {24, 16, 8, 0}; const int32_t R4300iOp::LWR_SHIFT[4] = {24, 16, 8, 0};
#define TEST_COP1_USABLE_EXCEPTION() \
if ((g_Reg->STATUS_REGISTER & STATUS_CU1) == 0) \
{ \
g_Reg->DoCopUnusableException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP, 1); \
g_System->m_PipelineStage = PIPELINE_STAGE_JUMP; \
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER); \
return; \
}
void R4300iOp::SPECIAL() void R4300iOp::SPECIAL()
{ {
Jump_Special[m_Opcode.funct](); Jump_Special[m_Opcode.funct]();
@ -1205,7 +1196,10 @@ void R4300iOp::LL()
void R4300iOp::LWC1() void R4300iOp::LWC1()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset;
g_MMU->LW_Memory(Address, *(uint32_t *)_FPR_S[m_Opcode.ft]); g_MMU->LW_Memory(Address, *(uint32_t *)_FPR_S[m_Opcode.ft]);
} }
@ -1235,14 +1229,20 @@ void R4300iOp::LD()
void R4300iOp::LDC1() void R4300iOp::LDC1()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset;
g_MMU->LD_Memory(Address, *(uint64_t *)_FPR_D[m_Opcode.ft]); g_MMU->LD_Memory(Address, *(uint64_t *)_FPR_D[m_Opcode.ft]);
} }
void R4300iOp::SWC1() void R4300iOp::SWC1()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset;
g_MMU->SW_Memory(Address, *(uint32_t *)_FPR_S[m_Opcode.ft]); g_MMU->SW_Memory(Address, *(uint32_t *)_FPR_S[m_Opcode.ft]);
@ -1250,7 +1250,10 @@ void R4300iOp::SWC1()
void R4300iOp::SDC1() void R4300iOp::SDC1()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset;
g_MMU->SD_Memory(Address, *((uint64_t *)_FPR_D[m_Opcode.ft])); g_MMU->SD_Memory(Address, *((uint64_t *)_FPR_D[m_Opcode.ft]));
} }
@ -1888,37 +1891,55 @@ void R4300iOp::COP0_CO_ERET()
void R4300iOp::COP1_MF() void R4300iOp::COP1_MF()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
_GPR[m_Opcode.rt].DW = *(int32_t *)_FPR_S[m_Opcode.fs]; _GPR[m_Opcode.rt].DW = *(int32_t *)_FPR_S[m_Opcode.fs];
} }
void R4300iOp::COP1_DMF() void R4300iOp::COP1_DMF()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
_GPR[m_Opcode.rt].DW = *(int64_t *)_FPR_D[m_Opcode.fs]; _GPR[m_Opcode.rt].DW = *(int64_t *)_FPR_D[m_Opcode.fs];
} }
void R4300iOp::COP1_CF() void R4300iOp::COP1_CF()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
_GPR[m_Opcode.rt].DW = (int32_t)_FPCR[m_Opcode.fs]; _GPR[m_Opcode.rt].DW = (int32_t)_FPCR[m_Opcode.fs];
} }
void R4300iOp::COP1_MT() void R4300iOp::COP1_MT()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
*(int32_t *)_FPR_S[m_Opcode.fs] = _GPR[m_Opcode.rt].W[0]; *(int32_t *)_FPR_S[m_Opcode.fs] = _GPR[m_Opcode.rt].W[0];
} }
void R4300iOp::COP1_DMT() void R4300iOp::COP1_DMT()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
*(int64_t *)_FPR_D[m_Opcode.fs] = _GPR[m_Opcode.rt].DW; *(int64_t *)_FPR_D[m_Opcode.fs] = _GPR[m_Opcode.rt].DW;
} }
void R4300iOp::COP1_CT() void R4300iOp::COP1_CT()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
g_Reg->Cop1_CT(m_Opcode.fs, _GPR[m_Opcode.rt].W[0]); g_Reg->Cop1_CT(m_Opcode.fs, _GPR[m_Opcode.rt].W[0]);
} }
@ -1926,7 +1947,10 @@ void R4300iOp::COP1_CT()
void R4300iOp::COP1_BCF() void R4300iOp::COP1_BCF()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
if ((_FPCR[31] & FPCSR_C) == 0) if ((_FPCR[31] & FPCSR_C) == 0)
{ {
@ -1940,7 +1964,10 @@ void R4300iOp::COP1_BCF()
void R4300iOp::COP1_BCT() void R4300iOp::COP1_BCT()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
if ((_FPCR[31] & FPCSR_C) != 0) if ((_FPCR[31] & FPCSR_C) != 0)
{ {
@ -1954,7 +1981,10 @@ void R4300iOp::COP1_BCT()
void R4300iOp::COP1_BCFL() void R4300iOp::COP1_BCFL()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
if ((_FPCR[31] & FPCSR_C) == 0) if ((_FPCR[31] & FPCSR_C) == 0)
{ {
g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
@ -1969,7 +1999,10 @@ void R4300iOp::COP1_BCFL()
void R4300iOp::COP1_BCTL() void R4300iOp::COP1_BCTL()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
if ((_FPCR[31] & FPCSR_C) != 0) if ((_FPCR[31] & FPCSR_C) != 0)
{ {
g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
@ -2068,35 +2101,50 @@ __inline void Float_RoundToInteger64(int64_t * Dest, const float * Source, int R
void R4300iOp::COP1_S_ADD() void R4300iOp::COP1_S_ADD()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
fesetround(*_RoundingModel); fesetround(*_RoundingModel);
*(float *)_FPR_S[m_Opcode.fd] = (*(float *)_FPR_S[m_Opcode.fs] + *(float *)_FPR_S[m_Opcode.ft]); *(float *)_FPR_S[m_Opcode.fd] = (*(float *)_FPR_S[m_Opcode.fs] + *(float *)_FPR_S[m_Opcode.ft]);
} }
void R4300iOp::COP1_S_SUB() void R4300iOp::COP1_S_SUB()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
fesetround(*_RoundingModel); fesetround(*_RoundingModel);
*(float *)_FPR_S[m_Opcode.fd] = (*(float *)_FPR_S[m_Opcode.fs] - *(float *)_FPR_S[m_Opcode.ft]); *(float *)_FPR_S[m_Opcode.fd] = (*(float *)_FPR_S[m_Opcode.fs] - *(float *)_FPR_S[m_Opcode.ft]);
} }
void R4300iOp::COP1_S_MUL() void R4300iOp::COP1_S_MUL()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
fesetround(*_RoundingModel); fesetround(*_RoundingModel);
*(float *)_FPR_S[m_Opcode.fd] = (*(float *)_FPR_S[m_Opcode.fs] * *(float *)_FPR_S[m_Opcode.ft]); *(float *)_FPR_S[m_Opcode.fd] = (*(float *)_FPR_S[m_Opcode.fs] * *(float *)_FPR_S[m_Opcode.ft]);
} }
void R4300iOp::COP1_S_DIV() void R4300iOp::COP1_S_DIV()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
fesetround(*_RoundingModel); fesetround(*_RoundingModel);
*(float *)_FPR_S[m_Opcode.fd] = (*(float *)_FPR_S[m_Opcode.fs] / *(float *)_FPR_S[m_Opcode.ft]); *(float *)_FPR_S[m_Opcode.fd] = (*(float *)_FPR_S[m_Opcode.fs] / *(float *)_FPR_S[m_Opcode.ft]);
} }
void R4300iOp::COP1_S_SQRT() void R4300iOp::COP1_S_SQRT()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
fesetround(*_RoundingModel); fesetround(*_RoundingModel);
*(float *)(_FPR_S[m_Opcode.fd]) = sqrtf(*(float *)(_FPR_S[m_Opcode.fs])); *(float *)(_FPR_S[m_Opcode.fd]) = sqrtf(*(float *)(_FPR_S[m_Opcode.fs]));
@ -2104,89 +2152,131 @@ void R4300iOp::COP1_S_SQRT()
void R4300iOp::COP1_S_ABS() void R4300iOp::COP1_S_ABS()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
fesetround(*_RoundingModel); fesetround(*_RoundingModel);
*(float *)_FPR_S[m_Opcode.fd] = (float)fabs(*(float *)_FPR_S[m_Opcode.fs]); *(float *)_FPR_S[m_Opcode.fd] = (float)fabs(*(float *)_FPR_S[m_Opcode.fs]);
} }
void R4300iOp::COP1_S_MOV() void R4300iOp::COP1_S_MOV()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
fesetround(*_RoundingModel); fesetround(*_RoundingModel);
*(float *)_FPR_S[m_Opcode.fd] = *(float *)_FPR_S[m_Opcode.fs]; *(float *)_FPR_S[m_Opcode.fd] = *(float *)_FPR_S[m_Opcode.fs];
} }
void R4300iOp::COP1_S_NEG() void R4300iOp::COP1_S_NEG()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
fesetround(*_RoundingModel); fesetround(*_RoundingModel);
*(float *)_FPR_S[m_Opcode.fd] = (*(float *)_FPR_S[m_Opcode.fs] * -1.0f); *(float *)_FPR_S[m_Opcode.fd] = (*(float *)_FPR_S[m_Opcode.fs] * -1.0f);
} }
void R4300iOp::COP1_S_ROUND_L() void R4300iOp::COP1_S_ROUND_L()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
Float_RoundToInteger64(&*(int64_t *)_FPR_D[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], FE_TONEAREST); Float_RoundToInteger64(&*(int64_t *)_FPR_D[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], FE_TONEAREST);
} }
void R4300iOp::COP1_S_TRUNC_L() void R4300iOp::COP1_S_TRUNC_L()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
Float_RoundToInteger64(&*(int64_t *)_FPR_D[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], FE_TOWARDZERO); Float_RoundToInteger64(&*(int64_t *)_FPR_D[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], FE_TOWARDZERO);
} }
void R4300iOp::COP1_S_CEIL_L() void R4300iOp::COP1_S_CEIL_L()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
Float_RoundToInteger64(&*(int64_t *)_FPR_D[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], FE_UPWARD); Float_RoundToInteger64(&*(int64_t *)_FPR_D[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], FE_UPWARD);
} }
void R4300iOp::COP1_S_FLOOR_L() void R4300iOp::COP1_S_FLOOR_L()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
Float_RoundToInteger64(&*(int64_t *)_FPR_D[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], FE_DOWNWARD); Float_RoundToInteger64(&*(int64_t *)_FPR_D[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], FE_DOWNWARD);
} }
void R4300iOp::COP1_S_ROUND_W() void R4300iOp::COP1_S_ROUND_W()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
Float_RoundToInteger32(&*(int32_t *)_FPR_S[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], FE_TONEAREST); Float_RoundToInteger32(&*(int32_t *)_FPR_S[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], FE_TONEAREST);
} }
void R4300iOp::COP1_S_TRUNC_W() void R4300iOp::COP1_S_TRUNC_W()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
Float_RoundToInteger32(&*(int32_t *)_FPR_S[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], FE_TOWARDZERO); Float_RoundToInteger32(&*(int32_t *)_FPR_S[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], FE_TOWARDZERO);
} }
void R4300iOp::COP1_S_CEIL_W() void R4300iOp::COP1_S_CEIL_W()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
Float_RoundToInteger32(&*(int32_t *)_FPR_S[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], FE_UPWARD); Float_RoundToInteger32(&*(int32_t *)_FPR_S[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], FE_UPWARD);
} }
void R4300iOp::COP1_S_FLOOR_W() void R4300iOp::COP1_S_FLOOR_W()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
Float_RoundToInteger32(&*(int32_t *)_FPR_S[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], FE_DOWNWARD); Float_RoundToInteger32(&*(int32_t *)_FPR_S[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], FE_DOWNWARD);
} }
void R4300iOp::COP1_S_CVT_D() void R4300iOp::COP1_S_CVT_D()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
fesetround(*_RoundingModel); fesetround(*_RoundingModel);
*(double *)_FPR_D[m_Opcode.fd] = (double)(*(float *)_FPR_S[m_Opcode.fs]); *(double *)_FPR_D[m_Opcode.fd] = (double)(*(float *)_FPR_S[m_Opcode.fs]);
} }
void R4300iOp::COP1_S_CVT_W() void R4300iOp::COP1_S_CVT_W()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
Float_RoundToInteger32(&*(int32_t *)_FPR_S[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], *_RoundingModel); Float_RoundToInteger32(&*(int32_t *)_FPR_S[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], *_RoundingModel);
} }
void R4300iOp::COP1_S_CVT_L() void R4300iOp::COP1_S_CVT_L()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
Float_RoundToInteger64(&*(int64_t *)_FPR_D[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], *_RoundingModel); Float_RoundToInteger64(&*(int64_t *)_FPR_D[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], *_RoundingModel);
} }
@ -2195,7 +2285,10 @@ void R4300iOp::COP1_S_CMP()
bool less, equal, unorded; bool less, equal, unorded;
int32_t condition; int32_t condition;
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
float Temp0 = *(float *)_FPR_S[m_Opcode.fs]; float Temp0 = *(float *)_FPR_S[m_Opcode.fs];
float Temp1 = *(float *)_FPR_S[m_Opcode.ft]; float Temp1 = *(float *)_FPR_S[m_Opcode.ft];
@ -2331,124 +2424,181 @@ __inline void Double_RoundToInteger64(int64_t * Dest, const double * Source, int
void R4300iOp::COP1_D_ADD() void R4300iOp::COP1_D_ADD()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
fesetround(*_RoundingModel); fesetround(*_RoundingModel);
*(double *)_FPR_D[m_Opcode.fd] = *(double *)_FPR_D[m_Opcode.fs] + *(double *)_FPR_D[m_Opcode.ft]; *(double *)_FPR_D[m_Opcode.fd] = *(double *)_FPR_D[m_Opcode.fs] + *(double *)_FPR_D[m_Opcode.ft];
} }
void R4300iOp::COP1_D_SUB() void R4300iOp::COP1_D_SUB()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
fesetround(*_RoundingModel); fesetround(*_RoundingModel);
*(double *)_FPR_D[m_Opcode.fd] = *(double *)_FPR_D[m_Opcode.fs] - *(double *)_FPR_D[m_Opcode.ft]; *(double *)_FPR_D[m_Opcode.fd] = *(double *)_FPR_D[m_Opcode.fs] - *(double *)_FPR_D[m_Opcode.ft];
} }
void R4300iOp::COP1_D_MUL() void R4300iOp::COP1_D_MUL()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
fesetround(*_RoundingModel); fesetround(*_RoundingModel);
*(double *)_FPR_D[m_Opcode.fd] = *(double *)_FPR_D[m_Opcode.fs] * *(double *)_FPR_D[m_Opcode.ft]; *(double *)_FPR_D[m_Opcode.fd] = *(double *)_FPR_D[m_Opcode.fs] * *(double *)_FPR_D[m_Opcode.ft];
} }
void R4300iOp::COP1_D_DIV() void R4300iOp::COP1_D_DIV()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
fesetround(*_RoundingModel); fesetround(*_RoundingModel);
*(double *)_FPR_D[m_Opcode.fd] = *(double *)_FPR_D[m_Opcode.fs] / *(double *)_FPR_D[m_Opcode.ft]; *(double *)_FPR_D[m_Opcode.fd] = *(double *)_FPR_D[m_Opcode.fs] / *(double *)_FPR_D[m_Opcode.ft];
} }
void R4300iOp::COP1_D_SQRT() void R4300iOp::COP1_D_SQRT()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
fesetround(*_RoundingModel); fesetround(*_RoundingModel);
*(double *)_FPR_D[m_Opcode.fd] = (double)sqrt(*(double *)_FPR_D[m_Opcode.fs]); *(double *)_FPR_D[m_Opcode.fd] = (double)sqrt(*(double *)_FPR_D[m_Opcode.fs]);
} }
void R4300iOp::COP1_D_ABS() void R4300iOp::COP1_D_ABS()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
fesetround(*_RoundingModel); fesetround(*_RoundingModel);
*(double *)_FPR_D[m_Opcode.fd] = fabs(*(double *)_FPR_D[m_Opcode.fs]); *(double *)_FPR_D[m_Opcode.fd] = fabs(*(double *)_FPR_D[m_Opcode.fs]);
} }
void R4300iOp::COP1_D_MOV() void R4300iOp::COP1_D_MOV()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
fesetround(*_RoundingModel); fesetround(*_RoundingModel);
*(int64_t *)_FPR_D[m_Opcode.fd] = *(int64_t *)_FPR_D[m_Opcode.fs]; *(int64_t *)_FPR_D[m_Opcode.fd] = *(int64_t *)_FPR_D[m_Opcode.fs];
} }
void R4300iOp::COP1_D_NEG() void R4300iOp::COP1_D_NEG()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
fesetround(*_RoundingModel); fesetround(*_RoundingModel);
*(double *)_FPR_D[m_Opcode.fd] = (*(double *)_FPR_D[m_Opcode.fs] * -1.0); *(double *)_FPR_D[m_Opcode.fd] = (*(double *)_FPR_D[m_Opcode.fs] * -1.0);
} }
void R4300iOp::COP1_D_ROUND_L() void R4300iOp::COP1_D_ROUND_L()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
Double_RoundToInteger64(&*(int64_t *)_FPR_D[m_Opcode.fd], &*(double *)_FPR_D[m_Opcode.fs], FE_TONEAREST); Double_RoundToInteger64(&*(int64_t *)_FPR_D[m_Opcode.fd], &*(double *)_FPR_D[m_Opcode.fs], FE_TONEAREST);
} }
void R4300iOp::COP1_D_TRUNC_L() void R4300iOp::COP1_D_TRUNC_L()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
Double_RoundToInteger64(&*(int64_t *)_FPR_D[m_Opcode.fd], &*(double *)_FPR_D[m_Opcode.fs], FE_TOWARDZERO); Double_RoundToInteger64(&*(int64_t *)_FPR_D[m_Opcode.fd], &*(double *)_FPR_D[m_Opcode.fs], FE_TOWARDZERO);
} }
void R4300iOp::COP1_D_CEIL_L() void R4300iOp::COP1_D_CEIL_L()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
Double_RoundToInteger64(&*(int64_t *)_FPR_D[m_Opcode.fd], &*(double *)_FPR_D[m_Opcode.fs], FE_UPWARD); Double_RoundToInteger64(&*(int64_t *)_FPR_D[m_Opcode.fd], &*(double *)_FPR_D[m_Opcode.fs], FE_UPWARD);
} }
void R4300iOp::COP1_D_FLOOR_L() void R4300iOp::COP1_D_FLOOR_L()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
Double_RoundToInteger64(&*(int64_t *)_FPR_D[m_Opcode.fd], &*(double *)_FPR_S[m_Opcode.fs], FE_DOWNWARD); Double_RoundToInteger64(&*(int64_t *)_FPR_D[m_Opcode.fd], &*(double *)_FPR_S[m_Opcode.fs], FE_DOWNWARD);
} }
void R4300iOp::COP1_D_ROUND_W() void R4300iOp::COP1_D_ROUND_W()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
Double_RoundToInteger32(&*(int32_t *)_FPR_S[m_Opcode.fd], &*(double *)_FPR_D[m_Opcode.fs], FE_TONEAREST); Double_RoundToInteger32(&*(int32_t *)_FPR_S[m_Opcode.fd], &*(double *)_FPR_D[m_Opcode.fs], FE_TONEAREST);
} }
void R4300iOp::COP1_D_TRUNC_W() void R4300iOp::COP1_D_TRUNC_W()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
Double_RoundToInteger32(&*(int32_t *)_FPR_S[m_Opcode.fd], &*(double *)_FPR_D[m_Opcode.fs], FE_TOWARDZERO); Double_RoundToInteger32(&*(int32_t *)_FPR_S[m_Opcode.fd], &*(double *)_FPR_D[m_Opcode.fs], FE_TOWARDZERO);
} }
void R4300iOp::COP1_D_CEIL_W() void R4300iOp::COP1_D_CEIL_W()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
Double_RoundToInteger32(&*(int32_t *)_FPR_S[m_Opcode.fd], &*(double *)_FPR_D[m_Opcode.fs], FE_UPWARD); Double_RoundToInteger32(&*(int32_t *)_FPR_S[m_Opcode.fd], &*(double *)_FPR_D[m_Opcode.fs], FE_UPWARD);
} }
void R4300iOp::COP1_D_FLOOR_W() void R4300iOp::COP1_D_FLOOR_W()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
Double_RoundToInteger32(&*(int32_t *)_FPR_D[m_Opcode.fd], &*(double *)_FPR_S[m_Opcode.fs], FE_DOWNWARD); Double_RoundToInteger32(&*(int32_t *)_FPR_D[m_Opcode.fd], &*(double *)_FPR_S[m_Opcode.fs], FE_DOWNWARD);
} }
void R4300iOp::COP1_D_CVT_S() void R4300iOp::COP1_D_CVT_S()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
fesetround(*_RoundingModel); fesetround(*_RoundingModel);
*(float *)_FPR_S[m_Opcode.fd] = (float)*(double *)_FPR_D[m_Opcode.fs]; *(float *)_FPR_S[m_Opcode.fd] = (float)*(double *)_FPR_D[m_Opcode.fs];
} }
void R4300iOp::COP1_D_CVT_W() void R4300iOp::COP1_D_CVT_W()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
Double_RoundToInteger32(&*(int32_t *)_FPR_S[m_Opcode.fd], &*(double *)_FPR_D[m_Opcode.fs], *_RoundingModel); Double_RoundToInteger32(&*(int32_t *)_FPR_S[m_Opcode.fd], &*(double *)_FPR_D[m_Opcode.fs], *_RoundingModel);
} }
void R4300iOp::COP1_D_CVT_L() void R4300iOp::COP1_D_CVT_L()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
Double_RoundToInteger64(&*(int64_t *)_FPR_D[m_Opcode.fd], &*(double *)_FPR_D[m_Opcode.fs], *_RoundingModel); Double_RoundToInteger64(&*(int64_t *)_FPR_D[m_Opcode.fd], &*(double *)_FPR_D[m_Opcode.fs], *_RoundingModel);
} }
@ -2458,7 +2608,10 @@ void R4300iOp::COP1_D_CMP()
int32_t condition; int32_t condition;
MIPS_DWORD Temp0, Temp1; MIPS_DWORD Temp0, Temp1;
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
Temp0.DW = *(int64_t *)_FPR_D[m_Opcode.fs]; Temp0.DW = *(int64_t *)_FPR_D[m_Opcode.fs];
Temp1.DW = *(int64_t *)_FPR_D[m_Opcode.ft]; Temp1.DW = *(int64_t *)_FPR_D[m_Opcode.ft];
@ -2504,14 +2657,20 @@ void R4300iOp::COP1_D_CMP()
void R4300iOp::COP1_W_CVT_S() void R4300iOp::COP1_W_CVT_S()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
fesetround(*_RoundingModel); fesetround(*_RoundingModel);
*(float *)_FPR_S[m_Opcode.fd] = (float)*(int32_t *)_FPR_S[m_Opcode.fs]; *(float *)_FPR_S[m_Opcode.fd] = (float)*(int32_t *)_FPR_S[m_Opcode.fs];
} }
void R4300iOp::COP1_W_CVT_D() void R4300iOp::COP1_W_CVT_D()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
fesetround(*_RoundingModel); fesetround(*_RoundingModel);
*(double *)_FPR_D[m_Opcode.fd] = (double)*(int32_t *)_FPR_S[m_Opcode.fs]; *(double *)_FPR_D[m_Opcode.fd] = (double)*(int32_t *)_FPR_S[m_Opcode.fs];
} }
@ -2520,14 +2679,20 @@ void R4300iOp::COP1_W_CVT_D()
void R4300iOp::COP1_L_CVT_S() void R4300iOp::COP1_L_CVT_S()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
fesetround(*_RoundingModel); fesetround(*_RoundingModel);
*(float *)_FPR_S[m_Opcode.fd] = (float)*(int64_t *)_FPR_D[m_Opcode.fs]; *(float *)_FPR_S[m_Opcode.fd] = (float)*(int64_t *)_FPR_D[m_Opcode.fs];
} }
void R4300iOp::COP1_L_CVT_D() void R4300iOp::COP1_L_CVT_D()
{ {
TEST_COP1_USABLE_EXCEPTION(); if (TestCop1UsableException())
{
return;
}
fesetround(*_RoundingModel); fesetround(*_RoundingModel);
*(double *)_FPR_D[m_Opcode.fd] = (double)*(int64_t *)_FPR_D[m_Opcode.fs]; *(double *)_FPR_D[m_Opcode.fd] = (double)*(int64_t *)_FPR_D[m_Opcode.fs];
} }
@ -2609,3 +2774,15 @@ void R4300iOp::GenerateTLBWriteException(uint64_t VAddr, const char * function)
g_System->m_PipelineStage = PIPELINE_STAGE_JUMP; g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER); g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);
} }
bool R4300iOp::TestCop1UsableException(void)
{
if ((g_Reg->STATUS_REGISTER & STATUS_CU1) == 0)
{
g_Reg->DoCopUnusableException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP, 1);
g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);
return true;
}
return false;
}

View File

@ -250,6 +250,7 @@ protected:
static void GenerateOverflowException(void); static void GenerateOverflowException(void);
static void GenerateTLBReadException(uint64_t VAddr, const char * function); static void GenerateTLBReadException(uint64_t VAddr, const char * function);
static void GenerateTLBWriteException(uint64_t VAddr, const char * function); static void GenerateTLBWriteException(uint64_t VAddr, const char * function);
static bool TestCop1UsableException(void);
static const uint32_t SWL_MASK[4], SWR_MASK[4], LWL_MASK[4], LWR_MASK[4]; static const uint32_t SWL_MASK[4], SWR_MASK[4], LWL_MASK[4], LWR_MASK[4];
static const int32_t SWL_SHIFT[4], SWR_SHIFT[4], LWL_SHIFT[4], LWR_SHIFT[4]; static const int32_t SWL_SHIFT[4], SWR_SHIFT[4], LWL_SHIFT[4], LWR_SHIFT[4];