| /** | 
 |  * This file has no copyright assigned and is placed in the Public Domain. | 
 |  * This file is part of the mingw-w64 runtime package. | 
 |  * No warranty is given; refer to the file DISCLAIMER.PD within this package. | 
 |  */ | 
 | #ifndef _MINGWEX_FASTMATH_H_ | 
 | #define _MINGWEX_FASTMATH_H_ | 
 |  | 
 | /* Fast math inlines | 
 |    No range or domain checks. No setting of errno.  No tweaks to | 
 |    protect precision near range limits. */ | 
 |  | 
 | /* For now this is an internal header with just the functions that | 
 |    are currently used in building libmingwex.a math components */ | 
 |  | 
 | /* FIXME: We really should get rid of the code duplication using euther | 
 |    C++ templates or tgmath-type macros.  */   | 
 |  | 
 | static __inline__ double __fast_sqrt (double x) | 
 | { | 
 |   double res; | 
 |   asm __volatile__ ("fsqrt" : "=t" (res) : "0" (x)); | 
 |   return res; | 
 | } | 
 |  | 
 | static __inline__ long double __fast_sqrtl (long double x) | 
 | { | 
 |   long double res; | 
 |   asm __volatile__ ("fsqrt" : "=t" (res) : "0" (x)); | 
 |   return res; | 
 | } | 
 |  | 
 | static __inline__ float __fast_sqrtf (float x) | 
 | { | 
 |   float res; | 
 |   asm __volatile__ ("fsqrt" : "=t" (res) : "0" (x)); | 
 |   return res; | 
 | } | 
 |  | 
 |  | 
 | static __inline__ double __fast_log (double x) | 
 | { | 
 |    double res; | 
 |    asm __volatile__ | 
 |      ("fldln2\n\t" | 
 |       "fxch\n\t" | 
 |       "fyl2x" | 
 |        : "=t" (res) : "0" (x) : "st(1)"); | 
 |    return res; | 
 | } | 
 |  | 
 | static __inline__ long double __fast_logl (long double x) | 
 | { | 
 |   long double res; | 
 |    asm __volatile__ | 
 |      ("fldln2\n\t" | 
 |       "fxch\n\t" | 
 |       "fyl2x" | 
 |        : "=t" (res) : "0" (x) : "st(1)"); | 
 |    return res; | 
 | } | 
 |  | 
 |  | 
 | static __inline__ float __fast_logf (float x) | 
 | { | 
 |    float res; | 
 |    asm __volatile__ | 
 |      ("fldln2\n\t" | 
 |       "fxch\n\t" | 
 |       "fyl2x" | 
 |        : "=t" (res) : "0" (x) : "st(1)"); | 
 |    return res; | 
 | } | 
 |  | 
 | static __inline__ double __fast_log1p (double x) | 
 | { | 
 |   double res; | 
 |   /* fyl2xp1 accurate only for |x| <= 1.0 - 0.5 * sqrt (2.0) */ | 
 |   if (fabs (x) >= 1.0 - 0.5 * 1.41421356237309504880) | 
 |     res = __fast_log (1.0 + x); | 
 |   else | 
 |     asm __volatile__ | 
 |       ("fldln2\n\t" | 
 |        "fxch\n\t" | 
 |        "fyl2xp1" | 
 |        : "=t" (res) : "0" (x) : "st(1)"); | 
 |    return res; | 
 | } | 
 |  | 
 | static __inline__ long double __fast_log1pl (long double x) | 
 | { | 
 |   long double res; | 
 |   /* fyl2xp1 accurate only for |x| <= 1.0 - 0.5 * sqrt (2.0) */ | 
 |   if (fabsl (x) >= 1.0L - 0.5L * 1.41421356237309504880L) | 
 |     res = __fast_logl (1.0L + x); | 
 |   else | 
 |     asm __volatile__ | 
 |       ("fldln2\n\t" | 
 |        "fxch\n\t" | 
 |        "fyl2xp1" | 
 |        : "=t" (res) : "0" (x) : "st(1)"); | 
 |    return res; | 
 | } | 
 |  | 
 | static __inline__ float __fast_log1pf (float x) | 
 | { | 
 |   float res; | 
 |   /* fyl2xp1 accurate only for |x| <= 1.0 - 0.5 * sqrt (2.0) */ | 
 |   if (fabsf (x) >= 1.0 - 0.5 * 1.41421356237309504880) | 
 |     res = __fast_logf (1.0 + x); | 
 |   else | 
 |     asm __volatile__ | 
 |       ("fldln2\n\t" | 
 |        "fxch\n\t" | 
 |        "fyl2xp1" | 
 |        : "=t" (res) : "0" (x) : "st(1)"); | 
 |    return res; | 
 | } | 
 |  | 
 | #endif |