/* This file is part of the dynarmic project. * Copyright (c) 2018 MerryMage * This software may be used and distributed according to the terms of the GNU * General Public License version 2 or any later version. */ #include #include #include #include "common/common_types.h" #include "common/fp/mantissa_util.h" #include "common/safe_ops.h" #include "rand_int.h" using namespace Dynarmic; using namespace Dynarmic::FP; TEST_CASE("ResidualErrorOnRightShift", "[fp]") { const std::vector> test_cases { {0x00000001, 1, ResidualError::Half}, {0x00000002, 1, ResidualError::Zero}, {0x00000001, 2, ResidualError::LessThanHalf}, {0x00000002, 2, ResidualError::Half}, {0x00000003, 2, ResidualError::GreaterThanHalf}, {0x00000004, 2, ResidualError::Zero}, {0x00000005, 2, ResidualError::LessThanHalf}, {0x00000006, 2, ResidualError::Half}, {0x00000007, 2, ResidualError::GreaterThanHalf}, }; for (auto [mantissa, shift, expected_result] : test_cases) { const ResidualError result = ResidualErrorOnRightShift(mantissa, shift); REQUIRE(result == expected_result); } } TEST_CASE("ResidualErrorOnRightShift Randomized", "[fp]") { for (size_t test = 0; test < 100000; test++) { const u64 mantissa = Common::SignExtend<32, u64>(RandInt(0, 0xFFFFFFFF)); const int shift = RandInt(-60, 60); const ResidualError result = ResidualErrorOnRightShift(mantissa, shift); const u64 calculated_error = Safe::ArithmeticShiftRightDouble(mantissa, u64(0), shift); const ResidualError expected_result = [&]{ constexpr u64 half_error = 0x8000'0000'0000'0000ull; if (calculated_error == 0) { return ResidualError::Zero; } if (calculated_error < half_error) { return ResidualError::LessThanHalf; } if (calculated_error == half_error) { return ResidualError::Half; } return ResidualError::GreaterThanHalf; }(); INFO(std::hex << "mantissa " << mantissa << " shift " << shift << " calculated_error " << calculated_error); REQUIRE(result == expected_result); } }