include: Fix __dmb declaration.
[wine.git] / dlls / msvcrt / unixlib.c
blobb08663f387a2c0bd75c9112469de85b1406e27a6
1 /*
2 * MSVCRT Unix interface
4 * Copyright 2020 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #if 0
22 #pragma makedep unix
23 #endif
25 #include "config.h"
26 #include "wine/port.h"
28 #include <stdio.h>
29 #include <stdarg.h>
30 #define __USE_ISOC9X 1
31 #define __USE_ISOC99 1
32 #include <math.h>
33 #ifdef HAVE_IEEEFP_H
34 #include <ieeefp.h>
35 #endif
37 #include "ntstatus.h"
38 #define WIN32_NO_STATUS
39 #include "winternl.h"
40 #include "unixlib.h"
41 #include "wine/debug.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
45 /*********************************************************************
46 * acosh
48 static double CDECL unix_acosh(double x)
50 #ifdef HAVE_ACOSH
51 return acosh(x);
52 #else
53 if (!isfinite(x*x)) return log(2) + log(x);
54 return log(x + sqrt(x*x-1));
55 #endif
58 /*********************************************************************
59 * acoshf
61 static float CDECL unix_acoshf(float x)
63 #ifdef HAVE_ACOSHF
64 return acoshf(x);
65 #else
66 return unix_acosh(x);
67 #endif
70 /*********************************************************************
71 * asinh
73 static double CDECL unix_asinh(double x)
75 #ifdef HAVE_ASINH
76 return asinh(x);
77 #else
78 if (!isfinite(x*x+1))
80 if (x > 0) return log(2) + log(x);
81 else return -log(2) - log(-x);
83 return log(x + sqrt(x*x+1));
84 #endif
87 /*********************************************************************
88 * asinhf
90 static float CDECL unix_asinhf(float x)
92 #ifdef HAVE_ASINHF
93 return asinhf(x);
94 #else
95 return unix_asinh(x);
96 #endif
99 /*********************************************************************
100 * atanh
102 static double CDECL unix_atanh(double x)
104 #ifdef HAVE_ATANH
105 return atanh(x);
106 #else
107 if (-1e-6 < x && x < 1e-6) return x + x*x*x/3;
108 else return (log(1+x) - log(1-x)) / 2;
109 #endif
112 /*********************************************************************
113 * atanhf
115 static float CDECL unix_atanhf(float x)
117 #ifdef HAVE_ATANHF
118 return atanhf(x);
119 #else
120 return unix_atanh(x);
121 #endif
124 /*********************************************************************
125 * cbrt
127 static double CDECL unix_cbrt(double x)
129 #ifdef HAVE_CBRT
130 return cbrt(x);
131 #else
132 return x < 0 ? -pow(-x, 1.0 / 3.0) : pow(x, 1.0 / 3.0);
133 #endif
136 /*********************************************************************
137 * cbrtf
139 static float CDECL unix_cbrtf(float x)
141 #ifdef HAVE_CBRTF
142 return cbrtf(x);
143 #else
144 return unix_cbrt(x);
145 #endif
148 /*********************************************************************
149 * ceil
151 static double CDECL unix_ceil( double x )
153 return ceil( x );
156 /*********************************************************************
157 * ceilf
159 static float CDECL unix_ceilf( float x )
161 return ceilf( x );
164 /*********************************************************************
165 * cos
167 static double CDECL unix_cos( double x )
169 return cos( x );
172 /*********************************************************************
173 * cosf
175 static float CDECL unix_cosf( float x )
177 return cosf( x );
180 /*********************************************************************
181 * cosh
183 static double CDECL unix_cosh( double x )
185 return cosh( x );
188 /*********************************************************************
189 * coshf
191 static float CDECL unix_coshf( float x )
193 return coshf( x );
196 /*********************************************************************
197 * erf
199 static double CDECL unix_erf(double x)
201 #ifdef HAVE_ERF
202 return erf(x);
203 #else
204 /* Abramowitz and Stegun approximation, maximum error: 1.5*10^-7 */
205 double t, y;
206 int sign = signbit(x);
208 if (sign) x = -x;
209 t = 1 / (1 + 0.3275911 * x);
210 y = ((((1.061405429*t - 1.453152027)*t + 1.421413741)*t - 0.284496736)*t + 0.254829592)*t;
211 y = 1.0 - y*exp(-x*x);
212 return sign ? -y : y;
213 #endif
216 /*********************************************************************
217 * erff
219 static float CDECL unix_erff(float x)
221 #ifdef HAVE_ERFF
222 return erff(x);
223 #else
224 return unix_erf(x);
225 #endif
228 /*********************************************************************
229 * erfc
231 static double CDECL unix_erfc(double x)
233 #ifdef HAVE_ERFC
234 return erfc(x);
235 #else
236 return 1 - unix_erf(x);
237 #endif
240 /*********************************************************************
241 * erfcf
243 static float CDECL unix_erfcf(float x)
245 #ifdef HAVE_ERFCF
246 return erfcf(x);
247 #else
248 return unix_erfc(x);
249 #endif
252 /*********************************************************************
253 * exp
255 static double CDECL unix_exp( double x )
257 return exp( x );
260 /*********************************************************************
261 * expf
263 static float CDECL unix_expf( float x )
265 return expf( x );
268 /*********************************************************************
269 * exp2
271 static double CDECL unix_exp2( double x )
273 #ifdef HAVE_EXP2
274 return exp2(x);
275 #else
276 return pow(2, x);
277 #endif
280 /*********************************************************************
281 * exp2f
283 static float CDECL unix_exp2f( float x )
285 #ifdef HAVE_EXP2F
286 return exp2f(x);
287 #else
288 return unix_exp2(x);
289 #endif
292 /*********************************************************************
293 * expm1
295 static double CDECL unix_expm1(double x)
297 #ifdef HAVE_EXPM1
298 return expm1(x);
299 #else
300 return exp(x) - 1;
301 #endif
304 /*********************************************************************
305 * expm1f
307 static float CDECL unix_expm1f(float x)
309 #ifdef HAVE_EXPM1F
310 return expm1f(x);
311 #else
312 return exp(x) - 1;
313 #endif
316 /*********************************************************************
317 * floor
319 static double CDECL unix_floor( double x )
321 return floor( x );
324 /*********************************************************************
325 * floorf
327 static float CDECL unix_floorf( float x )
329 return floorf( x );
332 /*********************************************************************
333 * fma
335 static double CDECL unix_fma( double x, double y, double z )
337 #ifdef HAVE_FMA
338 return fma(x, y, z);
339 #else
340 return x * y + z;
341 #endif
344 /*********************************************************************
345 * fmaf
347 static float CDECL unix_fmaf( float x, float y, float z )
349 #ifdef HAVE_FMAF
350 return fmaf(x, y, z);
351 #else
352 return x * y + z;
353 #endif
356 /*********************************************************************
357 * fmod
359 static double CDECL unix_fmod( double x, double y )
361 return fmod( x, y );
364 /*********************************************************************
365 * fmodf
367 static float CDECL unix_fmodf( float x, float y )
369 return fmodf( x, y );
372 /*********************************************************************
373 * frexp
375 static double CDECL unix_frexp( double x, int *exp )
377 return frexp( x, exp );
380 /*********************************************************************
381 * frexpf
383 static float CDECL unix_frexpf( float x, int *exp )
385 return frexpf( x, exp );
388 /*********************************************************************
389 * hypot
391 static double CDECL unix_hypot(double x, double y)
393 return hypot( x, y );
396 /*********************************************************************
397 * hypotf
399 static float CDECL unix_hypotf(float x, float y)
401 return hypotf( x, y );
404 /*********************************************************************
405 * j0
407 static double CDECL unix_j0(double num)
409 #ifdef HAVE_J0
410 return j0(num);
411 #else
412 FIXME("not implemented\n");
413 return 0;
414 #endif
417 /*********************************************************************
418 * j1
420 static double CDECL unix_j1(double num)
422 #ifdef HAVE_J1
423 return j1(num);
424 #else
425 FIXME("not implemented\n");
426 return 0;
427 #endif
430 /*********************************************************************
431 * jn
433 static double CDECL unix_jn(int n, double num)
435 #ifdef HAVE_JN
436 return jn(n, num);
437 #else
438 FIXME("not implemented\n");
439 return 0;
440 #endif
443 /*********************************************************************
444 * ldexp
446 static double CDECL unix_ldexp(double num, int exp)
448 return ldexp( num, exp );
451 /*********************************************************************
452 * lgamma
454 static double CDECL unix_lgamma(double x)
456 #ifdef HAVE_LGAMMA
457 return lgamma(x);
458 #else
459 FIXME( "not implemented\n" );
460 return 0;
461 #endif
464 /*********************************************************************
465 * lgammaf
467 static float CDECL unix_lgammaf(float x)
469 #ifdef HAVE_LGAMMAF
470 return lgammaf(x);
471 #else
472 FIXME( "not implemented\n" );
473 return 0;
474 #endif
477 /*********************************************************************
478 * llrint
480 static __int64 CDECL unix_llrint(double x)
482 #ifdef HAVE_LLRINT
483 return llrint(x);
484 #else
485 return x >= 0 ? floor(x + 0.5) : ceil(x - 0.5);
486 #endif
489 /*********************************************************************
490 * llrintf
492 static __int64 CDECL unix_llrintf(float x)
494 #ifdef HAVE_LLRINTF
495 return llrintf(x);
496 #else
497 return x >= 0 ? floorf(x + 0.5) : ceilf(x - 0.5);
498 #endif
501 /*********************************************************************
502 * log
504 static double CDECL unix_log( double x )
506 return log( x );
509 /*********************************************************************
510 * logf
512 static float CDECL unix_logf( float x )
514 return logf( x );
517 /*********************************************************************
518 * log10
520 static double CDECL unix_log10( double x )
522 return log10( x );
525 /*********************************************************************
526 * log10f
528 static float CDECL unix_log10f( float x )
530 return log10f( x );
533 /*********************************************************************
534 * log1p
536 static double CDECL unix_log1p(double x)
538 #ifdef HAVE_LOG1P
539 return log1p(x);
540 #else
541 return log(1 + x);
542 #endif
545 /*********************************************************************
546 * log1pf
548 static float CDECL unix_log1pf(float x)
550 #ifdef HAVE_LOG1PF
551 return log1pf(x);
552 #else
553 return log(1 + x);
554 #endif
557 /*********************************************************************
558 * log2
560 static double CDECL unix_log2(double x)
562 #ifdef HAVE_LOG2
563 return log2(x);
564 #else
565 return log(x) / log(2);
566 #endif
569 /*********************************************************************
570 * log2f
572 static float CDECL unix_log2f(float x)
574 #ifdef HAVE_LOG2F
575 return log2f(x);
576 #else
577 return unix_log2(x);
578 #endif
581 /*********************************************************************
582 * logb
584 static double CDECL unix_logb( double x )
586 return logb( x );
589 /*********************************************************************
590 * logbf
592 static float CDECL unix_logbf( float x )
594 return logbf( x );
597 /*********************************************************************
598 * lrint
600 static int CDECL unix_lrint(double x)
602 #ifdef HAVE_LRINT
603 return lrint(x);
604 #else
605 return x >= 0 ? floor(x + 0.5) : ceil(x - 0.5);
606 #endif
609 /*********************************************************************
610 * lrintf
612 static int CDECL unix_lrintf(float x)
614 #ifdef HAVE_LRINTF
615 return lrintf(x);
616 #else
617 return x >= 0 ? floorf(x + 0.5) : ceilf(x - 0.5);
618 #endif
621 /*********************************************************************
622 * modf
624 static double CDECL unix_modf( double x, double *iptr )
626 return modf( x, iptr );
629 /*********************************************************************
630 * modff
632 static float CDECL unix_modff( float x, float *iptr )
634 return modff( x, iptr );
637 /*********************************************************************
638 * nearbyint
640 static double CDECL unix_nearbyint(double num)
642 #ifdef HAVE_NEARBYINT
643 return nearbyint(num);
644 #else
645 return num >= 0 ? floor(num + 0.5) : ceil(num - 0.5);
646 #endif
649 /*********************************************************************
650 * nearbyintf
652 static float CDECL unix_nearbyintf(float num)
654 #ifdef HAVE_NEARBYINTF
655 return nearbyintf(num);
656 #else
657 return unix_nearbyint(num);
658 #endif
661 /*********************************************************************
662 * nextafter
664 static double CDECL unix_nextafter(double num, double next)
666 return nextafter(num,next);
669 /*********************************************************************
670 * nextafterf
672 static float CDECL unix_nextafterf(float num, float next)
674 return nextafterf(num,next);
677 /*********************************************************************
678 * nexttoward
680 static double CDECL unix_nexttoward(double num, double next)
682 #ifdef HAVE_NEXTTOWARD
683 return nexttoward(num, next);
684 #else
685 FIXME("not implemented\n");
686 return 0;
687 #endif
690 /*********************************************************************
691 * nexttowardf
693 static float CDECL unix_nexttowardf(float num, double next)
695 #ifdef HAVE_NEXTTOWARDF
696 return nexttowardf(num, next);
697 #else
698 FIXME("not implemented\n");
699 return 0;
700 #endif
703 /*********************************************************************
704 * pow
706 static double CDECL unix_pow( double x, double y )
708 return pow( x, y );
711 /*********************************************************************
712 * powf
714 static float CDECL unix_powf( float x, float y )
716 return powf( x, y );
719 /*********************************************************************
720 * remainder
722 static double CDECL unix_remainder(double x, double y)
724 #ifdef HAVE_REMAINDER
725 return remainder(x, y);
726 #else
727 FIXME( "not implemented\n" );
728 return 0;
729 #endif
732 /*********************************************************************
733 * remainderf
735 static float CDECL unix_remainderf(float x, float y)
737 #ifdef HAVE_REMAINDERF
738 return remainderf(x, y);
739 #else
740 FIXME( "not implemented\n" );
741 return 0;
742 #endif
745 /*********************************************************************
746 * remquo
748 static double CDECL unix_remquo(double x, double y, int *quo)
750 #ifdef HAVE_REMQUO
751 return remquo(x, y, quo);
752 #else
753 FIXME( "not implemented\n" );
754 return 0;
755 #endif
758 /*********************************************************************
759 * remquof
761 static float CDECL unix_remquof(float x, float y, int *quo)
763 #ifdef HAVE_REMQUOF
764 return remquof(x, y, quo);
765 #else
766 FIXME( "not implemented\n" );
767 return 0;
768 #endif
771 /*********************************************************************
772 * rint
774 static double CDECL unix_rint(double x)
776 #ifdef HAVE_RINT
777 return rint(x);
778 #else
779 return x >= 0 ? floor(x + 0.5) : ceil(x - 0.5);
780 #endif
783 /*********************************************************************
784 * rintf
786 static float CDECL unix_rintf(float x)
788 #ifdef HAVE_RINTF
789 return rintf(x);
790 #else
791 return x >= 0 ? floorf(x + 0.5) : ceilf(x - 0.5);
792 #endif
795 /*********************************************************************
796 * round
798 static double CDECL unix_round(double x)
800 #ifdef HAVE_ROUND
801 return round(x);
802 #else
803 return unix_rint(x);
804 #endif
807 /*********************************************************************
808 * roundf
810 static float CDECL unix_roundf(float x)
812 #ifdef HAVE_ROUNDF
813 return roundf(x);
814 #else
815 return unix_round(x);
816 #endif
819 /*********************************************************************
820 * lround
822 static int CDECL unix_lround(double x)
824 #ifdef HAVE_LROUND
825 return lround(x);
826 #else
827 return unix_round(x);
828 #endif
831 /*********************************************************************
832 * lroundf
834 static int CDECL unix_lroundf(float x)
836 #ifdef HAVE_LROUNDF
837 return lroundf(x);
838 #else
839 return unix_lround(x);
840 #endif
843 /*********************************************************************
844 * llround
846 static __int64 CDECL unix_llround(double x)
848 #ifdef HAVE_LLROUND
849 return llround(x);
850 #else
851 return unix_round(x);
852 #endif
855 /*********************************************************************
856 * llroundf
858 static __int64 CDECL unix_llroundf(float x)
860 #ifdef HAVE_LLROUNDF
861 return llroundf(x);
862 #else
863 return unix_llround(x);
864 #endif
867 /*********************************************************************
868 * sin
870 static double CDECL unix_sin( double x )
872 return sin( x );
875 /*********************************************************************
876 * sinf
878 static float CDECL unix_sinf( float x )
880 return sinf( x );
883 /*********************************************************************
884 * sinh
886 static double CDECL unix_sinh( double x )
888 return sinh( x );
891 /*********************************************************************
892 * sinhf
894 static float CDECL unix_sinhf( float x )
896 return sinhf( x );
899 /*********************************************************************
900 * tan
902 static double CDECL unix_tan( double x )
904 return tan( x );
907 /*********************************************************************
908 * tanf
910 static float CDECL unix_tanf( float x )
912 return tanf( x );
915 /*********************************************************************
916 * tanh
918 static double CDECL unix_tanh( double x )
920 return tanh( x );
923 /*********************************************************************
924 * tanhf
926 static float CDECL unix_tanhf( float x )
928 return tanhf( x );
931 /*********************************************************************
932 * tgamma
934 static double CDECL unix_tgamma(double x)
936 #ifdef HAVE_TGAMMA
937 return tgamma(x);
938 #else
939 FIXME( "not implemented\n" );
940 return 0;
941 #endif
944 /*********************************************************************
945 * trunc
947 static double CDECL unix_trunc(double x)
949 #ifdef HAVE_TRUNC
950 return trunc(x);
951 #else
952 return (x > 0) ? floor(x) : ceil(x);
953 #endif
956 /*********************************************************************
957 * truncf
959 static float CDECL unix_truncf(float x)
961 #ifdef HAVE_TRUNCF
962 return truncf(x);
963 #else
964 return unix_trunc(x);
965 #endif
968 /*********************************************************************
969 * tgammaf
971 static float CDECL unix_tgammaf(float x)
973 #ifdef HAVE_TGAMMAF
974 return tgammaf(x);
975 #else
976 FIXME( "not implemented\n" );
977 return 0;
978 #endif
981 /*********************************************************************
982 * y0
984 static double CDECL unix_y0(double num)
986 #ifdef HAVE_Y0
987 return y0(num);
988 #else
989 FIXME("not implemented\n");
990 return 0;
991 #endif
994 /*********************************************************************
995 * y1
997 static double CDECL unix_y1(double num)
999 #ifdef HAVE_Y1
1000 return y1(num);
1001 #else
1002 FIXME("not implemented\n");
1003 return 0;
1004 #endif
1007 /*********************************************************************
1008 * yn
1010 static double CDECL unix_yn(int order, double num)
1012 #ifdef HAVE_YN
1013 return yn(order,num);
1014 #else
1015 FIXME("not implemented\n");
1016 return 0;
1017 #endif
1020 static const struct unix_funcs funcs =
1022 unix_acosh,
1023 unix_acoshf,
1024 unix_asinh,
1025 unix_asinhf,
1026 unix_atanh,
1027 unix_atanhf,
1028 unix_cbrt,
1029 unix_cbrtf,
1030 unix_ceil,
1031 unix_ceilf,
1032 unix_cos,
1033 unix_cosf,
1034 unix_cosh,
1035 unix_coshf,
1036 unix_erf,
1037 unix_erfc,
1038 unix_erfcf,
1039 unix_erff,
1040 unix_exp,
1041 unix_expf,
1042 unix_exp2,
1043 unix_exp2f,
1044 unix_expm1,
1045 unix_expm1f,
1046 unix_floor,
1047 unix_floorf,
1048 unix_fma,
1049 unix_fmaf,
1050 unix_fmod,
1051 unix_fmodf,
1052 unix_frexp,
1053 unix_frexpf,
1054 unix_hypot,
1055 unix_hypotf,
1056 unix_j0,
1057 unix_j1,
1058 unix_jn,
1059 unix_ldexp,
1060 unix_lgamma,
1061 unix_lgammaf,
1062 unix_llrint,
1063 unix_llrintf,
1064 unix_llround,
1065 unix_llroundf,
1066 unix_log,
1067 unix_logf,
1068 unix_log10,
1069 unix_log10f,
1070 unix_log1p,
1071 unix_log1pf,
1072 unix_log2,
1073 unix_log2f,
1074 unix_logb,
1075 unix_logbf,
1076 unix_lrint,
1077 unix_lrintf,
1078 unix_lround,
1079 unix_lroundf,
1080 unix_modf,
1081 unix_modff,
1082 unix_nearbyint,
1083 unix_nearbyintf,
1084 unix_nextafter,
1085 unix_nextafterf,
1086 unix_nexttoward,
1087 unix_nexttowardf,
1088 unix_pow,
1089 unix_powf,
1090 unix_remainder,
1091 unix_remainderf,
1092 unix_remquo,
1093 unix_remquof,
1094 unix_rint,
1095 unix_rintf,
1096 unix_round,
1097 unix_roundf,
1098 unix_sin,
1099 unix_sinf,
1100 unix_sinh,
1101 unix_sinhf,
1102 unix_tan,
1103 unix_tanf,
1104 unix_tanh,
1105 unix_tanhf,
1106 unix_tgamma,
1107 unix_tgammaf,
1108 unix_trunc,
1109 unix_truncf,
1110 unix_y0,
1111 unix_y1,
1112 unix_yn
1115 NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )
1117 if (reason != DLL_PROCESS_ATTACH) return STATUS_SUCCESS;
1118 TRACE( "\n" );
1119 *(const struct unix_funcs **)ptr_out = &funcs;
1120 return STATUS_SUCCESS;