mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-27 07:31:28 +00:00
[builtins] Support building the 128-bit float functions on ld80 platforms (#68132)
GCC provides these functions (e.g. __addtf3, etc.) in libgcc on x86_64. Since Clang supports float128, we can also enable the existing code by using float128 for fp_t if either __FLOAT128__ or __SIZEOF_FLOAT128__ is defined instead of only supporting these builtins for platforms with 128-bit IEEE long doubles. This commit defines a new tf_float typedef that matches a float with attribute((mode(TF)) on each given architecture. There are more tests that could be enabled for x86, but to keep the diff smaller, I restricted test changes to ones that started failing as part of this refactoring. This change has been tested on x86 (natively) and aarch64,powerpc64,riscv64 and sparc64 via qemu-user. This supersedes https://reviews.llvm.org/D98261 and should also cover the changes from https://github.com/llvm/llvm-project/pull/68041.
This commit is contained in:
parent
16fe53c47e
commit
d2ce3e9621
@ -187,8 +187,6 @@ set(BF16_SOURCES
|
||||
truncsfbf2.c
|
||||
)
|
||||
|
||||
# TODO: Several "tf" files (and divtc3.c, but not multc3.c) are in
|
||||
# GENERIC_SOURCES instead of here.
|
||||
set(GENERIC_TF_SOURCES
|
||||
addtf3.c
|
||||
comparetf2.c
|
||||
|
@ -137,49 +137,54 @@ si_int __ucmpti2(tu_int a, tu_int b);
|
||||
di_int __fixsfdi( float a);
|
||||
di_int __fixdfdi( double a);
|
||||
di_int __fixxfdi(long double a);
|
||||
di_int __fixtfdi( tf_float a);
|
||||
|
||||
ti_int __fixsfti( float a);
|
||||
ti_int __fixdfti( double a);
|
||||
ti_int __fixxfti(long double a);
|
||||
uint64_t __fixtfdi(long double input); // ppc only, doesn't match documentation
|
||||
ti_int __fixtfti( tf_float a);
|
||||
|
||||
su_int __fixunssfsi( float a);
|
||||
su_int __fixunsdfsi( double a);
|
||||
su_int __fixunsxfsi(long double a);
|
||||
su_int __fixunstfsi( tf_float a);
|
||||
|
||||
du_int __fixunssfdi( float a);
|
||||
du_int __fixunsdfdi( double a);
|
||||
du_int __fixunsxfdi(long double a);
|
||||
du_int __fixunstfdi( tf_float a);
|
||||
|
||||
tu_int __fixunssfti( float a);
|
||||
tu_int __fixunsdfti( double a);
|
||||
tu_int __fixunsxfti(long double a);
|
||||
uint64_t __fixunstfdi(long double input); // ppc only
|
||||
tu_int __fixunstfti( tf_float a);
|
||||
|
||||
float __floatdisf(di_int a);
|
||||
double __floatdidf(di_int a);
|
||||
long double __floatdixf(di_int a);
|
||||
long double __floatditf(int64_t a); // ppc only
|
||||
tf_float __floatditf(int64_t a);
|
||||
|
||||
float __floattisf(ti_int a);
|
||||
double __floattidf(ti_int a);
|
||||
long double __floattixf(ti_int a);
|
||||
tf_float __floattitf(ti_int a);
|
||||
|
||||
float __floatundisf(du_int a);
|
||||
double __floatundidf(du_int a);
|
||||
long double __floatundixf(du_int a);
|
||||
long double __floatunditf(uint64_t a); // ppc only
|
||||
tf_float __floatunditf(du_int a);
|
||||
|
||||
float __floatuntisf(tu_int a);
|
||||
double __floatuntidf(tu_int a);
|
||||
long double __floatuntixf(tu_int a);
|
||||
tf_float __floatuntixf(tu_int a);
|
||||
|
||||
// Floating point raised to integer power
|
||||
|
||||
float __powisf2( float a, int b); // a ^ b
|
||||
double __powidf2( double a, int b); // a ^ b
|
||||
long double __powixf2(long double a, int b); // a ^ b
|
||||
long double __powitf2(long double a, int b); // ppc only, a ^ b
|
||||
tf_float __powitf2( tf_float a, int b); // a ^ b
|
||||
|
||||
// Complex arithmetic
|
||||
|
||||
@ -189,8 +194,7 @@ long double __powitf2(long double a, int b); // ppc only, a ^ b
|
||||
double _Complex __muldc3(double a, double b, double c, double d);
|
||||
long double _Complex __mulxc3(long double a, long double b,
|
||||
long double c, long double d);
|
||||
long double _Complex __multc3(long double a, long double b,
|
||||
long double c, long double d); // ppc only
|
||||
tf_float _Complex __multc3(tf_float a, tf_float b, tf_float c, tf_float d);
|
||||
|
||||
// (a + ib) / (c + id)
|
||||
|
||||
@ -198,8 +202,7 @@ long double _Complex __multc3(long double a, long double b,
|
||||
double _Complex __divdc3(double a, double b, double c, double d);
|
||||
long double _Complex __divxc3(long double a, long double b,
|
||||
long double c, long double d);
|
||||
long double _Complex __divtc3(long double a, long double b,
|
||||
long double c, long double d); // ppc only
|
||||
tf_float _Complex __divtc3(tf_float a, tf_float b, tf_float c, tf_float d);
|
||||
|
||||
|
||||
// Runtime support
|
||||
|
@ -12,44 +12,45 @@
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "fp_lib.h"
|
||||
#include "int_lib.h"
|
||||
#include "int_math.h"
|
||||
|
||||
#if defined(CRT_HAS_TF_MODE)
|
||||
|
||||
// Returns: the quotient of (a + ib) / (c + id)
|
||||
|
||||
COMPILER_RT_ABI Lcomplex __divtc3(long double __a, long double __b,
|
||||
long double __c, long double __d) {
|
||||
COMPILER_RT_ABI Qcomplex __divtc3(fp_t __a, fp_t __b, fp_t __c, fp_t __d) {
|
||||
int __ilogbw = 0;
|
||||
long double __logbw =
|
||||
__compiler_rt_logbl(__compiler_rt_fmaxl(crt_fabsl(__c), crt_fabsl(__d)));
|
||||
fp_t __logbw = __compiler_rt_logbtf(
|
||||
__compiler_rt_fmaxtf(crt_fabstf(__c), crt_fabstf(__d)));
|
||||
if (crt_isfinite(__logbw)) {
|
||||
__ilogbw = (int)__logbw;
|
||||
__c = __compiler_rt_scalbnl(__c, -__ilogbw);
|
||||
__d = __compiler_rt_scalbnl(__d, -__ilogbw);
|
||||
__c = __compiler_rt_scalbntf(__c, -__ilogbw);
|
||||
__d = __compiler_rt_scalbntf(__d, -__ilogbw);
|
||||
}
|
||||
long double __denom = __c * __c + __d * __d;
|
||||
Lcomplex z;
|
||||
COMPLEX_REAL(z) =
|
||||
__compiler_rt_scalbnl((__a * __c + __b * __d) / __denom, -__ilogbw);
|
||||
COMPLEX_IMAGINARY(z) =
|
||||
__compiler_rt_scalbnl((__b * __c - __a * __d) / __denom, -__ilogbw);
|
||||
if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z))) {
|
||||
fp_t __denom = __c * __c + __d * __d;
|
||||
Qcomplex z;
|
||||
COMPLEXTF_REAL(z) =
|
||||
__compiler_rt_scalbntf((__a * __c + __b * __d) / __denom, -__ilogbw);
|
||||
COMPLEXTF_IMAGINARY(z) =
|
||||
__compiler_rt_scalbntf((__b * __c - __a * __d) / __denom, -__ilogbw);
|
||||
if (crt_isnan(COMPLEXTF_REAL(z)) && crt_isnan(COMPLEXTF_IMAGINARY(z))) {
|
||||
if ((__denom == 0.0) && (!crt_isnan(__a) || !crt_isnan(__b))) {
|
||||
COMPLEX_REAL(z) = crt_copysignl(CRT_INFINITY, __c) * __a;
|
||||
COMPLEX_IMAGINARY(z) = crt_copysignl(CRT_INFINITY, __c) * __b;
|
||||
COMPLEXTF_REAL(z) = crt_copysigntf(CRT_INFINITY, __c) * __a;
|
||||
COMPLEXTF_IMAGINARY(z) = crt_copysigntf(CRT_INFINITY, __c) * __b;
|
||||
} else if ((crt_isinf(__a) || crt_isinf(__b)) && crt_isfinite(__c) &&
|
||||
crt_isfinite(__d)) {
|
||||
__a = crt_copysignl(crt_isinf(__a) ? 1.0 : 0.0, __a);
|
||||
__b = crt_copysignl(crt_isinf(__b) ? 1.0 : 0.0, __b);
|
||||
COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c + __b * __d);
|
||||
COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__b * __c - __a * __d);
|
||||
__a = crt_copysigntf(crt_isinf(__a) ? (fp_t)1.0 : (fp_t)0.0, __a);
|
||||
__b = crt_copysigntf(crt_isinf(__b) ? (fp_t)1.0 : (fp_t)0.0, __b);
|
||||
COMPLEXTF_REAL(z) = CRT_INFINITY * (__a * __c + __b * __d);
|
||||
COMPLEXTF_IMAGINARY(z) = CRT_INFINITY * (__b * __c - __a * __d);
|
||||
} else if (crt_isinf(__logbw) && __logbw > 0.0 && crt_isfinite(__a) &&
|
||||
crt_isfinite(__b)) {
|
||||
__c = crt_copysignl(crt_isinf(__c) ? 1.0 : 0.0, __c);
|
||||
__d = crt_copysignl(crt_isinf(__d) ? 1.0 : 0.0, __d);
|
||||
COMPLEX_REAL(z) = 0.0 * (__a * __c + __b * __d);
|
||||
COMPLEX_IMAGINARY(z) = 0.0 * (__b * __c - __a * __d);
|
||||
__c = crt_copysigntf(crt_isinf(__c) ? (fp_t)1.0 : (fp_t)0.0, __c);
|
||||
__d = crt_copysigntf(crt_isinf(__d) ? (fp_t)1.0 : (fp_t)0.0, __d);
|
||||
COMPLEXTF_REAL(z) = 0.0 * (__a * __c + __b * __d);
|
||||
COMPLEXTF_IMAGINARY(z) = 0.0 * (__b * __c - __a * __d);
|
||||
}
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -14,8 +14,6 @@
|
||||
#define DST_QUAD
|
||||
#include "fp_extend_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI fp_t __extenddftf2(double a) {
|
||||
return __extendXfYf2__(a);
|
||||
}
|
||||
COMPILER_RT_ABI dst_t __extenddftf2(src_t a) { return __extendXfYf2__(a); }
|
||||
|
||||
#endif
|
||||
|
@ -15,8 +15,6 @@
|
||||
#define DST_QUAD
|
||||
#include "fp_extend_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI long double __extendhftf2(_Float16 a) {
|
||||
return __extendXfYf2__(a);
|
||||
}
|
||||
COMPILER_RT_ABI dst_t __extendhftf2(src_t a) { return __extendXfYf2__(a); }
|
||||
|
||||
#endif
|
||||
|
@ -14,8 +14,6 @@
|
||||
#define DST_QUAD
|
||||
#include "fp_extend_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI fp_t __extendsftf2(float a) {
|
||||
return __extendXfYf2__(a);
|
||||
}
|
||||
COMPILER_RT_ABI dst_t __extendsftf2(src_t a) { return __extendXfYf2__(a); }
|
||||
|
||||
#endif
|
||||
|
@ -9,14 +9,15 @@
|
||||
// Assumption: long double is a IEEE 80 bit floating point type padded to 128
|
||||
// bits.
|
||||
|
||||
// TODO: use fp_lib.h once QUAD_PRECISION is available on x86_64.
|
||||
#if __LDBL_MANT_DIG__ == 64 && defined(__x86_64__) && \
|
||||
(defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__))
|
||||
#define QUAD_PRECISION
|
||||
#include "fp_lib.h"
|
||||
|
||||
#if defined(CRT_HAS_TF_MODE) && __LDBL_MANT_DIG__ == 64 && defined(__x86_64__)
|
||||
#define SRC_80
|
||||
#define DST_QUAD
|
||||
#include "fp_extend_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI __float128 __extendxftf2(long double a) {
|
||||
COMPILER_RT_ABI tf_float __extendxftf2(long double a) {
|
||||
return __extendXfYf2__(a);
|
||||
}
|
||||
|
||||
|
@ -102,13 +102,7 @@ static const int dstSigFracBits = 52;
|
||||
static const int dstExpBits = 11;
|
||||
|
||||
#elif defined DST_QUAD
|
||||
// TODO: use fp_lib.h once QUAD_PRECISION is available on x86_64.
|
||||
#if __LDBL_MANT_DIG__ == 113
|
||||
typedef long double dst_t;
|
||||
#elif defined(__x86_64__) && \
|
||||
(defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__))
|
||||
typedef __float128 dst_t;
|
||||
#endif
|
||||
typedef tf_float dst_t;
|
||||
typedef __uint128_t dst_rep_t;
|
||||
#define DST_REP_C (__uint128_t)
|
||||
static const int dstBits = sizeof(dst_t) * CHAR_BIT;
|
||||
|
@ -105,18 +105,11 @@ static __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) {
|
||||
COMPILER_RT_ABI fp_t __adddf3(fp_t a, fp_t b);
|
||||
|
||||
#elif defined QUAD_PRECISION
|
||||
#if __LDBL_MANT_DIG__ == 113 && defined(__SIZEOF_INT128__)
|
||||
// TODO: Availability of the *tf functions should not depend on long double
|
||||
// being IEEE 128, but instead on being able to use a 128-bit floating-point
|
||||
// type, which includes __float128.
|
||||
// Right now this (incorrectly) stops the builtins from being used for x86.
|
||||
#define CRT_LDBL_128BIT
|
||||
#define CRT_HAS_TF_MODE
|
||||
#define TF_C(c) c##L
|
||||
#if defined(CRT_HAS_TF_MODE)
|
||||
typedef uint64_t half_rep_t;
|
||||
typedef __uint128_t rep_t;
|
||||
typedef __int128_t srep_t;
|
||||
typedef long double fp_t;
|
||||
typedef tf_float fp_t;
|
||||
#define HALF_REP_C UINT64_C
|
||||
#define REP_C (__uint128_t)
|
||||
// Note: Since there is no explicit way to tell compiler the constant is a
|
||||
@ -207,13 +200,13 @@ static __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) {
|
||||
#undef Word_HiMask
|
||||
#undef Word_LoMask
|
||||
#undef Word_FullMask
|
||||
#endif // __LDBL_MANT_DIG__ == 113 && __SIZEOF_INT128__
|
||||
#endif // defined(CRT_HAS_TF_MODE)
|
||||
#else
|
||||
#error SINGLE_PRECISION, DOUBLE_PRECISION or QUAD_PRECISION must be defined.
|
||||
#endif
|
||||
|
||||
#if defined(SINGLE_PRECISION) || defined(DOUBLE_PRECISION) || \
|
||||
defined(CRT_LDBL_128BIT)
|
||||
(defined(QUAD_PRECISION) && defined(CRT_HAS_TF_MODE))
|
||||
#define typeWidth (sizeof(rep_t) * CHAR_BIT)
|
||||
#define exponentBits (typeWidth - significandBits - 1)
|
||||
#define maxExponent ((1 << exponentBits) - 1)
|
||||
@ -393,31 +386,40 @@ static __inline fp_t __compiler_rt_fmax(fp_t x, fp_t y) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#elif defined(QUAD_PRECISION)
|
||||
|
||||
#if defined(CRT_LDBL_128BIT)
|
||||
static __inline fp_t __compiler_rt_logbl(fp_t x) {
|
||||
return __compiler_rt_logbX(x);
|
||||
}
|
||||
static __inline fp_t __compiler_rt_scalbnl(fp_t x, int y) {
|
||||
return __compiler_rt_scalbnX(x, y);
|
||||
}
|
||||
static __inline fp_t __compiler_rt_fmaxl(fp_t x, fp_t y) {
|
||||
return __compiler_rt_fmaxX(x, y);
|
||||
}
|
||||
#else
|
||||
#elif defined(QUAD_PRECISION) && defined(CRT_HAS_TF_MODE)
|
||||
// The generic implementation only works for ieee754 floating point. For other
|
||||
// floating point types, continue to rely on the libm implementation for now.
|
||||
static __inline long double __compiler_rt_logbl(long double x) {
|
||||
#if defined(CRT_HAS_IEEE_TF)
|
||||
static __inline tf_float __compiler_rt_logbtf(tf_float x) {
|
||||
return __compiler_rt_logbX(x);
|
||||
}
|
||||
static __inline tf_float __compiler_rt_scalbntf(tf_float x, int y) {
|
||||
return __compiler_rt_scalbnX(x, y);
|
||||
}
|
||||
static __inline tf_float __compiler_rt_fmaxtf(tf_float x, tf_float y) {
|
||||
return __compiler_rt_fmaxX(x, y);
|
||||
}
|
||||
#define __compiler_rt_logbl __compiler_rt_logbtf
|
||||
#define __compiler_rt_scalbnl __compiler_rt_scalbntf
|
||||
#define __compiler_rt_fmaxl __compiler_rt_fmaxtf
|
||||
#define crt_fabstf crt_fabsf128
|
||||
#define crt_copysigntf crt_copysignf128
|
||||
#elif defined(CRT_LDBL_128BIT)
|
||||
static __inline tf_float __compiler_rt_logbtf(tf_float x) {
|
||||
return crt_logbl(x);
|
||||
}
|
||||
static __inline long double __compiler_rt_scalbnl(long double x, int y) {
|
||||
static __inline tf_float __compiler_rt_scalbntf(tf_float x, int y) {
|
||||
return crt_scalbnl(x, y);
|
||||
}
|
||||
static __inline long double __compiler_rt_fmaxl(long double x, long double y) {
|
||||
static __inline tf_float __compiler_rt_fmaxtf(tf_float x, tf_float y) {
|
||||
return crt_fmaxl(x, y);
|
||||
}
|
||||
#endif // CRT_LDBL_128BIT
|
||||
#define __compiler_rt_logbl crt_logbl
|
||||
#define __compiler_rt_scalbnl crt_scalbnl
|
||||
#define __compiler_rt_fmaxl crt_fmaxl
|
||||
#else
|
||||
#error Unsupported TF mode type
|
||||
#endif
|
||||
|
||||
#endif // *_PRECISION
|
||||
|
||||
|
@ -36,13 +36,7 @@ static const int srcSigFracBits = 52;
|
||||
static const int srcExpBits = 11;
|
||||
|
||||
#elif defined SRC_QUAD
|
||||
// TODO: use fp_lib.h once QUAD_PRECISION is available on x86_64.
|
||||
#if __LDBL_MANT_DIG__ == 113
|
||||
typedef long double src_t;
|
||||
#elif defined(__x86_64__) && \
|
||||
(defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__))
|
||||
typedef __float128 src_t;
|
||||
#endif
|
||||
typedef tf_float src_t;
|
||||
typedef __uint128_t src_rep_t;
|
||||
#define SRC_REP_C (__uint128_t)
|
||||
static const int srcBits = sizeof(src_t) * CHAR_BIT;
|
||||
|
@ -65,6 +65,11 @@
|
||||
#define crt_copysign(x, y) __builtin_copysign((x), (y))
|
||||
#define crt_copysignf(x, y) __builtin_copysignf((x), (y))
|
||||
#define crt_copysignl(x, y) __builtin_copysignl((x), (y))
|
||||
#if __has_builtin(__builtin_copysignf128)
|
||||
#define crt_copysignf128(x, y) __builtin_copysignf128((x), (y))
|
||||
#elif __has_builtin(__builtin_copysignq) || (defined(__GNUC__) && __GNUC__ >= 7)
|
||||
#define crt_copysignf128(x, y) __builtin_copysignq((x), (y))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
@ -75,6 +80,11 @@
|
||||
#define crt_fabs(x) __builtin_fabs((x))
|
||||
#define crt_fabsf(x) __builtin_fabsf((x))
|
||||
#define crt_fabsl(x) __builtin_fabsl((x))
|
||||
#if __has_builtin(__builtin_fabsf128)
|
||||
#define crt_fabsf128(x) __builtin_fabsf128((x))
|
||||
#elif __has_builtin(__builtin_fabsq) || (defined(__GNUC__) && __GNUC__ >= 7)
|
||||
#define crt_fabsf128(x) __builtin_fabsq((x))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
|
@ -59,7 +59,7 @@ enum {
|
||||
};
|
||||
|
||||
#elif defined DST_QUAD
|
||||
typedef long double dst_t;
|
||||
typedef tf_float dst_t;
|
||||
typedef __uint128_t dst_rep_t;
|
||||
#define DST_REP_C (__uint128_t)
|
||||
|
||||
|
@ -165,6 +165,53 @@ typedef struct {
|
||||
#define HAS_80_BIT_LONG_DOUBLE 0
|
||||
#endif
|
||||
|
||||
#ifdef __powerpc64__
|
||||
// From https://gcc.gnu.org/wiki/Ieee128PowerPC:
|
||||
// PowerPC64 uses the following suffixes:
|
||||
// IFmode: IBM extended double
|
||||
// KFmode: IEEE 128-bit floating point
|
||||
// TFmode: Matches the default for long double. With -mabi=ieeelongdouble,
|
||||
// it is IEEE 128-bit, with -mabi=ibmlongdouble IBM extended double
|
||||
// Since compiler-rt only implements the tf set of libcalls, we use long double
|
||||
// for the tf_float typedef.
|
||||
typedef long double tf_float;
|
||||
#define CRT_LDBL_128BIT
|
||||
#define CRT_HAS_F128
|
||||
#if __LDBL_MANT_DIG__ == 113 && !defined(__LONG_DOUBLE_IBM128__)
|
||||
#define CRT_HAS_IEEE_TF
|
||||
#define CRT_LDBL_IEEE_F128
|
||||
#endif
|
||||
#define TF_C(x) x##L
|
||||
#elif __LDBL_MANT_DIG__ == 113
|
||||
// Use long double instead of __float128 if it matches the IEEE 128-bit format.
|
||||
#define CRT_LDBL_128BIT
|
||||
#define CRT_HAS_F128
|
||||
#define CRT_HAS_IEEE_TF
|
||||
#define CRT_LDBL_IEEE_F128
|
||||
typedef long double tf_float;
|
||||
#define TF_C(x) x##L
|
||||
#elif defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)
|
||||
#define CRT_HAS___FLOAT128_KEYWORD
|
||||
#define CRT_HAS_F128
|
||||
// NB: we assume the __float128 type uses IEEE representation.
|
||||
#define CRT_HAS_IEEE_TF
|
||||
typedef __float128 tf_float;
|
||||
#define TF_C(x) x##Q
|
||||
#endif
|
||||
|
||||
#ifdef CRT_HAS_F128
|
||||
typedef union {
|
||||
uqwords u;
|
||||
tf_float f;
|
||||
} tf_bits;
|
||||
#endif
|
||||
|
||||
// __(u)int128_t is currently needed to compile the *tf builtins as we would
|
||||
// otherwise need to manually expand the bit manipulation on two 64-bit value.
|
||||
#if defined(CRT_HAS_128BIT) && defined(CRT_HAS_F128)
|
||||
#define CRT_HAS_TF_MODE
|
||||
#endif
|
||||
|
||||
#if CRT_HAS_FLOATING_POINT
|
||||
typedef union {
|
||||
uqwords u;
|
||||
@ -175,6 +222,20 @@ typedef union {
|
||||
typedef float _Complex Fcomplex;
|
||||
typedef double _Complex Dcomplex;
|
||||
typedef long double _Complex Lcomplex;
|
||||
#if defined(CRT_LDBL_128BIT)
|
||||
typedef Lcomplex Qcomplex;
|
||||
#define CRT_HAS_NATIVE_COMPLEX_F128
|
||||
#elif defined(CRT_HAS___FLOAT128_KEYWORD)
|
||||
#if defined(__clang_major__) && __clang_major__ > 10
|
||||
// Clang prior to 11 did not support __float128 _Complex.
|
||||
typedef __float128 _Complex Qcomplex;
|
||||
#define CRT_HAS_NATIVE_COMPLEX_F128
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 7
|
||||
// GCC does not allow __float128 _Complex, but accepts _Float128 _Complex.
|
||||
typedef _Float128 _Complex Qcomplex;
|
||||
#define CRT_HAS_NATIVE_COMPLEX_F128
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define COMPLEX_REAL(x) __real__(x)
|
||||
#define COMPLEX_IMAGINARY(x) __imag__(x)
|
||||
@ -194,5 +255,17 @@ typedef struct {
|
||||
#define COMPLEX_REAL(x) (x).real
|
||||
#define COMPLEX_IMAGINARY(x) (x).imaginary
|
||||
#endif
|
||||
|
||||
#ifdef CRT_HAS_NATIVE_COMPLEX_F128
|
||||
#define COMPLEXTF_REAL(x) __real__(x)
|
||||
#define COMPLEXTF_IMAGINARY(x) __imag__(x)
|
||||
#elif defined(CRT_HAS_F128)
|
||||
typedef struct {
|
||||
tf_float real, imaginary;
|
||||
} Qcomplex;
|
||||
#define COMPLEXTF_REAL(x) (x).real
|
||||
#define COMPLEXTF_IMAGINARY(x) (x).imaginary
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif // INT_TYPES_H
|
||||
|
@ -10,56 +10,61 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "fp_lib.h"
|
||||
#include "int_lib.h"
|
||||
#include "int_math.h"
|
||||
|
||||
#if defined(CRT_HAS_TF_MODE)
|
||||
|
||||
// Returns: the product of a + ib and c + id
|
||||
|
||||
COMPILER_RT_ABI long double _Complex __multc3(long double a, long double b,
|
||||
long double c, long double d) {
|
||||
long double ac = a * c;
|
||||
long double bd = b * d;
|
||||
long double ad = a * d;
|
||||
long double bc = b * c;
|
||||
long double _Complex z;
|
||||
__real__ z = ac - bd;
|
||||
__imag__ z = ad + bc;
|
||||
if (crt_isnan(__real__ z) && crt_isnan(__imag__ z)) {
|
||||
COMPILER_RT_ABI Qcomplex __multc3(fp_t a, fp_t b, fp_t c, fp_t d) {
|
||||
fp_t ac = a * c;
|
||||
fp_t bd = b * d;
|
||||
fp_t ad = a * d;
|
||||
fp_t bc = b * c;
|
||||
Qcomplex z;
|
||||
COMPLEXTF_REAL(z) = ac - bd;
|
||||
COMPLEXTF_IMAGINARY(z) = ad + bc;
|
||||
if (crt_isnan(COMPLEXTF_REAL(z)) && crt_isnan(COMPLEXTF_IMAGINARY(z))) {
|
||||
int recalc = 0;
|
||||
if (crt_isinf(a) || crt_isinf(b)) {
|
||||
a = crt_copysignl(crt_isinf(a) ? 1 : 0, a);
|
||||
b = crt_copysignl(crt_isinf(b) ? 1 : 0, b);
|
||||
a = crt_copysigntf(crt_isinf(a) ? 1 : 0, a);
|
||||
b = crt_copysigntf(crt_isinf(b) ? 1 : 0, b);
|
||||
if (crt_isnan(c))
|
||||
c = crt_copysignl(0, c);
|
||||
c = crt_copysigntf(0, c);
|
||||
if (crt_isnan(d))
|
||||
d = crt_copysignl(0, d);
|
||||
d = crt_copysigntf(0, d);
|
||||
recalc = 1;
|
||||
}
|
||||
if (crt_isinf(c) || crt_isinf(d)) {
|
||||
c = crt_copysignl(crt_isinf(c) ? 1 : 0, c);
|
||||
d = crt_copysignl(crt_isinf(d) ? 1 : 0, d);
|
||||
c = crt_copysigntf(crt_isinf(c) ? 1 : 0, c);
|
||||
d = crt_copysigntf(crt_isinf(d) ? 1 : 0, d);
|
||||
if (crt_isnan(a))
|
||||
a = crt_copysignl(0, a);
|
||||
a = crt_copysigntf(0, a);
|
||||
if (crt_isnan(b))
|
||||
b = crt_copysignl(0, b);
|
||||
b = crt_copysigntf(0, b);
|
||||
recalc = 1;
|
||||
}
|
||||
if (!recalc &&
|
||||
(crt_isinf(ac) || crt_isinf(bd) || crt_isinf(ad) || crt_isinf(bc))) {
|
||||
if (crt_isnan(a))
|
||||
a = crt_copysignl(0, a);
|
||||
a = crt_copysigntf(0, a);
|
||||
if (crt_isnan(b))
|
||||
b = crt_copysignl(0, b);
|
||||
b = crt_copysigntf(0, b);
|
||||
if (crt_isnan(c))
|
||||
c = crt_copysignl(0, c);
|
||||
c = crt_copysigntf(0, c);
|
||||
if (crt_isnan(d))
|
||||
d = crt_copysignl(0, d);
|
||||
d = crt_copysigntf(0, d);
|
||||
recalc = 1;
|
||||
}
|
||||
if (recalc) {
|
||||
__real__ z = CRT_INFINITY * (a * c - b * d);
|
||||
__imag__ z = CRT_INFINITY * (a * d + b * c);
|
||||
COMPLEXTF_REAL(z) = CRT_INFINITY * (a * c - b * d);
|
||||
COMPLEXTF_IMAGINARY(z) = CRT_INFINITY * (a * d + b * c);
|
||||
}
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -17,9 +17,9 @@
|
||||
|
||||
// Returns: a ^ b
|
||||
|
||||
COMPILER_RT_ABI long double __powitf2(long double a, int b) {
|
||||
COMPILER_RT_ABI fp_t __powitf2(fp_t a, int b) {
|
||||
const int recip = b < 0;
|
||||
long double r = 1;
|
||||
fp_t r = 1;
|
||||
while (1) {
|
||||
if (b & 1)
|
||||
r *= a;
|
||||
|
@ -14,6 +14,6 @@
|
||||
#define DST_DOUBLE
|
||||
#include "fp_trunc_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI double __trunctfdf2(long double a) { return __truncXfYf2__(a); }
|
||||
COMPILER_RT_ABI dst_t __trunctfdf2(src_t a) { return __truncXfYf2__(a); }
|
||||
|
||||
#endif
|
||||
|
@ -15,8 +15,6 @@
|
||||
#define DST_HALF
|
||||
#include "fp_trunc_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI _Float16 __trunctfhf2(long double a) {
|
||||
return __truncXfYf2__(a);
|
||||
}
|
||||
COMPILER_RT_ABI dst_t __trunctfhf2(src_t a) { return __truncXfYf2__(a); }
|
||||
|
||||
#endif
|
||||
|
@ -14,6 +14,6 @@
|
||||
#define DST_SINGLE
|
||||
#include "fp_trunc_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI float __trunctfsf2(long double a) { return __truncXfYf2__(a); }
|
||||
COMPILER_RT_ABI dst_t __trunctfsf2(src_t a) { return __truncXfYf2__(a); }
|
||||
|
||||
#endif
|
||||
|
@ -9,15 +9,16 @@
|
||||
// Assumption: long double is a IEEE 80 bit floating point type padded to 128
|
||||
// bits.
|
||||
|
||||
// TODO: use fp_lib.h once QUAD_PRECISION is available on x86_64.
|
||||
#if __LDBL_MANT_DIG__ == 64 && defined(__x86_64__) && \
|
||||
(defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__))
|
||||
#define QUAD_PRECISION
|
||||
#include "fp_lib.h"
|
||||
|
||||
#if defined(CRT_HAS_TF_MODE) && __LDBL_MANT_DIG__ == 64 && defined(__x86_64__)
|
||||
|
||||
#define SRC_QUAD
|
||||
#define DST_80
|
||||
#include "fp_trunc_impl.inc"
|
||||
|
||||
COMPILER_RT_ABI long double __trunctfxf2(__float128 a) {
|
||||
COMPILER_RT_ABI long double __trunctfxf2(tf_float a) {
|
||||
return __truncXfYf2__(a);
|
||||
}
|
||||
|
||||
|
@ -4,102 +4,90 @@
|
||||
#include <fenv.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if __LDBL_MANT_DIG__ == 113
|
||||
// The testcase currently assumes IEEE TF format, once that has been
|
||||
// fixed the defined(CRT_HAS_IEEE_TF) guard can be removed to enable it for
|
||||
// IBM 128 floats as well.
|
||||
#if defined(CRT_HAS_IEEE_TF)
|
||||
|
||||
#include "int_lib.h"
|
||||
#include "fp_test.h"
|
||||
# include "fp_test.h"
|
||||
# include "int_lib.h"
|
||||
|
||||
// Returns: a + b
|
||||
COMPILER_RT_ABI long double __addtf3(long double a, long double b);
|
||||
COMPILER_RT_ABI tf_float __addtf3(tf_float a, tf_float b);
|
||||
|
||||
int test__addtf3(long double a, long double b,
|
||||
uint64_t expectedHi, uint64_t expectedLo)
|
||||
{
|
||||
long double x = __addtf3(a, b);
|
||||
int ret = compareResultF128(x, expectedHi, expectedLo);
|
||||
int test__addtf3(tf_float a, tf_float b, uint64_t expectedHi,
|
||||
uint64_t expectedLo) {
|
||||
tf_float x = __addtf3(a, b);
|
||||
int ret = compareResultF128(x, expectedHi, expectedLo);
|
||||
|
||||
if (ret){
|
||||
printf("error in test__addtf3(%.20Lf, %.20Lf) = %.20Lf, "
|
||||
"expected %.20Lf\n", a, b, x,
|
||||
fromRep128(expectedHi, expectedLo));
|
||||
}
|
||||
if (ret) {
|
||||
printf("error in test__addtf3(%.20Lf, %.20Lf) = %.20Lf, "
|
||||
"expected %.20Lf\n",
|
||||
a, b, x, fromRep128(expectedHi, expectedLo));
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0};
|
||||
char assumption_1[sizeof(tf_float) * CHAR_BIT == 128] = {0};
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
#if __LDBL_MANT_DIG__ == 113
|
||||
// qNaN + any = qNaN
|
||||
if (test__addtf3(makeQNaN128(),
|
||||
0x1.23456789abcdefp+5L,
|
||||
UINT64_C(0x7fff800000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// NaN + any = NaN
|
||||
if (test__addtf3(makeNaN128(UINT64_C(0x800030000000)),
|
||||
0x1.23456789abcdefp+5L,
|
||||
UINT64_C(0x7fff800000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// inf + inf = inf
|
||||
if (test__addtf3(makeInf128(),
|
||||
makeInf128(),
|
||||
UINT64_C(0x7fff000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// inf + any = inf
|
||||
if (test__addtf3(makeInf128(),
|
||||
0x1.2335653452436234723489432abcdefp+5L,
|
||||
UINT64_C(0x7fff000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// any + any
|
||||
if (test__addtf3(0x1.23456734245345543849abcdefp+5L,
|
||||
0x1.edcba52449872455634654321fp-1L,
|
||||
UINT64_C(0x40042afc95c8b579),
|
||||
UINT64_C(0x61e58dd6c51eb77c)))
|
||||
return 1;
|
||||
int main() {
|
||||
#if defined(CRT_HAS_IEEE_TF)
|
||||
// qNaN + any = qNaN
|
||||
if (test__addtf3(makeQNaN128(), 0x1.23456789abcdefp+5L,
|
||||
UINT64_C(0x7fff800000000000), UINT64_C(0x0)))
|
||||
return 1;
|
||||
// NaN + any = NaN
|
||||
if (test__addtf3(makeNaN128(UINT64_C(0x800030000000)),
|
||||
TF_C(0x1.23456789abcdefp+5), UINT64_C(0x7fff800000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// inf + inf = inf
|
||||
if (test__addtf3(makeInf128(), makeInf128(), UINT64_C(0x7fff000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// inf + any = inf
|
||||
if (test__addtf3(makeInf128(), TF_C(0x1.2335653452436234723489432abcdefp+5),
|
||||
UINT64_C(0x7fff000000000000), UINT64_C(0x0)))
|
||||
return 1;
|
||||
// any + any
|
||||
if (test__addtf3(TF_C(0x1.23456734245345543849abcdefp+5),
|
||||
TF_C(0x1.edcba52449872455634654321fp-1),
|
||||
UINT64_C(0x40042afc95c8b579), UINT64_C(0x61e58dd6c51eb77c)))
|
||||
return 1;
|
||||
|
||||
#if (defined(__arm__) || defined(__aarch64__)) && defined(__ARM_FP) || \
|
||||
defined(i386) || defined(__x86_64__) || (defined(__loongarch__) && \
|
||||
__loongarch_frlen != 0)
|
||||
// Rounding mode tests on supported architectures
|
||||
const long double m = 1234.0L, n = 0.01L;
|
||||
# if (defined(__arm__) || defined(__aarch64__)) && defined(__ARM_FP) || \
|
||||
defined(i386) || defined(__x86_64__) || \
|
||||
(defined(__loongarch__) && __loongarch_frlen != 0)
|
||||
// Rounding mode tests on supported architectures
|
||||
const tf_float m = 1234.0L, n = 0.01L;
|
||||
|
||||
fesetround(FE_UPWARD);
|
||||
if (test__addtf3(m, n,
|
||||
UINT64_C(0x40093480a3d70a3d),
|
||||
UINT64_C(0x70a3d70a3d70a3d8)))
|
||||
return 1;
|
||||
fesetround(FE_UPWARD);
|
||||
if (test__addtf3(m, n, UINT64_C(0x40093480a3d70a3d),
|
||||
UINT64_C(0x70a3d70a3d70a3d8)))
|
||||
return 1;
|
||||
|
||||
fesetround(FE_DOWNWARD);
|
||||
if (test__addtf3(m, n,
|
||||
UINT64_C(0x40093480a3d70a3d),
|
||||
UINT64_C(0x70a3d70a3d70a3d7)))
|
||||
return 1;
|
||||
fesetround(FE_DOWNWARD);
|
||||
if (test__addtf3(m, n, UINT64_C(0x40093480a3d70a3d),
|
||||
UINT64_C(0x70a3d70a3d70a3d7)))
|
||||
return 1;
|
||||
|
||||
fesetround(FE_TOWARDZERO);
|
||||
if (test__addtf3(m, n, UINT64_C(0x40093480a3d70a3d),
|
||||
UINT64_C(0x70a3d70a3d70a3d7)))
|
||||
return 1;
|
||||
|
||||
fesetround(FE_TOWARDZERO);
|
||||
if (test__addtf3(m, n,
|
||||
UINT64_C(0x40093480a3d70a3d),
|
||||
UINT64_C(0x70a3d70a3d70a3d7)))
|
||||
return 1;
|
||||
|
||||
fesetround(FE_TONEAREST);
|
||||
if (test__addtf3(m, n,
|
||||
UINT64_C(0x40093480a3d70a3d),
|
||||
UINT64_C(0x70a3d70a3d70a3d7)))
|
||||
return 1;
|
||||
#endif
|
||||
fesetround(FE_TONEAREST);
|
||||
if (test__addtf3(m, n, UINT64_C(0x40093480a3d70a3d),
|
||||
UINT64_C(0x70a3d70a3d70a3d7)))
|
||||
return 1;
|
||||
# endif
|
||||
|
||||
#else
|
||||
printf("skipped\n");
|
||||
printf("skipped\n");
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
@ -6,7 +6,10 @@
|
||||
#include <stdio.h>
|
||||
#include "fp_lib.h"
|
||||
|
||||
#if defined(CRT_HAS_TF_MODE)
|
||||
// Since we are comparing the compiler-rt IEEE implementation against libc's
|
||||
// long double implementation, this test can only succeed if long double
|
||||
// is an IEEE 128-bit floating point number.
|
||||
#if defined(CRT_HAS_TF_MODE) && defined(CRT_LDBL_IEEE_F128)
|
||||
|
||||
int test__compiler_rt_fmaxl(fp_t x, fp_t y) {
|
||||
fp_t crt_value = __compiler_rt_fmaxl(x, y);
|
||||
@ -40,10 +43,7 @@ fp_t cases[] = {
|
||||
-1.001, 1.001, -1.002, 1.002,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
#if defined(CRT_HAS_TF_MODE)
|
||||
const unsigned N = sizeof(cases) / sizeof(cases[0]);
|
||||
unsigned i, j;
|
||||
for (i = 0; i < N; ++i) {
|
||||
@ -51,8 +51,11 @@ int main() {
|
||||
if (test__compiler_rt_fmaxl(cases[i], cases[j])) return 1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
printf("skipped\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int main() {
|
||||
printf("skipped\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -1,18 +1,18 @@
|
||||
// RUN: %clang_builtins %s %librt -o %t && %run %t
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include "fp_lib.h"
|
||||
#include "int_lib.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(CRT_HAS_TF_MODE)
|
||||
|
||||
int test__compiler_rt_logbl(fp_t x) {
|
||||
#if defined(__ve__)
|
||||
# if defined(__ve__)
|
||||
if (fpclassify(x) == FP_SUBNORMAL)
|
||||
return 0;
|
||||
#endif
|
||||
# endif
|
||||
fp_t crt_value = __compiler_rt_logbl(x);
|
||||
fp_t libm_value = logbl(x);
|
||||
// Compare the values, considering all NaNs equivalent, as the spec doesn't
|
||||
@ -24,49 +24,62 @@ int test__compiler_rt_logbl(fp_t x) {
|
||||
x_t.all = toRep(x);
|
||||
crt_value_t.all = toRep(crt_value);
|
||||
libm_value_t.all = toRep(libm_value);
|
||||
printf(
|
||||
"error: in __compiler_rt_logbl([%llX %llX]) = [%llX %llX] != "
|
||||
"[%llX %llX]\n",
|
||||
x_t.s.high, x_t.s.low, crt_value_t.s.high, crt_value_t.s.low,
|
||||
libm_value_t.s.high, libm_value_t.s.low);
|
||||
printf("error: in __compiler_rt_logbl([%llX %llX]) = [%llX %llX] != "
|
||||
"[%llX %llX]\n",
|
||||
x_t.s.high, x_t.s.low, crt_value_t.s.high, crt_value_t.s.low,
|
||||
libm_value_t.s.high, libm_value_t.s.low);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
double cases[] = {
|
||||
fp_t cases[] = {
|
||||
1.e-6, -1.e-6, NAN, -NAN, INFINITY, -INFINITY, -1,
|
||||
-0.0, 0.0, 1, -2, 2, -0.5, 0.5,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
#if defined(CRT_HAS_TF_MODE)
|
||||
const unsigned N = sizeof(cases) / sizeof(cases[0]);
|
||||
unsigned i;
|
||||
for (i = 0; i < N; ++i) {
|
||||
if (test__compiler_rt_logbl(cases[i])) return 1;
|
||||
for (unsigned i = 0; i < N; ++i) {
|
||||
if (test__compiler_rt_logbl(cases[i]))
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Test a moving 1 bit, especially to handle denormal values.
|
||||
// Test the negation as well.
|
||||
// Since we are comparing the compiler-rt IEEE implementation against libc's
|
||||
// long double implementation, this test can only succeed if long double
|
||||
// is an IEEE 128-bit floating point number (otherwise we will see mismatches
|
||||
// once we reach numbers that cannot be precisely represented in long double
|
||||
// format).
|
||||
# if defined(CRT_LDBL_IEEE_F128)
|
||||
rep_t x = signBit;
|
||||
int i = 0;
|
||||
while (x) {
|
||||
if (test__compiler_rt_logbl(fromRep(x))) return 1;
|
||||
if (test__compiler_rt_logbl(fromRep(signBit ^ x))) return 1;
|
||||
if (test__compiler_rt_logbl(fromRep(x)))
|
||||
return 1;
|
||||
if (test__compiler_rt_logbl(fromRep(signBit ^ x)))
|
||||
return 1;
|
||||
x >>= 1;
|
||||
printf("l1: %d\n", i++);
|
||||
}
|
||||
// Also try a couple moving ones
|
||||
x = signBit | (signBit >> 1) | (signBit >> 2);
|
||||
while (x) {
|
||||
if (test__compiler_rt_logbl(fromRep(x))) return 1;
|
||||
if (test__compiler_rt_logbl(fromRep(signBit ^ x))) return 1;
|
||||
if (test__compiler_rt_logbl(fromRep(x)))
|
||||
return 1;
|
||||
if (test__compiler_rt_logbl(fromRep(signBit ^ x)))
|
||||
return 1;
|
||||
x >>= 1;
|
||||
printf("l1: %d\n", i++);
|
||||
}
|
||||
#else
|
||||
printf("skipped\n");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int main() {
|
||||
printf("skipped\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -1,12 +1,12 @@
|
||||
// RUN: %clang_builtins %s %librt -o %t && %run %t
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "fp_lib.h"
|
||||
#include <fenv.h>
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include "fp_lib.h"
|
||||
|
||||
#if defined(CRT_HAS_TF_MODE)
|
||||
|
||||
@ -14,7 +14,7 @@ int test__compiler_rt_scalbnl(const char *mode, fp_t x, int y) {
|
||||
#if defined(__ve__)
|
||||
if (fpclassify(x) == FP_SUBNORMAL)
|
||||
return 0;
|
||||
#endif
|
||||
# endif
|
||||
fp_t crt_value = __compiler_rt_scalbnl(x, y);
|
||||
fp_t libm_value = scalbnl(x, y);
|
||||
// Consider +/-0 unequal, but disregard the sign/payload of NaN.
|
||||
@ -39,13 +39,34 @@ int test__compiler_rt_scalbnl(const char *mode, fp_t x, int y) {
|
||||
}
|
||||
|
||||
fp_t cases[] = {
|
||||
-NAN, NAN, -INFINITY, INFINITY, -0.0, 0.0, -1, 1, -2, 2,
|
||||
LDBL_TRUE_MIN, LDBL_MIN, LDBL_MAX,
|
||||
-1.001, 1.001, -1.002, 1.002, 1.e-6, -1.e-6,
|
||||
0x1.0p-16381L,
|
||||
0x1.0p-16382L,
|
||||
0x1.0p-16383L, // subnormal
|
||||
0x1.0p-16384L, // subnormal
|
||||
-NAN,
|
||||
NAN,
|
||||
-INFINITY,
|
||||
INFINITY,
|
||||
-0.0,
|
||||
0.0,
|
||||
-1,
|
||||
1,
|
||||
-2,
|
||||
2,
|
||||
// Since we are comparing the compiler-rt IEEE implementation against libc's
|
||||
// long double implementation, this test can only succeed if long double
|
||||
// is an IEEE 128-bit floating point number.
|
||||
# if defined(CRT_LDBL_IEEE_F128)
|
||||
LDBL_TRUE_MIN,
|
||||
# endif
|
||||
LDBL_MIN,
|
||||
LDBL_MAX,
|
||||
-1.001,
|
||||
1.001,
|
||||
-1.002,
|
||||
1.002,
|
||||
1.e-6,
|
||||
-1.e-6,
|
||||
TF_C(0x1.0p-16381),
|
||||
TF_C(0x1.0p-16382),
|
||||
TF_C(0x1.0p-16383), // subnormal
|
||||
TF_C(0x1.0p-16384), // subnormal
|
||||
};
|
||||
|
||||
int iterate_cases(const char *mode) {
|
||||
@ -54,28 +75,35 @@ int iterate_cases(const char *mode) {
|
||||
for (i = 0; i < N; ++i) {
|
||||
int j;
|
||||
for (j = -5; j <= 5; ++j) {
|
||||
if (test__compiler_rt_scalbnl(mode, cases[i], j)) return 1;
|
||||
printf("%d, %d\n", i, j);
|
||||
if (test__compiler_rt_scalbnl(mode, cases[i], j))
|
||||
return 1;
|
||||
}
|
||||
if (test__compiler_rt_scalbnl(mode, cases[i], -100000)) return 1;
|
||||
if (test__compiler_rt_scalbnl(mode, cases[i], 100000)) return 1;
|
||||
if (test__compiler_rt_scalbnl(mode, cases[i], INT_MIN)) return 1;
|
||||
if (test__compiler_rt_scalbnl(mode, cases[i], INT_MAX)) return 1;
|
||||
if (test__compiler_rt_scalbnl(mode, cases[i], -100000))
|
||||
return 1;
|
||||
if (test__compiler_rt_scalbnl(mode, cases[i], 100000))
|
||||
return 1;
|
||||
if (test__compiler_rt_scalbnl(mode, cases[i], INT_MIN))
|
||||
return 1;
|
||||
if (test__compiler_rt_scalbnl(mode, cases[i], INT_MAX))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
#if defined(CRT_HAS_TF_MODE)
|
||||
if (iterate_cases("default")) return 1;
|
||||
if (iterate_cases("default"))
|
||||
return 1;
|
||||
|
||||
// Skip rounding mode tests (fesetround) because compiler-rt's quad-precision
|
||||
// multiply also ignores the current rounding mode.
|
||||
|
||||
#else
|
||||
printf("skipped\n");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
int main() {
|
||||
printf("skipped\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -9,362 +9,357 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "int_lib.h"
|
||||
#include <math.h>
|
||||
#include "int_math.h"
|
||||
#include <complex.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
// Returns: the quotient of (a + ib) / (c + id)
|
||||
|
||||
COMPILER_RT_ABI long double _Complex
|
||||
__divtc3(long double __a, long double __b, long double __c, long double __d);
|
||||
COMPILER_RT_ABI Qcomplex __divtc3(tf_float __a, tf_float __b, tf_float __c,
|
||||
tf_float __d);
|
||||
|
||||
enum {zero, non_zero, inf, NaN, non_zero_nan};
|
||||
|
||||
int
|
||||
classify(long double _Complex x)
|
||||
{
|
||||
if (x == 0)
|
||||
return zero;
|
||||
if (isinf(creall(x)) || isinf(cimagl(x)))
|
||||
return inf;
|
||||
if (isnan(creall(x)) && isnan(cimagl(x)))
|
||||
return NaN;
|
||||
if (isnan(creall(x)))
|
||||
{
|
||||
if (cimagl(x) == 0)
|
||||
return NaN;
|
||||
return non_zero_nan;
|
||||
}
|
||||
if (isnan(cimagl(x)))
|
||||
{
|
||||
if (creall(x) == 0)
|
||||
return NaN;
|
||||
return non_zero_nan;
|
||||
}
|
||||
return non_zero;
|
||||
static int classify(Qcomplex x) {
|
||||
tf_float real = COMPLEXTF_REAL(x);
|
||||
tf_float imag = COMPLEXTF_IMAGINARY(x);
|
||||
if (real == 0.0 && imag == 0.0)
|
||||
return zero;
|
||||
if (crt_isinf(real) || crt_isinf(imag))
|
||||
return inf;
|
||||
if (crt_isnan(real) && crt_isnan(imag))
|
||||
return NaN;
|
||||
if (crt_isnan(real)) {
|
||||
if (imag == 0.0)
|
||||
return NaN;
|
||||
return non_zero_nan;
|
||||
}
|
||||
if (crt_isnan(imag)) {
|
||||
if (real == 0.0)
|
||||
return NaN;
|
||||
return non_zero_nan;
|
||||
}
|
||||
return non_zero;
|
||||
}
|
||||
|
||||
int test__divtc3(long double a, long double b, long double c, long double d)
|
||||
{
|
||||
long double _Complex r = __divtc3(a, b, c, d);
|
||||
// printf("test__divtc3(%Lf, %Lf, %Lf, %Lf) = %Lf + I%Lf\n",
|
||||
// a, b, c, d, creall(r), cimagl(r));
|
||||
|
||||
long double _Complex dividend;
|
||||
long double _Complex divisor;
|
||||
|
||||
__real__ dividend = a;
|
||||
__imag__ dividend = b;
|
||||
__real__ divisor = c;
|
||||
__imag__ divisor = d;
|
||||
|
||||
switch (classify(dividend))
|
||||
{
|
||||
static int test__divtc3(tf_float a, tf_float b, tf_float c, tf_float d) {
|
||||
Qcomplex r = __divtc3(a, b, c, d);
|
||||
Qcomplex dividend;
|
||||
Qcomplex divisor;
|
||||
|
||||
COMPLEXTF_REAL(dividend) = a;
|
||||
COMPLEXTF_IMAGINARY(dividend) = b;
|
||||
COMPLEXTF_REAL(divisor) = c;
|
||||
COMPLEXTF_IMAGINARY(divisor) = d;
|
||||
|
||||
switch (classify(dividend)) {
|
||||
case zero:
|
||||
switch (classify(divisor)) {
|
||||
case zero:
|
||||
switch (classify(divisor))
|
||||
{
|
||||
case zero:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
case non_zero:
|
||||
if (classify(r) != zero)
|
||||
return 1;
|
||||
break;
|
||||
case inf:
|
||||
if (classify(r) != zero)
|
||||
return 1;
|
||||
break;
|
||||
case NaN:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
case non_zero_nan:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
case non_zero:
|
||||
switch (classify(divisor))
|
||||
{
|
||||
case zero:
|
||||
if (classify(r) != inf)
|
||||
return 1;
|
||||
break;
|
||||
case non_zero:
|
||||
if (classify(r) != non_zero)
|
||||
return 1;
|
||||
{
|
||||
long double _Complex z = (a * c + b * d) / (c * c + d * d)
|
||||
+ (b * c - a * d) / (c * c + d * d) * _Complex_I;
|
||||
if (cabsl((r - z)/r) > 1.e-6)
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case inf:
|
||||
if (classify(r) != zero)
|
||||
return 1;
|
||||
break;
|
||||
case NaN:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
case non_zero_nan:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
if (classify(r) != zero)
|
||||
return 1;
|
||||
break;
|
||||
case inf:
|
||||
switch (classify(divisor))
|
||||
{
|
||||
case zero:
|
||||
if (classify(r) != inf)
|
||||
return 1;
|
||||
break;
|
||||
case non_zero:
|
||||
if (classify(r) != inf)
|
||||
return 1;
|
||||
break;
|
||||
case inf:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
case NaN:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
case non_zero_nan:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
if (classify(r) != zero)
|
||||
return 1;
|
||||
break;
|
||||
case NaN:
|
||||
switch (classify(divisor))
|
||||
{
|
||||
case zero:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
case non_zero:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
case inf:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
case NaN:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
case non_zero_nan:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
case non_zero_nan:
|
||||
switch (classify(divisor))
|
||||
{
|
||||
case zero:
|
||||
if (classify(r) != inf)
|
||||
return 1;
|
||||
break;
|
||||
case non_zero:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
case inf:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
case NaN:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
case non_zero_nan:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
break;
|
||||
case non_zero:
|
||||
switch (classify(divisor)) {
|
||||
case zero:
|
||||
if (classify(r) != inf)
|
||||
return 1;
|
||||
break;
|
||||
case non_zero:
|
||||
if (classify(r) != non_zero)
|
||||
return 1;
|
||||
{
|
||||
tf_float zReal = (a * c + b * d) / (c * c + d * d);
|
||||
tf_float zImag = (b * c - a * d) / (c * c + d * d);
|
||||
Qcomplex diff =
|
||||
__divtc3(COMPLEXTF_REAL(r) - zReal, COMPLEXTF_IMAGINARY(r) - zImag,
|
||||
COMPLEXTF_REAL(r), COMPLEXTF_IMAGINARY(r));
|
||||
// cabsl(z) == hypotl(creall(z), cimagl(z))
|
||||
#ifdef CRT_LDBL_128BIT
|
||||
if (hypotl(COMPLEXTF_REAL(diff), COMPLEXTF_IMAGINARY(diff)) > 1.e-6)
|
||||
#else
|
||||
// Avoid dependency on __trunctfxf2 for ld80 platforms and use double instead.
|
||||
if (hypot(COMPLEXTF_REAL(diff), COMPLEXTF_IMAGINARY(diff)) > 1.e-6)
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case inf:
|
||||
if (classify(r) != zero)
|
||||
return 1;
|
||||
break;
|
||||
case NaN:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
case non_zero_nan:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case inf:
|
||||
switch (classify(divisor)) {
|
||||
case zero:
|
||||
if (classify(r) != inf)
|
||||
return 1;
|
||||
break;
|
||||
case non_zero:
|
||||
if (classify(r) != inf)
|
||||
return 1;
|
||||
break;
|
||||
case inf:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
case NaN:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
case non_zero_nan:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NaN:
|
||||
switch (classify(divisor)) {
|
||||
case zero:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
case non_zero:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
case inf:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
case NaN:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
case non_zero_nan:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case non_zero_nan:
|
||||
switch (classify(divisor)) {
|
||||
case zero:
|
||||
if (classify(r) != inf)
|
||||
return 1;
|
||||
break;
|
||||
case non_zero:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
case inf:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
case NaN:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
case non_zero_nan:
|
||||
if (classify(r) != NaN)
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
long double x[][2] =
|
||||
{
|
||||
{ 1.e-6, 1.e-6},
|
||||
{-1.e-6, 1.e-6},
|
||||
{-1.e-6, -1.e-6},
|
||||
{ 1.e-6, -1.e-6},
|
||||
tf_float x[][2] = {{1.e-6, 1.e-6},
|
||||
{-1.e-6, 1.e-6},
|
||||
{-1.e-6, -1.e-6},
|
||||
{1.e-6, -1.e-6},
|
||||
|
||||
{ 1.e+6, 1.e-6},
|
||||
{-1.e+6, 1.e-6},
|
||||
{-1.e+6, -1.e-6},
|
||||
{ 1.e+6, -1.e-6},
|
||||
{1.e+6, 1.e-6},
|
||||
{-1.e+6, 1.e-6},
|
||||
{-1.e+6, -1.e-6},
|
||||
{1.e+6, -1.e-6},
|
||||
|
||||
{ 1.e-6, 1.e+6},
|
||||
{-1.e-6, 1.e+6},
|
||||
{-1.e-6, -1.e+6},
|
||||
{ 1.e-6, -1.e+6},
|
||||
{1.e-6, 1.e+6},
|
||||
{-1.e-6, 1.e+6},
|
||||
{-1.e-6, -1.e+6},
|
||||
{1.e-6, -1.e+6},
|
||||
|
||||
{ 1.e+6, 1.e+6},
|
||||
{-1.e+6, 1.e+6},
|
||||
{-1.e+6, -1.e+6},
|
||||
{ 1.e+6, -1.e+6},
|
||||
{1.e+6, 1.e+6},
|
||||
{-1.e+6, 1.e+6},
|
||||
{-1.e+6, -1.e+6},
|
||||
{1.e+6, -1.e+6},
|
||||
|
||||
{NAN, NAN},
|
||||
{-INFINITY, NAN},
|
||||
{-2, NAN},
|
||||
{-1, NAN},
|
||||
{-0.5, NAN},
|
||||
{-0., NAN},
|
||||
{+0., NAN},
|
||||
{0.5, NAN},
|
||||
{1, NAN},
|
||||
{2, NAN},
|
||||
{INFINITY, NAN},
|
||||
{NAN, NAN},
|
||||
{-INFINITY, NAN},
|
||||
{-2, NAN},
|
||||
{-1, NAN},
|
||||
{-0.5, NAN},
|
||||
{-0., NAN},
|
||||
{+0., NAN},
|
||||
{0.5, NAN},
|
||||
{1, NAN},
|
||||
{2, NAN},
|
||||
{INFINITY, NAN},
|
||||
|
||||
{NAN, -INFINITY},
|
||||
{-INFINITY, -INFINITY},
|
||||
{-2, -INFINITY},
|
||||
{-1, -INFINITY},
|
||||
{-0.5, -INFINITY},
|
||||
{-0., -INFINITY},
|
||||
{+0., -INFINITY},
|
||||
{0.5, -INFINITY},
|
||||
{1, -INFINITY},
|
||||
{2, -INFINITY},
|
||||
{INFINITY, -INFINITY},
|
||||
{NAN, -INFINITY},
|
||||
{-INFINITY, -INFINITY},
|
||||
{-2, -INFINITY},
|
||||
{-1, -INFINITY},
|
||||
{-0.5, -INFINITY},
|
||||
{-0., -INFINITY},
|
||||
{+0., -INFINITY},
|
||||
{0.5, -INFINITY},
|
||||
{1, -INFINITY},
|
||||
{2, -INFINITY},
|
||||
{INFINITY, -INFINITY},
|
||||
|
||||
{NAN, -2},
|
||||
{-INFINITY, -2},
|
||||
{-2, -2},
|
||||
{-1, -2},
|
||||
{-0.5, -2},
|
||||
{-0., -2},
|
||||
{+0., -2},
|
||||
{0.5, -2},
|
||||
{1, -2},
|
||||
{2, -2},
|
||||
{INFINITY, -2},
|
||||
{NAN, -2},
|
||||
{-INFINITY, -2},
|
||||
{-2, -2},
|
||||
{-1, -2},
|
||||
{-0.5, -2},
|
||||
{-0., -2},
|
||||
{+0., -2},
|
||||
{0.5, -2},
|
||||
{1, -2},
|
||||
{2, -2},
|
||||
{INFINITY, -2},
|
||||
|
||||
{NAN, -1},
|
||||
{-INFINITY, -1},
|
||||
{-2, -1},
|
||||
{-1, -1},
|
||||
{-0.5, -1},
|
||||
{-0., -1},
|
||||
{+0., -1},
|
||||
{0.5, -1},
|
||||
{1, -1},
|
||||
{2, -1},
|
||||
{INFINITY, -1},
|
||||
{NAN, -1},
|
||||
{-INFINITY, -1},
|
||||
{-2, -1},
|
||||
{-1, -1},
|
||||
{-0.5, -1},
|
||||
{-0., -1},
|
||||
{+0., -1},
|
||||
{0.5, -1},
|
||||
{1, -1},
|
||||
{2, -1},
|
||||
{INFINITY, -1},
|
||||
|
||||
{NAN, -0.5},
|
||||
{-INFINITY, -0.5},
|
||||
{-2, -0.5},
|
||||
{-1, -0.5},
|
||||
{-0.5, -0.5},
|
||||
{-0., -0.5},
|
||||
{+0., -0.5},
|
||||
{0.5, -0.5},
|
||||
{1, -0.5},
|
||||
{2, -0.5},
|
||||
{INFINITY, -0.5},
|
||||
{NAN, -0.5},
|
||||
{-INFINITY, -0.5},
|
||||
{-2, -0.5},
|
||||
{-1, -0.5},
|
||||
{-0.5, -0.5},
|
||||
{-0., -0.5},
|
||||
{+0., -0.5},
|
||||
{0.5, -0.5},
|
||||
{1, -0.5},
|
||||
{2, -0.5},
|
||||
{INFINITY, -0.5},
|
||||
|
||||
{NAN, -0.},
|
||||
{-INFINITY, -0.},
|
||||
{-2, -0.},
|
||||
{-1, -0.},
|
||||
{-0.5, -0.},
|
||||
{-0., -0.},
|
||||
{+0., -0.},
|
||||
{0.5, -0.},
|
||||
{1, -0.},
|
||||
{2, -0.},
|
||||
{INFINITY, -0.},
|
||||
{NAN, -0.},
|
||||
{-INFINITY, -0.},
|
||||
{-2, -0.},
|
||||
{-1, -0.},
|
||||
{-0.5, -0.},
|
||||
{-0., -0.},
|
||||
{+0., -0.},
|
||||
{0.5, -0.},
|
||||
{1, -0.},
|
||||
{2, -0.},
|
||||
{INFINITY, -0.},
|
||||
|
||||
{NAN, 0.},
|
||||
{-INFINITY, 0.},
|
||||
{-2, 0.},
|
||||
{-1, 0.},
|
||||
{-0.5, 0.},
|
||||
{-0., 0.},
|
||||
{+0., 0.},
|
||||
{0.5, 0.},
|
||||
{1, 0.},
|
||||
{2, 0.},
|
||||
{INFINITY, 0.},
|
||||
{NAN, 0.},
|
||||
{-INFINITY, 0.},
|
||||
{-2, 0.},
|
||||
{-1, 0.},
|
||||
{-0.5, 0.},
|
||||
{-0., 0.},
|
||||
{+0., 0.},
|
||||
{0.5, 0.},
|
||||
{1, 0.},
|
||||
{2, 0.},
|
||||
{INFINITY, 0.},
|
||||
|
||||
{NAN, 0.5},
|
||||
{-INFINITY, 0.5},
|
||||
{-2, 0.5},
|
||||
{-1, 0.5},
|
||||
{-0.5, 0.5},
|
||||
{-0., 0.5},
|
||||
{+0., 0.5},
|
||||
{0.5, 0.5},
|
||||
{1, 0.5},
|
||||
{2, 0.5},
|
||||
{INFINITY, 0.5},
|
||||
{NAN, 0.5},
|
||||
{-INFINITY, 0.5},
|
||||
{-2, 0.5},
|
||||
{-1, 0.5},
|
||||
{-0.5, 0.5},
|
||||
{-0., 0.5},
|
||||
{+0., 0.5},
|
||||
{0.5, 0.5},
|
||||
{1, 0.5},
|
||||
{2, 0.5},
|
||||
{INFINITY, 0.5},
|
||||
|
||||
{NAN, 1},
|
||||
{-INFINITY, 1},
|
||||
{-2, 1},
|
||||
{-1, 1},
|
||||
{-0.5, 1},
|
||||
{-0., 1},
|
||||
{+0., 1},
|
||||
{0.5, 1},
|
||||
{1, 1},
|
||||
{2, 1},
|
||||
{INFINITY, 1},
|
||||
{NAN, 1},
|
||||
{-INFINITY, 1},
|
||||
{-2, 1},
|
||||
{-1, 1},
|
||||
{-0.5, 1},
|
||||
{-0., 1},
|
||||
{+0., 1},
|
||||
{0.5, 1},
|
||||
{1, 1},
|
||||
{2, 1},
|
||||
{INFINITY, 1},
|
||||
|
||||
{NAN, 2},
|
||||
{-INFINITY, 2},
|
||||
{-2, 2},
|
||||
{-1, 2},
|
||||
{-0.5, 2},
|
||||
{-0., 2},
|
||||
{+0., 2},
|
||||
{0.5, 2},
|
||||
{1, 2},
|
||||
{2, 2},
|
||||
{INFINITY, 2},
|
||||
{NAN, 2},
|
||||
{-INFINITY, 2},
|
||||
{-2, 2},
|
||||
{-1, 2},
|
||||
{-0.5, 2},
|
||||
{-0., 2},
|
||||
{+0., 2},
|
||||
{0.5, 2},
|
||||
{1, 2},
|
||||
{2, 2},
|
||||
{INFINITY, 2},
|
||||
|
||||
{NAN, INFINITY},
|
||||
{-INFINITY, INFINITY},
|
||||
{-2, INFINITY},
|
||||
{-1, INFINITY},
|
||||
{-0.5, INFINITY},
|
||||
{-0., INFINITY},
|
||||
{+0., INFINITY},
|
||||
{0.5, INFINITY},
|
||||
{1, INFINITY},
|
||||
{2, INFINITY},
|
||||
{INFINITY, INFINITY}
|
||||
{NAN, INFINITY},
|
||||
{-INFINITY, INFINITY},
|
||||
{-2, INFINITY},
|
||||
{-1, INFINITY},
|
||||
{-0.5, INFINITY},
|
||||
{-0., INFINITY},
|
||||
{+0., INFINITY},
|
||||
{0.5, INFINITY},
|
||||
{1, INFINITY},
|
||||
{2, INFINITY},
|
||||
{INFINITY, INFINITY}
|
||||
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
const unsigned N = sizeof(x) / sizeof(x[0]);
|
||||
unsigned i, j;
|
||||
for (i = 0; i < N; ++i)
|
||||
{
|
||||
for (j = 0; j < N; ++j)
|
||||
{
|
||||
if (test__divtc3(x[i][0], x[i][1], x[j][0], x[j][1]))
|
||||
return 1;
|
||||
}
|
||||
int main() {
|
||||
const unsigned N = sizeof(x) / sizeof(x[0]);
|
||||
unsigned i, j;
|
||||
for (i = 0; i < N; ++i) {
|
||||
for (j = 0; j < N; ++j) {
|
||||
if (test__divtc3(x[i][0], x[i][1], x[j][0], x[j][1])) {
|
||||
fprintf(stderr, "Failed for %g, %g, %g, %g\n", (double)x[i][0],
|
||||
(double)x[i][1], (double)x[j][0], (double)x[j][1]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// printf("No errors found.\n");
|
||||
return 0;
|
||||
fprintf(stderr, "No errors found.\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -4,190 +4,161 @@
|
||||
#include "int_lib.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#if __LDBL_MANT_DIG__ == 113
|
||||
// The testcase currently assumes IEEE TF format, once that has been
|
||||
// fixed the defined(CRT_HAS_IEEE_TF) guard can be removed to enable it for
|
||||
// IBM 128 floats as well.
|
||||
#if defined(CRT_HAS_IEEE_TF)
|
||||
|
||||
#include "fp_test.h"
|
||||
# include "fp_test.h"
|
||||
|
||||
// Returns: a / b
|
||||
COMPILER_RT_ABI long double __divtf3(long double a, long double b);
|
||||
COMPILER_RT_ABI tf_float __divtf3(tf_float a, tf_float b);
|
||||
|
||||
int test__divtf3(long double a, long double b,
|
||||
uint64_t expectedHi, uint64_t expectedLo)
|
||||
{
|
||||
long double x = __divtf3(a, b);
|
||||
int ret = compareResultF128(x, expectedHi, expectedLo);
|
||||
int test__divtf3(tf_float a, tf_float b, uint64_t expectedHi,
|
||||
uint64_t expectedLo) {
|
||||
tf_float x = __divtf3(a, b);
|
||||
int ret = compareResultF128(x, expectedHi, expectedLo);
|
||||
|
||||
if (ret){
|
||||
printf("error in test__divtf3(%.20Le, %.20Le) = %.20Le, "
|
||||
"expected %.20Le\n", a, b, x,
|
||||
fromRep128(expectedHi, expectedLo));
|
||||
}
|
||||
return ret;
|
||||
if (ret) {
|
||||
printf("error in test__divtf3(%.20Le, %.20Le) = %.20Le, "
|
||||
"expected %.20Le\n",
|
||||
a, b, x, fromRep128(expectedHi, expectedLo));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0};
|
||||
char assumption_1[sizeof(tf_float) * CHAR_BIT == 128] = {0};
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
#if __LDBL_MANT_DIG__ == 113
|
||||
// Returned NaNs are assumed to be qNaN by default
|
||||
int main() {
|
||||
#if defined(CRT_HAS_IEEE_TF)
|
||||
// Returned NaNs are assumed to be qNaN by default
|
||||
|
||||
// qNaN / any = qNaN
|
||||
if (test__divtf3(makeQNaN128(),
|
||||
0x1.23456789abcdefp+5L,
|
||||
UINT64_C(0x7fff800000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// NaN / any = NaN
|
||||
if (test__divtf3(makeNaN128(UINT64_C(0x30000000)),
|
||||
0x1.23456789abcdefp+5L,
|
||||
UINT64_C(0x7fff800000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// any / qNaN = qNaN
|
||||
if (test__divtf3(0x1.23456789abcdefp+5L,
|
||||
makeQNaN128(),
|
||||
UINT64_C(0x7fff800000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// any / NaN = NaN
|
||||
if (test__divtf3(0x1.23456789abcdefp+5L,
|
||||
makeNaN128(UINT64_C(0x30000000)),
|
||||
UINT64_C(0x7fff800000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// qNaN / any = qNaN
|
||||
if (test__divtf3(makeQNaN128(), TF_C(0x1.23456789abcdefp+5),
|
||||
UINT64_C(0x7fff800000000000), UINT64_C(0x0)))
|
||||
return 1;
|
||||
// NaN / any = NaN
|
||||
if (test__divtf3(makeNaN128(UINT64_C(0x30000000)),
|
||||
TF_C(0x1.23456789abcdefp+5), UINT64_C(0x7fff800000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// any / qNaN = qNaN
|
||||
if (test__divtf3(TF_C(0x1.23456789abcdefp+5), makeQNaN128(),
|
||||
UINT64_C(0x7fff800000000000), UINT64_C(0x0)))
|
||||
return 1;
|
||||
// any / NaN = NaN
|
||||
if (test__divtf3(TF_C(0x1.23456789abcdefp+5),
|
||||
makeNaN128(UINT64_C(0x30000000)),
|
||||
UINT64_C(0x7fff800000000000), UINT64_C(0x0)))
|
||||
return 1;
|
||||
|
||||
// +Inf / positive = +Inf
|
||||
if (test__divtf3(makeInf128(), 3.L,
|
||||
UINT64_C(0x7fff000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// +Inf / negative = -Inf
|
||||
if (test__divtf3(makeInf128(), -3.L,
|
||||
UINT64_C(0xffff000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// -Inf / positive = -Inf
|
||||
if (test__divtf3(makeNegativeInf128(), 3.L,
|
||||
UINT64_C(0xffff000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// -Inf / negative = +Inf
|
||||
if (test__divtf3(makeNegativeInf128(), -3.L,
|
||||
UINT64_C(0x7fff000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// +Inf / positive = +Inf
|
||||
if (test__divtf3(makeInf128(), TF_C(3.), UINT64_C(0x7fff000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// +Inf / negative = -Inf
|
||||
if (test__divtf3(makeInf128(), -TF_C(3.), UINT64_C(0xffff000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// -Inf / positive = -Inf
|
||||
if (test__divtf3(makeNegativeInf128(), TF_C(3.), UINT64_C(0xffff000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// -Inf / negative = +Inf
|
||||
if (test__divtf3(makeNegativeInf128(), -TF_C(3.),
|
||||
UINT64_C(0x7fff000000000000), UINT64_C(0x0)))
|
||||
return 1;
|
||||
|
||||
// Inf / Inf = NaN
|
||||
if (test__divtf3(makeInf128(), makeInf128(),
|
||||
UINT64_C(0x7fff800000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// 0.0 / 0.0 = NaN
|
||||
if (test__divtf3(+0x0.0p+0L, +0x0.0p+0L,
|
||||
UINT64_C(0x7fff800000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// +0.0 / +Inf = +0.0
|
||||
if (test__divtf3(+0x0.0p+0L, makeInf128(),
|
||||
UINT64_C(0x0),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// +Inf / +0.0 = +Inf
|
||||
if (test__divtf3(makeInf128(), +0x0.0p+0L,
|
||||
UINT64_C(0x7fff000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// Inf / Inf = NaN
|
||||
if (test__divtf3(makeInf128(), makeInf128(), UINT64_C(0x7fff800000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// 0.0 / 0.0 = NaN
|
||||
if (test__divtf3(+TF_C(0x0.0p+0), +TF_C(0x0.0p+0),
|
||||
UINT64_C(0x7fff800000000000), UINT64_C(0x0)))
|
||||
return 1;
|
||||
// +0.0 / +Inf = +0.0
|
||||
if (test__divtf3(+TF_C(0x0.0p+0), makeInf128(), UINT64_C(0x0), UINT64_C(0x0)))
|
||||
return 1;
|
||||
// +Inf / +0.0 = +Inf
|
||||
if (test__divtf3(makeInf128(), +TF_C(0x0.0p+0), UINT64_C(0x7fff000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
|
||||
// positive / +0.0 = +Inf
|
||||
if (test__divtf3(+1.0L, +0x0.0p+0L,
|
||||
UINT64_C(0x7fff000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// positive / -0.0 = -Inf
|
||||
if (test__divtf3(+1.0L, -0x0.0p+0L,
|
||||
UINT64_C(0xffff000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// negative / +0.0 = -Inf
|
||||
if (test__divtf3(-1.0L, +0x0.0p+0L,
|
||||
UINT64_C(0xffff000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// negative / -0.0 = +Inf
|
||||
if (test__divtf3(-1.0L, -0x0.0p+0L,
|
||||
UINT64_C(0x7fff000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// positive / +0.0 = +Inf
|
||||
if (test__divtf3(+TF_C(1.0), +TF_C(0x0.0p+0), UINT64_C(0x7fff000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// positive / -0.0 = -Inf
|
||||
if (test__divtf3(+1.0L, -TF_C(0x0.0p+0), UINT64_C(0xffff000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// negative / +0.0 = -Inf
|
||||
if (test__divtf3(-1.0L, +TF_C(0x0.0p+0), UINT64_C(0xffff000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// negative / -0.0 = +Inf
|
||||
if (test__divtf3(TF_C(-1.0), -TF_C(0x0.0p+0), UINT64_C(0x7fff000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
|
||||
// 1/3
|
||||
if (test__divtf3(1.L, 3.L,
|
||||
UINT64_C(0x3ffd555555555555),
|
||||
UINT64_C(0x5555555555555555)))
|
||||
return 1;
|
||||
// smallest normal result
|
||||
if (test__divtf3(0x1.0p-16381L, 2.L,
|
||||
UINT64_C(0x0001000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// 1/3
|
||||
if (test__divtf3(TF_C(1.), TF_C(3.), UINT64_C(0x3ffd555555555555),
|
||||
UINT64_C(0x5555555555555555)))
|
||||
return 1;
|
||||
// smallest normal result
|
||||
if (test__divtf3(TF_C(0x1.0p-16381), TF_C(2.), UINT64_C(0x0001000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
|
||||
// divisor is exactly 1.0
|
||||
if (test__divtf3(0x1.0p+0L,
|
||||
0x1.0p+0L,
|
||||
UINT64_C(0x3fff000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// divisor is truncated to exactly 1.0 in UQ1.63
|
||||
if (test__divtf3(0x1.0p+0L,
|
||||
0x1.0000000000000001p+0L,
|
||||
UINT64_C(0x3ffeffffffffffff),
|
||||
UINT64_C(0xfffe000000000000)))
|
||||
return 1;
|
||||
// divisor is exactly 1.0
|
||||
if (test__divtf3(TF_C(0x1.0p+0), TF_C(0x1.0p+0), UINT64_C(0x3fff000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// divisor is truncated to exactly 1.0 in UQ1.63
|
||||
if (test__divtf3(TF_C(0x1.0p+0), TF_C(0x1.0000000000000001p+0),
|
||||
UINT64_C(0x3ffeffffffffffff), UINT64_C(0xfffe000000000000)))
|
||||
return 1;
|
||||
|
||||
// smallest normal value divided by 2.0
|
||||
if (test__divtf3(0x1.0p-16382L, 2.L, UINT64_C(0x0000800000000000), UINT64_C(0x0)))
|
||||
return 1;
|
||||
// smallest subnormal result
|
||||
if (test__divtf3(0x1.0p-16382L, 0x1p+112L, UINT64_C(0x0), UINT64_C(0x1)))
|
||||
return 1;
|
||||
// smallest normal value divided by 2.0
|
||||
if (test__divtf3(TF_C(0x1.0p-16382), 2.L, UINT64_C(0x0000800000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
// smallest subnormal result
|
||||
if (test__divtf3(TF_C(0x1.0p-16382), TF_C(0x1p+112), UINT64_C(0x0),
|
||||
UINT64_C(0x1)))
|
||||
return 1;
|
||||
|
||||
// any / any
|
||||
if (test__divtf3(0x1.a23b45362464523375893ab4cdefp+5L,
|
||||
0x1.eedcbaba3a94546558237654321fp-1L,
|
||||
UINT64_C(0x4004b0b72924d407),
|
||||
UINT64_C(0x0717e84356c6eba2)))
|
||||
return 1;
|
||||
if (test__divtf3(0x1.a2b34c56d745382f9abf2c3dfeffp-50L,
|
||||
0x1.ed2c3ba15935332532287654321fp-9L,
|
||||
UINT64_C(0x3fd5b2af3f828c9b),
|
||||
UINT64_C(0x40e51f64cde8b1f2)))
|
||||
return 15;
|
||||
if (test__divtf3(0x1.2345f6aaaa786555f42432abcdefp+456L,
|
||||
0x1.edacbba9874f765463544dd3621fp+6400L,
|
||||
UINT64_C(0x28c62e15dc464466),
|
||||
UINT64_C(0xb5a07586348557ac)))
|
||||
return 1;
|
||||
if (test__divtf3(0x1.2d3456f789ba6322bc665544edefp-234L,
|
||||
0x1.eddcdba39f3c8b7a36564354321fp-4455L,
|
||||
UINT64_C(0x507b38442b539266),
|
||||
UINT64_C(0x22ce0f1d024e1252)))
|
||||
return 1;
|
||||
if (test__divtf3(0x1.2345f6b77b7a8953365433abcdefp+234L,
|
||||
0x1.edcba987d6bb3aa467754354321fp-4055L,
|
||||
UINT64_C(0x50bf2e02f0798d36),
|
||||
UINT64_C(0x5e6fcb6b60044078)))
|
||||
return 1;
|
||||
if (test__divtf3(6.72420628622418701252535563464350521E-4932L,
|
||||
2.L,
|
||||
UINT64_C(0x0001000000000000),
|
||||
UINT64_C(0)))
|
||||
return 1;
|
||||
// any / any
|
||||
if (test__divtf3(TF_C(0x1.a23b45362464523375893ab4cdefp+5),
|
||||
TF_C(0x1.eedcbaba3a94546558237654321fp-1),
|
||||
UINT64_C(0x4004b0b72924d407), UINT64_C(0x0717e84356c6eba2)))
|
||||
return 1;
|
||||
if (test__divtf3(TF_C(0x1.a2b34c56d745382f9abf2c3dfeffp-50),
|
||||
TF_C(0x1.ed2c3ba15935332532287654321fp-9),
|
||||
UINT64_C(0x3fd5b2af3f828c9b), UINT64_C(0x40e51f64cde8b1f2)))
|
||||
return 15;
|
||||
if (test__divtf3(TF_C(0x1.2345f6aaaa786555f42432abcdefp+456),
|
||||
TF_C(0x1.edacbba9874f765463544dd3621fp+6400),
|
||||
UINT64_C(0x28c62e15dc464466), UINT64_C(0xb5a07586348557ac)))
|
||||
return 1;
|
||||
if (test__divtf3(TF_C(0x1.2d3456f789ba6322bc665544edefp-234),
|
||||
TF_C(0x1.eddcdba39f3c8b7a36564354321fp-4455),
|
||||
UINT64_C(0x507b38442b539266), UINT64_C(0x22ce0f1d024e1252)))
|
||||
return 1;
|
||||
if (test__divtf3(TF_C(0x1.2345f6b77b7a8953365433abcdefp+234),
|
||||
TF_C(0x1.edcba987d6bb3aa467754354321fp-4055),
|
||||
UINT64_C(0x50bf2e02f0798d36), UINT64_C(0x5e6fcb6b60044078)))
|
||||
return 1;
|
||||
if (test__divtf3(TF_C(6.72420628622418701252535563464350521E-4932), TF_C(2.),
|
||||
UINT64_C(0x0001000000000000), UINT64_C(0)))
|
||||
return 1;
|
||||
|
||||
#else
|
||||
printf("skipped\n");
|
||||
printf("skipped\n");
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
@ -9,10 +9,10 @@
|
||||
|
||||
#include "fp_test.h"
|
||||
|
||||
COMPILER_RT_ABI __float128 __extendxftf2(long double a);
|
||||
COMPILER_RT_ABI tf_float __extendxftf2(long double a);
|
||||
|
||||
int test__extendxftf2(long double a, uint64_t expectedHi, uint64_t expectedLo) {
|
||||
__float128 x = __extendxftf2(a);
|
||||
tf_float x = __extendxftf2(a);
|
||||
int ret = compareResultF128(x, expectedHi, expectedLo);
|
||||
|
||||
if (ret) {
|
||||
|
@ -2,58 +2,66 @@
|
||||
// REQUIRES: librt_has_floatditf
|
||||
|
||||
#include "int_lib.h"
|
||||
#include <math.h>
|
||||
#include <complex.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if __LDBL_MANT_DIG__ == 113
|
||||
// The testcase currently assumes IEEE TF format, once that has been
|
||||
// fixed the defined(CRT_HAS_IEEE_TF) guard can be removed to enable it for
|
||||
// IBM 128 floats as well.
|
||||
#if defined(CRT_HAS_IEEE_TF)
|
||||
|
||||
#include "fp_test.h"
|
||||
# include "fp_test.h"
|
||||
|
||||
// Returns: long integer converted to long double
|
||||
// Returns: long integer converted to tf_float
|
||||
|
||||
COMPILER_RT_ABI long double __floatditf(di_int a);
|
||||
COMPILER_RT_ABI tf_float __floatditf(di_int a);
|
||||
|
||||
int test__floatditf(di_int a, uint64_t expectedHi, uint64_t expectedLo)
|
||||
{
|
||||
long double x = __floatditf(a);
|
||||
int ret = compareResultF128(x, expectedHi, expectedLo);
|
||||
int test__floatditf(di_int a, uint64_t expectedHi, uint64_t expectedLo) {
|
||||
tf_float x = __floatditf(a);
|
||||
int ret = compareResultF128(x, expectedHi, expectedLo);
|
||||
|
||||
if (ret)
|
||||
printf("error in __floatditf(%Ld) = %.20Lf, "
|
||||
"expected %.20Lf\n", a, x, fromRep128(expectedHi, expectedLo));
|
||||
return ret;
|
||||
if (ret)
|
||||
printf("error in __floatditf(%Ld) = %.20Lf, "
|
||||
"expected %.20Lf\n",
|
||||
a, x, fromRep128(expectedHi, expectedLo));
|
||||
return ret;
|
||||
}
|
||||
|
||||
char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0};
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
#if __LDBL_MANT_DIG__ == 113
|
||||
if (test__floatditf(0x7fffffffffffffff, UINT64_C(0x403dffffffffffff), UINT64_C(0xfffc000000000000)))
|
||||
return 1;
|
||||
if (test__floatditf(0x123456789abcdef1, UINT64_C(0x403b23456789abcd), UINT64_C(0xef10000000000000)))
|
||||
return 1;
|
||||
if (test__floatditf(0x2, UINT64_C(0x4000000000000000), UINT64_C(0x0)))
|
||||
return 1;
|
||||
if (test__floatditf(0x1, UINT64_C(0x3fff000000000000), UINT64_C(0x0)))
|
||||
return 1;
|
||||
if (test__floatditf(0x0, UINT64_C(0x0), UINT64_C(0x0)))
|
||||
return 1;
|
||||
if (test__floatditf(0xffffffffffffffff, UINT64_C(0xbfff000000000000), UINT64_C(0x0)))
|
||||
return 1;
|
||||
if (test__floatditf(0xfffffffffffffffe, UINT64_C(0xc000000000000000), UINT64_C(0x0)))
|
||||
return 1;
|
||||
if (test__floatditf(-0x123456789abcdef1, UINT64_C(0xc03b23456789abcd), UINT64_C(0xef10000000000000)))
|
||||
return 1;
|
||||
if (test__floatditf(0x8000000000000000, UINT64_C(0xc03e000000000000), UINT64_C(0x0)))
|
||||
return 1;
|
||||
int main() {
|
||||
#if defined(CRT_HAS_IEEE_TF)
|
||||
if (test__floatditf(0x7fffffffffffffff, UINT64_C(0x403dffffffffffff),
|
||||
UINT64_C(0xfffc000000000000)))
|
||||
return 1;
|
||||
if (test__floatditf(0x123456789abcdef1, UINT64_C(0x403b23456789abcd),
|
||||
UINT64_C(0xef10000000000000)))
|
||||
return 1;
|
||||
if (test__floatditf(0x2, UINT64_C(0x4000000000000000), UINT64_C(0x0)))
|
||||
return 1;
|
||||
if (test__floatditf(0x1, UINT64_C(0x3fff000000000000), UINT64_C(0x0)))
|
||||
return 1;
|
||||
if (test__floatditf(0x0, UINT64_C(0x0), UINT64_C(0x0)))
|
||||
return 1;
|
||||
if (test__floatditf(0xffffffffffffffff, UINT64_C(0xbfff000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
if (test__floatditf(0xfffffffffffffffe, UINT64_C(0xc000000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
if (test__floatditf(-0x123456789abcdef1, UINT64_C(0xc03b23456789abcd),
|
||||
UINT64_C(0xef10000000000000)))
|
||||
return 1;
|
||||
if (test__floatditf(0x8000000000000000, UINT64_C(0xc03e000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
|
||||
#else
|
||||
printf("skipped\n");
|
||||
printf("skipped\n");
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
@ -7,7 +7,12 @@
|
||||
#include <float.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(CRT_HAS_TF_MODE)
|
||||
// The testcase currently assumes IEEE TF format, once that has been
|
||||
// fixed the defined(CRT_HAS_IEEE_TF) guard can be removed to enable it for
|
||||
// IBM 128 floats as well.
|
||||
#if defined(CRT_HAS_IEEE_TF)
|
||||
|
||||
# include "fp_test.h"
|
||||
|
||||
/* Returns: convert a ti_int to a fp_t, rounding toward even. */
|
||||
|
||||
@ -21,93 +26,97 @@
|
||||
|
||||
COMPILER_RT_ABI fp_t __floattitf(ti_int a);
|
||||
|
||||
int test__floattitf(ti_int a, fp_t expected) {
|
||||
int _test__floattitf(int line, ti_int a, fp_t expected) {
|
||||
fp_t x = __floattitf(a);
|
||||
if (x != expected) {
|
||||
twords at;
|
||||
at.all = a;
|
||||
printf("error in __floattitf(0x%.16llX%.16llX) = %LA, expected %LA\n",
|
||||
at.s.high, at.s.low, x, expected);
|
||||
__uint128_t expected_rep = toRep128(expected);
|
||||
__uint128_t res_rep = toRep128(x);
|
||||
printf("%s:%d: error in __floattitf(0x%.16llX%.16llX) = "
|
||||
"0x%.16llX%.16llX, expected 0x%.16llX%.16llX\n",
|
||||
__FILE__, line, at.s.high, at.s.low, (uint64_t)(res_rep >> 64),
|
||||
(uint64_t)res_rep, (uint64_t)(expected_rep >> 64),
|
||||
(uint64_t)expected_rep);
|
||||
}
|
||||
return x != expected;
|
||||
}
|
||||
|
||||
# define test__floattitf(a, e) _test__floattitf(__LINE__, a, e)
|
||||
|
||||
char assumption_1[sizeof(ti_int) == 2 * sizeof(di_int)] = {0};
|
||||
char assumption_2[sizeof(ti_int) * CHAR_BIT == 128] = {0};
|
||||
char assumption_3[sizeof(fp_t) * CHAR_BIT == 128] = {0};
|
||||
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
#if defined(CRT_HAS_TF_MODE)
|
||||
if (test__floattitf(0, 0.0))
|
||||
if (test__floattitf(0, TF_C(0.0)))
|
||||
return 1;
|
||||
|
||||
if (test__floattitf(1, 1.0))
|
||||
if (test__floattitf(1, TF_C(1.0)))
|
||||
return 1;
|
||||
if (test__floattitf(2, 2.0))
|
||||
if (test__floattitf(2, TF_C(2.0)))
|
||||
return 1;
|
||||
if (test__floattitf(20, 20.0))
|
||||
if (test__floattitf(20, TF_C(20.0)))
|
||||
return 1;
|
||||
if (test__floattitf(-1, -1.0))
|
||||
if (test__floattitf(-1, -TF_C(1.0)))
|
||||
return 1;
|
||||
if (test__floattitf(-2, -2.0))
|
||||
if (test__floattitf(-2, -TF_C(2.0)))
|
||||
return 1;
|
||||
if (test__floattitf(-20, -20.0))
|
||||
if (test__floattitf(-20, -TF_C(20.0)))
|
||||
return 1;
|
||||
|
||||
if (test__floattitf(0x7FFFFF8000000000LL, 0x1.FFFFFEp+62))
|
||||
if (test__floattitf(0x7FFFFF8000000000LL, TF_C(0x1.FFFFFEp+62)))
|
||||
return 1;
|
||||
if (test__floattitf(0x7FFFFFFFFFFFF800LL, 0x1.FFFFFFFFFFFFEp+62))
|
||||
if (test__floattitf(0x7FFFFFFFFFFFF800LL, TF_C(0x1.FFFFFFFFFFFFEp+62)))
|
||||
return 1;
|
||||
if (test__floattitf(0x7FFFFF0000000000LL, 0x1.FFFFFCp+62))
|
||||
if (test__floattitf(0x7FFFFF0000000000LL, TF_C(0x1.FFFFFCp+62)))
|
||||
return 1;
|
||||
if (test__floattitf(0x7FFFFFFFFFFFF000LL, 0x1.FFFFFFFFFFFFCp+62))
|
||||
if (test__floattitf(0x7FFFFFFFFFFFF000LL, TF_C(0x1.FFFFFFFFFFFFCp+62)))
|
||||
return 1;
|
||||
|
||||
if (test__floattitf(make_ti(0x8000008000000000LL, 0), -0x1.FFFFFEp+126))
|
||||
if (test__floattitf(make_ti(0x8000008000000000LL, 0), -TF_C(0x1.FFFFFEp+126)))
|
||||
return 1;
|
||||
if (test__floattitf(make_ti(0x8000000000000800LL, 0),
|
||||
-0x1.FFFFFFFFFFFFEp+126))
|
||||
-TF_C(0x1.FFFFFFFFFFFFEp+126)))
|
||||
return 1;
|
||||
if (test__floattitf(make_ti(0x8000010000000000LL, 0), -0x1.FFFFFCp+126))
|
||||
if (test__floattitf(make_ti(0x8000010000000000LL, 0), -TF_C(0x1.FFFFFCp+126)))
|
||||
return 1;
|
||||
if (test__floattitf(make_ti(0x8000000000001000LL, 0),
|
||||
-0x1.FFFFFFFFFFFFCp+126))
|
||||
-TF_C(0x1.FFFFFFFFFFFFCp+126)))
|
||||
return 1;
|
||||
|
||||
if (test__floattitf(make_ti(0x8000000000000000LL, 0), -0x1.000000p+127))
|
||||
if (test__floattitf(make_ti(0x8000000000000000LL, 0), -TF_C(0x1.000000p+127)))
|
||||
return 1;
|
||||
if (test__floattitf(make_ti(0x8000000000000001LL, 0),
|
||||
-TF_C(0x1.FFFFFFFFFFFFFFFCp+126)))
|
||||
return 1;
|
||||
|
||||
if (test__floattitf(0x0007FB72E8000000LL, 0x1.FEDCBAp+50))
|
||||
if (test__floattitf(0x0007FB72E8000000LL, TF_C(0x1.FEDCBAp+50)))
|
||||
return 1;
|
||||
|
||||
if (test__floattitf(0x0007FB72EA000000LL, 0x1.FEDCBA8p+50))
|
||||
if (test__floattitf(0x0007FB72EA000000LL, TF_C(0x1.FEDCBA8p+50)))
|
||||
return 1;
|
||||
if (test__floattitf(0x0007FB72EB000000LL, 0x1.FEDCBACp+50))
|
||||
if (test__floattitf(0x0007FB72EB000000LL, TF_C(0x1.FEDCBACp+50)))
|
||||
return 1;
|
||||
if (test__floattitf(0x0007FB72EBFFFFFFLL, 0x1.FEDCBAFFFFFFCp+50))
|
||||
if (test__floattitf(0x0007FB72EBFFFFFFLL, TF_C(0x1.FEDCBAFFFFFFCp+50)))
|
||||
return 1;
|
||||
if (test__floattitf(0x0007FB72EC000000LL, 0x1.FEDCBBp+50))
|
||||
if (test__floattitf(0x0007FB72EC000000LL, TF_C(0x1.FEDCBBp+50)))
|
||||
return 1;
|
||||
if (test__floattitf(0x0007FB72E8000001LL, 0x1.FEDCBA0000004p+50))
|
||||
if (test__floattitf(0x0007FB72E8000001LL, TF_C(0x1.FEDCBA0000004p+50)))
|
||||
return 1;
|
||||
|
||||
if (test__floattitf(0x0007FB72E6000000LL, 0x1.FEDCB98p+50))
|
||||
if (test__floattitf(0x0007FB72E6000000LL, TF_C(0x1.FEDCB98p+50)))
|
||||
return 1;
|
||||
if (test__floattitf(0x0007FB72E7000000LL, 0x1.FEDCB9Cp+50))
|
||||
if (test__floattitf(0x0007FB72E7000000LL, TF_C(0x1.FEDCB9Cp+50)))
|
||||
return 1;
|
||||
if (test__floattitf(0x0007FB72E7FFFFFFLL, 0x1.FEDCB9FFFFFFCp+50))
|
||||
if (test__floattitf(0x0007FB72E7FFFFFFLL, TF_C(0x1.FEDCB9FFFFFFCp+50)))
|
||||
return 1;
|
||||
if (test__floattitf(0x0007FB72E4000001LL, 0x1.FEDCB90000004p+50))
|
||||
if (test__floattitf(0x0007FB72E4000001LL, TF_C(0x1.FEDCB90000004p+50)))
|
||||
return 1;
|
||||
if (test__floattitf(0x0007FB72E4000000LL, 0x1.FEDCB9p+50))
|
||||
if (test__floattitf(0x0007FB72E4000000LL, TF_C(0x1.FEDCB9p+50)))
|
||||
return 1;
|
||||
|
||||
if (test__floattitf(0x023479FD0E092DC0LL, 0x1.1A3CFE870496Ep+57))
|
||||
if (test__floattitf(0x023479FD0E092DC0LL, TF_C(0x1.1A3CFE870496Ep+57)))
|
||||
return 1;
|
||||
if (test__floattitf(0x023479FD0E092DA1LL, TF_C(0x1.1A3CFE870496D08p+57)))
|
||||
return 1;
|
||||
@ -135,7 +144,7 @@ int main() {
|
||||
return 1;
|
||||
if (test__floattitf(0x023479FD0E092DDFLL, TF_C(0x1.1A3CFE870496EF8p+57)))
|
||||
return 1;
|
||||
if (test__floattitf(0x023479FD0E092DE0LL, 0x1.1A3CFE870496Fp+57))
|
||||
if (test__floattitf(0x023479FD0E092DE0LL, TF_C(0x1.1A3CFE870496Fp+57)))
|
||||
return 1;
|
||||
|
||||
if (test__floattitf(make_ti(0x023479FD0E092DC0LL, 0),
|
||||
@ -215,8 +224,12 @@ int main() {
|
||||
if (test__floattitf(make_ti(0x123456789ABCDEF0LL, 0x123456789ABC57FFLL),
|
||||
TF_C(0x1.23456789ABCDEF0123456789ABC5p+124)))
|
||||
return 1;
|
||||
#else
|
||||
printf("skipped\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
int main() {
|
||||
printf("skipped\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -2,56 +2,63 @@
|
||||
// REQUIRES: librt_has_floatunditf
|
||||
|
||||
#include "int_lib.h"
|
||||
#include <math.h>
|
||||
#include <complex.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if __LDBL_MANT_DIG__ == 113
|
||||
// The testcase currently assumes IEEE TF format, once that has been
|
||||
// fixed the defined(CRT_HAS_IEEE_TF) guard can be removed to enable it for
|
||||
// IBM 128 floats as well.
|
||||
#if defined(CRT_HAS_IEEE_TF)
|
||||
|
||||
#include "fp_test.h"
|
||||
# include "fp_test.h"
|
||||
|
||||
// Returns: long integer converted to long double
|
||||
|
||||
COMPILER_RT_ABI long double __floatunditf(du_int a);
|
||||
COMPILER_RT_ABI tf_float __floatunditf(du_int a);
|
||||
|
||||
int test__floatunditf(du_int a, uint64_t expectedHi, uint64_t expectedLo)
|
||||
{
|
||||
long double x = __floatunditf(a);
|
||||
int ret = compareResultF128(x, expectedHi, expectedLo);
|
||||
int test__floatunditf(du_int a, uint64_t expectedHi, uint64_t expectedLo) {
|
||||
tf_float x = __floatunditf(a);
|
||||
int ret = compareResultF128(x, expectedHi, expectedLo);
|
||||
|
||||
if (ret)
|
||||
printf("error in __floatunditf(%Lu) = %.20Lf, "
|
||||
"expected %.20Lf\n", a, x, fromRep128(expectedHi, expectedLo));
|
||||
return ret;
|
||||
if (ret)
|
||||
printf("error in __floatunditf(%Lu) = %.20Lf, "
|
||||
"expected %.20Lf\n",
|
||||
a, x, fromRep128(expectedHi, expectedLo));
|
||||
return ret;
|
||||
}
|
||||
|
||||
char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0};
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
#if __LDBL_MANT_DIG__ == 113
|
||||
if (test__floatunditf(0xffffffffffffffffULL, UINT64_C(0x403effffffffffff), UINT64_C(0xfffe000000000000)))
|
||||
return 1;
|
||||
if (test__floatunditf(0xfffffffffffffffeULL, UINT64_C(0x403effffffffffff), UINT64_C(0xfffc000000000000)))
|
||||
return 1;
|
||||
if (test__floatunditf(0x8000000000000000ULL, UINT64_C(0x403e000000000000), UINT64_C(0x0)))
|
||||
return 1;
|
||||
if (test__floatunditf(0x7fffffffffffffffULL, UINT64_C(0x403dffffffffffff), UINT64_C(0xfffc000000000000)))
|
||||
return 1;
|
||||
if (test__floatunditf(0x123456789abcdef1ULL, UINT64_C(0x403b23456789abcd), UINT64_C(0xef10000000000000)))
|
||||
return 1;
|
||||
if (test__floatunditf(0x2ULL, UINT64_C(0x4000000000000000), UINT64_C(0x0)))
|
||||
return 1;
|
||||
if (test__floatunditf(0x1ULL, UINT64_C(0x3fff000000000000), UINT64_C(0x0)))
|
||||
return 1;
|
||||
if (test__floatunditf(0x0ULL, UINT64_C(0x0), UINT64_C(0x0)))
|
||||
return 1;
|
||||
int main() {
|
||||
#if defined(CRT_HAS_IEEE_TF)
|
||||
if (test__floatunditf(0xffffffffffffffffULL, UINT64_C(0x403effffffffffff),
|
||||
UINT64_C(0xfffe000000000000)))
|
||||
return 1;
|
||||
if (test__floatunditf(0xfffffffffffffffeULL, UINT64_C(0x403effffffffffff),
|
||||
UINT64_C(0xfffc000000000000)))
|
||||
return 1;
|
||||
if (test__floatunditf(0x8000000000000000ULL, UINT64_C(0x403e000000000000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
if (test__floatunditf(0x7fffffffffffffffULL, UINT64_C(0x403dffffffffffff),
|
||||
UINT64_C(0xfffc000000000000)))
|
||||
return 1;
|
||||
if (test__floatunditf(0x123456789abcdef1ULL, UINT64_C(0x403b23456789abcd),
|
||||
UINT64_C(0xef10000000000000)))
|
||||
return 1;
|
||||
if (test__floatunditf(0x2ULL, UINT64_C(0x4000000000000000), UINT64_C(0x0)))
|
||||
return 1;
|
||||
if (test__floatunditf(0x1ULL, UINT64_C(0x3fff000000000000), UINT64_C(0x0)))
|
||||
return 1;
|
||||
if (test__floatunditf(0x0ULL, UINT64_C(0x0), UINT64_C(0x0)))
|
||||
return 1;
|
||||
|
||||
#else
|
||||
printf("skipped\n");
|
||||
printf("skipped\n");
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
@ -4,43 +4,48 @@
|
||||
#include "int_lib.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#if __LDBL_MANT_DIG__ == 113
|
||||
// The testcase currently assumes IEEE TF format, once that has been
|
||||
// fixed the defined(CRT_HAS_IEEE_TF) guard can be removed to enable it for
|
||||
// IBM 128 floats as well.
|
||||
#if defined(CRT_HAS_IEEE_TF)
|
||||
|
||||
#include "fp_test.h"
|
||||
# include "fp_test.h"
|
||||
|
||||
COMPILER_RT_ABI long double __floatunsitf(su_int a);
|
||||
COMPILER_RT_ABI tf_float __floatunsitf(su_int a);
|
||||
|
||||
int test__floatunsitf(su_int a, uint64_t expectedHi, uint64_t expectedLo)
|
||||
{
|
||||
long double x = __floatunsitf(a);
|
||||
int ret = compareResultF128(x, expectedHi, expectedLo);
|
||||
int test__floatunsitf(su_int a, uint64_t expectedHi, uint64_t expectedLo) {
|
||||
tf_float x = __floatunsitf(a);
|
||||
int ret = compareResultF128(x, expectedHi, expectedLo);
|
||||
|
||||
if (ret){
|
||||
printf("error in test__floatunsitf(%u) = %.20Lf, "
|
||||
"expected %.20Lf\n", a, x, fromRep128(expectedHi, expectedLo));
|
||||
}
|
||||
return ret;
|
||||
if (ret) {
|
||||
printf("error in test__floatunsitf(%u) = %.20Lf, "
|
||||
"expected %.20Lf\n",
|
||||
a, x, fromRep128(expectedHi, expectedLo));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0};
|
||||
char assumption_1[sizeof(tf_float) * CHAR_BIT == 128] = {0};
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
#if __LDBL_MANT_DIG__ == 113
|
||||
if (test__floatunsitf(0x7fffffff, UINT64_C(0x401dfffffffc0000), UINT64_C(0x0)))
|
||||
return 1;
|
||||
if (test__floatunsitf(0, UINT64_C(0x0), UINT64_C(0x0)))
|
||||
return 1;
|
||||
if (test__floatunsitf(0xffffffff, UINT64_C(0x401efffffffe0000), UINT64_C(0x0)))
|
||||
return 1;
|
||||
if (test__floatunsitf(0x12345678, UINT64_C(0x401b234567800000), UINT64_C(0x0)))
|
||||
return 1;
|
||||
int main() {
|
||||
#if defined(CRT_HAS_IEEE_TF)
|
||||
if (test__floatunsitf(0x7fffffff, UINT64_C(0x401dfffffffc0000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
if (test__floatunsitf(0, UINT64_C(0x0), UINT64_C(0x0)))
|
||||
return 1;
|
||||
if (test__floatunsitf(0xffffffff, UINT64_C(0x401efffffffe0000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
if (test__floatunsitf(0x12345678, UINT64_C(0x401b234567800000),
|
||||
UINT64_C(0x0)))
|
||||
return 1;
|
||||
|
||||
#else
|
||||
printf("skipped\n");
|
||||
printf("skipped\n");
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
@ -7,11 +7,16 @@
|
||||
#include <float.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(CRT_HAS_TF_MODE)
|
||||
// The testcase currently assumes IEEE TF format, once that has been
|
||||
// fixed the defined(CRT_HAS_IEEE_TF) guard can be removed to enable it for
|
||||
// IBM 128 floats as well.
|
||||
#if defined(CRT_HAS_IEEE_TF)
|
||||
|
||||
/* Returns: convert a tu_int to a fp_t, rounding toward even. */
|
||||
# include "fp_test.h"
|
||||
|
||||
/* Assumption: fp_t is a IEEE 128 bit floating point type
|
||||
/* Returns: convert a tu_int to a tf_float, rounding toward even. */
|
||||
|
||||
/* Assumption: tf_float is a IEEE 128 bit floating point type
|
||||
* tu_int is a 128 bit integral type
|
||||
*/
|
||||
|
||||
@ -19,92 +24,98 @@
|
||||
* mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
|
||||
*/
|
||||
|
||||
COMPILER_RT_ABI fp_t __floatuntitf(tu_int a);
|
||||
COMPILER_RT_ABI tf_float __floatuntitf(tu_int a);
|
||||
|
||||
int test__floatuntitf(tu_int a, fp_t expected) {
|
||||
fp_t x = __floatuntitf(a);
|
||||
int _test__floatuntitf(int line, tu_int a, tf_float expected) {
|
||||
tf_float x = __floatuntitf(a);
|
||||
if (x != expected) {
|
||||
utwords at;
|
||||
at.all = a;
|
||||
printf("error in __floatuntitf(0x%.16llX%.16llX) = %LA, expected %LA\n",
|
||||
at.s.high, at.s.low, x, expected);
|
||||
__uint128_t expected_rep = toRep128(expected);
|
||||
__uint128_t res_rep = toRep128(x);
|
||||
printf("%s:%d: error in __floatuntitf(0x%.16llX%.16llX) = "
|
||||
"0x%.16llX%.16llX, expected 0x%.16llX%.16llX\n",
|
||||
__FILE__, line, at.s.high, at.s.low, (uint64_t)(res_rep >> 64),
|
||||
(uint64_t)res_rep, (uint64_t)(expected_rep >> 64),
|
||||
(uint64_t)expected_rep);
|
||||
}
|
||||
return x != expected;
|
||||
}
|
||||
# define test__floatuntitf(a, e) _test__floatuntitf(__LINE__, a, e)
|
||||
|
||||
char assumption_1[sizeof(tu_int) == 2 * sizeof(du_int)] = {0};
|
||||
char assumption_2[sizeof(tu_int) * CHAR_BIT == 128] = {0};
|
||||
char assumption_3[sizeof(fp_t) * CHAR_BIT == 128] = {0};
|
||||
char assumption_3[sizeof(tf_float) * CHAR_BIT == 128] = {0};
|
||||
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
#if defined(CRT_HAS_TF_MODE)
|
||||
if (test__floatuntitf(0, 0.0))
|
||||
#if defined(CRT_HAS_IEEE_TF)
|
||||
if (test__floatuntitf(0, TF_C(0.0)))
|
||||
return 1;
|
||||
|
||||
if (test__floatuntitf(1, 1.0))
|
||||
if (test__floatuntitf(1, TF_C(1.0)))
|
||||
return 1;
|
||||
if (test__floatuntitf(2, 2.0))
|
||||
if (test__floatuntitf(2, TF_C(2.0)))
|
||||
return 1;
|
||||
if (test__floatuntitf(20, 20.0))
|
||||
if (test__floatuntitf(20, TF_C(20.0)))
|
||||
return 1;
|
||||
|
||||
if (test__floatuntitf(0x7FFFFF8000000000ULL, 0x1.FFFFFEp+62))
|
||||
if (test__floatuntitf(0x7FFFFF8000000000ULL, TF_C(0x1.FFFFFEp+62)))
|
||||
return 1;
|
||||
if (test__floatuntitf(0x7FFFFFFFFFFFF800ULL, 0x1.FFFFFFFFFFFFEp+62))
|
||||
if (test__floatuntitf(0x7FFFFFFFFFFFF800ULL, TF_C(0x1.FFFFFFFFFFFFEp+62)))
|
||||
return 1;
|
||||
if (test__floatuntitf(0x7FFFFF0000000000ULL, 0x1.FFFFFCp+62))
|
||||
if (test__floatuntitf(0x7FFFFF0000000000ULL, TF_C(0x1.FFFFFCp+62)))
|
||||
return 1;
|
||||
if (test__floatuntitf(0x7FFFFFFFFFFFF000ULL, 0x1.FFFFFFFFFFFFCp+62))
|
||||
if (test__floatuntitf(0x7FFFFFFFFFFFF000ULL, TF_C(0x1.FFFFFFFFFFFFCp+62)))
|
||||
return 1;
|
||||
if (test__floatuntitf(0x7FFFFFFFFFFFFFFFULL, 0xF.FFFFFFFFFFFFFFEp+59L))
|
||||
if (test__floatuntitf(0x7FFFFFFFFFFFFFFFULL, TF_C(0xF.FFFFFFFFFFFFFFEp+59)))
|
||||
return 1;
|
||||
if (test__floatuntitf(0xFFFFFFFFFFFFFFFEULL, 0xF.FFFFFFFFFFFFFFEp+60L))
|
||||
if (test__floatuntitf(0xFFFFFFFFFFFFFFFEULL, TF_C(0xF.FFFFFFFFFFFFFFEp+60)))
|
||||
return 1;
|
||||
if (test__floatuntitf(0xFFFFFFFFFFFFFFFFULL, 0xF.FFFFFFFFFFFFFFFp+60L))
|
||||
if (test__floatuntitf(0xFFFFFFFFFFFFFFFFULL, TF_C(0xF.FFFFFFFFFFFFFFFp+60)))
|
||||
return 1;
|
||||
|
||||
if (test__floatuntitf(0x8000008000000000ULL, 0x8.000008p+60))
|
||||
if (test__floatuntitf(0x8000008000000000ULL, TF_C(0x8.000008p+60)))
|
||||
return 1;
|
||||
if (test__floatuntitf(0x8000000000000800ULL, 0x8.0000000000008p+60))
|
||||
if (test__floatuntitf(0x8000000000000800ULL, TF_C(0x8.0000000000008p+60)))
|
||||
return 1;
|
||||
if (test__floatuntitf(0x8000010000000000ULL, 0x8.00001p+60))
|
||||
if (test__floatuntitf(0x8000010000000000ULL, TF_C(0x8.00001p+60)))
|
||||
return 1;
|
||||
if (test__floatuntitf(0x8000000000001000ULL, 0x8.000000000001p+60))
|
||||
if (test__floatuntitf(0x8000000000001000ULL, TF_C(0x8.000000000001p+60)))
|
||||
return 1;
|
||||
|
||||
if (test__floatuntitf(0x8000000000000000ULL, 0x8p+60))
|
||||
if (test__floatuntitf(0x8000000000000000ULL, TF_C(0x8p+60)))
|
||||
return 1;
|
||||
if (test__floatuntitf(0x8000000000000001ULL, TF_C(0x8.000000000000001p+60)))
|
||||
return 1;
|
||||
|
||||
if (test__floatuntitf(0x0007FB72E8000000LL, 0x1.FEDCBAp+50))
|
||||
if (test__floatuntitf(0x0007FB72E8000000LL, TF_C(0x1.FEDCBAp+50)))
|
||||
return 1;
|
||||
|
||||
if (test__floatuntitf(0x0007FB72EA000000LL, 0x1.FEDCBA8p+50))
|
||||
if (test__floatuntitf(0x0007FB72EA000000LL, TF_C(0x1.FEDCBA8p+50)))
|
||||
return 1;
|
||||
if (test__floatuntitf(0x0007FB72EB000000LL, 0x1.FEDCBACp+50))
|
||||
if (test__floatuntitf(0x0007FB72EB000000LL, TF_C(0x1.FEDCBACp+50)))
|
||||
return 1;
|
||||
if (test__floatuntitf(0x0007FB72EBFFFFFFLL, 0x1.FEDCBAFFFFFFCp+50))
|
||||
if (test__floatuntitf(0x0007FB72EBFFFFFFLL, TF_C(0x1.FEDCBAFFFFFFCp+50)))
|
||||
return 1;
|
||||
if (test__floatuntitf(0x0007FB72EC000000LL, 0x1.FEDCBBp+50))
|
||||
if (test__floatuntitf(0x0007FB72EC000000LL, TF_C(0x1.FEDCBBp+50)))
|
||||
return 1;
|
||||
if (test__floatuntitf(0x0007FB72E8000001LL, 0x1.FEDCBA0000004p+50))
|
||||
if (test__floatuntitf(0x0007FB72E8000001LL, TF_C(0x1.FEDCBA0000004p+50)))
|
||||
return 1;
|
||||
|
||||
if (test__floatuntitf(0x0007FB72E6000000LL, 0x1.FEDCB98p+50))
|
||||
if (test__floatuntitf(0x0007FB72E6000000LL, TF_C(0x1.FEDCB98p+50)))
|
||||
return 1;
|
||||
if (test__floatuntitf(0x0007FB72E7000000LL, 0x1.FEDCB9Cp+50))
|
||||
if (test__floatuntitf(0x0007FB72E7000000LL, TF_C(0x1.FEDCB9Cp+50)))
|
||||
return 1;
|
||||
if (test__floatuntitf(0x0007FB72E7FFFFFFLL, 0x1.FEDCB9FFFFFFCp+50))
|
||||
if (test__floatuntitf(0x0007FB72E7FFFFFFLL, TF_C(0x1.FEDCB9FFFFFFCp+50)))
|
||||
return 1;
|
||||
if (test__floatuntitf(0x0007FB72E4000001LL, 0x1.FEDCB90000004p+50))
|
||||
if (test__floatuntitf(0x0007FB72E4000001LL, TF_C(0x1.FEDCB90000004p+50)))
|
||||
return 1;
|
||||
if (test__floatuntitf(0x0007FB72E4000000LL, 0x1.FEDCB9p+50))
|
||||
if (test__floatuntitf(0x0007FB72E4000000LL, TF_C(0x1.FEDCB9p+50)))
|
||||
return 1;
|
||||
|
||||
if (test__floatuntitf(0x023479FD0E092DC0LL, 0x1.1A3CFE870496Ep+57))
|
||||
if (test__floatuntitf(0x023479FD0E092DC0LL, TF_C(0x1.1A3CFE870496Ep+57)))
|
||||
return 1;
|
||||
if (test__floatuntitf(0x023479FD0E092DA1LL, TF_C(0x1.1A3CFE870496D08p+57)))
|
||||
return 1;
|
||||
@ -132,7 +143,7 @@ int main() {
|
||||
return 1;
|
||||
if (test__floatuntitf(0x023479FD0E092DDFLL, TF_C(0x1.1A3CFE870496EF8p+57)))
|
||||
return 1;
|
||||
if (test__floatuntitf(0x023479FD0E092DE0LL, 0x1.1A3CFE870496Fp+57))
|
||||
if (test__floatuntitf(0x023479FD0E092DE0LL, TF_C(0x1.1A3CFE870496Fp+57)))
|
||||
return 1;
|
||||
|
||||
if (test__floatuntitf(make_ti(0x023479FD0E092DC0LL, 0),
|
||||
|
@ -3,24 +3,14 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "int_types.h"
|
||||
|
||||
#ifdef COMPILER_RT_HAS_FLOAT16
|
||||
#define TYPE_FP16 _Float16
|
||||
#else
|
||||
#define TYPE_FP16 uint16_t
|
||||
#endif
|
||||
|
||||
// TODO: Switch to using fp_lib.h once QUAD_PRECISION is available on x86_64.
|
||||
#if __LDBL_MANT_DIG__ == 113 || \
|
||||
((__LDBL_MANT_DIG__ == 64) && defined(__x86_64__) && \
|
||||
(defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)))
|
||||
#if __LDBL_MANT_DIG__ == 113
|
||||
#define TYPE_FP128 long double
|
||||
#else
|
||||
#define TYPE_FP128 __float128
|
||||
#endif
|
||||
#define TEST_COMPILER_RT_HAS_FLOAT128
|
||||
#endif
|
||||
|
||||
enum EXPECTED_RESULT {
|
||||
LESS_0, LESS_EQUAL_0, EQUAL_0, GREATER_0, GREATER_EQUAL_0, NEQUAL_0
|
||||
};
|
||||
@ -50,10 +40,10 @@ static inline double fromRep64(uint64_t x)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef TEST_COMPILER_RT_HAS_FLOAT128
|
||||
static inline TYPE_FP128 fromRep128(uint64_t hi, uint64_t lo) {
|
||||
#if defined(CRT_HAS_TF_MODE)
|
||||
static inline tf_float fromRep128(uint64_t hi, uint64_t lo) {
|
||||
__uint128_t x = ((__uint128_t)hi << 64) + lo;
|
||||
TYPE_FP128 ret;
|
||||
tf_float ret;
|
||||
memcpy(&ret, &x, 16);
|
||||
return ret;
|
||||
}
|
||||
@ -84,8 +74,8 @@ static inline uint64_t toRep64(double x)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef TEST_COMPILER_RT_HAS_FLOAT128
|
||||
static inline __uint128_t toRep128(TYPE_FP128 x) {
|
||||
#if defined(CRT_HAS_TF_MODE)
|
||||
static inline __uint128_t toRep128(tf_float x) {
|
||||
__uint128_t ret;
|
||||
memcpy(&ret, &x, 16);
|
||||
return ret;
|
||||
@ -146,11 +136,11 @@ static inline int compareResultD(double result,
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef TEST_COMPILER_RT_HAS_FLOAT128
|
||||
#if defined(CRT_HAS_TF_MODE)
|
||||
// return 0 if equal
|
||||
// use two 64-bit integers instead of one 128-bit integer
|
||||
// because 128-bit integer constant can't be assigned directly
|
||||
static inline int compareResultF128(TYPE_FP128 result, uint64_t expectedHi,
|
||||
static inline int compareResultF128(tf_float result, uint64_t expectedHi,
|
||||
uint64_t expectedLo) {
|
||||
__uint128_t rep = toRep128(result);
|
||||
uint64_t hi = rep >> 64;
|
||||
@ -277,8 +267,8 @@ static inline long double makeInf80(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TEST_COMPILER_RT_HAS_FLOAT128
|
||||
static inline TYPE_FP128 makeQNaN128(void) {
|
||||
#if defined(CRT_HAS_TF_MODE)
|
||||
static inline tf_float makeQNaN128(void) {
|
||||
return fromRep128(0x7fff800000000000UL, 0x0UL);
|
||||
}
|
||||
#endif
|
||||
@ -298,8 +288,8 @@ static inline double makeNaN64(uint64_t rand)
|
||||
return fromRep64(0x7ff0000000000000UL | (rand & 0xfffffffffffffUL));
|
||||
}
|
||||
|
||||
#ifdef TEST_COMPILER_RT_HAS_FLOAT128
|
||||
static inline TYPE_FP128 makeNaN128(uint64_t rand) {
|
||||
#if defined(CRT_HAS_TF_MODE)
|
||||
static inline tf_float makeNaN128(uint64_t rand) {
|
||||
return fromRep128(0x7fff000000000000UL | (rand & 0xffffffffffffUL), 0x0UL);
|
||||
}
|
||||
#endif
|
||||
@ -329,12 +319,12 @@ static inline double makeNegativeInf64(void)
|
||||
return fromRep64(0xfff0000000000000UL);
|
||||
}
|
||||
|
||||
#ifdef TEST_COMPILER_RT_HAS_FLOAT128
|
||||
static inline TYPE_FP128 makeInf128(void) {
|
||||
#if defined(CRT_HAS_TF_MODE)
|
||||
static inline tf_float makeInf128(void) {
|
||||
return fromRep128(0x7fff000000000000UL, 0x0UL);
|
||||
}
|
||||
|
||||
static inline TYPE_FP128 makeNegativeInf128(void) {
|
||||
static inline tf_float makeNegativeInf128(void) {
|
||||
return fromRep128(0xffff000000000000UL, 0x0UL);
|
||||
}
|
||||
#endif
|
||||
|
@ -9,9 +9,9 @@
|
||||
|
||||
#include "fp_test.h"
|
||||
|
||||
COMPILER_RT_ABI long double __trunctfxf2(__float128 a);
|
||||
COMPILER_RT_ABI long double __trunctfxf2(tf_float a);
|
||||
|
||||
int test__trunctfxf2(__float128 a, uint64_t expectedHi, uint64_t expectedLo) {
|
||||
int test__trunctfxf2(tf_float a, uint64_t expectedHi, uint64_t expectedLo) {
|
||||
long double x = __trunctfxf2(a);
|
||||
int ret = compareResultF80(x, expectedHi, expectedLo);
|
||||
;
|
||||
@ -59,24 +59,24 @@ int main() {
|
||||
return 1;
|
||||
|
||||
// Test rounding near halfway.
|
||||
__float128 halfwayPlus =
|
||||
tf_float halfwayPlus =
|
||||
fromRep128(UINT64_C(0x7ffa000000000000),
|
||||
((UINT64_C(1) << (112 - 63 - 1)) + UINT64_C(1)));
|
||||
if (test__trunctfxf2(halfwayPlus, UINT64_C(0x7ffa),
|
||||
UINT64_C(0x8000000000000001)))
|
||||
return 1;
|
||||
__float128 halfwayExactOdd = fromRep128(
|
||||
tf_float halfwayExactOdd = fromRep128(
|
||||
UINT64_C(0x7ffa000000000000),
|
||||
((UINT64_C(1) << (112 - 63)) + (UINT64_C(1) << (112 - 63 - 1))));
|
||||
if (test__trunctfxf2(halfwayExactOdd, UINT64_C(0x7ffa),
|
||||
UINT64_C(0x8000000000000002)))
|
||||
return 1;
|
||||
__float128 halfwayExactEven =
|
||||
tf_float halfwayExactEven =
|
||||
fromRep128(UINT64_C(0x7ffa000000000000), (UINT64_C(1) << (112 - 63 - 1)));
|
||||
if (test__trunctfxf2(halfwayExactEven, UINT64_C(0x7ffa),
|
||||
UINT64_C(0x8000000000000000)))
|
||||
return 1;
|
||||
__float128 halfwayRoundingWillChangeExponent =
|
||||
tf_float halfwayRoundingWillChangeExponent =
|
||||
fromRep128(UINT64_C(0x7ffaffffffffffff), UINT64_C(0xffff000000000001));
|
||||
if (test__trunctfxf2(halfwayRoundingWillChangeExponent, UINT64_C(0x7ffb),
|
||||
UINT64_C(0x8000000000000000)))
|
||||
|
Loading…
Reference in New Issue
Block a user