• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)19 static __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)26 static __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)33 static __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)41 static __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)52 static __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)64 static __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)75 static __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)90 static __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)105 static __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