70 changes: 70 additions & 0 deletions libc/test/src/math/smoke/GetPayloadTest.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//===-- Utility class to test different flavors of getpayload ---*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LIBC_TEST_SRC_MATH_SMOKE_GETPAYLOADTEST_H
#define LIBC_TEST_SRC_MATH_SMOKE_GETPAYLOADTEST_H

#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"

template <typename T>
class GetPayloadTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {

DECLARE_SPECIAL_CONSTANTS(T)

public:
typedef T (*GetPayloadFunc)(const T *);

T funcWrapper(GetPayloadFunc func, T x) { return func(&x); }

void testNonNaNs(GetPayloadFunc func) {
EXPECT_FP_EQ(T(-1.0), funcWrapper(func, T(0.0)));
EXPECT_FP_EQ(T(-1.0), funcWrapper(func, T(-0.0)));
EXPECT_FP_EQ(T(-1.0), funcWrapper(func, T(0.1)));
EXPECT_FP_EQ(T(-1.0), funcWrapper(func, T(-0.1)));
EXPECT_FP_EQ(T(-1.0), funcWrapper(func, T(123.38)));
EXPECT_FP_EQ(T(-1.0), funcWrapper(func, T(-123.38)));
EXPECT_FP_EQ(T(-1.0), funcWrapper(func, inf));
EXPECT_FP_EQ(T(-1.0), funcWrapper(func, neg_inf));
}

void testNaNs(GetPayloadFunc func) {
EXPECT_FP_EQ(T(0.0), funcWrapper(func, aNaN));
EXPECT_FP_EQ(T(0.0), funcWrapper(func, neg_aNaN));

T default_snan_payload = StorageType(1) << (FPBits::SIG_LEN - 2);
EXPECT_FP_EQ(default_snan_payload, funcWrapper(func, sNaN));
EXPECT_FP_EQ(default_snan_payload, funcWrapper(func, neg_sNaN));

T qnan_42 = FPBits::quiet_nan(Sign::POS, 0x42).get_val();
T neg_qnan_42 = FPBits::quiet_nan(Sign::NEG, 0x42).get_val();
T snan_42 = FPBits::signaling_nan(Sign::POS, 0x42).get_val();
T neg_snan_42 = FPBits::signaling_nan(Sign::NEG, 0x42).get_val();
EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, qnan_42));
EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, neg_qnan_42));
EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, snan_42));
EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, neg_snan_42));

T qnan_123 = FPBits::quiet_nan(Sign::POS, 0x123).get_val();
T neg_qnan_123 = FPBits::quiet_nan(Sign::NEG, 0x123).get_val();
T snan_123 = FPBits::signaling_nan(Sign::POS, 0x123).get_val();
T neg_snan_123 = FPBits::signaling_nan(Sign::NEG, 0x123).get_val();
EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, qnan_123));
EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, neg_qnan_123));
EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, snan_123));
EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, neg_snan_123));
}
};

#define LIST_GETPAYLOAD_TESTS(T, func) \
using LlvmLibcGetPayloadTest = GetPayloadTestTemplate<T>; \
TEST_F(LlvmLibcGetPayloadTest, NonNaNs) { testNonNaNs(&func); } \
TEST_F(LlvmLibcGetPayloadTest, NaNs) { testNaNs(&func); }

#endif // LIBC_TEST_SRC_MATH_SMOKE_GETPAYLOADTEST_H
74 changes: 74 additions & 0 deletions libc/test/src/math/smoke/SetPayloadSigTest.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//===-- Utility class to test flavors of setpayloadsig ----------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LIBC_TEST_SRC_MATH_SMOKE_SETPAYLOADSIGTEST_H
#define LIBC_TEST_SRC_MATH_SMOKE_SETPAYLOADSIGTEST_H

#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"

template <typename T>
class SetPayloadSigTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {

DECLARE_SPECIAL_CONSTANTS(T)

public:
typedef int (*SetPayloadSigFunc)(T *, T);

void testInvalidPayloads(SetPayloadSigFunc func) {
T res;

EXPECT_EQ(1, func(&res, T(aNaN)));
EXPECT_EQ(1, func(&res, T(neg_aNaN)));
EXPECT_EQ(1, func(&res, T(inf)));
EXPECT_EQ(1, func(&res, T(neg_inf)));
EXPECT_EQ(1, func(&res, T(0.0)));
EXPECT_EQ(1, func(&res, T(-0.0)));
EXPECT_EQ(1, func(&res, T(0.1)));
EXPECT_EQ(1, func(&res, T(-0.1)));
EXPECT_EQ(1, func(&res, T(-1.0)));
EXPECT_EQ(1, func(&res, T(0x42.1p+0)));
EXPECT_EQ(1, func(&res, T(-0x42.1p+0)));
EXPECT_EQ(1, func(&res, T(StorageType(1) << (FPBits::FRACTION_LEN - 1))));
}

void testValidPayloads(SetPayloadSigFunc func) {
T res;

EXPECT_EQ(0, func(&res, T(1.0)));
EXPECT_TRUE(FPBits(res).is_signaling_nan());
EXPECT_EQ(FPBits::signaling_nan(Sign::POS, 1).uintval(),
FPBits(res).uintval());

EXPECT_EQ(0, func(&res, T(0x42.0p+0)));
EXPECT_TRUE(FPBits(res).is_signaling_nan());
EXPECT_EQ(FPBits::signaling_nan(Sign::POS, 0x42).uintval(),
FPBits(res).uintval());

EXPECT_EQ(0, func(&res, T(0x123.0p+0)));
EXPECT_TRUE(FPBits(res).is_signaling_nan());
EXPECT_EQ(FPBits::signaling_nan(Sign::POS, 0x123).uintval(),
FPBits(res).uintval());

EXPECT_EQ(0, func(&res, T(FPBits::FRACTION_MASK >> 1)));
EXPECT_TRUE(FPBits(res).is_signaling_nan());
EXPECT_EQ(
FPBits::signaling_nan(Sign::POS, FPBits::FRACTION_MASK >> 1).uintval(),
FPBits(res).uintval());
}
};

