[PATCH 2/2] msvcrt: Add float functions based on their double versions

Maarten Lankhorst m.b.lankhorst at gmail.com
Sat May 1 09:32:46 CDT 2010


---
 dlls/msvcrt/math.c      |  207 +++++++++++++++++++++++++++++++++++++++++++++++
 dlls/msvcrt/msvcrt.spec |   23 +++++
 2 files changed, 230 insertions(+), 0 deletions(-)

diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c
index 93e13d0..594555f 100644
--- a/dlls/msvcrt/math.c
+++ b/dlls/msvcrt/math.c
@@ -51,6 +51,204 @@ typedef int (*MSVCRT_matherr_func)(struct MSVCRT__exception *);
 
 static MSVCRT_matherr_func MSVCRT_default_matherr_func = NULL;
 
+#ifdef __x86_64__
+
+/*********************************************************************
+ *      MSVCRT_acosf (MSVCRT.@)
+ */
+float CDECL MSVCRT_acosf( float x )
+{
+  if (x < -1.0 || x > 1.0 || !finitef(x)) *MSVCRT__errno() = MSVCRT_EDOM;
+  /* glibc implements acos() as the FPU equivalent of atan2(sqrt(1 - x ^ 2), x).
+   * asin() uses a similar construction. This is bad because as x gets nearer to
+   * 1 the error in the expression "1 - x^2" can get relatively large due to
+   * cancellation. The sqrt() makes things worse. A safer way to calculate
+   * acos() is to use atan2(sqrt((1 - x) * (1 + x)), x). */
+  return atan2f(sqrtf((1 - x) * (1 + x)), x);
+}
+
+/*********************************************************************
+ *      MSVCRT_asinf (MSVCRT.@)
+ */
+float CDECL MSVCRT_asinf( float x )
+{
+  if (x < -1.0 || x > 1.0 || !finitef(x)) *MSVCRT__errno() = MSVCRT_EDOM;
+  return atan2f(x, sqrtf((1 - x) * (1 + x)));
+}
+
+/*********************************************************************
+ *      MSVCRT_atanf (MSVCRT.@)
+ */
+float CDECL MSVCRT_atanf( float x )
+{
+  if (!finitef(x)) *MSVCRT__errno() = MSVCRT_EDOM;
+  return atanf(x);
+}
+
+/*********************************************************************
+ *              MSVCRT_atan2f (MSVCRT.@)
+ */
+float CDECL MSVCRT_atan2f( float x, float y )
+{
+  if (!finitef(x)) *MSVCRT__errno() = MSVCRT_EDOM;
+  return atan2f(x,y);
+}
+
+/*********************************************************************
+ *      MSVCRT_cosf (MSVCRT.@)
+ */
+float CDECL MSVCRT_cosf( float x )
+{
+  if (!finitef(x)) *MSVCRT__errno() = MSVCRT_EDOM;
+  return cosf(x);
+}
+
+/*********************************************************************
+ *      MSVCRT_coshf (MSVCRT.@)
+ */
+float CDECL MSVCRT_coshf( float x )
+{
+  if (!finitef(x)) *MSVCRT__errno() = MSVCRT_EDOM;
+  return coshf(x);
+}
+
+/*********************************************************************
+ *      MSVCRT_expf (MSVCRT.@)
+ */
+float CDECL MSVCRT_expf( float x )
+{
+  if (!finitef(x)) *MSVCRT__errno() = MSVCRT_EDOM;
+  return expf(x);
+}
+
+/*********************************************************************
+ *      MSVCRT_fmodf (MSVCRT.@)
+ */
+float CDECL MSVCRT_fmodf( float x, float y )
+{
+  if (!finitef(x) || !finitef(y)) *MSVCRT__errno() = MSVCRT_EDOM;
+  return fmodf(x,y);
+}
+
+/*********************************************************************
+ *      MSVCRT_logf (MSVCRT.@)
+ */
+float CDECL MSVCRT_logf( float x)
+{
+  if (x < 0.0 || !finitef(x)) *MSVCRT__errno() = MSVCRT_EDOM;
+  if (x == 0.0) *MSVCRT__errno() = MSVCRT_ERANGE;
+  return logf(x);
+}
+
+/*********************************************************************
+ *      MSVCRT_log10f (MSVCRT.@)
+ */
+float CDECL MSVCRT_log10f( float x )
+{
+  if (x < 0.0 || !finitef(x)) *MSVCRT__errno() = MSVCRT_EDOM;
+  if (x == 0.0) *MSVCRT__errno() = MSVCRT_ERANGE;
+  return log10f(x);
+}
+
+/*********************************************************************
+ *      MSVCRT_powf (MSVCRT.@)
+ */
+float CDECL MSVCRT_powf( float x, float y )
+{
+  /* FIXME: If x < 0 and y is not integral, set EDOM */
+  float z = powf(x,y);
+  if (!finitef(z)) *MSVCRT__errno() = MSVCRT_EDOM;
+  return z;
+}
+
+/*********************************************************************
+ *      MSVCRT_sinf (MSVCRT.@)
+ */
+float CDECL MSVCRT_sinf( float x )
+{
+  if (!finitef(x)) *MSVCRT__errno() = MSVCRT_EDOM;
+  return sinf(x);
+}
+
+/*********************************************************************
+ *      MSVCRT_sinhf (MSVCRT.@)
+ */
+float CDECL MSVCRT_sinhf( float x )
+{
+  if (!finitef(x)) *MSVCRT__errno() = MSVCRT_EDOM;
+  return sinhf(x);
+}
+
+/*********************************************************************
+ *      MSVCRT_sqrtf (MSVCRT.@)
+ */
+float CDECL MSVCRT_sqrtf( float x )
+{
+  if (x < 0.0 || !finitef(x)) *MSVCRT__errno() = MSVCRT_EDOM;
+  return sqrtf(x);
+}
+
+/*********************************************************************
+ *      MSVCRT_tanf (MSVCRT.@)
+ */
+float CDECL MSVCRT_tanf( float x )
+{
+  if (!finitef(x)) *MSVCRT__errno() = MSVCRT_EDOM;
+  return tanf(x);
+}
+
+/*********************************************************************
+ *      MSVCRT_tanhf (MSVCRT.@)
+ */
+float CDECL MSVCRT_tanhf( float x )
+{
+  if (!finitef(x)) *MSVCRT__errno() = MSVCRT_EDOM;
+  return tanhf(x);
+}
+
+/*********************************************************************
+ *      ceilf (MSVCRT.@)
+ */
+float CDECL MSVCRT_ceilf( float x )
+{
+  return ceilf(x);
+}
+
+/*********************************************************************
+ *      floorf (MSVCRT.@)
+ */
+float CDECL MSVCRT_floorf( float x )
+{
+  return floorf(x);
+}
+
+/*********************************************************************
+ *      frexpf (MSVCRT.@)
+ */
+float CDECL MSVCRT_frexpf( float x, int *exp )
+{
+  return frexpf( x, exp );
+}
+
+/*********************************************************************
+ *      _scalbf (MSVCRT.@)
+ */
+float CDECL MSVCRT__scalbf(float num, MSVCRT_long power)
+{
+  if (!finitef(num)) *MSVCRT__errno() = MSVCRT_EDOM;
+  return ldexpf(num, power);
+}
+
+/*********************************************************************
+ *      modff (MSVCRT.@)
+ */
+double CDECL MSVCRT_modff( float x, float *iptr )
+{
+  return modff( x, iptr );
+}
+
+#endif
+
 /*********************************************************************
  *		MSVCRT_acos (MSVCRT.@)
  */
