diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp index 5759e0f65..af100bf17 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp @@ -481,7 +481,7 @@ R4300iOp::Func * R4300iOp::BuildInterpreter() Jump_CoP1_S[5] = COP1_S_ABS; Jump_CoP1_S[6] = COP1_S_MOV; Jump_CoP1_S[7] = COP1_S_NEG; - Jump_CoP1_S[8] = UnknownOpcode; + Jump_CoP1_S[8] = COP1_S_ROUND_L; Jump_CoP1_S[9] = COP1_S_TRUNC_L; Jump_CoP1_S[10] = COP1_S_CEIL_L; //added by Witten Jump_CoP1_S[11] = COP1_S_FLOOR_L; //added by Witten @@ -546,7 +546,7 @@ R4300iOp::Func * R4300iOp::BuildInterpreter() Jump_CoP1_D[5] = COP1_D_ABS; Jump_CoP1_D[6] = COP1_D_MOV; Jump_CoP1_D[7] = COP1_D_NEG; - Jump_CoP1_D[8] = UnknownOpcode; + Jump_CoP1_D[8] = COP1_D_ROUND_L; Jump_CoP1_D[9] = COP1_D_TRUNC_L; //added by Witten Jump_CoP1_D[10] = COP1_D_CEIL_L; //added by Witten Jump_CoP1_D[11] = COP1_D_FLOOR_L; //added by Witten @@ -2461,6 +2461,12 @@ void R4300iOp::COP1_S_NEG() *(float *)_FPR_S[m_Opcode.fd] = (*(float *)_FPR_S[m_Opcode.fs] * -1.0f); } +void R4300iOp::COP1_S_ROUND_L() +{ + TEST_COP1_USABLE_EXCEPTION(); + Float_RoundToInteger64(&*(int64_t *)_FPR_D[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], FE_TONEAREST); +} + void R4300iOp::COP1_S_TRUNC_L() { TEST_COP1_USABLE_EXCEPTION(); @@ -2652,6 +2658,12 @@ void R4300iOp::COP1_D_NEG() *(double *)_FPR_D[m_Opcode.fd] = (*(double *)_FPR_D[m_Opcode.fs] * -1.0); } +void R4300iOp::COP1_D_ROUND_L() +{ + TEST_COP1_USABLE_EXCEPTION(); + Double_RoundToInteger64(&*(uint64_t *)_FPR_S[m_Opcode.fd], &*(double *)_FPR_D[m_Opcode.fs], FE_TONEAREST); +} + void R4300iOp::COP1_D_TRUNC_L() { //added by Witten TEST_COP1_USABLE_EXCEPTION(); diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps.h b/Source/Project64-core/N64System/Interpreter/InterpreterOps.h index 6aeb7000d..cf370db61 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps.h +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps.h @@ -160,6 +160,7 @@ public: static void COP1_S_ABS(); static void COP1_S_MOV(); static void COP1_S_NEG(); + static void COP1_S_ROUND_L(); static void COP1_S_TRUNC_L(); static void COP1_S_CEIL_L(); //added by Witten static void COP1_S_FLOOR_L(); //added by Witten @@ -181,6 +182,7 @@ public: static void COP1_D_ABS(); static void COP1_D_MOV(); static void COP1_D_NEG(); + static void COP1_D_ROUND_L(); static void COP1_D_TRUNC_L(); //added by Witten static void COP1_D_CEIL_L(); //added by Witten static void COP1_D_FLOOR_L(); //added by Witten diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps32.cpp b/Source/Project64-core/N64System/Interpreter/InterpreterOps32.cpp index 09447ae6d..6d8324b36 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps32.cpp +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps32.cpp @@ -376,7 +376,7 @@ R4300iOp32::Func * R4300iOp32::BuildInterpreter() Jump_CoP1_S[5] = R4300iOp::COP1_S_ABS; Jump_CoP1_S[6] = R4300iOp::COP1_S_MOV; Jump_CoP1_S[7] = R4300iOp::COP1_S_NEG; - Jump_CoP1_S[8] = R4300iOp::UnknownOpcode; + Jump_CoP1_S[8] = R4300iOp::COP1_S_ROUND_L; Jump_CoP1_S[9] = R4300iOp::COP1_S_TRUNC_L; Jump_CoP1_S[10] = R4300iOp::COP1_S_CEIL_L; //added by Witten Jump_CoP1_S[11] = R4300iOp::COP1_S_FLOOR_L; //added by Witten @@ -441,7 +441,7 @@ R4300iOp32::Func * R4300iOp32::BuildInterpreter() Jump_CoP1_D[5] = R4300iOp::COP1_D_ABS; Jump_CoP1_D[6] = R4300iOp::COP1_D_MOV; Jump_CoP1_D[7] = R4300iOp::COP1_D_NEG; - Jump_CoP1_D[8] = R4300iOp::UnknownOpcode; + Jump_CoP1_D[8] = R4300iOp::COP1_D_ROUND_L; Jump_CoP1_D[9] = R4300iOp::COP1_D_TRUNC_L; //added by Witten Jump_CoP1_D[10] = R4300iOp::COP1_D_CEIL_L; //added by Witten Jump_CoP1_D[11] = R4300iOp::COP1_D_FLOOR_L; //added by Witten diff --git a/Source/Project64-core/N64System/Recompiler/CodeSection.cpp b/Source/Project64-core/N64System/Recompiler/CodeSection.cpp index 9cfc153db..f98aef1c2 100644 --- a/Source/Project64-core/N64System/Recompiler/CodeSection.cpp +++ b/Source/Project64-core/N64System/Recompiler/CodeSection.cpp @@ -1292,6 +1292,7 @@ bool CCodeSection::GenerateX86Code(uint32_t Test) case R4300i_COP1_FUNCT_NEG: COP1_S_NEG(); break; case R4300i_COP1_FUNCT_SQRT: COP1_S_SQRT(); break; case R4300i_COP1_FUNCT_MOV: COP1_S_MOV(); break; + case R4300i_COP1_FUNCT_ROUND_L: COP1_S_ROUND_L(); break; case R4300i_COP1_FUNCT_TRUNC_L: COP1_S_TRUNC_L(); break; case R4300i_COP1_FUNCT_CEIL_L: COP1_S_CEIL_L(); break; //added by Witten case R4300i_COP1_FUNCT_FLOOR_L: COP1_S_FLOOR_L(); break; //added by Witten @@ -1326,6 +1327,7 @@ bool CCodeSection::GenerateX86Code(uint32_t Test) case R4300i_COP1_FUNCT_NEG: COP1_D_NEG(); break; case R4300i_COP1_FUNCT_SQRT: COP1_D_SQRT(); break; case R4300i_COP1_FUNCT_MOV: COP1_D_MOV(); break; + case R4300i_COP1_FUNCT_ROUND_L: COP1_D_ROUND_L(); break; case R4300i_COP1_FUNCT_TRUNC_L: COP1_D_TRUNC_L(); break; //added by Witten case R4300i_COP1_FUNCT_CEIL_L: COP1_D_CEIL_L(); break; //added by Witten case R4300i_COP1_FUNCT_FLOOR_L: COP1_D_FLOOR_L(); break; //added by Witten diff --git a/Source/Project64-core/N64System/Recompiler/RecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/RecompilerOps.cpp index c7dd1f425..d697e157d 100644 --- a/Source/Project64-core/N64System/Recompiler/RecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/RecompilerOps.cpp @@ -5946,6 +5946,18 @@ void CRecompilerOps::COP1_S_MOV() Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); } +void CRecompilerOps::COP1_S_ROUND_L() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Qword, CRegInfo::RoundNearest); +} + void CRecompilerOps::COP1_S_TRUNC_L() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); @@ -6296,6 +6308,22 @@ void CRecompilerOps::COP1_D_MOV() Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); } +void CRecompilerOps::COP1_D_ROUND_L() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) + { + UnMap_FPR(m_Opcode.fs, true); + } + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Double)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Qword, CRegInfo::RoundNearest); +} + void CRecompilerOps::COP1_D_TRUNC_L() //added by Witten { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); diff --git a/Source/Project64-core/N64System/Recompiler/RecompilerOps.h b/Source/Project64-core/N64System/Recompiler/RecompilerOps.h index 0bcc46866..281829bba 100644 --- a/Source/Project64-core/N64System/Recompiler/RecompilerOps.h +++ b/Source/Project64-core/N64System/Recompiler/RecompilerOps.h @@ -160,6 +160,7 @@ protected: static void COP1_S_NEG (); static void COP1_S_SQRT (); static void COP1_S_MOV (); + static void COP1_S_ROUND_L (); static void COP1_S_TRUNC_L (); static void COP1_S_CEIL_L (); //added by Witten static void COP1_S_FLOOR_L (); //added by Witten @@ -181,6 +182,7 @@ protected: static void COP1_D_NEG (); static void COP1_D_SQRT (); static void COP1_D_MOV (); + static void COP1_D_ROUND_L (); static void COP1_D_TRUNC_L (); //added by Witten static void COP1_D_CEIL_L (); //added by Witten static void COP1_D_FLOOR_L (); //added by Witten