Compare commits

...

7 Commits

Author SHA1 Message Date
Rosalie Wanders b78738e6ef a 2025-10-11 14:32:51 +02:00
Rosalie Wanders 9457552941 more work™️ 2025-10-11 13:40:36 +02:00
Rosalie Wanders a322eb773c gcc fix weeee 2025-10-11 13:40:36 +02:00
Rosalie Wanders c9d83bd67b try and fix compile error 2025-10-11 13:40:36 +02:00
Rosalie Wanders c8223edc9d work™️ 2025-10-11 13:40:36 +02:00
Rosalie Wanders ba24d0bc04 3rdParty: further improve accuracy for FPU functions in mupen64plus-core 2025-10-11 13:40:36 +02:00
Rosalie Wanders e3e04f3498 3rdParty: further improve accuracy for FPU functions in mupen64plus-core 2025-10-11 13:40:36 +02:00
4 changed files with 792 additions and 261 deletions
@@ -604,6 +604,7 @@ enum r4300_opcode r4300_decode(struct precomp_instr* inst, struct r4300_core* r4
idec_u53(iw, idec->u53[0], &inst->f.cf.fd);
switch(dummy)
{
case 0x10: inst->ops = cached_interp_CVT_S_S; return idec->opcode;
case 0x11: inst->ops = cached_interp_CVT_S_D; return idec->opcode;
case 0x14: inst->ops = cached_interp_CVT_S_W; return idec->opcode;
case 0x15: inst->ops = cached_interp_CVT_S_L; return idec->opcode;
File diff suppressed because it is too large Load Diff
@@ -1553,8 +1553,17 @@ DECLARE_INSTRUCTION(CTC1)
(*r4300_cp1_fcr31(&r4300->cp1)) = rrt32;
update_x86_rounding_mode(&r4300->cp1);
}
//if (((*r4300_cp1_fcr31(&r4300->cp1)) >> 7) & 0x1F) printf("FPU Exception enabled : %x\n",
// (int)(((*r4300_cp1_fcr31(&r4300->cp1)) >> 7) & 0x1F));
//printf("CTC1 rtt32 = 0x%08X\n", rrt32);
if (fpu_throw_exception(&rrt32))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -1630,7 +1639,13 @@ DECLARE_INSTRUCTION(ABS_S)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
abs_s(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (r4300_cp1_regs_simple(&r4300->cp1))[cffd]);
if (abs_s(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (r4300_cp1_regs_simple(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -1638,7 +1653,13 @@ DECLARE_INSTRUCTION(ABS_D)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
abs_d(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_double(&r4300->cp1))[cffs], (r4300_cp1_regs_double(&r4300->cp1))[cffd]);
if (abs_d(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_double(&r4300->cp1))[cffs], (r4300_cp1_regs_double(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -1646,7 +1667,13 @@ DECLARE_INSTRUCTION(ADD_S)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
add_s(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (r4300_cp1_regs_simple(&r4300->cp1))[cfft], (r4300_cp1_regs_simple(&r4300->cp1))[cffd]);
if (add_s(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (r4300_cp1_regs_simple(&r4300->cp1))[cfft], (r4300_cp1_regs_simple(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -1654,7 +1681,13 @@ DECLARE_INSTRUCTION(ADD_D)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
add_d(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_double(&r4300->cp1))[cffs], (r4300_cp1_regs_double(&r4300->cp1))[cfft], (r4300_cp1_regs_double(&r4300->cp1))[cffd]);
if (add_d(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_double(&r4300->cp1))[cffs], (r4300_cp1_regs_double(&r4300->cp1))[cfft], (r4300_cp1_regs_double(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -1662,7 +1695,13 @@ DECLARE_INSTRUCTION(DIV_S)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
div_s(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (r4300_cp1_regs_simple(&r4300->cp1))[cfft], (r4300_cp1_regs_simple(&r4300->cp1))[cffd]);
if (div_s(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (r4300_cp1_regs_simple(&r4300->cp1))[cfft], (r4300_cp1_regs_simple(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -1670,7 +1709,13 @@ DECLARE_INSTRUCTION(DIV_D)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
div_d(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_double(&r4300->cp1))[cffs], (r4300_cp1_regs_double(&r4300->cp1))[cfft], (r4300_cp1_regs_double(&r4300->cp1))[cffd]);
if (div_d(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_double(&r4300->cp1))[cffs], (r4300_cp1_regs_double(&r4300->cp1))[cfft], (r4300_cp1_regs_double(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -1694,7 +1739,13 @@ DECLARE_INSTRUCTION(MUL_S)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
mul_s(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (r4300_cp1_regs_simple(&r4300->cp1))[cfft], (r4300_cp1_regs_simple(&r4300->cp1))[cffd]);
if (mul_s(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (r4300_cp1_regs_simple(&r4300->cp1))[cfft], (r4300_cp1_regs_simple(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -1702,7 +1753,13 @@ DECLARE_INSTRUCTION(MUL_D)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
mul_d(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_double(&r4300->cp1))[cffs], (r4300_cp1_regs_double(&r4300->cp1))[cfft], (r4300_cp1_regs_double(&r4300->cp1))[cffd]);
if (mul_d(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_double(&r4300->cp1))[cffs], (r4300_cp1_regs_double(&r4300->cp1))[cfft], (r4300_cp1_regs_double(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -1710,7 +1767,13 @@ DECLARE_INSTRUCTION(NEG_S)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
neg_s(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (r4300_cp1_regs_simple(&r4300->cp1))[cffd]);
if (neg_s(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (r4300_cp1_regs_simple(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -1718,7 +1781,13 @@ DECLARE_INSTRUCTION(NEG_D)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
neg_d(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_double(&r4300->cp1))[cffs], (r4300_cp1_regs_double(&r4300->cp1))[cffd]);
if (neg_d(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_double(&r4300->cp1))[cffs], (r4300_cp1_regs_double(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -1726,7 +1795,13 @@ DECLARE_INSTRUCTION(SQRT_S)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
sqrt_s(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (r4300_cp1_regs_simple(&r4300->cp1))[cffd]);
if (sqrt_s(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (r4300_cp1_regs_simple(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -1734,7 +1809,13 @@ DECLARE_INSTRUCTION(SQRT_D)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
sqrt_d(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_double(&r4300->cp1))[cffs], (r4300_cp1_regs_double(&r4300->cp1))[cffd]);
if (sqrt_d(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_double(&r4300->cp1))[cffs], (r4300_cp1_regs_double(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -1742,7 +1823,13 @@ DECLARE_INSTRUCTION(SUB_S)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
sub_s(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (r4300_cp1_regs_simple(&r4300->cp1))[cfft], (r4300_cp1_regs_simple(&r4300->cp1))[cffd]);
if (sub_s(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (r4300_cp1_regs_simple(&r4300->cp1))[cfft], (r4300_cp1_regs_simple(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -1750,7 +1837,13 @@ DECLARE_INSTRUCTION(SUB_D)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
sub_d(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_double(&r4300->cp1))[cffs], (r4300_cp1_regs_double(&r4300->cp1))[cfft], (r4300_cp1_regs_double(&r4300->cp1))[cffd]);
if (sub_d(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_double(&r4300->cp1))[cffs], (r4300_cp1_regs_double(&r4300->cp1))[cfft], (r4300_cp1_regs_double(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -1758,7 +1851,13 @@ DECLARE_INSTRUCTION(TRUNC_W_S)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
trunc_w_s((r4300_cp1_regs_simple(&r4300->cp1))[cffs], (int32_t*) (r4300_cp1_regs_simple(&r4300->cp1))[cffd]);
if (trunc_w_s(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (int32_t*) (r4300_cp1_regs_simple(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -1790,7 +1889,13 @@ DECLARE_INSTRUCTION(ROUND_W_S)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
round_w_s((r4300_cp1_regs_simple(&r4300->cp1))[cffs], (int32_t*) (r4300_cp1_regs_simple(&r4300->cp1))[cffd]);
if (round_w_s(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (int32_t*) (r4300_cp1_regs_simple(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -1822,7 +1927,13 @@ DECLARE_INSTRUCTION(CEIL_W_S)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
ceil_w_s((r4300_cp1_regs_simple(&r4300->cp1))[cffs], (int32_t*) (r4300_cp1_regs_simple(&r4300->cp1))[cffd]);
if (ceil_w_s(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (int32_t*) (r4300_cp1_regs_simple(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -1882,11 +1993,29 @@ DECLARE_INSTRUCTION(FLOOR_L_D)
ADD_TO_PC(1);
}
DECLARE_INSTRUCTION(CVT_S_S)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
*r4300_cp1_fcr31(&r4300->cp1) |= FCR31_CAUSE_UNIMPLOP_BIT;
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
}
DECLARE_INSTRUCTION(CVT_S_D)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
cvt_s_d(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_double(&r4300->cp1))[cffs], (r4300_cp1_regs_simple(&r4300->cp1))[cffd]);
if (cvt_s_d(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_double(&r4300->cp1))[cffs], (r4300_cp1_regs_simple(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -1894,7 +2023,13 @@ DECLARE_INSTRUCTION(CVT_S_W)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
cvt_s_w(r4300_cp1_fcr31(&r4300->cp1), (int32_t*) (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (r4300_cp1_regs_simple(&r4300->cp1))[cffd]);
if (cvt_s_w(r4300_cp1_fcr31(&r4300->cp1), (int32_t*) (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (r4300_cp1_regs_simple(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -1902,7 +2037,13 @@ DECLARE_INSTRUCTION(CVT_S_L)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
cvt_s_l(r4300_cp1_fcr31(&r4300->cp1), (int64_t*) (r4300_cp1_regs_double(&r4300->cp1))[cffs], (r4300_cp1_regs_simple(&r4300->cp1))[cffd]);
if (cvt_s_l(r4300_cp1_fcr31(&r4300->cp1), (int64_t*) (r4300_cp1_regs_double(&r4300->cp1))[cffs], (r4300_cp1_regs_simple(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -1910,15 +2051,39 @@ DECLARE_INSTRUCTION(CVT_D_S)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
cvt_d_s(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (r4300_cp1_regs_double(&r4300->cp1))[cffd]);
if (cvt_d_s(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (r4300_cp1_regs_double(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
DECLARE_INSTRUCTION(CVT_D_D)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
*r4300_cp1_fcr31(&r4300->cp1) |= FCR31_CAUSE_UNIMPLOP_BIT;
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
}
DECLARE_INSTRUCTION(CVT_D_W)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
cvt_d_w(r4300_cp1_fcr31(&r4300->cp1), (int32_t*) (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (r4300_cp1_regs_double(&r4300->cp1))[cffd]);
if (cvt_d_w(r4300_cp1_fcr31(&r4300->cp1), (int32_t*) (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (r4300_cp1_regs_double(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -1926,7 +2091,13 @@ DECLARE_INSTRUCTION(CVT_D_L)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
cvt_d_l(r4300_cp1_fcr31(&r4300->cp1), (int64_t*) (r4300_cp1_regs_double(&r4300->cp1))[cffs], (r4300_cp1_regs_double(&r4300->cp1))[cffd]);
if (cvt_d_l(r4300_cp1_fcr31(&r4300->cp1), (int64_t*) (r4300_cp1_regs_double(&r4300->cp1))[cffs], (r4300_cp1_regs_double(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -1934,7 +2105,13 @@ DECLARE_INSTRUCTION(CVT_W_S)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
cvt_w_s(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (int32_t*) (r4300_cp1_regs_simple(&r4300->cp1))[cffd]);
if (cvt_w_s(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_simple(&r4300->cp1))[cffs], (int32_t*) (r4300_cp1_regs_simple(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -1942,7 +2119,13 @@ DECLARE_INSTRUCTION(CVT_W_D)
{
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
cvt_w_d(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_double(&r4300->cp1))[cffs], (int32_t*) (r4300_cp1_regs_simple(&r4300->cp1))[cffd]);
if (cvt_w_d(r4300_cp1_fcr31(&r4300->cp1), (r4300_cp1_regs_double(&r4300->cp1))[cffs], (int32_t*) (r4300_cp1_regs_simple(&r4300->cp1))[cffd]))
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_FPE;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
}
@@ -525,6 +525,7 @@ void InterpretOpcode(struct r4300_core* r4300)
case 13: TRUNC_W_S(r4300, op); break;
case 14: CEIL_W_S(r4300, op); break;
case 15: FLOOR_W_S(r4300, op); break;
case 32: CVT_S_S(r4300, op); break;
case 33: CVT_D_S(r4300, op); break;
case 36: CVT_W_S(r4300, op); break;
case 37: CVT_L_S(r4300, op); break;
@@ -569,6 +570,7 @@ void InterpretOpcode(struct r4300_core* r4300)
case 14: CEIL_W_D(r4300, op); break;
case 15: FLOOR_W_D(r4300, op); break;
case 32: CVT_S_D(r4300, op); break;
case 33: CVT_D_D(r4300, op); break;
case 36: CVT_W_D(r4300, op); break;
case 37: CVT_L_D(r4300, op); break;
case 48: C_F_D(r4300, op); break;
@@ -621,18 +623,9 @@ void InterpretOpcode(struct r4300_core* r4300)
break;
case 18: /* Coprocessor 2 prefix */
switch ((op >> 21) & 0x1F) {
case 0: /* Coprocessor 2 opcode 0: MFC2 */
if (RT_OF(op) != 0) MFC2(r4300, op);
else NOP(r4300, 0);
break;
case 1: /* Coprocessor 2 opcode 1: DMFC2 */
if (RT_OF(op) != 0) DMFC2(r4300, op);
else NOP(r4300, 0);
break;
case 2: /* Coprocessor 2 opcode 2: CFC2 */
if (RT_OF(op) != 0) CFC2(r4300, op);
else NOP(r4300, 0);
break;
case 0: MFC2(r4300, op); break;
case 1: DMFC2(r4300, op); break;
case 2: CFC2(r4300, op); break;
case 4: MTC2(r4300, op); break;
case 5: DMTC2(r4300, op); break;
case 6: CTC2(r4300, op); break;