@@ -479,6 +677,15 @@ double CDECL _hypot(double x, double y)
 }
 
 /*********************************************************************
+ *      _hypotf (MSVCRT.@)
+ */
+float CDECL _hypotf(float x, float y)
+{
+  /* FIXME: errno handling */
+  return hypotf( x, y );
+}
+
+/*********************************************************************
  *		ceil (MSVCRT.@)
  */
 double CDECL MSVCRT_ceil( double x )
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index 0909cd0..6362bb6 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -471,6 +471,7 @@
 @ stub _heapused #(ptr ptr)
 @ cdecl _heapwalk(ptr)
 @ cdecl _hypot(double double)
+@ cdecl _hypotf(double double)
 @ cdecl _i64toa(long long ptr long) ntdll._i64toa
 # stub _i64toa_s
 @ cdecl _i64tow(long long ptr long) ntdll._i64tow
@@ -794,6 +795,7 @@
 @ cdecl -arch=i386 _safe_fprem()
 @ cdecl -arch=i386 _safe_fprem1()
 @ cdecl _scalb(double long) MSVCRT__scalb
+@ cdecl -arch=x86_64 _scalbf(double long) MSVCRT__scalbf
 @ varargs _scanf_l(str ptr) MSVCRT__scanf_l
 @ varargs _scanf_s_l(str ptr) MSVCRT__scanf_s_l
 # stub _scprintf
@@ -1154,11 +1156,16 @@
 @ cdecl abort() MSVCRT_abort
 @ cdecl abs(long) ntdll.abs
 @ cdecl acos(double) MSVCRT_acos
+@ cdecl -arch=x86_64 acosf(double) MSVCRT_acosf
 @ cdecl asctime(ptr) MSVCRT_asctime
 # stub asctime_s
 @ cdecl asin(double) MSVCRT_asin
 @ cdecl atan(double) MSVCRT_atan
 @ cdecl atan2(double double) MSVCRT_atan2
+@ cdecl -arch=x86_64 asinf(double) MSVCRT_asinf
+@ cdecl -arch=x86_64 atanf(double) MSVCRT_atanf
+@ cdecl -arch=x86_64 atan2f(double double) MSVCRT_atan2f
+
 @ cdecl atexit(ptr) MSVCRT_atexit
 @ cdecl atof(str) MSVCRT_atof
 @ cdecl atoi(str) ntdll.atoi
@@ -1168,16 +1175,20 @@
 # stub btowc
 @ cdecl calloc(long long) MSVCRT_calloc
 @ cdecl ceil(double) MSVCRT_ceil
