1 /** 2 * This file has no copyright assigned and is placed in the Public Domain. 3 * This file is part of the mingw-w64 runtime package. 4 * No warranty is given; refer to the file DISCLAIMER.PD within this package. 5 */ 6 #ifndef _MINGWEX_FASTMATH_H_ 7 #define _MINGWEX_FASTMATH_H_ 8 9 /* Fast math inlines 10 No range or domain checks. No setting of errno. No tweaks to 11 protect precision near range limits. */ 12 13 /* For now this is an internal header with just the functions that 14 are currently used in building libmingwex.a math components */ 15 16 /* FIXME: We really should get rid of the code duplication using euther 17 C++ templates or tgmath-type macros. */ 18 __fast_sqrt(double x)19static __inline__ double __fast_sqrt (double x) 20 { 21 double res; 22 asm __volatile__ ("fsqrt" : "=t" (res) : "0" (x)); 23 return res; 24 } 25 __fast_sqrtl(long double x)26static __inline__ long double __fast_sqrtl (long double x) 27 { 28 long double res; 29 asm __volatile__ ("fsqrt" : "=t" (res) : "0" (x)); 30 return res; 31 } 32 __fast_sqrtf(float x)33static __inline__ float __fast_sqrtf (float x) 34 { 35 float res; 36 asm __volatile__ ("fsqrt" : "=t" (res) : "0" (x)); 37 return res; 38 } 39 40 __fast_log(double x)41static __inline__ double __fast_log (double x) 42 { 43 double res; 44 asm __volatile__ 45 ("fldln2\n\t" 46 "fxch\n\t" 47 "fyl2x" 48 : "=t" (res) : "0" (x) : "st(1)"); 49 return res; 50 } 51 __fast_logl(long double x)52static __inline__ long double __fast_logl (long double x) 53 { 54 long double res; 55 asm __volatile__ 56 ("fldln2\n\t" 57 "fxch\n\t" 58 "fyl2x" 59 : "=t" (res) : "0" (x) : "st(1)"); 60 return res; 61 } 62 63 __fast_logf(float x)64static __inline__ float __fast_logf (float x) 65 { 66 float res; 67 asm __volatile__ 68 ("fldln2\n\t" 69 "fxch\n\t" 70 "fyl2x" 71 : "=t" (res) : "0" (x) : "st(1)"); 72 return res; 73 } 74 __fast_log1p(double x)75static __inline__ double __fast_log1p (double x) 76 { 77 double res; 78 /* fyl2xp1 accurate only for |x| <= 1.0 - 0.5 * sqrt (2.0) */ 79 if (fabs (x) >= 1.0 - 0.5 * 1.41421356237309504880) 80 res = __fast_log (1.0 + x); 81 else 82 asm __volatile__ 83 ("fldln2\n\t" 84 "fxch\n\t" 85 "fyl2xp1" 86 : "=t" (res) : "0" (x) : "st(1)"); 87 return res; 88 } 89 __fast_log1pl(long double x)90static __inline__ long double __fast_log1pl (long double x) 91 { 92 long double res; 93 /* fyl2xp1 accurate only for |x| <= 1.0 - 0.5 * sqrt (2.0) */ 94 if (fabsl (x) >= 1.0L - 0.5L * 1.41421356237309504880L) 95 res = __fast_logl (1.0L + x); 96 else 97 asm __volatile__ 98 ("fldln2\n\t" 99 "fxch\n\t" 100 "fyl2xp1" 101 : "=t" (res) : "0" (x) : "st(1)"); 102 return res; 103 } 104 __fast_log1pf(float x)105static __inline__ float __fast_log1pf (float x) 106 { 107 float res; 108 /* fyl2xp1 accurate only for |x| <= 1.0 - 0.5 * sqrt (2.0) */ 109 if (fabsf (x) >= 1.0 - 0.5 * 1.41421356237309504880) 110 res = __fast_logf (1.0 + x); 111 else 112 asm __volatile__ 113 ("fldln2\n\t" 114 "fxch\n\t" 115 "fyl2xp1" 116 : "=t" (res) : "0" (x) : "st(1)"); 117 return res; 118 } 119 120 #endif 121