#define LIST_SETPAYLOADSIG_TESTS(T, func) \
using LlvmLibcSetPayloadSigTest = SetPayloadSigTestTemplate<T>; \
TEST_F(LlvmLibcSetPayloadSigTest, InvalidPayloads) { \
testInvalidPayloads(&func); \
} \
TEST_F(LlvmLibcSetPayloadSigTest, ValidPayloads) { testValidPayloads(&func); }

#endif // LIBC_TEST_SRC_MATH_SMOKE_SETPAYLOADSIGTEST_H
75 changes: 75 additions & 0 deletions libc/test/src/math/smoke/SetPayloadTest.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//===-- Utility class to test different flavors of setpayload ---*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LIBC_TEST_SRC_MATH_SMOKE_SETPAYLOADTEST_H
#define LIBC_TEST_SRC_MATH_SMOKE_SETPAYLOADTEST_H

#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"

template <typename T>
class SetPayloadTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {

DECLARE_SPECIAL_CONSTANTS(T)

public:
typedef int (*SetPayloadFunc)(T *, T);

void testInvalidPayloads(SetPayloadFunc func) {
T res;

EXPECT_EQ(1, func(&res, T(aNaN)));
EXPECT_EQ(1, func(&res, T(neg_aNaN)));
EXPECT_EQ(1, func(&res, T(inf)));
EXPECT_EQ(1, func(&res, T(neg_inf)));
EXPECT_EQ(1, func(&res, T(0.1)));
EXPECT_EQ(1, func(&res, T(-0.1)));
EXPECT_EQ(1, func(&res, T(-1.0)));
EXPECT_EQ(1, func(&res, T(0x42.1p+0)));
EXPECT_EQ(1, func(&res, T(-0x42.1p+0)));
EXPECT_EQ(1, func(&res, T(StorageType(1) << (FPBits::FRACTION_LEN - 1))));
}

void testValidPayloads(SetPayloadFunc func) {
T res;

EXPECT_EQ(0, func(&res, T(0.0)));
EXPECT_TRUE(FPBits(res).is_quiet_nan());
EXPECT_EQ(FPBits(aNaN).uintval(), FPBits(res).uintval());

EXPECT_EQ(0, func(&res, T(1.0)));
EXPECT_TRUE(FPBits(res).is_quiet_nan());
EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 1).uintval(), FPBits(res).uintval());

EXPECT_EQ(0, func(&res, T(0x42.0p+0)));
EXPECT_TRUE(FPBits(res).is_quiet_nan());
EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 0x42).uintval(),
FPBits(res).uintval());

EXPECT_EQ(0, func(&res, T(0x123.0p+0)));
EXPECT_TRUE(FPBits(res).is_quiet_nan());
EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 0x123).uintval(),
FPBits(res).uintval());

EXPECT_EQ(0, func(&res, T(FPBits::FRACTION_MASK >> 1)));
EXPECT_TRUE(FPBits(res).is_quiet_nan());
EXPECT_EQ(
FPBits::quiet_nan(Sign::POS, FPBits::FRACTION_MASK >> 1).uintval(),
FPBits(res).uintval());
}
};

#define LIST_SETPAYLOAD_TESTS(T, func) \
using LlvmLibcSetPayloadTest = SetPayloadTestTemplate<T>; \
TEST_F(LlvmLibcSetPayloadTest, InvalidPayloads) { \
testInvalidPayloads(&func); \
} \
TEST_F(LlvmLibcSetPayloadTest, ValidPayloads) { testValidPayloads(&func); }

#endif // LIBC_TEST_SRC_MATH_SMOKE_SETPAYLOADTEST_H
13 changes: 13 additions & 0 deletions libc/test/src/math/smoke/getpayloadf16_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//===-- Unittests for getpayloadf16 ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "GetPayloadTest.h"

#include "src/math/getpayloadf16.h"

LIST_GETPAYLOAD_TESTS(float16, LIBC_NAMESPACE::getpayloadf16)
13 changes: 13 additions & 0 deletions libc/test/src/math/smoke/setpayloadf16_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//===-- Unittests for setpayloadf16 ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "SetPayloadTest.h"

#include "src/math/setpayloadf16.h"

LIST_SETPAYLOAD_TESTS(float16, LIBC_NAMESPACE::setpayloadf16)
13 changes: 13 additions & 0 deletions libc/test/src/math/smoke/setpayloadsigf16_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//===-- Unittests for setpayloadsigf16 ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "SetPayloadSigTest.h"

#include "src/math/setpayloadsigf16.h"

LIST_SETPAYLOADSIG_TESTS(float16, LIBC_NAMESPACE::setpayloadsigf16)