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