[newlib-cygwin/main] Cygwin: Adapt math functions to use 64bit long double on aarch64
Corinna Vinschen via Cygwin-cvs <[email protected]> Thu, 30 Apr 2026 16:10:06 +0000 (GMT)
| Newsgroups | gmane.os.cygwin.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3Da1f347c0d5b= 85c9ddbacee0512e5c2c5200c88cb commit a1f347c0d5b85c9ddbacee0512e5c2c5200c88cb Author: chandru-mcw <Chandru.kumaresan-ftNtnR/FhrXEC4y91aVriVaTQe2KTcn/@public.gmane.org> AuthorDate: Wed Apr 29 15:34:20 2026 +0530 Commit: Corinna Vinschen <[email protected]> CommitDate: Thu Apr 30 13:47:31 2026 +0200 Cygwin: Adapt math functions to use 64bit long double on aarch64 =20 Many long double math functions currently rely on x87-specific assembly and assume extended precision, which breaks on targets where long double is the same as double (e.g. aarch64). Use __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ to detect such targets and provide fallback implementations that call the corresponding double functions. Also guard x87 assembly with x86/x86_64 checks and fix missing includes. This makes the math code portable while keeping existing x86 optimizations unchanged. =20 Signed-off-by: Martin Vejbora <[email protected]> Signed-off-by: Thirumalai Nagalingam <thirumalai.nagalingam@multicorewa= reinc.com> Signed-off-by: chandru-mcw <Chandru.kumaresan-ftNtnR/FhrXEC4y91aVriVaTQe2KTcn/@public.gmane.org> Diff: --- winsup/cygwin/math/acosl.c | 7 +++++++ winsup/cygwin/math/asinl.c | 7 +++++++ winsup/cygwin/math/atan2l.c | 7 +++++++ winsup/cygwin/math/atanl.c | 8 +++++++- winsup/cygwin/math/cephes_mconf.h | 4 ++-- winsup/cygwin/math/cosl_internal.S | 5 ++++- winsup/cygwin/math/cossin.c | 17 +++++++++++++++++ winsup/cygwin/math/exp.def.h | 8 +++++++- winsup/cygwin/math/exp2l.S | 5 ++++- winsup/cygwin/math/expm1.def.h | 4 ++++ winsup/cygwin/math/fabsl.c | 2 +- winsup/cygwin/math/fastmath.h | 29 +++++++++++++++++++++++------ winsup/cygwin/math/fmodl.c | 7 +++++++ winsup/cygwin/math/frexpl.S | 13 +++++++++---- winsup/cygwin/math/ilogbl.S | 13 +++++++++---- winsup/cygwin/math/internal_logl.S | 13 +++++++++---- winsup/cygwin/math/ldexpl.c | 4 ++++ winsup/cygwin/math/lgammal.c | 4 ++-- winsup/cygwin/math/log10l.S | 17 +++++++++++------ winsup/cygwin/math/log1pl.S | 15 +++++++++++---- winsup/cygwin/math/log2l.S | 13 +++++++++---- winsup/cygwin/math/logbl.c | 4 ++++ winsup/cygwin/math/lrintl.c | 2 +- winsup/cygwin/math/nextafterl.c | 4 ++++ winsup/cygwin/math/pow.def.h | 12 +++++++++--- winsup/cygwin/math/remainder.S | 12 ++++++++---- winsup/cygwin/math/remainderf.S | 12 ++++++++---- winsup/cygwin/math/remainderl.S | 13 +++++++++---- winsup/cygwin/math/remquol.S | 13 +++++++++---- winsup/cygwin/math/rintl.c | 2 +- winsup/cygwin/math/scalbl.S | 23 +++++++++++++++++++---- winsup/cygwin/math/scalbnl.S | 17 ++++++++++++----- winsup/cygwin/math/sinl_internal.S | 13 +++++++++---- winsup/cygwin/math/sqrt.def.h | 2 ++ winsup/cygwin/math/tanl.S | 13 +++++++++---- winsup/cygwin/math/truncl.c | 4 ++-- 36 files changed, 267 insertions(+), 81 deletions(-) diff --git a/winsup/cygwin/math/acosl.c b/winsup/cygwin/math/acosl.c index 553d06f75a59..3c3c8580fb80 100644 --- a/winsup/cygwin/math/acosl.c +++ b/winsup/cygwin/math/acosl.c @@ -3,6 +3,9 @@ * This file is part of the mingw-w64 runtime package. * No warranty is given; refer to the file DISCLAIMER.PD within this packa= ge. */ + +#include <math.h> + long double acosl (long double x); =20 long double acosl (long double x) @@ -10,6 +13,7 @@ long double acosl (long double x) long double res =3D 0.0L; =20 /* acosl =3D atanl (sqrtl(1 - x^2) / x) */ +#if defined(__x86_64__) asm volatile ( "fld %%st\n\t" "fmul %%st(0)\n\t" /* x^2 */ @@ -19,5 +23,8 @@ long double acosl (long double x) "fxch %%st(1)\n\t" "fpatan" : "=3Dt" (res) : "0" (x) : "st(1)"); +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + res =3D atanl (sqrtl(1 - x*x) / x); +#endif return res; } diff --git a/winsup/cygwin/math/asinl.c b/winsup/cygwin/math/asinl.c index 35df3b5dd91e..3143f405f518 100644 --- a/winsup/cygwin/math/asinl.c +++ b/winsup/cygwin/math/asinl.c @@ -10,12 +10,16 @@ */ =20 /* asin =3D atan (x / sqrt(1 - x^2)) */ + +#include <math.h> + long double asinl (long double x); =20 long double asinl (long double x) { long double res =3D 0.0L; =20 +#if defined(__x86_64__) asm volatile ( "fld %%st\n\t" "fmul %%st(0)\n\t" /* x^2 */ @@ -24,5 +28,8 @@ long double asinl (long double x) "fsqrt\n\t" /* sqrt (1 - x^2) */ "fpatan" : "=3Dt" (res) : "0" (x) : "st(1)"); +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + res =3D (long double)asin((double)x); +#endif return res; } diff --git a/winsup/cygwin/math/atan2l.c b/winsup/cygwin/math/atan2l.c index a4300cbf4f0d..4571690b85c2 100644 --- a/winsup/cygwin/math/atan2l.c +++ b/winsup/cygwin/math/atan2l.c @@ -3,12 +3,19 @@ * This file is part of the mingw-w64 runtime package. * No warranty is given; refer to the file DISCLAIMER.PD within this packa= ge. */ + +#include <math.h> + long double atan2l (long double y, long double x); =20 long double atan2l (long double y, long double x) { long double res =3D 0.0L; +#if defined(__x86_64__) asm volatile ("fpatan" : "=3Dt" (res) : "u" (y), "0" (x) : "st(1)"); +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + res =3D (long double)atan2((double)y, (double)x); +#endif return res; } diff --git a/winsup/cygwin/math/atanl.c b/winsup/cygwin/math/atanl.c index d289ef08cd84..eb0fdeb29292 100644 --- a/winsup/cygwin/math/atanl.c +++ b/winsup/cygwin/math/atanl.c @@ -3,16 +3,22 @@ * This file is part of the mingw-w64 runtime package. * No warranty is given; refer to the file DISCLAIMER.PD within this packa= ge. */ + +#include <math.h> + long double atanl (long double x); =20 long double atanl (long double x) { long double res =3D 0.0L; - +#if defined(__x86_64__) asm volatile ( "fld1\n\t" "fpatan" : "=3Dt" (res) : "0" (x)); +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + res =3D (long double)atan((double)x); +#endif return res; } diff --git a/winsup/cygwin/math/cephes_mconf.h b/winsup/cygwin/math/cephes_= mconf.h index 832fae0df36e..4941dc64fd9c 100644 --- a/winsup/cygwin/math/cephes_mconf.h +++ b/winsup/cygwin/math/cephes_mconf.h @@ -66,7 +66,7 @@ extern double __QNAN; #endif =20 /*long double*/ -#if defined(__arm__) || defined(_ARM_) +#if __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ #define MAXNUML 1.7976931348623158E308 #define MAXLOGL 7.09782712893383996843E2 #define MINLOGL -7.08396418532264106224E2 @@ -84,7 +84,7 @@ extern double __QNAN; #define PIL 3.1415926535897932384626L #define PIO2L 1.5707963267948966192313L #define PIO4L 7.8539816339744830961566E-1L -#endif /* defined(__arm__) || defined(_ARM_) */ +#endif /* __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ */ =20 #define isfinitel isfinite #define isinfl isinf diff --git a/winsup/cygwin/math/cosl_internal.S b/winsup/cygwin/math/cosl_i= nternal.S index 3c8f60d143e1..b63c40e4afab 100644 --- a/winsup/cygwin/math/cosl_internal.S +++ b/winsup/cygwin/math/cosl_internal.S @@ -34,7 +34,7 @@ __MINGW_USYMBOL(__cosl_internal): movq $0,8(%rcx) fstpt (%rcx) ret -#else +#elif __i386__ fldt 4(%esp) fcos fnstsw %ax @@ -51,5 +51,8 @@ __MINGW_USYMBOL(__cosl_internal): fstp %st(1) fcos ret +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + bl cos + ret #endif =20 diff --git a/winsup/cygwin/math/cossin.c b/winsup/cygwin/math/cossin.c index 0095daa66d3d..7363ab7eef74 100644 --- a/winsup/cygwin/math/cossin.c +++ b/winsup/cygwin/math/cossin.c @@ -4,6 +4,8 @@ * No warranty is given; refer to the file DISCLAIMER.PD within this packa= ge. */ =20 + #include <math.h> + void sincos (double __x, double *p_sin, double *p_cos); void sincosl (long double __x, long double *p_sin, long double *p_cos); void sincosf (float __x, float *p_sin, float *p_cos); @@ -12,6 +14,7 @@ void sincos (double __x, double *p_sin, double *p_cos) { long double c, s; =20 +#if defined(__x86_64__) __asm__ __volatile__ ("fsincos\n\t" "fnstsw %%ax\n\t" "testl $0x400, %%eax\n\t" @@ -26,6 +29,10 @@ void sincos (double __x, double *p_sin, double *p_cos) "fstp %%st(1)\n\t" "fsincos\n\t" "1:" : "=3Dt" (c), "=3Du" (s) : "0" (__x)); +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + s =3D sin(__x); + c =3D cos(__x); +#endif *p_sin =3D (double) s; *p_cos =3D (double) c; } @@ -34,6 +41,7 @@ void sincosf (float __x, float *p_sin, float *p_cos) { long double c, s; =20 +#if defined(__x86_64__) __asm__ __volatile__ ("fsincos\n\t" "fnstsw %%ax\n\t" "testl $0x400, %%eax\n\t" @@ -48,6 +56,10 @@ void sincosf (float __x, float *p_sin, float *p_cos) "fstp %%st(1)\n\t" "fsincos\n\t" "1:" : "=3Dt" (c), "=3Du" (s) : "0" (__x)); +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + s =3D sinf(__x); + c =3D cosf(__x); +#endif *p_sin =3D (float) s; *p_cos =3D (float) c; } @@ -56,6 +68,7 @@ void sincosl (long double __x, long double *p_sin, long d= ouble *p_cos) { long double c, s; =20 +#if defined(__x86_64__) __asm__ __volatile__ ("fsincos\n\t" "fnstsw %%ax\n\t" "testl $0x400, %%eax\n\t" @@ -70,6 +83,10 @@ void sincosl (long double __x, long double *p_sin, long = double *p_cos) "fstp %%st(1)\n\t" "fsincos\n\t" "1:" : "=3Dt" (c), "=3Du" (s) : "0" (__x)); +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + s =3D sin((double)__x); + c =3D cos((double)__x); +#endif *p_sin =3D s; *p_cos =3D c; } diff --git a/winsup/cygwin/math/exp.def.h b/winsup/cygwin/math/exp.def.h index 3066b745d000..a996013383aa 100644 --- a/winsup/cygwin/math/exp.def.h +++ b/winsup/cygwin/math/exp.def.h @@ -52,11 +52,12 @@ static long double __expl_internal (long double x) { long double res =3D 0.0L; +#if defined(__x86_64__) || defined(__i386__) asm volatile ( "fldl2e\n\t" /* 1 log2(e) */ "fmul %%st(1),%%st\n\t" /* 1 x log2(e) */ =20 -#ifdef __x86_64__ +#if defined(__x86_64__) "subq $8, %%rsp\n" "fnstcw 4(%%rsp)\n" "movzwl 4(%%rsp), %%eax\n" @@ -101,6 +102,11 @@ __expl_internal (long double x) "fstp %%st(1)\n\t" /* 1 */ "fstp %%st(1)\n\t" /* 0 */ : "=3Dt" (res) : "0" (x), "m" (c0), "m" (c1) : "ax", "dx"); +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + (void)c0; + (void)c1; + res =3D exp((double)x); +#endif return res; } =20 diff --git a/winsup/cygwin/math/exp2l.S b/winsup/cygwin/math/exp2l.S index b08d8e40aad9..deeb70f0be54 100644 --- a/winsup/cygwin/math/exp2l.S +++ b/winsup/cygwin/math/exp2l.S @@ -53,7 +53,7 @@ __MINGW_USYMBOL(exp2l): movq $0,8(%rcx) fstpt (%rcx) ret -#else +#elif __i386__ fldt 4(%esp) /* I added the following ugly construct because exp(+-Inf) resulted in NaN. The ugliness results from the bright minds at Intel. @@ -89,4 +89,7 @@ __MINGW_USYMBOL(exp2l): fstp %st fldz /* Set result to 0. */ 2: ret +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + bl exp2 + ret #endif diff --git a/winsup/cygwin/math/expm1.def.h b/winsup/cygwin/math/expm1.def.h index 028211f91c82..0e2cb6725624 100644 --- a/winsup/cygwin/math/expm1.def.h +++ b/winsup/cygwin/math/expm1.def.h @@ -65,7 +65,11 @@ __FLT_ABI(expm1) (__FLT_TYPE x) if (__FLT_ABI (fabs) (x) < __FLT_LOGE2) { x /=3D __FLT_LOGE2; +#if defined(_x86_64__) __asm__ __volatile__ ("f2xm1" : "=3Dt" (x) : "0" (x)); +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + x =3D exp2(x) - 1.0; +#endif return x; } return __FLT_ABI (exp) (x) - __FLT_CST (1.0); diff --git a/winsup/cygwin/math/fabsl.c b/winsup/cygwin/math/fabsl.c index f3864ea13eac..2f4f7d5af3bc 100644 --- a/winsup/cygwin/math/fabsl.c +++ b/winsup/cygwin/math/fabsl.c @@ -12,7 +12,7 @@ fabsl (long double x) long double res =3D 0.0L; asm volatile ("fabs;" : "=3Dt" (res) : "0" (x)); return res; -#elif defined(__arm__) || defined(_ARM_) +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ return __builtin_fabsl (x); #endif /* defined(__x86_64__) || defined(_AMD64_) || defined(__i386__) || = defined(_X86_) */ } diff --git a/winsup/cygwin/math/fastmath.h b/winsup/cygwin/math/fastmath.h index eb1846cb35ef..f6d7f74513cc 100644 --- a/winsup/cygwin/math/fastmath.h +++ b/winsup/cygwin/math/fastmath.h @@ -26,7 +26,11 @@ static __inline__ double __fast_sqrt (double x) static __inline__ long double __fast_sqrtl (long double x) { long double res; +#if defined(__x86_64__) asm __volatile__ ("fsqrt" : "=3Dt" (res) : "0" (x)); +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + res =3D sqrt((double)x); +#endif return res; } =20 @@ -41,22 +45,30 @@ static __inline__ float __fast_sqrtf (float x) static __inline__ double __fast_log (double x) { double res; +#if defined(__x86_64__) asm __volatile__ ("fldln2\n\t" "fxch\n\t" "fyl2x" : "=3Dt" (res) : "0" (x) : "st(1)"); +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + res =3D log(x); +#endif return res; } =20 static __inline__ long double __fast_logl (long double x) { long double res; - asm __volatile__ - ("fldln2\n\t" - "fxch\n\t" - "fyl2x" - : "=3Dt" (res) : "0" (x) : "st(1)"); +#if defined(__x86_64__) + asm __volatile__ + ("fldln2\n\t" + "fxch\n\t" + "fyl2x" + : "=3Dt" (res) : "0" (x) : "st(1)"); +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + res =3D log((double)x); +#endif return res; } =20 @@ -93,12 +105,17 @@ static __inline__ long double __fast_log1pl (long doub= le x) /* fyl2xp1 accurate only for |x| <=3D 1.0 - 0.5 * sqrt (2.0) */ if (fabsl (x) >=3D 1.0L - 0.5L * 1.41421356237309504880L) res =3D __fast_logl (1.0L + x); - else + else { +#if defined(__x86_64__) asm __volatile__ ("fldln2\n\t" "fxch\n\t" "fyl2xp1" : "=3Dt" (res) : "0" (x) : "st(1)"); +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + res =3D log1p((double)x); +#endif + } return res; } =20 diff --git a/winsup/cygwin/math/fmodl.c b/winsup/cygwin/math/fmodl.c index 462b6fa79f3d..52cc3ce042f9 100644 --- a/winsup/cygwin/math/fmodl.c +++ b/winsup/cygwin/math/fmodl.c @@ -3,6 +3,9 @@ * This file is part of the mingw-w64 runtime package. * No warranty is given; refer to the file DISCLAIMER.PD within this packa= ge. */ + +#include <math.h> + long double fmodl (long double x, long double y); =20 long double @@ -10,6 +13,7 @@ fmodl (long double x, long double y) { long double res =3D 0.0L; =20 +#if defined(__x86_64__) asm volatile ( "1:\tfprem\n\t" "fstsw %%ax\n\t" @@ -17,5 +21,8 @@ fmodl (long double x, long double y) "jp 1b\n\t" "fstp %%st(1)" : "=3Dt" (res) : "0" (x), "u" (y) : "ax", "st(1)"); +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + res =3D fmod((double)x, (double)y); +#endif return res; } diff --git a/winsup/cygwin/math/frexpl.S b/winsup/cygwin/math/frexpl.S index 12782c29e0d0..b3129dcd8fec 100644 --- a/winsup/cygwin/math/frexpl.S +++ b/winsup/cygwin/math/frexpl.S @@ -10,14 +10,14 @@ * It returns an integer power of two to expnt and the significand * between 0.5 and 1 to y. Thus x =3D y * 2**expn. */ -#ifdef __x86_64__ +#if defined(__x86_64__) .align 8 -#else +#elif defined(__i386__) .align 2 #endif .globl __MINGW_USYMBOL(frexpl) __MINGW_USYMBOL(frexpl): -#ifdef __x86_64__ +#if defined(__x86_64__) pushq %rbp movq %rsp,%rbp subq $48,%rsp @@ -72,7 +72,7 @@ L24: fstpt (%r9) leave ret -#else +#elif defined(__i386__) pushl %ebp movl %esp,%ebp subl $24,%esp @@ -127,4 +127,9 @@ L24: popl %esi leave ret +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + bl frexp + ret +#else + .error "Not supported on your platform yet" #endif diff --git a/winsup/cygwin/math/ilogbl.S b/winsup/cygwin/math/ilogbl.S index c75a7d0fde9d..9aea4e3a7ded 100644 --- a/winsup/cygwin/math/ilogbl.S +++ b/winsup/cygwin/math/ilogbl.S @@ -7,15 +7,15 @@ =20 .file "ilogbl.S" .text -#ifdef __x86_64__ +#if defined(__x86_64__) .align 8 -#else +#elif defined(__i386__) .align 4 #endif .globl __MINGW_USYMBOL(ilogbl) .def __MINGW_USYMBOL(ilogbl); .scl 2; .type 32; .endef __MINGW_USYMBOL(ilogbl): -#ifdef __x86_64__ +#if defined(__x86_64__) fldt (%rcx) fxam /* Is NaN or +-Inf? */ fstsw %ax @@ -44,7 +44,7 @@ __MINGW_USYMBOL(ilogbl): 2: fstp %st movl $0x80000001, %eax /* FP_ILOGB0 */ ret -#else +#elif defined(__i386__) fldt 4(%esp) /* I added the following ugly construct because ilogb(+-Inf) is required to return INT_MAX in ISO C99. @@ -76,4 +76,9 @@ __MINGW_USYMBOL(ilogbl): 2: fstp %st movl $0x80000001, %eax /* FP_ILOGB0 */ ret +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + bl ilogb + ret +#else + .error "Not supported on your platform yet" #endif diff --git a/winsup/cygwin/math/internal_logl.S b/winsup/cygwin/math/intern= al_logl.S index f8a075774a68..f57f2731af4b 100644 --- a/winsup/cygwin/math/internal_logl.S +++ b/winsup/cygwin/math/internal_logl.S @@ -7,9 +7,9 @@ =20 .file "internal_logl.S" .text -#ifdef __x86_64__ +#if defined(__x86_64__) .align 8 -#else +#elif defined(__i386__) .align 4 #endif one: .double 1.0 @@ -21,7 +21,7 @@ limit: .double 0.29 .globl __MINGW_USYMBOL(__logl_internal) .def __MINGW_USYMBOL(__logl_internal); .scl 2; .type 32; .endef __MINGW_USYMBOL(__logl_internal): -#ifdef __x86_64__ +#if defined(__x86_64__) fldln2 // log(2) fldt (%rdx) // x : log(2) fld %st // x : x : log(2) @@ -45,7 +45,7 @@ __MINGW_USYMBOL(__logl_internal): movq $0,8(%rcx) fstpt (%rcx) ret -#else +#elif defined(__i386__) fldln2 // log(2) fldt 4(%esp) // x : log(2) fld %st // x : x : log(2) @@ -63,4 +63,9 @@ __MINGW_USYMBOL(__logl_internal): 2: fstp %st(0) // x : log(2) fyl2x // log(x) ret +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + bl log + ret +#else + .error "Not supported on your platform yet" #endif diff --git a/winsup/cygwin/math/ldexpl.c b/winsup/cygwin/math/ldexpl.c index 2438617c3c01..a44a3a3b13c5 100644 --- a/winsup/cygwin/math/ldexpl.c +++ b/winsup/cygwin/math/ldexpl.c @@ -12,9 +12,13 @@ long double ldexpl(long double x, int expn) if (!isfinite (x) || x =3D=3D 0.0L) return x; =20 +#if defined(__x86_64__) || defined(__i386__) __asm__ __volatile__ ("fscale" : "=3Dt" (res) : "0" (x), "u" ((long double) expn)); +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + res =3D ldexp((double)x, expn); +#endif =20 if (!isfinite (res) || res =3D=3D 0.0L) errno =3D ERANGE; diff --git a/winsup/cygwin/math/lgammal.c b/winsup/cygwin/math/lgammal.c index 022a16acf0ec..91d102d574ba 100644 --- a/winsup/cygwin/math/lgammal.c +++ b/winsup/cygwin/math/lgammal.c @@ -198,11 +198,11 @@ static uLD C[] =3D { =20 /* log( sqrt( 2*pi ) ) */ static const long double LS2PI =3D 0.91893853320467274178L; -#if defined(__arm__) || defined(_ARM_) +#if __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ #define MAXLGM 2.035093e36 #else #define MAXLGM 1.04848146839019521116e+4928L -#endif /* defined(__arm__) || defined(_ARM_) */ +#endif /* __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ */ =20 /* Logarithm of gamma function */ /* Reentrant version */ diff --git a/winsup/cygwin/math/log10l.S b/winsup/cygwin/math/log10l.S index 33d45a3a8770..3d7df34fc3ad 100644 --- a/winsup/cygwin/math/log10l.S +++ b/winsup/cygwin/math/log10l.S @@ -7,9 +7,9 @@ =20 .file "log10l.S" .text -#ifdef __x86_64__ +#if defined(__x86_64__) .align 8 -#else +#elif defined(__i386__) .align 4 #endif one: .double 1.0 @@ -19,15 +19,15 @@ one: .double 1.0 limit: .double 0.29 =20 .text -#ifdef __x86_64__ +#if defined(__x86_64__) .align 8 -#else +#elif defined(__i386__) .align 4 #endif .globl __MINGW_USYMBOL(log10l) .def __MINGW_USYMBOL(log10l); .scl 2; .type 32; .endef __MINGW_USYMBOL(log10l): -#ifdef __x86_64__ +#if defined(__x86_64__) fldlg2 // log10(2) fldt (%rdx) // x : log10(2) fxam @@ -63,7 +63,7 @@ __MINGW_USYMBOL(log10l): movq $0,8(%rcx) fstpt (%rcx) ret -#else +#elif defined(__i386__) fldlg2 // log10(2) fldt 4(%esp) // x : log10(2) fxam @@ -90,4 +90,9 @@ __MINGW_USYMBOL(log10l): fstp %st(1) fstp %st(1) ret +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + bl log10 + ret +#else + .error "Not supported on your platform yet" #endif diff --git a/winsup/cygwin/math/log1pl.S b/winsup/cygwin/math/log1pl.S index a56bcf4ec655..3193b6092a02 100644 --- a/winsup/cygwin/math/log1pl.S +++ b/winsup/cygwin/math/log1pl.S @@ -12,18 +12,20 @@ 0.29 is a safe value. */ =20 +#if defined(__x86_64__) || defined(__i386__) /* Only gcc understands the .tfloat type The series of .long below represents limit: .tfloat 0.29 */ .align 16 +#endif limit: .long 2920577761 .long 2491081031 .long 16381 -#ifdef __x86_64__ +#if defined(__x86_64__) .align 8 -#else +#elif defined(__i386__) .align 4 #endif /* Please note: we use a double value here. Since 1.0 has @@ -38,7 +40,7 @@ one: .double 1.0 .globl __MINGW_USYMBOL(log1pl) .def __MINGW_USYMBOL(log1pl); .scl 2; .type 32; .endef __MINGW_USYMBOL(log1pl): -#ifdef __x86_64__ +#if defined(__x86_64__) fldln2 fldt (%rdx) fxam @@ -73,7 +75,7 @@ __MINGW_USYMBOL(log1pl): movq $0,8(%rcx) fstpt (%rcx) ret -#else +#elif defined(__i386__) fldln2 fldt 4(%esp) fxam @@ -99,4 +101,9 @@ __MINGW_USYMBOL(log1pl): fstp %st(1) fstp %st(1) ret +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + bl log1p + ret +#else + .error "Not supported on your platform yet" #endif diff --git a/winsup/cygwin/math/log2l.S b/winsup/cygwin/math/log2l.S index 771cd8ae4ee5..337a3d62f39e 100644 --- a/winsup/cygwin/math/log2l.S +++ b/winsup/cygwin/math/log2l.S @@ -7,9 +7,9 @@ =20 .file "log2l.S" .text -#ifdef __x86_64__ +#if defined(__x86_64__) .align 8 -#else +#elif defined(__i386__) .align 4 #endif one: .double 1.0 @@ -21,7 +21,7 @@ limit: .double 0.29 .globl __MINGW_USYMBOL(log2l) .def __MINGW_USYMBOL(log2l); .scl 2; .type 32; .endef __MINGW_USYMBOL(log2l): -#ifdef __x86_64__ +#if defined(__x86_64__) fldl one(%rip) fldt (%rdx) // x : 1 fxam @@ -57,7 +57,7 @@ __MINGW_USYMBOL(log2l): movq $0,8(%rcx) fstpt (%rcx) ret -#else +#elif defined(__i386__) fldl one fldt 4(%esp) // x : 1 fxam @@ -84,4 +84,9 @@ __MINGW_USYMBOL(log2l): fstp %st(1) fstp %st(1) ret +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + bl log2 + ret +#else + .error "Not supported on your platform yet" #endif diff --git a/winsup/cygwin/math/logbl.c b/winsup/cygwin/math/logbl.c index 5e533c07cb77..1ee7e57ab895 100644 --- a/winsup/cygwin/math/logbl.c +++ b/winsup/cygwin/math/logbl.c @@ -16,8 +16,12 @@ logbl (long double x) { long double res =3D 0.0L; =20 +#if defined(__x86_64__) || defined(__i386__) asm volatile ( "fxtract\n\t" "fstp %%st" : "=3Dt" (res) : "0" (x)); +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + res =3D logb((double)x); +#endif return res; } diff --git a/winsup/cygwin/math/lrintl.c b/winsup/cygwin/math/lrintl.c index 42f2d3c669f7..d5e3ac906064 100644 --- a/winsup/cygwin/math/lrintl.c +++ b/winsup/cygwin/math/lrintl.c @@ -12,7 +12,7 @@ long lrintl (long double x) __asm__ __volatile__ ("fistpll %0" : "=3Dm" (retval) : "t" (x) : "st"); #elif defined(_AMD64_) || defined(__x86_64__) || defined(_X86_) || defined= (__i386__) __asm__ __volatile__ ("fistpl %0" : "=3Dm" (retval) : "t" (x) : "st"); -#elif defined(__arm__) || defined(_ARM_) +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ retval =3D lrint(x); #endif return retval; diff --git a/winsup/cygwin/math/nextafterl.c b/winsup/cygwin/math/nextafter= l.c index b1e479a95e1d..1ac408dd4093 100644 --- a/winsup/cygwin/math/nextafterl.c +++ b/winsup/cygwin/math/nextafterl.c @@ -16,6 +16,9 @@ long double nextafterl (long double x, long double y) { +#if __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ && (LDBL_MANT_DIG =3D= =3D DBL_MANT_DIG) + return (long double) nexttoward (x, y); +# else union { long double ld; struct { @@ -63,6 +66,7 @@ nextafterl (long double x, long double y) u.parts.mantissa |=3D normal_bit; =20 return u.ld; +# endif /* __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ */ } =20 /* nexttowardl is the same function with a different name. */ diff --git a/winsup/cygwin/math/pow.def.h b/winsup/cygwin/math/pow.def.h index 2ea825720157..bf741561e7e3 100644 --- a/winsup/cygwin/math/pow.def.h +++ b/winsup/cygwin/math/pow.def.h @@ -81,7 +81,7 @@ internal_modf (__FLT_TYPE value, __FLT_TYPE *iptr) __FLT_TYPE int_part =3D (__FLT_TYPE) 0.0; /* truncate */ /* truncate */ -#ifdef __x86_64__ +#if defined(__x86_64__) asm volatile ("pushq %%rax\n\tsubq $8, %%rsp\n" "fnstcw 4(%%rsp)\n" "movzwl 4(%%rsp), %%eax\n" @@ -91,7 +91,7 @@ internal_modf (__FLT_TYPE value, __FLT_TYPE *iptr) "frndint\n" "fldcw 4(%%rsp)\n" "addq $8, %%rsp\npopq %%rax" : "=3Dt" (int_part) : "0" (value)); /* ro= und */ -#else +#elif defined(__i386__) asm volatile ("push %%eax\n\tsubl $8, %%esp\n" "fnstcw 4(%%esp)\n" "movzwl 4(%%esp), %%eax\n" @@ -101,6 +101,8 @@ internal_modf (__FLT_TYPE value, __FLT_TYPE *iptr) "frndint\n" "fldcw 4(%%esp)\n" "addl $8, %%esp\n\tpop %%eax\n" : "=3Dt" (int_part) : "0" (value)); /*= round */ +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + int_part =3D round (value); #endif if (iptr) *iptr =3D int_part; @@ -204,7 +206,11 @@ __FLT_ABI(pow) (__FLT_TYPE x, __FLT_TYPE y) } if (y =3D=3D __FLT_CST(0.5)) { - asm volatile ("fsqrt" : "=3Dt" (rslt) : "0" (x)); + #if defined(__x86_64__) || defined(__i386__) + asm volatile ("fsqrt" : "=3Dt" (rslt) : "0" (x)); + #elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + asm volatile ("fsqrt %d0, %d1" : "=3Dw" (rslt) : "w" (x)); + #endif return rslt; } } diff --git a/winsup/cygwin/math/remainder.S b/winsup/cygwin/math/remainder.S index 5a713f9040f7..c9d9e2e7805c 100644 --- a/winsup/cygwin/math/remainder.S +++ b/winsup/cygwin/math/remainder.S @@ -7,15 +7,15 @@ =20 .file "remainder.S" .text -#ifdef __x86_64__ +#if defined(__x86_64__) .align 8 -#else +#elif defined(__i386__) .align 4 #endif .globl __MINGW_USYMBOL(remainder) .def __MINGW_USYMBOL(remainder); .scl 2; .type 32; .endef __MINGW_USYMBOL(remainder): -#ifdef __x86_64__ +#if defined(__x86_64__) movsd %xmm0,-16(%rsp) movsd %xmm1,-32(%rsp) fldl -32(%rsp) @@ -28,7 +28,7 @@ __MINGW_USYMBOL(remainder): fstpl -16(%rsp) movsd -16(%rsp),%xmm0 ret -#else +#elif defined(__i386__) fldl 12(%esp) fldl 4(%esp) 1: fprem1 @@ -37,4 +37,8 @@ __MINGW_USYMBOL(remainder): jp 1b fstp %st(1) ret +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + /* AArch64: system libm provides remainder() natively, no stub needed */ +#else + .error "Not supported on your platform yet" #endif diff --git a/winsup/cygwin/math/remainderf.S b/winsup/cygwin/math/remainder= f.S index c3a3a3dc53f5..73d0f6b7a336 100644 --- a/winsup/cygwin/math/remainderf.S +++ b/winsup/cygwin/math/remainderf.S @@ -7,15 +7,15 @@ =20 .file "remainderf.S" .text -#ifdef __x86_64__ +#if defined(__x86_64__) .align 8 -#else +#elif defined(__i386__) .align 4 #endif .globl __MINGW_USYMBOL(remainder) .def __MINGW_USYMBOL(remainderf); .scl 2; .type 32; .endef __MINGW_USYMBOL(remainderf): -#ifdef __x86_64__ +#if defined(__x86_64__) movss %xmm1,-12(%rsp) flds -12(%rsp) movss %xmm0,-12(%rsp) @@ -28,7 +28,7 @@ __MINGW_USYMBOL(remainderf): fstps -12(%rsp) movss -12(%rsp),%xmm0 ret -#else +#elif defined(__i386__) flds 8(%esp) flds 4(%esp) 1: fprem1 @@ -37,4 +37,8 @@ __MINGW_USYMBOL(remainderf): jp 1b fstp %st(1) ret +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + /* AArch64: system libm provides remainderf() natively, no stub needed */ +#else + .error "Not supported on your platform yet" #endif diff --git a/winsup/cygwin/math/remainderl.S b/winsup/cygwin/math/remainder= l.S index a69e382961c2..f05724e9404a 100644 --- a/winsup/cygwin/math/remainderl.S +++ b/winsup/cygwin/math/remainderl.S @@ -7,15 +7,15 @@ =20 .file "remainderl.S" .text -#ifdef __x86_64__ +#if defined(__x86_64__) .align 8 -#else +#elif defined(__i386__) .align 4 #endif .globl __MINGW_USYMBOL(remainderl) .def __MINGW_USYMBOL(remainderl); .scl 2; .type 32; .endef __MINGW_USYMBOL(remainderl): -#ifdef __x86_64__ +#if defined(__x86_64__) fldt (%r8) fldt (%rdx) 1: fprem1 @@ -27,7 +27,7 @@ __MINGW_USYMBOL(remainderl): movq $0,8(%rcx) fstpt (%rcx) ret -#else +#elif defined(__i386__) fldt 16(%esp) fldt 4(%esp) 1: fprem1 @@ -36,4 +36,9 @@ __MINGW_USYMBOL(remainderl): jp 1b fstp %st(1) ret +#elif _defined(__aarch64__) + bl remainder + ret +#else + .error "Not supported on your platform yet" #endif diff --git a/winsup/cygwin/math/remquol.S b/winsup/cygwin/math/remquol.S index e16df8ad2a86..34041dc12cd2 100644 --- a/winsup/cygwin/math/remquol.S +++ b/winsup/cygwin/math/remquol.S @@ -7,14 +7,14 @@ =20 .file "remquol.S" .text -#ifdef __x86_64__ +#if defined(__x86_64__) .align 8 -#else +#elif defined(__i386__) .align 4 #endif .globl __MINGW_USYMBOL(remquol) __MINGW_USYMBOL(remquol): -#ifdef __x86_64__ +#if defined(__x86_64__) pushq %rcx fldt (%r8) fldt (%rdx) @@ -45,7 +45,7 @@ __MINGW_USYMBOL(remquol): movq $0,8(%rcx) fstpt (%rcx) ret -#else +#elif defined(__i386__) fldt 4 +12(%esp) fldt 4(%esp) 1: fprem1 @@ -72,4 +72,9 @@ __MINGW_USYMBOL(remquol): 1: movl %eax, (%ecx) =20 ret +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + bl remquo + ret +#else + .error "Not supported on your platform yet" #endif diff --git a/winsup/cygwin/math/rintl.c b/winsup/cygwin/math/rintl.c index 9ec159d17612..f9ca15f31e27 100644 --- a/winsup/cygwin/math/rintl.c +++ b/winsup/cygwin/math/rintl.c @@ -9,7 +9,7 @@ long double rintl (long double x) { long double retval =3D 0.0L; #if defined(_AMD64_) || defined(__x86_64__) || defined(_X86_) || defined(_= _i386__) __asm__ __volatile__ ("frndint;": "=3Dt" (retval) : "0" (x)); -#elif defined(__arm__) || defined(_ARM_) +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ retval =3D rint(x); #endif return retval; diff --git a/winsup/cygwin/math/scalbl.S b/winsup/cygwin/math/scalbl.S index f9675ac4ba50..ca66c6dfa3f8 100644 --- a/winsup/cygwin/math/scalbl.S +++ b/winsup/cygwin/math/scalbl.S @@ -7,15 +7,15 @@ =20 .file "scalbl.S" .text -#ifdef __x86_64__ +#if defined(__x86_64__) .align 8 -#else +#elif defined(__i386__) .align 4 #endif .globl __MINGW_USYMBOL(scalbl) .def __MINGW_USYMBOL(scalbl); .scl 2; .type 32; .endef __MINGW_USYMBOL(scalbl): -#ifdef __x86_64__ +#if defined(__x86_64__) subq $24, %rsp fldt (%r8) fldt (%rdx) @@ -26,10 +26,25 @@ __MINGW_USYMBOL(scalbl): fstpt (%rcx) addq $24, %rsp ret -#else +#elif defined(__i386__) fildl 16(%esp) fldt 4(%esp) fscale fstp %st(1) ret +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + fcvtzs x1, d1 + fmov x0, d0 + ubfx x2, x0, #52, #11 + add x2, x2, x1 + cmp x2, #0 + csel x2, xzr, x2, lt + mov x3, #0x7FF + cmp x2, x3 + csel x2, x2, x3, lt + bfi x0, x2, #52, #11 + fmov d0, x0 + ret +#else + .error "unimplemented for this target yet" #endif diff --git a/winsup/cygwin/math/scalbnl.S b/winsup/cygwin/math/scalbnl.S index 5ff0a68f3912..96e57e77cbed 100644 --- a/winsup/cygwin/math/scalbnl.S +++ b/winsup/cygwin/math/scalbnl.S @@ -7,15 +7,15 @@ =20 .file "scalbnl.S" .text -#ifdef __x86_64__ +#if defined(__x86_64__) .align 8 -#else +#elif defined(__i386__) .align 4 #endif .globl __MINGW_USYMBOL(scalbnl) .def __MINGW_USYMBOL(scalbnl); .scl 2; .type 32; .endef __MINGW_USYMBOL(scalbnl): -#ifdef __x86_64__ +#if defined(__x86_64__) subq $24, %rsp andl $-1, %r8d movq %r8, (%rsp) @@ -28,14 +28,21 @@ __MINGW_USYMBOL(scalbnl): fstpt (%rcx) addq $24, %rsp ret -#else +#elif defined(__i386__) fildl 16(%esp) fldt 4(%esp) fscale fstp %st(1) ret +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + scvtf d1, w1 + fmov d2, #2.0 + bl pow + fmul d0, d0, d1 + ret +#else + .error "Not supported on your platform yet" #endif =20 .globl __MINGW_USYMBOL(scalblnl) .set __MINGW_USYMBOL(scalblnl),__MINGW_USYMBOL(scalbnl) - diff --git a/winsup/cygwin/math/sinl_internal.S b/winsup/cygwin/math/sinl_i= nternal.S index 6d766b098d52..9def0ac0e16c 100644 --- a/winsup/cygwin/math/sinl_internal.S +++ b/winsup/cygwin/math/sinl_internal.S @@ -7,15 +7,15 @@ =20 .file "sinl_internal.S" .text -#ifdef __x86_64__ +#if defined(__x86_64__) .align 8 -#else +#elif defined(__i386__) .align 4 #endif .globl __MINGW_USYMBOL(__sinl_internal) .def __MINGW_USYMBOL(__sinl_internal); .scl 2; .type 32; .endef __MINGW_USYMBOL(__sinl_internal): -#ifdef __x86_64__ +#if defined(__x86_64__) fldt (%rdx) fsin fnstsw %ax @@ -38,7 +38,7 @@ __MINGW_USYMBOL(__sinl_internal): movq $0,8(%rcx) fstpt (%rcx) ret -#else +#elif defined(__i386__) fldt 4(%esp) fsin fnstsw %ax @@ -55,4 +55,9 @@ __MINGW_USYMBOL(__sinl_internal): fstp %st(1) fsin ret +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + bl sin + ret +#else + .error "Not supported on your platform yet" #endif diff --git a/winsup/cygwin/math/sqrt.def.h b/winsup/cygwin/math/sqrt.def.h index 3d1a00908b59..e3fbba81af28 100644 --- a/winsup/cygwin/math/sqrt.def.h +++ b/winsup/cygwin/math/sqrt.def.h @@ -89,6 +89,8 @@ __FLT_ABI (sqrt) (__FLT_TYPE x) __fsqrt_internal(x); #elif defined(_X86_) || defined(__i386__) || defined(_AMD64_) || defined(_= _x86_64__) asm volatile ("fsqrt" : "=3Dt" (res) : "0" (x)); +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + asm volatile ("fsqrt %d0, %d1" : "=3Dw"(res) : "w"(x)); #else #error Not supported on your platform yet #endif diff --git a/winsup/cygwin/math/tanl.S b/winsup/cygwin/math/tanl.S index f11b53920bed..7b62dabadbb4 100644 --- a/winsup/cygwin/math/tanl.S +++ b/winsup/cygwin/math/tanl.S @@ -7,15 +7,15 @@ =20 .file "tanl.S" .text -#ifdef __x86_64__ +#if defined(__x86_64__) .align 8 -#else +#elif defined(__i386__) .align 4 #endif .globl __MINGW_USYMBOL(tanl) .def __MINGW_USYMBOL(tanl); .scl 2; .type 32; .endef __MINGW_USYMBOL(tanl): -#ifdef __x86_64__ +#if defined(__x86_64__) fldt (%rdx) fptan fnstsw %ax @@ -40,7 +40,7 @@ __MINGW_USYMBOL(tanl): movq $0,8(%rcx) fstpt (%rcx) ret -#else +#elif defined(__i386__) fldt 4(%esp) fptan fnstsw %ax @@ -59,4 +59,9 @@ __MINGW_USYMBOL(tanl): fptan fstp %st(0) ret +#elif __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ + bl tan + ret +#else + .error "Not supported on your platform yet" #endif diff --git a/winsup/cygwin/math/truncl.c b/winsup/cygwin/math/truncl.c index 9380f9571df4..86e71d108564 100644 --- a/winsup/cygwin/math/truncl.c +++ b/winsup/cygwin/math/truncl.c @@ -13,7 +13,7 @@ long double truncl (long double _x) { -#if defined(_ARM_) || defined(__arm__) +#if __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ return trunc(_x); #else long double retval =3D 0.0L; @@ -26,5 +26,5 @@ truncl (long double _x) __asm__ __volatile__ ("frndint;" : "=3Dt" (retval) : "0" (_x)); /* roun= d towards zero */ __asm__ __volatile__ ("fldcw %0;" : : "m" (saved_cw) ); /* restore saved= control word */ return retval; -#endif /* defined(_ARM_) || defined(__arm__) */ +#endif /* __SIZEOF_LONG_DOUBLE__ =3D=3D __SIZEOF_DOUBLE__ */ }