diff --git a/Source/UnitTests/Core/CMakeLists.txt b/Source/UnitTests/Core/CMakeLists.txt index 5934d2655c..6dd344e638 100644 --- a/Source/UnitTests/Core/CMakeLists.txt +++ b/Source/UnitTests/Core/CMakeLists.txt @@ -24,6 +24,7 @@ elseif(_M_ARM_64) add_dolphin_test(PowerPCTest PowerPC/DivUtilsTest.cpp PowerPC/JitArm64/ConvertSingleDouble.cpp + PowerPC/JitArm64/FPRF.cpp PowerPC/JitArm64/MovI2R.cpp ) else() diff --git a/Source/UnitTests/Core/PowerPC/JitArm64/FPRF.cpp b/Source/UnitTests/Core/PowerPC/JitArm64/FPRF.cpp new file mode 100644 index 0000000000..ef82fa6d1b --- /dev/null +++ b/Source/UnitTests/Core/PowerPC/JitArm64/FPRF.cpp @@ -0,0 +1,86 @@ +// Copyright 2021 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include +#include +#include + +#include "Common/Arm64Emitter.h" +#include "Common/BitUtils.h" +#include "Common/CommonTypes.h" +#include "Core/PowerPC/Interpreter/Interpreter_FPUtils.h" +#include "Core/PowerPC/JitArm64/Jit.h" +#include "Core/PowerPC/PowerPC.h" + +#include "../TestValues.h" + +#include + +namespace +{ +using namespace Arm64Gen; + +class TestFPRF : public JitArm64 +{ +public: + TestFPRF() + { + AllocCodeSpace(4096); + + const u8* raw_fprf_single = GetCodePtr(); + GenerateFPRF(true); + const u8* raw_fprf_double = GetCodePtr(); + GenerateFPRF(false); + + fprf_single = Common::BitCast(GetCodePtr()); + MOV(ARM64Reg::X15, ARM64Reg::X30); + MOV(ARM64Reg::X14, PPC_REG); + MOVP2R(PPC_REG, &PowerPC::ppcState); + BL(raw_fprf_single); + MOV(ARM64Reg::X30, ARM64Reg::X15); + MOV(PPC_REG, ARM64Reg::X14); + RET(); + + fprf_double = Common::BitCast(GetCodePtr()); + MOV(ARM64Reg::X15, ARM64Reg::X30); + MOV(ARM64Reg::X14, PPC_REG); + MOVP2R(PPC_REG, &PowerPC::ppcState); + BL(raw_fprf_double); + MOV(ARM64Reg::X30, ARM64Reg::X15); + MOV(PPC_REG, ARM64Reg::X14); + RET(); + } + + std::function fprf_single; + std::function fprf_double; +}; + +} // namespace + +static u32 RunUpdateFPRF(const std::function& f) +{ + PowerPC::ppcState.fpscr.Hex = 0x12345678; + f(); + return PowerPC::ppcState.fpscr.Hex; +} + +TEST(JitArm64, FPRF) +{ + TestFPRF test; + + for (const u64 double_input : double_test_values) + { + const u32 expected_double = + RunUpdateFPRF([&] { PowerPC::UpdateFPRF(Common::BitCast(double_input)); }); + const u32 actual_double = RunUpdateFPRF([&] { test.fprf_double(double_input); }); + EXPECT_EQ(expected_double, actual_double); + + const u32 single_input = ConvertToSingle(double_input); + + const u32 expected_single = RunUpdateFPRF( + [&] { PowerPC::UpdateFPRF(Common::BitCast(ConvertToDouble(single_input))); }); + const u32 actual_single = RunUpdateFPRF([&] { test.fprf_single(single_input); }); + EXPECT_EQ(expected_single, actual_single); + } +} diff --git a/Source/UnitTests/UnitTests.vcxproj b/Source/UnitTests/UnitTests.vcxproj index 39063ab33e..69349d51b0 100644 --- a/Source/UnitTests/UnitTests.vcxproj +++ b/Source/UnitTests/UnitTests.vcxproj @@ -83,6 +83,7 @@ +