master
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
19static __inline__ double __fast_sqrt (double x)
20{
21 double res;
22 asm __volatile__ ("fsqrt" : "=t" (res) : "0" (x));
23 return res;
24}
25
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
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
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
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
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
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
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
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