Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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