diff --git a/compiler-rt/test/builtins/Unit/extendhfxf2_test.c b/compiler-rt/test/builtins/Unit/extendhfxf2_test.c index bbe40a433c008..d7227a9f1d156 100644 --- a/compiler-rt/test/builtins/Unit/extendhfxf2_test.c +++ b/compiler-rt/test/builtins/Unit/extendhfxf2_test.c @@ -7,59 +7,58 @@ #include "fp_test.h" -#if __LDBL_MANT_DIG__ == 64 && defined(__x86_64__) && \ - defined(COMPILER_RT_HAS_FLOAT16) +#if HAS_80_BIT_LONG_DOUBLE xf_float __extendhfxf2(TYPE_FP16 f); -int test_extendhfxf2(TYPE_FP16 a, uint64_t expectedHi, uint64_t expectedLo) { +int test_extendhfxf2(TYPE_FP16 a, uint16_t expectedHi, uint64_t expectedLo) { xf_float x = __extendhfxf2(a); int ret = compareResultF80(x, expectedHi, expectedLo); if (ret) { printf("error in test__extendhfxf2(%#.4x) = %.20Lf, " "expected %.20Lf\n", - toRep16(a), x, F80FromRep128(expectedHi, expectedLo)); + toRep16(a), x, F80FromRep80(expectedHi, expectedLo)); } return ret; } int main() { // Small positive value - if (test_extendhfxf2(fromRep16(0x2e66), UINT64_C(0x3ffb), + if (test_extendhfxf2(fromRep16(0x2e66), UINT16_C(0x3ffb), UINT64_C(0xccc0000000000000))) return 1; // Small negative value - if (test_extendhfxf2(fromRep16(0xae66), UINT64_C(0xbffb), + if (test_extendhfxf2(fromRep16(0xae66), UINT16_C(0xbffb), UINT64_C(0xccc0000000000000))) return 1; // Zero - if (test_extendhfxf2(fromRep16(0), UINT64_C(0x0), UINT64_C(0x0))) + if (test_extendhfxf2(fromRep16(0), UINT16_C(0x0), UINT64_C(0x0))) return 1; // Smallest positive non-zero value - if (test_extendhfxf2(fromRep16(0x0100), UINT64_C(0x3fef), + if (test_extendhfxf2(fromRep16(0x0100), UINT16_C(0x3fef), UINT64_C(0x8000000000000000))) return 1; // Smallest negative non-zero value - if (test_extendhfxf2(fromRep16(0x8100), UINT64_C(0xbfef), + if (test_extendhfxf2(fromRep16(0x8100), UINT16_C(0xbfef), UINT64_C(0x8000000000000000))) return 1; // Positive infinity - if (test_extendhfxf2(makeInf16(), UINT64_C(0x7fff), + if (test_extendhfxf2(makeInf16(), UINT16_C(0x7fff), UINT64_C(0x8000000000000000))) return 1; // Negative infinity - if (test_extendhfxf2(makeNegativeInf16(), UINT64_C(0xffff), + if (test_extendhfxf2(makeNegativeInf16(), UINT16_C(0xffff), UINT64_C(0x8000000000000000))) return 1; // NaN - if (test_extendhfxf2(makeQNaN16(), UINT64_C(0x7fff), + if (test_extendhfxf2(makeQNaN16(), UINT16_C(0x7fff), UINT64_C(0xc000000000000000))) return 1; diff --git a/compiler-rt/test/builtins/Unit/fp_test.h b/compiler-rt/test/builtins/Unit/fp_test.h index b23e2ef7f3a16..3a8968a966044 100644 --- a/compiler-rt/test/builtins/Unit/fp_test.h +++ b/compiler-rt/test/builtins/Unit/fp_test.h @@ -1,7 +1,8 @@ -#include +#include #include -#include #include +#include +#include #include "int_types.h" @@ -230,44 +231,49 @@ static inline double makeQNaN64(void) return fromRep64(0x7ff8000000000000UL); } -#if __LDBL_MANT_DIG__ == 64 && defined(__x86_64__) -static inline long double F80FromRep128(uint64_t hi, uint64_t lo) { - __uint128_t x = ((__uint128_t)hi << 64) + lo; - long double ret; - memcpy(&ret, &x, 16); - return ret; +#if HAS_80_BIT_LONG_DOUBLE +static inline xf_float F80FromRep80(uint16_t hi, uint64_t lo) { + uqwords bits; + bits.high.all = hi; + bits.low.all = lo; + xf_float ret; + static_assert(sizeof(xf_float) <= sizeof(uqwords), "wrong representation"); + memcpy(&ret, &bits, sizeof(ret)); + return ret; } -static inline __uint128_t F80ToRep128(long double x) { - __uint128_t ret; - memcpy(&ret, &x, 16); - return ret; +static inline uqwords F80ToRep80(xf_float x) { + uqwords ret; + memset(&ret, 0, sizeof(ret)); + memcpy(&ret, &x, sizeof(x)); + // Any bits beyond the first 16 in high are undefined. + ret.high.all = (uint16_t)ret.high.all; + return ret; } -static inline int compareResultF80(long double result, uint64_t expectedHi, +static inline int compareResultF80(xf_float result, uint16_t expectedHi, uint64_t expectedLo) { - __uint128_t rep = F80ToRep128(result); - // F80 occupies the lower 80 bits of __uint128_t. - uint64_t hi = (rep >> 64) & ((1UL << (80 - 64)) - 1); - uint64_t lo = rep; - return !(hi == expectedHi && lo == expectedLo); + uqwords rep = F80ToRep80(result); + // F80 high occupies the lower 16 bits of high. + assert((uint64_t)(uint16_t)rep.high.all == rep.high.all); + return !(rep.high.all == expectedHi && rep.low.all == expectedLo); } -static inline long double makeQNaN80(void) { - return F80FromRep128(0x7fffUL, 0xc000000000000000UL); +static inline xf_float makeQNaN80(void) { + return F80FromRep80(0x7fffu, 0xc000000000000000UL); } -static inline long double makeNaN80(uint64_t rand) { - return F80FromRep128(0x7fffUL, - 0x8000000000000000 | (rand & 0x3fffffffffffffff)); +static inline xf_float makeNaN80(uint64_t rand) { + return F80FromRep80(0x7fffu, + 0x8000000000000000 | (rand & 0x3fffffffffffffff)); } -static inline long double makeInf80(void) { - return F80FromRep128(0x7fffUL, 0x8000000000000000UL); +static inline xf_float makeInf80(void) { + return F80FromRep80(0x7fffu, 0x8000000000000000UL); } -static inline long double makeNegativeInf80(void) { - return F80FromRep128(0xffffUL, 0x8000000000000000UL); +static inline xf_float makeNegativeInf80(void) { + return F80FromRep80(0xffffu, 0x8000000000000000UL); } #endif