blob: 5fb331b3cbc3e4361aae9b34c8c506d94df7230d [file] [log] [blame]
//===--- classify-fp80.h - Tests for x86 extended double ----------*- 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
//
//===----------------------------------------------------------------------===//
//
// This file contains tests of classification functions for x86 80-bit
// 'long double' type.
//
//===----------------------------------------------------------------------===//
#ifndef _CLASSIFY_F80_H_
#define _CLASSIFY_F80_H_
#if defined(__LDBL_MANT_DIG__) && (__LDBL_MANT_DIG__ == 64)
#define USE_X86_FP80_TYPE
#endif
#ifdef USE_X86_FP80_TYPE
#include "check-helper.h"
#include "fformat.h"
#include <float.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
typedef long double fp80;
// Values in the tables for this type are actually 128-bit integers, stored as
// pairs of 64-bit values.
#define VAL_FORMAT "%08" PRIx64 " %016" PRIx64
#define GET_VALUE(p) ((uint64_t *)(p))[1], ((uint64_t *)(p))[0]
uint64_t ExtendedDoubleSNaNValues[] = {
F80_MAKE(0, F80_EXP_MASK, F80_INTEGER_BIT | F80_PAYLOAD_MASK),
F80_MAKE(1, F80_EXP_MASK, F80_INTEGER_BIT | F80_PAYLOAD_MASK),
F80_MAKE(0, F80_EXP_MASK, F80_INTEGER_BIT | 0x2000000000000000ULL),
F80_MAKE(1, F80_EXP_MASK, F80_INTEGER_BIT | 0x1000000000000000ULL),
F80_MAKE(1, F80_EXP_MASK, F80_INTEGER_BIT | 0x02ULL),
F80_MAKE(0, F80_EXP_MASK, F80_INTEGER_BIT | 0x01ULL)};
uint64_t ExtendedDoubleQNaNValues[] = {
F80_MAKE(0, F80_EXP_MASK,
F80_INTEGER_BIT | F80_QNAN_BIT | F80_PAYLOAD_MASK),
F80_MAKE(1, F80_EXP_MASK,
F80_INTEGER_BIT | F80_QNAN_BIT | F80_PAYLOAD_MASK),
F80_MAKE(0, F80_EXP_MASK, F80_INTEGER_BIT | F80_QNAN_BIT),
F80_MAKE(1, F80_EXP_MASK, F80_INTEGER_BIT | F80_QNAN_BIT),
F80_MAKE(0, F80_EXP_MASK,
F80_INTEGER_BIT | F80_QNAN_BIT | 0x2000000000000000ULL),
F80_MAKE(1, F80_EXP_MASK,
F80_INTEGER_BIT | F80_QNAN_BIT | 0x1000000000000000ULL),
F80_MAKE(1, F80_EXP_MASK, F80_INTEGER_BIT | F80_QNAN_BIT | 0x02ULL),
F80_MAKE(0, F80_EXP_MASK, F80_INTEGER_BIT | F80_QNAN_BIT | 0x01ULL)};
uint64_t ExtendedDoubleInfValues[] = {
F80_MAKE(0, F80_EXP_MASK, F80_INTEGER_BIT),
F80_MAKE(1, F80_EXP_MASK, F80_INTEGER_BIT)};
uint64_t ExtendedDoubleZeroValues[] = {F80_MAKE(0, 0, 0), F80_MAKE(1, 0, 0)};
uint64_t ExtendedDoubleDenormValues[] = {
F80_MAKE(0, 0, 1), // smallest positive denornal
F80_MAKE(1, 0, 1), // smallest negative denornal
F80_MAKE(0, 0, F80_FRACTIONAL_MASK), // largest positive denormal
F80_MAKE(1, 0, F80_FRACTIONAL_MASK) // largest negative denormal
};
uint64_t ExtendedDoubleNormValues[] = {
F80_NORMAL(0, F80_EXP_MIN, 0), // smallest positive normal
F80_NORMAL(1, F80_EXP_MIN, 0), // smallest negative normal
F80_NORMAL(0, F80_EXP_MAX, F80_FRACTIONAL_MASK), // largest positive normal
F80_NORMAL(1, F80_EXP_MAX, F80_FRACTIONAL_MASK), // largest negative normal
F80_NORMAL(0, 0, 0), // +1
F80_NORMAL(0, -1, F80_FRACTIONAL_MASK), // largest number less than 1
F80_NORMAL(0, 0, 1), // smallest number larger than 1
F80_NORMAL(0, 0, F80_MANTISSA(1, 0, 0)), // +1.5
F80_NORMAL(0, 0, F80_MANTISSA(0, 1, 0)), // +1.25
F80_NORMAL(0, 0, F80_MANTISSA(0, 0, 1)), // +1.125
F80_NORMAL(0, -1, 0), // +0.5
F80_NORMAL(0, -2, 0), // +0.25
F80_NORMAL(0, -3, 0), // +0.125
F80_NORMAL(1, 0, 0), // -1
F80_NORMAL(1, -1, F80_FRACTIONAL_MASK),
F80_NORMAL(1, 0, 1),
F80_NORMAL(1, 0, F80_MANTISSA(1, 0, 0)), // -1.5
F80_NORMAL(1, 0, F80_MANTISSA(0, 1, 0)), // -1.25
F80_NORMAL(1, 0, F80_MANTISSA(0, 0, 1)), // -1.125
F80_NORMAL(1, -1, 0), // -0.5
F80_NORMAL(1, -2, 0), // -0.25
F80_NORMAL(1, -3, 0), // -0.125
F80_NORMAL(0, 1, 0), // 2
F80_NORMAL(0, 1, F80_MANTISSA(1, 0, 0)), // 3
F80_NORMAL(1, 1, 0), // -2
F80_NORMAL(1, 1, F80_MANTISSA(1, 0, 0)) // -3
};
uint64_t ExtendedDoubleUnsupportedValues[] = {
// Pseudo-NaNs.
F80_MAKE(0, F80_EXP_MASK, F80_PAYLOAD_MASK),
F80_MAKE(1, F80_EXP_MASK, F80_PAYLOAD_MASK),
F80_MAKE(0, F80_EXP_MASK, 0x2000000000000000ULL),
F80_MAKE(1, F80_EXP_MASK, 0x1000000000000000ULL),
F80_MAKE(1, F80_EXP_MASK, 0x02ULL),
F80_MAKE(0, F80_EXP_MASK, 0x01ULL),
F80_MAKE(0, F80_EXP_MASK, F80_QNAN_BIT | F80_PAYLOAD_MASK),
F80_MAKE(1, F80_EXP_MASK, F80_QNAN_BIT | F80_PAYLOAD_MASK),
F80_MAKE(0, F80_EXP_MASK, F80_QNAN_BIT),
F80_MAKE(1, F80_EXP_MASK, F80_QNAN_BIT),
F80_MAKE(0, F80_EXP_MASK, F80_QNAN_BIT | 0x2000000000000000ULL),
F80_MAKE(1, F80_EXP_MASK, F80_QNAN_BIT | 0x1000000000000000ULL),
F80_MAKE(1, F80_EXP_MASK, F80_QNAN_BIT | 0x02ULL),
F80_MAKE(0, F80_EXP_MASK, F80_QNAN_BIT | 0x01ULL),
// Pseudo-infinities.
F80_MAKE(0, F80_EXP_MASK, 0),
F80_MAKE(1, F80_EXP_MASK, 0),
// Unnormals.
F80_MAKE(0, 1, 0),
F80_MAKE(1, 1, 0),
F80_MAKE(0, 0x7FFE, 0),
F80_MAKE(1, 0x7FFE, 0),
};
uint64_t ExtendedDoublePseudoDenormalValues[] = {
// Pseudo-denormals.
F80_MAKE(0, 0, F80_INTEGER_BIT),
F80_MAKE(1, 0, F80_INTEGER_BIT),
F80_MAKE(0, 0, F80_INTEGER_BIT | 1),
F80_MAKE(1, 0, F80_INTEGER_BIT | 1),
F80_MAKE(0, 0, F80_INTEGER_BIT | F80_FRACTIONAL_MASK),
F80_MAKE(1, 0, F80_INTEGER_BIT | F80_FRACTIONAL_MASK),
};
int test_fp80() {
for (unsigned i = 0; i < DimOf(ExtendedDoubleQNaNValues); i += 2) {
uint64_t *P = (uint64_t *)(ExtendedDoubleQNaNValues + i);
long double X = *(long double *)P;
CHECK_VALUE(__builtin_isnan(X), P);
CHECK_VALUE(!__builtin_issignaling(X), P);
CHECK_VALUE(!__builtin_isinf(X), P);
CHECK_VALUE(!__builtin_isfinite(X), P);
CHECK_VALUE(!__builtin_isnormal(X), P);
CHECK_VALUE(!__builtin_issubnormal(X), P);
CHECK_VALUE(!__builtin_iszero(X), P);
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 0, P);
}
for (unsigned i = 0; i < DimOf(ExtendedDoubleSNaNValues); i += 2) {
uint64_t *P = (uint64_t *)(ExtendedDoubleSNaNValues + i);
long double X = *(long double *)P;
CHECK_VALUE(__builtin_isnan(X), P);
CHECK_VALUE(__builtin_issignaling(X), P);
CHECK_VALUE(!__builtin_isinf(X), P);
CHECK_VALUE(!__builtin_isfinite(X), P);
CHECK_VALUE(!__builtin_isnormal(X), P);
CHECK_VALUE(!__builtin_issubnormal(X), P);
CHECK_VALUE(!__builtin_iszero(X), P);
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 0, P);
}
for (unsigned i = 0; i < DimOf(ExtendedDoubleInfValues); i += 2) {
uint64_t *P = (uint64_t *)(ExtendedDoubleInfValues + i);
long double X = *(long double *)P;
CHECK_VALUE(!__builtin_isnan(X), P);
CHECK_VALUE(!__builtin_issignaling(X), P);
CHECK_VALUE(__builtin_isinf(X), P);
CHECK_VALUE(!__builtin_isfinite(X), P);
CHECK_VALUE(!__builtin_isnormal(X), P);
CHECK_VALUE(!__builtin_issubnormal(X), P);
CHECK_VALUE(!__builtin_iszero(X), P);
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 1, P);
}
for (unsigned i = 0; i < DimOf(ExtendedDoubleZeroValues); i += 2) {
uint64_t *P = (uint64_t *)(ExtendedDoubleZeroValues + i);
long double X = *(long double *)P;
CHECK_VALUE(!__builtin_isnan(X), P);
CHECK_VALUE(!__builtin_issignaling(X), P);
CHECK_VALUE(!__builtin_isinf(X), P);
CHECK_VALUE(__builtin_isfinite(X), P);
CHECK_VALUE(!__builtin_isnormal(X), P);
CHECK_VALUE(!__builtin_issubnormal(X), P);
CHECK_VALUE(__builtin_iszero(X), P);
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 4, P);
}
for (unsigned i = 0; i < DimOf(ExtendedDoubleDenormValues); i += 2) {
uint64_t *P = (uint64_t *)(ExtendedDoubleDenormValues + i);
long double X = *(long double *)P;
CHECK_VALUE(!__builtin_isnan(X), P);
CHECK_VALUE(!__builtin_issignaling(X), P);
CHECK_VALUE(!__builtin_isinf(X), P);
CHECK_VALUE(__builtin_isfinite(X), P);
CHECK_VALUE(!__builtin_isnormal(X), P);
CHECK_VALUE(__builtin_issubnormal(X), P);
CHECK_VALUE(!__builtin_iszero(X), P);
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 3, P);
}
for (unsigned i = 0; i < DimOf(ExtendedDoubleNormValues); i += 2) {
uint64_t *P = (uint64_t *)(ExtendedDoubleNormValues + i);
long double X = *(long double *)P;
CHECK_VALUE(!__builtin_isnan(X), P);
CHECK_VALUE(!__builtin_issignaling(X), P);
CHECK_VALUE(!__builtin_isinf(X), P);
CHECK_VALUE(__builtin_isfinite(X), P);
CHECK_VALUE(__builtin_isnormal(X), P);
CHECK_VALUE(!__builtin_issubnormal(X), P);
CHECK_VALUE(!__builtin_iszero(X), P);
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 2, P);
}
for (unsigned i = 0; i < DimOf(ExtendedDoubleUnsupportedValues); i += 2) {
uint64_t *P = (uint64_t *)(ExtendedDoubleUnsupportedValues + i);
long double X = *(long double *)P;
CHECK_VALUE(__builtin_isnan(X), P);
CHECK_VALUE(!__builtin_issignaling(X), P);
CHECK_VALUE(!__builtin_isinf(X), P);
CHECK_VALUE(!__builtin_isfinite(X), P);
CHECK_VALUE(!__builtin_isnormal(X), P);
CHECK_VALUE(!__builtin_issubnormal(X), P);
CHECK_VALUE(!__builtin_iszero(X), P);
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 0, P);
}
return 0;
}
#define FLOAT_TYPE fp80
#include "gen_isfpclass_funcs.h"
void test_isfpclass_fp80() {
for (unsigned i = 0; i < DimOf(ExtendedDoubleZeroValues); i += 2) {
long double X = *(long double *)(ExtendedDoubleZeroValues + i);
if (__builtin_signbit(X))
test_fcNegZero_fp80(X);
else
test_fcPosZero_fp80(X);
}
for (unsigned i = 0; i < DimOf(ExtendedDoubleDenormValues); i += 2) {
long double X = *(long double *)(ExtendedDoubleDenormValues + i);
if (X < 0)
test_fcNegSubnormal_fp80(X);
else
test_fcPosSubnormal_fp80(X);
}
for (unsigned i = 0; i < DimOf(ExtendedDoubleNormValues); i += 2) {
long double X = *(long double *)(ExtendedDoubleNormValues + i);
if (X < 0)
test_fcNegNormal_fp80(X);
else
test_fcPosNormal_fp80(X);
}
for (unsigned i = 0; i < DimOf(ExtendedDoubleInfValues); i += 2) {
long double X = *(long double *)(ExtendedDoubleInfValues + i);
if (X > 0)
test_fcPosInf_fp80(X);
else
test_fcNegInf_fp80(X);
}
for (unsigned i = 0; i < DimOf(ExtendedDoubleQNaNValues); i += 2) {
long double X = *(long double *)(ExtendedDoubleQNaNValues + i);
test_fcQNan_fp80(X);
}
for (unsigned i = 0; i < DimOf(ExtendedDoubleSNaNValues); i += 2) {
long double X = *(long double *)(ExtendedDoubleSNaNValues + i);
test_fcSNan_fp80(X);
}
}
#undef VAL_FORMAT
#undef GET_VALUE
#undef FLOAT_TYPE
#endif // #ifdef USE_X86_FP80_TYPE
#endif // #ifndef _CLASSIFY_F80_H_