mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-17 19:49:12 +01:00
585899dba3
If the compiler can detect an issue with a format string at compile time, then we should take advantage of that and turn the issue into a hard compile-time error as such problems almost always lead to UB. This helps with catching logging or assertion messages that have been converted over to fmt but are still using the old, non-fmt variants of the logging macros. This commit also fixes all incorrect usages that I could find.
118 lines
4.0 KiB
C++
118 lines
4.0 KiB
C++
// Copyright 2019 Dolphin Emulator Project
|
|
// Licensed under GPLv2+
|
|
// Refer to the license.txt file included.
|
|
|
|
#include <cstring>
|
|
#include <tuple>
|
|
#include <vector>
|
|
|
|
#include "Common/CommonTypes.h"
|
|
#include "Common/x64ABI.h"
|
|
#include "Core/PowerPC/Gekko.h"
|
|
#include "Core/PowerPC/Interpreter/Interpreter_FPUtils.h"
|
|
#include "Core/PowerPC/Jit64/Jit.h"
|
|
#include "Core/PowerPC/Jit64Common/Jit64AsmCommon.h"
|
|
#include "Core/PowerPC/Jit64Common/Jit64PowerPCState.h"
|
|
|
|
#include <fmt/format.h>
|
|
#include <gtest/gtest.h>
|
|
|
|
namespace
|
|
{
|
|
class TestCommonAsmRoutines : public CommonAsmRoutines
|
|
{
|
|
public:
|
|
TestCommonAsmRoutines() : CommonAsmRoutines(jit)
|
|
{
|
|
using namespace Gen;
|
|
|
|
AllocCodeSpace(4096);
|
|
m_const_pool.Init(AllocChildCodeSpace(1024), 1024);
|
|
|
|
const auto raw_cdts = reinterpret_cast<double (*)(double)>(AlignCode4());
|
|
GenConvertDoubleToSingle();
|
|
|
|
wrapped_cdts = reinterpret_cast<u32 (*)(u64)>(AlignCode4());
|
|
ABI_PushRegistersAndAdjustStack(ABI_ALL_CALLEE_SAVED, 8, 16);
|
|
|
|
// Call
|
|
MOVQ_xmm(XMM0, R(ABI_PARAM1));
|
|
ABI_CallFunction(raw_cdts);
|
|
MOV(32, R(ABI_RETURN), R(RSCRATCH));
|
|
|
|
ABI_PopRegistersAndAdjustStack(ABI_ALL_CALLEE_SAVED, 8, 16);
|
|
RET();
|
|
}
|
|
|
|
u32 (*wrapped_cdts)(u64);
|
|
Jit64 jit;
|
|
};
|
|
} // namespace
|
|
|
|
TEST(Jit64, ConvertDoubleToSingle)
|
|
{
|
|
TestCommonAsmRoutines routines;
|
|
|
|
const std::vector<u64> input_values{
|
|
// Special values
|
|
0x0000'0000'0000'0000, // positive zero
|
|
0x0000'0000'0000'0001, // smallest positive denormal
|
|
0x0000'0000'0100'0000,
|
|
0x000F'FFFF'FFFF'FFFF, // largest positive denormal
|
|
0x0010'0000'0000'0000, // smallest positive normal
|
|
0x0010'0000'0000'0002,
|
|
0x3FF0'0000'0000'0000, // 1.0
|
|
0x7FEF'FFFF'FFFF'FFFF, // largest positive normal
|
|
0x7FF0'0000'0000'0000, // positive infinity
|
|
0x7FF0'0000'0000'0001, // first positive SNaN
|
|
0x7FF7'FFFF'FFFF'FFFF, // last positive SNaN
|
|
0x7FF8'0000'0000'0000, // first positive QNaN
|
|
0x7FFF'FFFF'FFFF'FFFF, // last positive QNaN
|
|
0x8000'0000'0000'0000, // negative zero
|
|
0x8000'0000'0000'0001, // smallest negative denormal
|
|
0x8000'0000'0100'0000,
|
|
0x800F'FFFF'FFFF'FFFF, // largest negative denormal
|
|
0x8010'0000'0000'0000, // smallest negative normal
|
|
0x8010'0000'0000'0002,
|
|
0xBFF0'0000'0000'0000, // -1.0
|
|
0xFFEF'FFFF'FFFF'FFFF, // largest negative normal
|
|
0xFFF0'0000'0000'0000, // negative infinity
|
|
0xFFF0'0000'0000'0001, // first negative SNaN
|
|
0xFFF7'FFFF'FFFF'FFFF, // last negative SNaN
|
|
0xFFF8'0000'0000'0000, // first negative QNaN
|
|
0xFFFF'FFFF'FFFF'FFFF, // last negative QNaN
|
|
|
|
// (exp > 896) Boundary Case
|
|
0x3800'0000'0000'0000, // 2^(-127) = Denormal in single-prec
|
|
0x3810'0000'0000'0000, // 2^(-126) = Smallest single-prec normal
|
|
0xB800'0000'0000'0000, // -2^(-127) = Denormal in single-prec
|
|
0xB810'0000'0000'0000, // -2^(-126) = Smallest single-prec normal
|
|
0x3800'1234'5678'9ABC, 0x3810'1234'5678'9ABC, 0xB800'1234'5678'9ABC, 0xB810'1234'5678'9ABC,
|
|
|
|
// (exp >= 874) Boundary Case
|
|
0x3680'0000'0000'0000, // 2^(-150) = Unrepresentable in single-prec
|
|
0x36A0'0000'0000'0000, // 2^(-149) = Smallest single-prec denormal
|
|
0x36B0'0000'0000'0000, // 2^(-148) = Single-prec denormal
|
|
0xB680'0000'0000'0000, // -2^(-150) = Unrepresentable in single-prec
|
|
0xB6A0'0000'0000'0000, // -2^(-149) = Smallest single-prec denormal
|
|
0xB6B0'0000'0000'0000, // -2^(-148) = Single-prec denormal
|
|
0x3680'1234'5678'9ABC, 0x36A0'1234'5678'9ABC, 0x36B0'1234'5678'9ABC, 0xB680'1234'5678'9ABC,
|
|
0xB6A0'1234'5678'9ABC, 0xB6B0'1234'5678'9ABC,
|
|
|
|
// Some typical numbers
|
|
0x3FF8'0000'0000'0000, // 1.5
|
|
0x408F'4000'0000'0000, // 1000
|
|
0xC008'0000'0000'0000, // -3
|
|
};
|
|
|
|
for (const u64 input : input_values)
|
|
{
|
|
const u32 expected = ConvertToSingle(input);
|
|
const u32 actual = routines.wrapped_cdts(input);
|
|
|
|
fmt::print("{:016x} -> {:08x} == {:08x}\n", input, actual, expected);
|
|
|
|
EXPECT_EQ(expected, actual);
|
|
}
|
|
}
|