diff --git a/Configure.cmake b/Configure.cmake index ddf5c5b3..7a33cb93 100644 --- a/Configure.cmake +++ b/Configure.cmake @@ -366,6 +366,13 @@ if (SLEEF_ENFORCE_FLOAT128 AND NOT COMPILER_SUPPORTS_FLOAT128) message(FATAL_ERROR "SLEEF_ENFORCE_FLOAT128 is specified and that feature is disabled or not supported by the compiler") endif() +if(COMPILER_SUPPORTS_FLOAT128) + CHECK_C_SOURCE_COMPILES(" + #include + int main() { __float128 r = 1; + }" COMPILER_SUPPORTS_QUADMATH) +endif() + # SSE2 option(SLEEF_DISABLE_SSE2 "Disable SSE2" OFF) diff --git a/src/common/quaddef.h b/src/common/quaddef.h index 3e802a05..f9762d24 100644 --- a/src/common/quaddef.h +++ b/src/common/quaddef.h @@ -16,7 +16,7 @@ #if !defined(Sleef_quad_DEFINED) #define Sleef_quad_DEFINED typedef struct { uint64_t x, y; } Sleef_uint64_2t; -#if defined(SLEEF_FLOAT128_IS_IEEEQP) +#if defined(SLEEF_FLOAT128_IS_IEEEQP) || defined(ENABLEFLOAT128) typedef __float128 Sleef_quad; #define SLEEF_QUAD_C(x) (x ## Q) #elif defined(SLEEF_LONGDOUBLE_IS_IEEEQP) @@ -27,6 +27,51 @@ typedef Sleef_uint64_2t Sleef_quad; #endif #endif +#if !defined(Sleef_quad1_DEFINED) +#define Sleef_quad1_DEFINED +typedef union { + struct { + Sleef_quad x; + }; + Sleef_quad s[1]; +} Sleef_quad1; +#endif + +#if !defined(Sleef_quad2_DEFINED) +#define Sleef_quad2_DEFINED +typedef union { + struct { + Sleef_quad x, y; + }; + Sleef_quad s[2]; +} Sleef_quad2; +#endif + +#if !defined(Sleef_quad4_DEFINED) +#define Sleef_quad4_DEFINED +typedef union { + struct { + Sleef_quad x, y, z, w; + }; + Sleef_quad s[4]; +} Sleef_quad4; +#endif + +#if !defined(Sleef_quad8_DEFINED) +#define Sleef_quad8_DEFINED +typedef union { + Sleef_quad s[8]; +} Sleef_quad8; +#endif + +#if defined(__ARM_FEATURE_SVE) && !defined(Sleef_quadx_DEFINED) +#define Sleef_quadx_DEFINED +typedef union { + Sleef_quad s[32]; +} Sleef_quadx; +#endif + + #else // #if !defined(SLEEF_GENHEADER) SLEEFSHARPif !defined(SLEEFXXX__NVCC__) && ((defined(SLEEFXXX__SIZEOF_FLOAT128__) && SLEEFXXX__SIZEOF_FLOAT128__ == 16) || (defined(SLEEFXXX__linux__) && defined(SLEEFXXX__GNUC__) && (defined(SLEEFXXX__i386__) || defined(SLEEFXXX__x86_64__))) || (defined(SLEEFXXX__PPC64__) && defined(SLEEFXXX__GNUC__) && !defined(SLEEFXXX__clang__) && SLEEFXXX__GNUC__ >= 8)) diff --git a/src/libm-tester/CMakeLists.txt b/src/libm-tester/CMakeLists.txt index 93c130dc..320a2a9f 100644 --- a/src/libm-tester/CMakeLists.txt +++ b/src/libm-tester/CMakeLists.txt @@ -426,10 +426,15 @@ if(LIB_MPFR AND NOT MINGW) if(COMPILER_SUPPORTS_LONG_DOUBLE) list(APPEND PRECISIONS ld) endif() + if(COMPILER_SUPPORTS_QUADMATH) + list(APPEND PRECISIONS qp) + set(LIBQUADMATH "-lquadmath") + set(ENABLEFLOAT128 PRIVATE ENABLEFLOAT128=1) + endif() foreach(P ${PRECISIONS}) set(T "tester2${P}") add_executable(${T} tester2${P}.c testerutil.c) - target_compile_definitions(${T} PRIVATE USEMPFR=1 ${COMMON_TARGET_DEFINITIONS}) + target_compile_definitions(${T} PRIVATE USEMPFR=1 ${ENABLEFLOAT128} ${COMMON_TARGET_DEFINITIONS}) set_target_properties(${T} PROPERTIES ${COMMON_TARGET_PROPERTIES}) if (FORCE_AAVPCS) target_compile_definitions(${T} PRIVATE ENABLE_AAVPCS=1) @@ -437,14 +442,11 @@ if(LIB_MPFR AND NOT MINGW) if (MPFR_INCLUDE_DIR) target_include_directories(${T} PRIVATE ${MPFR_INCLUDE_DIR}) endif() - - target_link_libraries(${T} ${TARGET_LIBSLEEF} ${LIB_MPFR} ${LIBM} ${LIBGMP}) + target_link_libraries(${T} ${TARGET_LIBSLEEF} ${LIBQUADMATH} ${LIB_MPFR} ${LIBM} ${LIBGMP}) add_dependencies(${T} ${TARGET_HEADERS}) add_dependencies(${T} ${TARGET_LIBSLEEF}) endforeach() - # No test defined with tester2 - # Compile executable 'tester' add_host_executable(${TARGET_TESTER} tester.c testerutil.c) if (NOT CMAKE_CROSSCOMPILING) diff --git a/src/libm-tester/tester2qp.c b/src/libm-tester/tester2qp.c index 614e422b..a1eec380 100644 --- a/src/libm-tester/tester2qp.c +++ b/src/libm-tester/tester2qp.c @@ -15,10 +15,12 @@ #include #include +#ifdef ENABLE_SYS_getrandom #define _GNU_SOURCE #include #include #include +#endif #include "sleef.h" @@ -94,14 +96,23 @@ Sleef_quad rnd() { case 0: return INFINITY; case 1: return -INFINITY; } +#ifdef ENABLE_SYS_getrandom syscall(SYS_getrandom, &c.u128, sizeof(c.u128), 0); +#else + c.u128 = random() | ((__int128)random() << 31) | ((__int128)random() << (31*2)) | ((__int128)random() << (31*3)) | ((__int128)random() << (31*4)); +#endif return c.d; + } Sleef_quad rnd_fr() { conv_t c; do { +#ifdef ENABLE_SYS_getrandom syscall(SYS_getrandom, &c.u128, sizeof(c.u128), 0); +#else + c.u128 = random() | ((__int128)random() << 31) | ((__int128)random() << (31*2)) | ((__int128)random() << (31*3)) | ((__int128)random() << (31*4)); +#endif } while(!isnumberq(c.d)); return c.d; } @@ -109,7 +120,11 @@ Sleef_quad rnd_fr() { Sleef_quad rnd_zo() { conv_t c; do { +#ifdef ENABLE_SYS_getrandom syscall(SYS_getrandom, &c.u128, sizeof(c.u128), 0); +#else + c.u128 = random() | ((__int128)random() << 31) | ((__int128)random() << (31*2)) | ((__int128)random() << (31*3)) | ((__int128)random() << (31*4)); +#endif } while(!isnumberq(c.d) || c.d < -1 || 1 < c.d); return c.d; } diff --git a/src/libm/CMakeLists.txt b/src/libm/CMakeLists.txt index d89e0ee9..4ee9d4fb 100644 --- a/src/libm/CMakeLists.txt +++ b/src/libm/CMakeLists.txt @@ -376,6 +376,13 @@ target_compile_definitions(${TARGET_LIBSLEEF} PRIVATE DORENAME=1 ${COMMON_TARGET_DEFINITIONS} ) +if(COMPILER_SUPPORTS_FLOAT128) + # TODO: Not supported for LLVM bitcode gen as it has a specific compilation flags + target_sources(${TARGET_LIBSLEEF} PRIVATE sleefqp.c) + target_compile_definitions(${TARGET_LIBSLEEF} + PRIVATE ENABLEFLOAT128=1 ${COMMON_TARGET_DEFINITIONS}) +endif() + if(COMPILER_SUPPORTS_BUILTIN_MATH) target_compile_definitions(${TARGET_LIBSLEEF} PRIVATE ENABLE_BUILTIN_MATH=1) endif() diff --git a/src/libm/sleeflibm_header.h.org.in b/src/libm/sleeflibm_header.h.org.in index 23713705..66d88db3 100644 --- a/src/libm/sleeflibm_header.h.org.in +++ b/src/libm/sleeflibm_header.h.org.in @@ -164,6 +164,37 @@ typedef struct { } Sleef_longdouble2; #endif +#if (defined(__SIZEOF_FLOAT128__) && __SIZEOF_FLOAT128__ == 16) || (defined(__linux__) && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))) || (defined(__PPC64__) && defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 8) +#define SLEEF_FLOAT128_IS_IEEEQP +#endif + +#if !defined(SLEEF_FLOAT128_IS_IEEEQP) && defined(__SIZEOF_LONG_DOUBLE__) && __SIZEOF_LONG_DOUBLE__ == 16 && (defined(__aarch64__) || defined(__zarch__)) +#define SLEEF_LONGDOUBLE_IS_IEEEQP +#endif + +#if !defined(Sleef_quad_DEFINED) +#define Sleef_quad_DEFINED +typedef struct { uint64_t x, y; } Sleef_uint64_2t; +#if defined(SLEEF_FLOAT128_IS_IEEEQP) || defined(ENABLEFLOAT128) +typedef __float128 Sleef_quad; +#define SLEEF_QUAD_C(x) (x ## Q) +#elif defined(SLEEF_LONGDOUBLE_IS_IEEEQP) +typedef long double Sleef_quad; +#define SLEEF_QUAD_C(x) (x ## L) +#else +typedef Sleef_uint64_2t Sleef_quad; +#endif +#endif +#if !defined(Sleef_quad2_DEFINED) +#define Sleef_quad2_DEFINED +typedef union { + struct { + Sleef_quad x, y; + }; + Sleef_quad s[2]; +} Sleef_quad2; +#endif + #ifdef __cplusplus extern "C" { @@ -326,3 +357,8 @@ SLEEF_PRAGMA_OMP_SIMD_SP SLEEF_IMPORT SLEEF_CONST float Sleef_erfcf_u15(float); SLEEF_IMPORT SLEEF_CONST Sleef_longdouble2 Sleef_sincospil_u05(long double); SLEEF_IMPORT SLEEF_CONST Sleef_longdouble2 Sleef_sincospil_u35(long double); + +#if defined(Sleef_quad2_DEFINED) +SLEEF_IMPORT SLEEF_CONST Sleef_quad2 Sleef_sincospiq_u05(Sleef_quad); +SLEEF_IMPORT SLEEF_CONST Sleef_quad2 Sleef_sincospiq_u35(Sleef_quad); +#endif diff --git a/src/libm/sleefqp.c b/src/libm/sleefqp.c index 4ac0eff2..81d705b7 100644 --- a/src/libm/sleefqp.c +++ b/src/libm/sleefqp.c @@ -12,6 +12,7 @@ #include #include "misc.h" +#include "quaddef.h" #ifdef DORENAME #include "rename.h"