Index: lib/builtins/comparetf2.c =================================================================== --- /dev/null +++ lib/builtins/comparetf2.c @@ -0,0 +1,134 @@ +//===-- lib/comparetf2.c - Quad-precision comparisons -------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// // This file implements the following soft-float comparison routines: +// +// __eqtf2 __getf2 __unordtf2 +// __letf2 __gttf2 +// __lttf2 +// __netf2 +// +// The semantics of the routines grouped in each column are identical, so there +// is a single implementation for each, and wrappers to provide the other names. +// +// The main routines behave as follows: +// +// __letf2(a,b) returns -1 if a < b +// 0 if a == b +// 1 if a > b +// 1 if either a or b is NaN +// +// __getf2(a,b) returns -1 if a < b +// 0 if a == b +// 1 if a > b +// -1 if either a or b is NaN +// +// __unordtf2(a,b) returns 0 if both a and b are numbers +// 1 if either a or b is NaN +// +// Note that __letf2( ) and __getf2( ) are identical except in their handling of +// NaN values. +// +//===----------------------------------------------------------------------===// + +#define QUAD_PRECISION +#include "fp_lib.h" + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) +enum LE_RESULT { + LE_LESS = -1, + LE_EQUAL = 0, + LE_GREATER = 1, + LE_UNORDERED = 1 +}; + +enum LE_RESULT __letf2(fp_t a, fp_t b) { + + const srep_t aInt = toRep(a); + const srep_t bInt = toRep(b); + const rep_t aAbs = aInt & absMask; + const rep_t bAbs = bInt & absMask; + + // If either a or b is NaN, they are unordered. + if (aAbs > infRep || bAbs > infRep) return LE_UNORDERED; + + // If a and b are both zeros, they are equal. + if ((aAbs | bAbs) == 0) return LE_EQUAL; + + // If at least one of a and b is positive, we get the same result comparing + // a and b as signed integers as we would with a floating-point compare. + if ((aInt & bInt) >= 0) { + if (aInt < bInt) return LE_LESS; + else if (aInt == bInt) return LE_EQUAL; + else return LE_GREATER; + } + + // Otherwise, both are negative, so we need to flip the sense of the + // comparison to get the correct result. (This assumes a twos- or ones- + // complement integer representation; if integers are represented in a + // sign-magnitude representation, then this flip is incorrect). + else { + if (aInt > bInt) return LE_LESS; + else if (aInt == bInt) return LE_EQUAL; + else return LE_GREATER; + } +} + +enum GE_RESULT { + GE_LESS = -1, + GE_EQUAL = 0, + GE_GREATER = 1, + GE_UNORDERED = -1 // Note: different from LE_UNORDERED +}; + +enum GE_RESULT __getf2(fp_t a, fp_t b) { + + const srep_t aInt = toRep(a); + const srep_t bInt = toRep(b); + const rep_t aAbs = aInt & absMask; + const rep_t bAbs = bInt & absMask; + + if (aAbs > infRep || bAbs > infRep) return GE_UNORDERED; + if ((aAbs | bAbs) == 0) return GE_EQUAL; + if ((aInt & bInt) >= 0) { + if (aInt < bInt) return GE_LESS; + else if (aInt == bInt) return GE_EQUAL; + else return GE_GREATER; + } else { + if (aInt > bInt) return GE_LESS; + else if (aInt == bInt) return GE_EQUAL; + else return GE_GREATER; + } +} + +int __unordtf2(fp_t a, fp_t b) { + const rep_t aAbs = toRep(a) & absMask; + const rep_t bAbs = toRep(b) & absMask; + return aAbs > infRep || bAbs > infRep; +} + +// The following are alternative names for the preceeding routines. + +enum LE_RESULT __eqtf2(fp_t a, fp_t b) { + return __letf2(a, b); +} + +enum LE_RESULT __lttf2(fp_t a, fp_t b) { + return __letf2(a, b); +} + +enum LE_RESULT __netf2(fp_t a, fp_t b) { + return __letf2(a, b); +} + +enum GE_RESULT __gttf2(fp_t a, fp_t b) { + return __getf2(a, b); +} + +#endif Index: test/builtins/Unit/eqtf2_test.c =================================================================== --- /dev/null +++ test/builtins/Unit/eqtf2_test.c @@ -0,0 +1,131 @@ +//===------------ eqtf2_test.c - Test __eqtf2------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file tests __eqtf2 for the compiler_rt library. +// +//===----------------------------------------------------------------------===// + +#include + +#if __LP64__ && __LDBL_MANT_DIG__ == 113 + +#include +#include + +enum EXPECTED_RESULT { + LESS_0, LESS_EQUAL_0, EQUAL_0, GREATER_0, GREATER_EQUAL_0, NEQUAL_0 +}; + +static inline long double fromRep(uint64_t hi, uint64_t lo) +{ + __uint128_t x = ((__uint128_t)hi << 64) + lo; + const union {long double f; __uint128_t i; } rep = {.i = x}; + return rep.f; +} + +static inline int compareResult(int result, + enum EXPECTED_RESULT expected) +{ + switch(expected){ + case EQUAL_0: + if (result == 0) + return 0; + break; + case NEQUAL_0: + if (result != 0) + return 0; + default: + return 1; + } + return 1; +} + +static inline char *expectedStr(enum EXPECTED_RESULT expected) +{ + switch(expected){ + case EQUAL_0: + return "=0"; + case NEQUAL_0: + return "!=0"; + default: + return ""; + } + return ""; +} + +int __eqtf2(long double a, long double b); + +int test__eqtf2(long double a, long double b, enum EXPECTED_RESULT expected) +{ + int x = __eqtf2(a, b); + int ret = compareResult(x, expected); + + if (ret){ + printf("error in test__eqtf2(%.20Lf, %.20Lf) = %d, " + "expected %s\n", a, b, x, expectedStr(expected)); + } + return ret; +} + +char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0}; + +#endif + +int main() +{ +#if __LP64__ && __LDBL_MANT_DIG__ == 113 + // NaN + if (test__eqtf2(fromRep(0x7fff800000000000UL, 0x0UL), + 0x1.234567890abcdef1234567890abcp+3L, + NEQUAL_0)) + return 1; + // < + // exp + if (test__eqtf2(0x1.234567890abcdef1234567890abcp-3L, + 0x1.234567890abcdef1234567890abcp+3L, + NEQUAL_0)) + return 1; + // mantissa + if (test__eqtf2(0x1.234567890abcdef1234567890abcp+3L, + 0x1.334567890abcdef1234567890abcp+3L, + NEQUAL_0)) + return 1; + // sign + if (test__eqtf2(-0x1.234567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp+3L, + NEQUAL_0)) + return 1; + // == + if (test__eqtf2(0x1.234567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp+3L, + EQUAL_0)) + return 1; + // > + // exp + if (test__eqtf2(0x1.234567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp-3L, + NEQUAL_0)) + return 1; + // mantissa + if (test__eqtf2(0x1.334567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp+3L, + NEQUAL_0)) + return 1; + // sign + if (test__eqtf2(0x1.234567890abcdef1234567890abcp+3L, + -0x1.234567890abcdef1234567890abcp+3L, + NEQUAL_0)) + return 1; + +#else + printf("skipped\n"); + +#endif + return 0; +} Index: test/builtins/Unit/getf2_test.c =================================================================== --- /dev/null +++ test/builtins/Unit/getf2_test.c @@ -0,0 +1,132 @@ +//===------------ getf2_test.c - Test __getf2------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file tests __getf2 for the compiler_rt library. +// +//===----------------------------------------------------------------------===// + +#include + +#if __LP64__ && __LDBL_MANT_DIG__ == 113 + +#include +#include + +enum EXPECTED_RESULT { + LESS_0, LESS_EQUAL_0, EQUAL_0, GREATER_0, GREATER_EQUAL_0, NEQUAL_0 +}; + +static inline long double fromRep(uint64_t hi, uint64_t lo) +{ + __uint128_t x = ((__uint128_t)hi << 64) + lo; + const union {long double f; __uint128_t i; } rep = {.i = x}; + return rep.f; +} + +static inline int compareResult(int result, + enum EXPECTED_RESULT expected) +{ + switch(expected){ + case LESS_0: + if (result < 0) + return 0; + break; + case GREATER_EQUAL_0: + if (result >= 0) + return 0; + break; + default: + return 1; + } + return 1; +} + +static inline char *expectedStr(enum EXPECTED_RESULT expected) +{ + switch(expected){ + case LESS_0: + return "<0"; + case GREATER_EQUAL_0: + return ">=0"; + default: + return ""; + } + return ""; +} + +int __getf2(long double a, long double b); + +int test__getf2(long double a, long double b, enum EXPECTED_RESULT expected) +{ + int x = __getf2(a, b); + int ret = compareResult(x, expected); + + if (ret){ + printf("error in test__getf2(%.20Lf, %.20Lf) = %d, " + "expected %s\n", a, b, x, expectedStr(expected)); + } + return ret; +} + +char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0}; + +#endif + +int main() +{ +#if __LP64__ && __LDBL_MANT_DIG__ == 113 + // NaN + if (test__getf2(fromRep(0x7fff800000000000UL, 0x0UL), + 0x1.234567890abcdef1234567890abcp+3L, + LESS_0)) + return 1; + // < + // exp + if (test__getf2(0x1.234567890abcdef1234567890abcp-3L, + 0x1.234567890abcdef1234567890abcp+3L, + LESS_0)) + return 1; + // mantissa + if (test__getf2(0x1.234567890abcdef1234567890abcp+3L, + 0x1.334567890abcdef1234567890abcp+3L, + LESS_0)) + return 1; + // sign + if (test__getf2(-0x1.234567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp+3L, + LESS_0)) + return 1; + // == + if (test__getf2(0x1.234567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp+3L, + GREATER_EQUAL_0)) + return 1; + // > + // exp + if (test__getf2(0x1.234567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp-3L, + GREATER_EQUAL_0)) + return 1; + // mantissa + if (test__getf2(0x1.334567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp+3L, + GREATER_EQUAL_0)) + return 1; + // sign + if (test__getf2(0x1.234567890abcdef1234567890abcp+3L, + -0x1.234567890abcdef1234567890abcp+3L, + GREATER_EQUAL_0)) + return 1; + +#else + printf("skipped\n"); + +#endif + return 0; +} Index: test/builtins/Unit/gttf2_test.c =================================================================== --- /dev/null +++ test/builtins/Unit/gttf2_test.c @@ -0,0 +1,132 @@ +//===------------ gttf2_test.c - Test __gttf2------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file tests __gttf2 for the compiler_rt library. +// +//===----------------------------------------------------------------------===// + +#include + +#if __LP64__ && __LDBL_MANT_DIG__ == 113 + +#include +#include + +enum EXPECTED_RESULT { + LESS_0, LESS_EQUAL_0, EQUAL_0, GREATER_0, GREATER_EQUAL_0, NEQUAL_0 +}; + +static inline long double fromRep(uint64_t hi, uint64_t lo) +{ + __uint128_t x = ((__uint128_t)hi << 64) + lo; + const union {long double f; __uint128_t i; } rep = {.i = x}; + return rep.f; +} + +static inline int compareResult(int result, + enum EXPECTED_RESULT expected) +{ + switch(expected){ + case LESS_EQUAL_0: + if (result <= 0) + return 0; + break; + case GREATER_0: + if (result > 0) + return 0; + break; + default: + return 1; + } + return 1; +} + +static inline char *expectedStr(enum EXPECTED_RESULT expected) +{ + switch(expected){ + case LESS_EQUAL_0: + return "<=0"; + case GREATER_0: + return ">0"; + default: + return ""; + } + return ""; +} + +int __gttf2(long double a, long double b); + +int test__gttf2(long double a, long double b, enum EXPECTED_RESULT expected) +{ + int x = __gttf2(a, b); + int ret = compareResult(x, expected); + + if (ret){ + printf("error in test__gttf2(%.20Lf, %.20Lf) = %d, " + "expected %s\n", a, b, x, expectedStr(expected)); + } + return ret; +} + +char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0}; + +#endif + +int main() +{ +#if __LP64__ && __LDBL_MANT_DIG__ == 113 + // NaN + if (test__gttf2(fromRep(0x7fff800000000000UL, 0x0UL), + 0x1.234567890abcdef1234567890abcp+3L, + LESS_EQUAL_0)) + return 1; + // < + // exp + if (test__gttf2(0x1.234567890abcdef1234567890abcp-3L, + 0x1.234567890abcdef1234567890abcp+3L, + LESS_EQUAL_0)) + return 1; + // mantissa + if (test__gttf2(0x1.234567890abcdef1234567890abcp+3L, + 0x1.334567890abcdef1234567890abcp+3L, + LESS_EQUAL_0)) + return 1; + // sign + if (test__gttf2(-0x1.234567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp+3L, + LESS_EQUAL_0)) + return 1; + // == + if (test__gttf2(0x1.234567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp+3L, + LESS_EQUAL_0)) + return 1; + // > + // exp + if (test__gttf2(0x1.234567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp-3L, + GREATER_0)) + return 1; + // mantissa + if (test__gttf2(0x1.334567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp+3L, + GREATER_0)) + return 1; + // sign + if (test__gttf2(0x1.234567890abcdef1234567890abcp+3L, + -0x1.234567890abcdef1234567890abcp+3L, + GREATER_0)) + return 1; + +#else + printf("skipped\n"); + +#endif + return 0; +} Index: test/builtins/Unit/letf2_test.c =================================================================== --- /dev/null +++ test/builtins/Unit/letf2_test.c @@ -0,0 +1,132 @@ +//===------------ letf2_test.c - Test __letf2------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file tests __letf2 for the compiler_rt library. +// +//===----------------------------------------------------------------------===// + +#include + +#if __LP64__ && __LDBL_MANT_DIG__ == 113 + +#include +#include + +enum EXPECTED_RESULT { + LESS_0, LESS_EQUAL_0, EQUAL_0, GREATER_0, GREATER_EQUAL_0, NEQUAL_0 +}; + +static inline long double fromRep(uint64_t hi, uint64_t lo) +{ + __uint128_t x = ((__uint128_t)hi << 64) + lo; + const union {long double f; __uint128_t i; } rep = {.i = x}; + return rep.f; +} + +static inline int compareResult(int result, + enum EXPECTED_RESULT expected) +{ + switch(expected){ + case LESS_EQUAL_0: + if (result <= 0) + return 0; + break; + case GREATER_0: + if (result > 0) + return 0; + break; + default: + return 1; + } + return 1; +} + +static inline char *expectedStr(enum EXPECTED_RESULT expected) +{ + switch(expected){ + case LESS_EQUAL_0: + return "<=0"; + case GREATER_0: + return ">0"; + default: + return ""; + } + return ""; +} + +int __letf2(long double a, long double b); + +int test__letf2(long double a, long double b, enum EXPECTED_RESULT expected) +{ + int x = __letf2(a, b); + int ret = compareResult(x, expected); + + if (ret){ + printf("error in test__letf2(%.20Lf, %.20Lf) = %d, " + "expected %s\n", a, b, x, expectedStr(expected)); + } + return ret; +} + +char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0}; + +#endif + +int main() +{ +#if __LP64__ && __LDBL_MANT_DIG__ == 113 + // NaN + if (test__letf2(fromRep(0x7fff800000000000UL, 0x0UL), + 0x1.234567890abcdef1234567890abcp+3L, + GREATER_0)) + return 1; + // < + // exp + if (test__letf2(0x1.234567890abcdef1234567890abcp-3L, + 0x1.234567890abcdef1234567890abcp+3L, + LESS_EQUAL_0)) + return 1; + // mantissa + if (test__letf2(0x1.234567890abcdef1234567890abcp+3L, + 0x1.334567890abcdef1234567890abcp+3L, + LESS_EQUAL_0)) + return 1; + // sign + if (test__letf2(-0x1.234567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp+3L, + LESS_EQUAL_0)) + return 1; + // == + if (test__letf2(0x1.234567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp+3L, + LESS_EQUAL_0)) + return 1; + // > + // exp + if (test__letf2(0x1.234567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp-3L, + GREATER_0)) + return 1; + // mantissa + if (test__letf2(0x1.334567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp+3L, + GREATER_0)) + return 1; + // sign + if (test__letf2(0x1.234567890abcdef1234567890abcp+3L, + -0x1.234567890abcdef1234567890abcp+3L, + GREATER_0)) + return 1; + +#else + printf("skipped\n"); + +#endif + return 0; +} Index: test/builtins/Unit/lttf2_test.c =================================================================== --- /dev/null +++ test/builtins/Unit/lttf2_test.c @@ -0,0 +1,132 @@ +//===------------ lttf2_test.c - Test __lttf2------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file tests __lttf2 for the compiler_rt library. +// +//===----------------------------------------------------------------------===// + +#include + +#if __LP64__ && __LDBL_MANT_DIG__ == 113 + +#include +#include + +enum EXPECTED_RESULT { + LESS_0, LESS_EQUAL_0, EQUAL_0, GREATER_0, GREATER_EQUAL_0, NEQUAL_0 +}; + +static inline long double fromRep(uint64_t hi, uint64_t lo) +{ + __uint128_t x = ((__uint128_t)hi << 64) + lo; + const union {long double f; __uint128_t i; } rep = {.i = x}; + return rep.f; +} + +static inline int compareResult(int result, + enum EXPECTED_RESULT expected) +{ + switch(expected){ + case LESS_0: + if (result < 0) + return 0; + break; + case GREATER_EQUAL_0: + if (result >= 0) + return 0; + break; + default: + return 1; + } + return 1; +} + +static inline char *expectedStr(enum EXPECTED_RESULT expected) +{ + switch(expected){ + case LESS_0: + return "<0"; + case GREATER_EQUAL_0: + return ">=0"; + default: + return ""; + } + return ""; +} + +int __lttf2(long double a, long double b); + +int test__lttf2(long double a, long double b, enum EXPECTED_RESULT expected) +{ + int x = __lttf2(a, b); + int ret = compareResult(x, expected); + + if (ret){ + printf("error in test__lttf2(%.20Lf, %.20Lf) = %d, " + "expected %s\n", a, b, x, expectedStr(expected)); + } + return ret; +} + +char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0}; + +#endif + +int main() +{ +#if __LP64__ && __LDBL_MANT_DIG__ == 113 + // NaN + if (test__lttf2(fromRep(0x7fff800000000000UL, 0x0UL), + 0x1.234567890abcdef1234567890abcp+3L, + GREATER_EQUAL_0)) + return 1; + // < + // exp + if (test__lttf2(0x1.234567890abcdef1234567890abcp-3L, + 0x1.234567890abcdef1234567890abcp+3L, + LESS_0)) + return 1; + // mantissa + if (test__lttf2(0x1.234567890abcdef1234567890abcp+3L, + 0x1.334567890abcdef1234567890abcp+3L, + LESS_0)) + return 1; + // sign + if (test__lttf2(-0x1.234567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp+3L, + LESS_0)) + return 1; + // == + if (test__lttf2(0x1.234567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp+3L, + GREATER_EQUAL_0)) + return 1; + // > + // exp + if (test__lttf2(0x1.234567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp-3L, + GREATER_EQUAL_0)) + return 1; + // mantissa + if (test__lttf2(0x1.334567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp+3L, + GREATER_EQUAL_0)) + return 1; + // sign + if (test__lttf2(0x1.234567890abcdef1234567890abcp+3L, + -0x1.234567890abcdef1234567890abcp+3L, + GREATER_EQUAL_0)) + return 1; + +#else + printf("skipped\n"); + +#endif + return 0; +} Index: test/builtins/Unit/netf2_test.c =================================================================== --- /dev/null +++ test/builtins/Unit/netf2_test.c @@ -0,0 +1,131 @@ +//===------------ netf2_test.c - Test __netf2------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file tests __netf2 for the compiler_rt library. +// +//===----------------------------------------------------------------------===// + +#include + +#if __LP64__ && __LDBL_MANT_DIG__ == 113 + +#include +#include + +enum EXPECTED_RESULT { + LESS_0, LESS_EQUAL_0, EQUAL_0, GREATER_0, GREATER_EQUAL_0, NEQUAL_0 +}; + +static inline long double fromRep(uint64_t hi, uint64_t lo) +{ + __uint128_t x = ((__uint128_t)hi << 64) + lo; + const union {long double f; __uint128_t i; } rep = {.i = x}; + return rep.f; +} + +static inline int compareResult(int result, + enum EXPECTED_RESULT expected) +{ + switch(expected){ + case EQUAL_0: + if (result == 0) + return 0; + break; + case NEQUAL_0: + if (result != 0) + return 0; + default: + return 1; + } + return 1; +} + +static inline char *expectedStr(enum EXPECTED_RESULT expected) +{ + switch(expected){ + case EQUAL_0: + return "=0"; + case NEQUAL_0: + return "!=0"; + default: + return ""; + } + return ""; +} + +int __netf2(long double a, long double b); + +int test__netf2(long double a, long double b, enum EXPECTED_RESULT expected) +{ + int x = __netf2(a, b); + int ret = compareResult(x, expected); + + if (ret){ + printf("error in test__netf2(%.20Lf, %.20Lf) = %d, " + "expected %s\n", a, b, x, expectedStr(expected)); + } + return ret; +} + +char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0}; + +#endif + +int main() +{ +#if __LP64__ && __LDBL_MANT_DIG__ == 113 + // NaN + if (test__netf2(fromRep(0x7fff800000000000UL, 0x0UL), + 0x1.234567890abcdef1234567890abcp+3L, + NEQUAL_0)) + return 1; + // < + // exp + if (test__netf2(0x1.234567890abcdef1234567890abcp-3L, + 0x1.234567890abcdef1234567890abcp+3L, + NEQUAL_0)) + return 1; + // mantissa + if (test__netf2(0x1.234567890abcdef1234567890abcp+3L, + 0x1.334567890abcdef1234567890abcp+3L, + NEQUAL_0)) + return 1; + // sign + if (test__netf2(-0x1.234567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp+3L, + NEQUAL_0)) + return 1; + // == + if (test__netf2(0x1.234567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp+3L, + EQUAL_0)) + return 1; + // > + // exp + if (test__netf2(0x1.234567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp-3L, + NEQUAL_0)) + return 1; + // mantissa + if (test__netf2(0x1.334567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp+3L, + NEQUAL_0)) + return 1; + // sign + if (test__netf2(0x1.234567890abcdef1234567890abcp+3L, + -0x1.234567890abcdef1234567890abcp+3L, + NEQUAL_0)) + return 1; + +#else + printf("skipped\n"); + +#endif + return 0; +} Index: test/builtins/Unit/unordtf2_test.c =================================================================== --- /dev/null +++ test/builtins/Unit/unordtf2_test.c @@ -0,0 +1,107 @@ +//===------------ unordtf2_test.c - Test __unordtf2------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file tests __unordtf2 for the compiler_rt library. +// +//===----------------------------------------------------------------------===// + +#include + +#if __LP64__ && __LDBL_MANT_DIG__ == 113 + +#include +#include + +enum EXPECTED_RESULT { + LESS_0, LESS_EQUAL_0, EQUAL_0, GREATER_0, GREATER_EQUAL_0, NEQUAL_0 +}; + +static inline long double fromRep(uint64_t hi, uint64_t lo) +{ + __uint128_t x = ((__uint128_t)hi << 64) + lo; + const union {long double f; __uint128_t i; } rep = {.i = x}; + return rep.f; +} + +static inline int compareResult(int result, + enum EXPECTED_RESULT expected) +{ + switch(expected){ + case EQUAL_0: + if (result == 0) + return 0; + break; + case NEQUAL_0: + if (result != 0) + return 0; + default: + return 1; + } + return 1; +} + +static inline char *expectedStr(enum EXPECTED_RESULT expected) +{ + switch(expected){ + case EQUAL_0: + return "=0"; + case NEQUAL_0: + return "!=0"; + default: + return ""; + } + return ""; +} + +int __unordtf2(long double a, long double b); + +int test__unordtf2(long double a, long double b, enum EXPECTED_RESULT expected) +{ + int x = __unordtf2(a, b); + int ret = compareResult(x, expected); + + if (ret){ + printf("error in test__unordtf2(%.20Lf, %.20Lf) = %d, " + "expected %s\n", a, b, x, expectedStr(expected)); + } + return ret; +} + +char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0}; + +#endif + +int main() +{ +#if __LP64__ && __LDBL_MANT_DIG__ == 113 + // NaN + if (test__unordtf2(fromRep(0x7fff800000000000UL, 0x0UL), + 0x1.234567890abcdef1234567890abcp+3L, + NEQUAL_0)) + return 1; + // other + if (test__unordtf2(0x1.234567890abcdef1234567890abcp+3L, + 0x1.334567890abcdef1234567890abcp+3L, + EQUAL_0)) + return 1; + if (test__unordtf2(0x1.234567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp+3L, + EQUAL_0)) + return 1; + if (test__unordtf2(0x1.234567890abcdef1234567890abcp+3L, + 0x1.234567890abcdef1234567890abcp-3L, + EQUAL_0)) + return 1; + +#else + printf("skipped\n"); + +#endif + return 0; +}