+@ cdecl -arch=x86_64 ceilf(double) MSVCRT_ceilf
 @ cdecl clearerr(ptr) MSVCRT_clearerr
 # stub clearerr_s
 @ cdecl clock() MSVCRT_clock
 @ cdecl cos(double) MSVCRT_cos
 @ cdecl cosh(double) MSVCRT_cosh
+@ cdecl -arch=x86_64 cosf(double) MSVCRT_cosf
+@ cdecl -arch=x86_64 coshf(double) MSVCRT_coshf
 @ cdecl ctime(ptr) MSVCRT_ctime
 @ cdecl difftime(long long) MSVCRT_difftime
 @ cdecl div(long long) MSVCRT_div
 @ cdecl exit(long) MSVCRT_exit
 @ cdecl exp(double) MSVCRT_exp
+@ cdecl -arch=x86_64 expf(double) MSVCRT_expf
 @ cdecl fabs(double) MSVCRT_fabs
 @ cdecl fclose(ptr) MSVCRT_fclose
 @ cdecl feof(ptr) MSVCRT_feof
@@ -1189,7 +1200,9 @@
 @ cdecl fgetwc(ptr) MSVCRT_fgetwc
 @ cdecl fgetws(ptr long ptr) MSVCRT_fgetws
 @ cdecl floor(double) MSVCRT_floor
+@ cdecl -arch=x86_64 floorf(double) MSVCRT_floorf
 @ cdecl fmod(double double) MSVCRT_fmod
+@ cdecl -arch=x86_64 fmodf(double double) MSVCRT_fmodf
 @ cdecl fopen(str str) MSVCRT_fopen
 @ cdecl fopen_s(ptr str str) MSVCRT_fopen_s
 @ varargs fprintf(ptr str) MSVCRT_fprintf
@@ -1203,6 +1216,7 @@
 @ cdecl freopen(str str ptr) MSVCRT_freopen
 # stub freopen_s
 @ cdecl frexp(double ptr) MSVCRT_frexp
+@ cdecl -arch=x86_64 frexpf(double ptr) MSVCRT_frexpf
 @ varargs fscanf(ptr str) MSVCRT_fscanf
 @ varargs fscanf_s(ptr str) MSVCRT_fscanf_s
 @ cdecl fseek(ptr long long) MSVCRT_fseek
@@ -1254,6 +1268,8 @@
 @ cdecl localtime(ptr) MSVCRT_localtime
 @ cdecl log(double) MSVCRT_log
 @ cdecl log10(double) MSVCRT_log10
+@ cdecl -arch=x86_64 logf(double) MSVCRT_logf
+@ cdecl -arch=x86_64 log10f(double) MSVCRT_log10f
 @ cdecl -i386 longjmp(ptr long) MSVCRT_longjmp
 @ cdecl malloc(long) MSVCRT_malloc
 @ cdecl mblen(ptr long) MSVCRT_mblen
@@ -1274,8 +1290,10 @@
 @ cdecl memset(ptr long long) ntdll.memset
 @ cdecl mktime(ptr) MSVCRT_mktime
 @ cdecl modf(double ptr) MSVCRT_modf
+@ cdecl -arch=x86_64 modff(double ptr) MSVCRT_modff
 @ cdecl perror(str) MSVCRT_perror
 @ cdecl pow(double double) MSVCRT_pow
+@ cdecl -arch=x86_64 powf(double double) MSVCRT_powf
 @ varargs printf(str) MSVCRT_printf
 # stub printf_s
 @ cdecl putc(long ptr) MSVCRT_putc
@@ -1301,9 +1319,12 @@
 @ cdecl signal(long long) MSVCRT_signal
 @ cdecl sin(double) MSVCRT_sin
 @ cdecl sinh(double) MSVCRT_sinh
+@ cdecl -arch=x86_64 sinf(double) MSVCRT_sinf
+@ cdecl -arch=x86_64 sinhf(double) MSVCRT_sinhf
 @ varargs sprintf(ptr str) MSVCRT_sprintf
 @ varargs sprintf_s(ptr long str) MSVCRT_sprintf_s
 @ cdecl sqrt(double) MSVCRT_sqrt
+@ cdecl -arch=x86_64 sqrtf(double) MSVCRT_sqrtf
 @ cdecl srand(long) MSVCRT_srand
 @ varargs sscanf(str str) MSVCRT_sscanf
 @ varargs sscanf_s(str str) MSVCRT_sscanf_s
@@ -1342,6 +1363,8 @@
 @ cdecl system(str) MSVCRT_system
 @ cdecl tan(double) MSVCRT_tan
 @ cdecl tanh(double) MSVCRT_tanh
+@ cdecl -arch=x86_64 tanf(double) MSVCRT_tanf
+@ cdecl -arch=x86_64 tanhf(double) MSVCRT_tanhf
 @ cdecl time(ptr) MSVCRT_time
 @ cdecl tmpfile() MSVCRT_tmpfile
 # stub tmpfile_s
-- 
1.7.0.4




More information about the wine-patches mailing list