ReactOS 0.4.16-dev-2104-gb84fa49
math.c
Go to the documentation of this file.
1/*
2 * msvcrt.dll math functions
3 *
4 * Copyright 2000 Jon Griffiths
5 *
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.
10 *
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.
15 *
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
19 *
20 *
21 * For functions copied from musl libc (http://musl.libc.org/):
22 * ====================================================
23 * Copyright 2005-2020 Rich Felker, et al.
24 *
25 * Permission is hereby granted, free of charge, to any person obtaining
26 * a copy of this software and associated documentation files (the
27 * "Software"), to deal in the Software without restriction, including
28 * without limitation the rights to use, copy, modify, merge, publish,
29 * distribute, sublicense, and/or sell copies of the Software, and to
30 * permit persons to whom the Software is furnished to do so, subject to
31 * the following conditions:
32 *
33 * The above copyright notice and this permission notice shall be
34 * included in all copies or substantial portions of the Software.
35 * ====================================================
36 */
37
38#include <assert.h>
39#include <complex.h>
40#include <stdio.h>
41#include <fenv.h>
42#include <fpieee.h>
43#include <limits.h>
44#include <locale.h>
45#include <math.h>
46
47#include "msvcrt.h"
48#include "winternl.h"
49
50#include "wine/asm.h"
51#include "wine/debug.h"
52
54
55#ifdef _MSC_VER
56#pragma function(abs,labs,div,ldiv)
57#endif
58
59#undef div
60#undef ldiv
61
62#define _DOMAIN 1 /* domain error in argument */
63#define _SING 2 /* singularity */
64#define _OVERFLOW 3 /* range overflow */
65#define _UNDERFLOW 4 /* range underflow */
66
68
70
73
75{
77#if _MSVCR_VER <=71
79#else
81#endif
82}
83
84static inline double ret_nan( BOOL update_sw )
85{
86 double x = 1.0;
87 if (!update_sw) return -NAN;
88 return (x - x) / (x - x);
89}
90
91#define SET_X87_CW(MASK) \
92 "subl $4, %esp\n\t" \
93 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") \
94 "fnstcw (%esp)\n\t" \
95 "movw (%esp), %ax\n\t" \
96 "movw %ax, 2(%esp)\n\t" \
97 "testw $" #MASK ", %ax\n\t" \
98 "jz 1f\n\t" \
99 "andw $~" #MASK ", %ax\n\t" \
100 "movw %ax, 2(%esp)\n\t" \
101 "fldcw 2(%esp)\n\t" \
102 "1:\n\t"
103
104#define RESET_X87_CW \
105 "movw (%esp), %ax\n\t" \
106 "cmpw %ax, 2(%esp)\n\t" \
107 "je 1f\n\t" \
108 "fstpl 8(%esp)\n\t" \
109 "fldcw (%esp)\n\t" \
110 "fldl 8(%esp)\n\t" \
111 "fwait\n\t" \
112 "1:\n\t" \
113 "addl $4, %esp\n\t" \
114 __ASM_CFI(".cfi_adjust_cfa_offset -4\n\t")
115
116/*********************************************************************
117 * _matherr (CRTDLL.@)
118 */
120{
121 return 0;
122}
123
124
125double math_error(int type, const char *name, double arg1, double arg2, double retval)
126{
127 struct _exception exception = {type, (char *)name, arg1, arg2, retval};
128
129 TRACE("(%d, %s, %g, %g, %g)\n", type, debugstr_a(name), arg1, arg2, retval);
130
132 return exception.retval;
133
134 switch (type)
135 {
136 case 0:
137 /* don't set errno */
138 break;
139 case _DOMAIN:
140 *_errno() = EDOM;
141 break;
142 case _SING:
143 case _OVERFLOW:
144 *_errno() = ERANGE;
145 break;
146 case _UNDERFLOW:
147 /* don't set errno */
148 break;
149 default:
150 ERR("Unhandled math error!\n");
151 }
152
153 return exception.retval;
154}
155
156/*********************************************************************
157 * __setusermatherr (MSVCRT.@)
158 */
160{
162 TRACE("new matherr handler %p\n", func);
163}
164
165/*********************************************************************
166 * _set_SSE2_enable (MSVCRT.@)
167 */
169{
171 return sse2_enabled;
172}
173
174#if defined(_WIN64)
175# if _MSVCR_VER>=140
176/*********************************************************************
177 * _get_FMA3_enable (UCRTBASE.@)
178 */
179int CDECL _get_FMA3_enable(void)
180{
181 FIXME("() stub\n");
182 return 0;
183}
184# endif
185
186# if _MSVCR_VER>=120
187/*********************************************************************
188 * _set_FMA3_enable (MSVCR120.@)
189 */
191{
192 FIXME("(%x) stub\n", flag);
193 return 0;
194}
195# endif
196#endif
197
198#if !defined(__i386__) || _MSVCR_VER>=120
199
200/*********************************************************************
201 * _chgsignf (MSVCRT.@)
202 */
203float CDECL _chgsignf( float num )
204{
205 union { float f; UINT32 i; } u = { num };
206 u.i ^= 0x80000000;
207 return u.f;
208}
209
210#endif
211
212#ifndef __i386__
213
214/*********************************************************************
215 * _fpclassf (MSVCRT.@)
216 */
217int CDECL _fpclassf( float num )
218{
219 union { float f; UINT32 i; } u = { num };
220 int e = u.i >> 23 & 0xff;
221 int s = u.i >> 31;
222
223 switch (e)
224 {
225 case 0:
226 if (u.i << 1) return s ? _FPCLASS_ND : _FPCLASS_PD;
227 return s ? _FPCLASS_NZ : _FPCLASS_PZ;
228 case 0xff:
229 if (u.i << 9) return ((u.i >> 22) & 1) ? _FPCLASS_QNAN : _FPCLASS_SNAN;
230 return s ? _FPCLASS_NINF : _FPCLASS_PINF;
231 default:
232 return s ? _FPCLASS_NN : _FPCLASS_PN;
233 }
234}
235
236/*********************************************************************
237 * _finitef (MSVCRT.@)
238 */
239int CDECL _finitef( float num )
240{
241 union { float f; UINT32 i; } u = { num };
242 return (u.i & 0x7fffffff) < 0x7f800000;
243}
244
245/*********************************************************************
246 * _isnanf (MSVCRT.@)
247 */
248int CDECL _isnanf( float num )
249{
250 union { float f; UINT32 i; } u = { num };
251 return (u.i & 0x7fffffff) > 0x7f800000;
252}
253
254/*********************************************************************
255 * atanf (MSVCRT.@)
256 */
257#if _MSVCR_VER == 0 /* other versions call atanf() directly */
258float CDECL MSVCRT_atanf( float x )
259{
260 if (isnan(x)) return math_error(_DOMAIN, "atanf", x, 0, x);
261 return atanf( x );
262}
263#endif
264
265#ifndef __i386__
266extern short CDECL _fdclass(float x);
267
268static BOOL sqrtf_validate( float *x )
269{
270 short c = _fdclass(*x);
271
272 if (c == FP_ZERO) return FALSE;
273 if (c == FP_NAN) return FALSE;
274 if (signbit(*x))
275 {
276 *x = math_error(_DOMAIN, "sqrtf", *x, 0, ret_nan(TRUE));
277 return FALSE;
278 }
279 if (c == FP_INFINITE) return FALSE;
280 return TRUE;
281}
282
283#ifdef __arm64ec__
284static float __attribute__((naked)) CDECL asm_sqrtf(float x)
285{
286 asm( "fsqrt s0,s0; ret" );
287}
288#elif defined __aarch64__
289float CDECL asm_sqrtf(float);
290__ASM_GLOBAL_FUNC( asm_sqrtf, "fsqrt s0,s0; ret" )
291#elif defined __arm__
292float CDECL asm_sqrtf(float);
293__ASM_GLOBAL_FUNC( asm_sqrtf, "vsqrt s0,s0; bx lr" )
294#elif defined __x86_64__
295float CDECL asm_sqrtf(float);
296__ASM_GLOBAL_FUNC( asm_sqrtf, "sqrtss %xmm0, %xmm0; ret" )
297#endif
298#endif
299
300/*********************************************************************
301 * sqrtf (MSVCRT.@)
302 */
303float CDECL MSVCRT_sqrtf( float x )
304{
305#ifndef __i386__
306 if (!sqrtf_validate(&x))
307 return x;
308
309 return asm_sqrtf(x);
310#else
311 return sqrtf( x );
312#endif
313}
314
315/*********************************************************************
316 * tanhf (MSVCRT.@)
317 */
318#if _MSVCR_VER < 140 /* other versions call tanhf() directly */
319float CDECL MSVCRT_tanhf( float x )
320{
321 if (isnan( x ))
322 {
323 *(UINT32*)&x |= 0x400000;
324 return math_error(_DOMAIN, "tanhf", x, 0, x);
325 }
326 return tanhf( x );
327}
328#endif
329
330#endif
331
332/*********************************************************************
333 * asin (MSVCRT.@)
334 */
335#ifdef __i386__
336double CDECL x87_asin(double);
337__ASM_GLOBAL_FUNC( x87_asin,
338 "fldl 4(%esp)\n\t"
339 SET_X87_CW(~0x37f)
340 "fld %st\n\t"
341 "fld1\n\t"
342 "fsubp\n\t"
343 "fld1\n\t"
344 "fadd %st(2)\n\t"
345 "fmulp\n\t"
346 "fsqrt\n\t"
347 "fpatan\n\t"
349 "ret" )
350#endif
351
352double CDECL MSVCRT_asin( double x )
353{
354#ifdef __i386__
355 unsigned int x87_cw, sse2_cw;
356 unsigned int hx = *(ULONGLONG*)&x >> 32;
357 unsigned int ix = hx & 0x7fffffff;
358
359 if (isnan(x)) return math_error(_DOMAIN, "asin", x, 0, x);
360
361 /* |x| < 1 */
362 if (ix < 0x3ff00000)
363 {
364 __control87_2(0, 0, &x87_cw, &sse2_cw);
365 if (!sse2_enabled || (x87_cw & _MCW_EM) != _MCW_EM
366 || (sse2_cw & (_MCW_EM | _MCW_RC)) != _MCW_EM)
367 return x87_asin(x);
368 }
369#else
370 if (isnan(x)) return x;
371#endif
372
373 return asin( x );
374}
375
376/*********************************************************************
377 * atan (MSVCRT.@)
378 */
379#if _MSVCR_VER == 0 /* other versions call atan() directly */
380double CDECL MSVCRT_atan( double x )
381{
382 if (isnan(x)) return math_error(_DOMAIN, "atan", x, 0, x);
383 return atan( x );
384}
385#endif
386
387/*********************************************************************
388 * exp (MSVCRT.@)
389 */
390#if _MSVCR_VER == 0 /* other versions call exp() directly */
391double CDECL MSVCRT_exp( double x )
392{
393 if (isnan( x )) return math_error(_DOMAIN, "exp", x, 0, 1.0 + x);
394 return exp( x );
395}
396#endif
397
398extern short CDECL _dclass(double x);
399
400static BOOL sqrt_validate( double *x, BOOL update_sw )
401{
402 short c = _dclass(*x);
403
404 if (c == FP_ZERO) return FALSE;
405 if (c == FP_NAN)
406 {
407#ifdef __i386__
408 if (update_sw)
409 *x = math_error(_DOMAIN, "sqrt", *x, 0, *x);
410#else
411 /* set signaling bit */
412 *(ULONGLONG*)x |= 0x8000000000000ULL;
413#endif
414 return FALSE;
415 }
416 if (signbit(*x))
417 {
418 *x = math_error(_DOMAIN, "sqrt", *x, 0, ret_nan(update_sw));
419 return FALSE;
420 }
421 if (c == FP_INFINITE) return FALSE;
422 return TRUE;
423}
424
425#ifdef __arm64ec__
426static double __attribute__((naked)) CDECL asm_sqrt(double x)
427{
428 asm( "fsqrt d0,d0; ret" );
429}
430#elif defined __aarch64__
431double CDECL asm_sqrt(double);
432__ASM_GLOBAL_FUNC( asm_sqrt, "fsqrt d0,d0; ret" )
433#elif defined __arm__
434double CDECL asm_sqrt(double);
435__ASM_GLOBAL_FUNC( asm_sqrt, "vsqrt d0,d0; bx lr" )
436#elif defined __x86_64__
437double CDECL asm_sqrt(double);
438__ASM_GLOBAL_FUNC( asm_sqrt, "sqrtsd %xmm0, %xmm0; ret" )
439#elif defined __i386__
440double CDECL asm_sqrt(double);
441__ASM_GLOBAL_FUNC( asm_sqrt,
442 "fldl 4(%esp)\n\t"
443 SET_X87_CW(0xc00)
444 "fsqrt\n\t"
446 "ret" )
447#endif
448
449/*********************************************************************
450 * sqrt (MSVCRT.@)
451 */
452double CDECL MSVCRT_sqrt( double x )
453{
454 if (!sqrt_validate(&x, TRUE))
455 return x;
456
457 return asm_sqrt(x);
458}
459
460/*********************************************************************
461 * tanh (MSVCRT.@)
462 */
463#if _MSVCR_VER < 140 /* other versions call tanh() directly */
464double CDECL MSVCRT_tanh( double x )
465{
466 if (isnan( x ))
467 {
468 *(UINT64*)&x |= 0x0008000000000000ULL;
469 return math_error(_DOMAIN, "tanh", x, 0, x);
470 }
471 return tanh( x );
472}
473#endif
474
475#if (defined(__GNUC__) || defined(__clang__)) && defined(__i386__)
476
477#define CREATE_FPU_FUNC1(name, call) \
478 __ASM_GLOBAL_FUNC(name, \
479 "pushl %ebp\n\t" \
480 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") \
481 __ASM_CFI(".cfi_rel_offset %ebp,0\n\t") \
482 "movl %esp, %ebp\n\t" \
483 __ASM_CFI(".cfi_def_cfa_register %ebp\n\t") \
484 "subl $68, %esp\n\t" /* sizeof(double)*8 + sizeof(int) */ \
485 "fstpl (%esp)\n\t" /* store function argument */ \
486 "fwait\n\t" \
487 "movl $1, %ecx\n\t" /* empty FPU stack */ \
488 "1:\n\t" \
489 "fxam\n\t" \
490 "fstsw %ax\n\t" \
491 "and $0x4500, %ax\n\t" \
492 "cmp $0x4100, %ax\n\t" \
493 "je 2f\n\t" \
494 "fstpl (%esp,%ecx,8)\n\t" \
495 "fwait\n\t" \
496 "incl %ecx\n\t" \
497 "jmp 1b\n\t" \
498 "2:\n\t" \
499 "movl %ecx, -4(%ebp)\n\t" \
500 "call " __ASM_NAME( #call ) "\n\t" \
501 "movl -4(%ebp), %ecx\n\t" \
502 "fstpl (%esp)\n\t" /* save result */ \
503 "3:\n\t" /* restore FPU stack */ \
504 "decl %ecx\n\t" \
505 "fldl (%esp,%ecx,8)\n\t" \
506 "cmpl $0, %ecx\n\t" \
507 "jne 3b\n\t" \
508 "leave\n\t" \
509 __ASM_CFI(".cfi_def_cfa %esp,4\n\t") \
510 __ASM_CFI(".cfi_same_value %ebp\n\t") \
511 "ret")
512
513#define CREATE_FPU_FUNC2(name, call) \
514 __ASM_GLOBAL_FUNC(name, \
515 "pushl %ebp\n\t" \
516 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") \
517 __ASM_CFI(".cfi_rel_offset %ebp,0\n\t") \
518 "movl %esp, %ebp\n\t" \
519 __ASM_CFI(".cfi_def_cfa_register %ebp\n\t") \
520 "subl $68, %esp\n\t" /* sizeof(double)*8 + sizeof(int) */ \
521 "fstpl 8(%esp)\n\t" /* store function argument */ \
522 "fwait\n\t" \
523 "fstpl (%esp)\n\t" \
524 "fwait\n\t" \
525 "movl $2, %ecx\n\t" /* empty FPU stack */ \
526 "1:\n\t" \
527 "fxam\n\t" \
528 "fstsw %ax\n\t" \
529 "and $0x4500, %ax\n\t" \
530 "cmp $0x4100, %ax\n\t" \
531 "je 2f\n\t" \
532 "fstpl (%esp,%ecx,8)\n\t" \
533 "fwait\n\t" \
534 "incl %ecx\n\t" \
535 "jmp 1b\n\t" \
536 "2:\n\t" \
537 "movl %ecx, -4(%ebp)\n\t" \
538 "call " __ASM_NAME( #call ) "\n\t" \
539 "movl -4(%ebp), %ecx\n\t" \
540 "fstpl 8(%esp)\n\t" /* save result */ \
541 "3:\n\t" /* restore FPU stack */ \
542 "decl %ecx\n\t" \
543 "fldl (%esp,%ecx,8)\n\t" \
544 "cmpl $1, %ecx\n\t" \
545 "jne 3b\n\t" \
546 "leave\n\t" \
547 __ASM_CFI(".cfi_def_cfa %esp,4\n\t") \
548 __ASM_CFI(".cfi_same_value %ebp\n\t") \
549 "ret")
550
551CREATE_FPU_FUNC1(_CIacos, acos)
552CREATE_FPU_FUNC1(_CIasin, asin)
553CREATE_FPU_FUNC1(_CIatan, atan)
554CREATE_FPU_FUNC2(_CIatan2, atan2)
555CREATE_FPU_FUNC1(_CIcos, cos)
556CREATE_FPU_FUNC1(_CIcosh, cosh)
557CREATE_FPU_FUNC1(_CIexp, exp)
558CREATE_FPU_FUNC2(_CIfmod, fmod)
559CREATE_FPU_FUNC1(_CIlog, log)
560CREATE_FPU_FUNC1(_CIlog10, log10)
561CREATE_FPU_FUNC2(_CIpow, pow)
562CREATE_FPU_FUNC1(_CIsin, sin)
563CREATE_FPU_FUNC1(_CIsinh, sinh)
564CREATE_FPU_FUNC1(_CIsqrt, sqrt)
565CREATE_FPU_FUNC1(_CItan, tan)
566CREATE_FPU_FUNC1(_CItanh, tanh)
567
569 "pushl %ebp\n\t"
570 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
571 __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
572 "movl %esp, %ebp\n\t"
573 __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
574 "subl $12, %esp\n\t" /* sizeof(LONGLONG) + 2*sizeof(WORD) */
575 "fnstcw (%esp)\n\t"
576 "mov (%esp), %ax\n\t"
577 "or $0xc00, %ax\n\t"
578 "mov %ax, 2(%esp)\n\t"
579 "fldcw 2(%esp)\n\t"
580 "fistpq 4(%esp)\n\t"
581 "fldcw (%esp)\n\t"
582 "movl 4(%esp), %eax\n\t"
583 "movl 8(%esp), %edx\n\t"
584 "leave\n\t"
585 __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
586 __ASM_CFI(".cfi_same_value %ebp\n\t")
587 "ret")
588
589#endif /* (defined(__GNUC__) || defined(__clang__)) && defined(__i386__) */
590
591#ifndef __REACTOS__
592/*********************************************************************
593 * _fpclass (MSVCRT.@)
594 */
595int CDECL _fpclass(double num)
596{
597 union { double f; UINT64 i; } u = { num };
598 int e = u.i >> 52 & 0x7ff;
599 int s = u.i >> 63;
600
601 switch (e)
602 {
603 case 0:
604 if (u.i << 1) return s ? _FPCLASS_ND : _FPCLASS_PD;
605 return s ? _FPCLASS_NZ : _FPCLASS_PZ;
606 case 0x7ff:
607 if (u.i << 12) return ((u.i >> 51) & 1) ? _FPCLASS_QNAN : _FPCLASS_SNAN;
608 return s ? _FPCLASS_NINF : _FPCLASS_PINF;
609 default:
610 return s ? _FPCLASS_NN : _FPCLASS_PN;
611 }
612}
613#endif // __REACTOS__
614
615/*********************************************************************
616 * _rotl (MSVCRT.@)
617 */
618unsigned int CDECL MSVCRT__rotl(unsigned int num, int shift)
619{
620 shift &= 31;
621 return (num << shift) | (num >> (32-shift));
622}
623
624/*********************************************************************
625 * _lrotl (MSVCRT.@)
626 */
628{
629 shift &= 0x1f;
630 return (num << shift) | (num >> (32-shift));
631}
632
633/*********************************************************************
634 * _lrotr (MSVCRT.@)
635 */
637{
638 shift &= 0x1f;
639 return (num >> shift) | (num << (32-shift));
640}
641
642/*********************************************************************
643 * _rotr (MSVCRT.@)
644 */
645unsigned int CDECL MSVCRT__rotr(unsigned int num, int shift)
646{
647 shift &= 0x1f;
648 return (num >> shift) | (num << (32-shift));
649}
650
651/*********************************************************************
652 * _rotl64 (MSVCRT.@)
653 */
655{
656 shift &= 63;
657 return (num << shift) | (num >> (64-shift));
658}
659
660/*********************************************************************
661 * _rotr64 (MSVCRT.@)
662 */
664{
665 shift &= 63;
666 return (num >> shift) | (num << (64-shift));
667}
668
669/*********************************************************************
670 * abs (MSVCRT.@)
671 */
672int CDECL abs( int n )
673{
674 return n >= 0 ? n : -n;
675}
676
677/*********************************************************************
678 * labs (MSVCRT.@)
679 */
681{
682 return n >= 0 ? n : -n;
683}
684
685#if _MSVCR_VER>=100
686/*********************************************************************
687 * llabs (MSVCR100.@)
688 */
690{
691 return n >= 0 ? n : -n;
692}
693#endif
694
695#if _MSVCR_VER>=120
696/*********************************************************************
697 * imaxabs (MSVCR120.@)
698 */
700{
701 return n >= 0 ? n : -n;
702}
703#endif
704
705/*********************************************************************
706 * _abs64 (MSVCRT.@)
707 */
708#ifdef _MSC_VER
709#pragma function(_abs64)
710#endif
712{
713 return n >= 0 ? n : -n;
714}
715
716#if defined(__i386__) || defined(__x86_64__)
717#ifdef _MSC_VER
718#define get_mxcsr() _mm_getcsr()
719#define set_mxcsr(val) _mm_setcsr(val)
720#else
721static unsigned int get_mxcsr(void)
722{
723 unsigned int ret;
724#ifdef __arm64ec__
725 extern NTSTATUS (*__os_arm64x_get_x64_information)(ULONG,void*,void*);
726 __os_arm64x_get_x64_information( 0, &ret, NULL );
727#else
728 __asm__ __volatile__( "stmxcsr %0" : "=m" (ret) );
729#endif
730 return ret;
731}
732
733static void set_mxcsr( unsigned int val )
734{
735#ifdef __arm64ec__
736 extern NTSTATUS (*__os_arm64x_set_x64_information)(ULONG,ULONG_PTR,void*);
737 __os_arm64x_set_x64_information( 0, val, NULL );
738#else
739 __asm__ __volatile__( "ldmxcsr %0" : : "m" (val) );
740#endif
741}
742#endif
743
744#ifdef __REACTOS__
746#endif
747static void _setfp_sse( unsigned int *cw, unsigned int cw_mask,
748 unsigned int *sw, unsigned int sw_mask )
749{
750#if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)
751 unsigned int old_fpword, fpword = get_mxcsr();
752 unsigned int flags;
753
754 old_fpword = fpword;
755
756 cw_mask &= _MCW_EM | _MCW_RC | _MCW_DN;
757 sw_mask &= _MCW_EM;
758
759 if (sw)
760 {
761 flags = 0;
762 if (fpword & 0x1) flags |= _SW_INVALID;
763 if (fpword & 0x2) flags |= _SW_DENORMAL;
764 if (fpword & 0x4) flags |= _SW_ZERODIVIDE;
765 if (fpword & 0x8) flags |= _SW_OVERFLOW;
766 if (fpword & 0x10) flags |= _SW_UNDERFLOW;
767 if (fpword & 0x20) flags |= _SW_INEXACT;
768
769 *sw = (flags & ~sw_mask) | (*sw & sw_mask);
770 TRACE("sse2 update sw %08x to %08x\n", flags, *sw);
771 fpword &= ~0x3f;
772 if (*sw & _SW_INVALID) fpword |= 0x1;
773 if (*sw & _SW_DENORMAL) fpword |= 0x2;
774 if (*sw & _SW_ZERODIVIDE) fpword |= 0x4;
775 if (*sw & _SW_OVERFLOW) fpword |= 0x8;
776 if (*sw & _SW_UNDERFLOW) fpword |= 0x10;
777 if (*sw & _SW_INEXACT) fpword |= 0x20;
778 *sw = flags;
779 }
780
781 if (cw)
782 {
783 flags = 0;
784 if (fpword & 0x80) flags |= _EM_INVALID;
785 if (fpword & 0x100) flags |= _EM_DENORMAL;
786 if (fpword & 0x200) flags |= _EM_ZERODIVIDE;
787 if (fpword & 0x400) flags |= _EM_OVERFLOW;
788 if (fpword & 0x800) flags |= _EM_UNDERFLOW;
789 if (fpword & 0x1000) flags |= _EM_INEXACT;
790 switch (fpword & 0x6000)
791 {
792 case 0x6000: flags |= _RC_UP|_RC_DOWN; break;
793 case 0x4000: flags |= _RC_UP; break;
794 case 0x2000: flags |= _RC_DOWN; break;
795 }
796 switch (fpword & 0x8040)
797 {
798 case 0x0040: flags |= _DN_FLUSH_OPERANDS_SAVE_RESULTS; break;
799 case 0x8000: flags |= _DN_SAVE_OPERANDS_FLUSH_RESULTS; break;
800 case 0x8040: flags |= _DN_FLUSH; break;
801 }
802
803 *cw = (flags & ~cw_mask) | (*cw & cw_mask);
804 TRACE("sse2 update cw %08x to %08x\n", flags, *cw);
805 fpword &= ~0xffc0;
806 if (*cw & _EM_INVALID) fpword |= 0x80;
807 if (*cw & _EM_DENORMAL) fpword |= 0x100;
808 if (*cw & _EM_ZERODIVIDE) fpword |= 0x200;
809 if (*cw & _EM_OVERFLOW) fpword |= 0x400;
810 if (*cw & _EM_UNDERFLOW) fpword |= 0x800;
811 if (*cw & _EM_INEXACT) fpword |= 0x1000;
812 switch (*cw & _MCW_RC)
813 {
814 case _RC_UP|_RC_DOWN: fpword |= 0x6000; break;
815 case _RC_UP: fpword |= 0x4000; break;
816 case _RC_DOWN: fpword |= 0x2000; break;
817 }
818 switch (*cw & _MCW_DN)
819 {
820 case _DN_FLUSH_OPERANDS_SAVE_RESULTS: fpword |= 0x0040; break;
821 case _DN_SAVE_OPERANDS_FLUSH_RESULTS: fpword |= 0x8000; break;
822 case _DN_FLUSH: fpword |= 0x8040; break;
823 }
824
825 /* clear status word if anything changes */
826 if (fpword != old_fpword && !sw)
827 {
828 TRACE("sse2 clear status word\n");
829 fpword &= ~0x3f;
830 }
831 }
832
833 if (fpword != old_fpword) set_mxcsr( fpword );
834#else
835 FIXME("not implemented\n");
836 if (cw) *cw = 0;
837 if (sw) *sw = 0;
838#endif
839}
840#endif
841
842static void _setfp( unsigned int *cw, unsigned int cw_mask,
843 unsigned int *sw, unsigned int sw_mask )
844{
845#if (defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)) && defined(__i386__)
846 unsigned long oldcw = 0, newcw = 0;
847 unsigned long oldsw = 0, newsw = 0;
848 unsigned int flags;
849
850 cw_mask &= _MCW_EM | _MCW_IC | _MCW_RC | _MCW_PC;
851 sw_mask &= _MCW_EM;
852
853 if (sw)
854 {
855#ifdef _MSC_VER
856 __asm { fstsw newsw }
857#else
858 __asm__ __volatile__( "fstsw %0" : "=m" (newsw) );
859#endif
860 oldsw = newsw;
861
862 flags = 0;
863 if (newsw & 0x1) flags |= _SW_INVALID;
864 if (newsw & 0x2) flags |= _SW_DENORMAL;
865 if (newsw & 0x4) flags |= _SW_ZERODIVIDE;
866 if (newsw & 0x8) flags |= _SW_OVERFLOW;
867 if (newsw & 0x10) flags |= _SW_UNDERFLOW;
868 if (newsw & 0x20) flags |= _SW_INEXACT;
869
870 *sw = (flags & ~sw_mask) | (*sw & sw_mask);
871 TRACE("x86 update sw %08x to %08x\n", flags, *sw);
872 newsw &= ~0x3f;
873 if (*sw & _SW_INVALID) newsw |= 0x1;
874 if (*sw & _SW_DENORMAL) newsw |= 0x2;
875 if (*sw & _SW_ZERODIVIDE) newsw |= 0x4;
876 if (*sw & _SW_OVERFLOW) newsw |= 0x8;
877 if (*sw & _SW_UNDERFLOW) newsw |= 0x10;
878 if (*sw & _SW_INEXACT) newsw |= 0x20;
879 *sw = flags;
880 }
881
882 if (cw)
883 {
884#ifdef _MSC_VER
885 __asm { fstcw newcw }
886#else
887 __asm__ __volatile__( "fstcw %0" : "=m" (newcw) );
888#endif
889 oldcw = newcw;
890
891 flags = 0;
892 if (newcw & 0x1) flags |= _EM_INVALID;
893 if (newcw & 0x2) flags |= _EM_DENORMAL;
894 if (newcw & 0x4) flags |= _EM_ZERODIVIDE;
895 if (newcw & 0x8) flags |= _EM_OVERFLOW;
896 if (newcw & 0x10) flags |= _EM_UNDERFLOW;
897 if (newcw & 0x20) flags |= _EM_INEXACT;
898 switch (newcw & 0xc00)
899 {
900 case 0xc00: flags |= _RC_UP|_RC_DOWN; break;
901 case 0x800: flags |= _RC_UP; break;
902 case 0x400: flags |= _RC_DOWN; break;
903 }
904 switch (newcw & 0x300)
905 {
906 case 0x0: flags |= _PC_24; break;
907 case 0x200: flags |= _PC_53; break;
908 case 0x300: flags |= _PC_64; break;
909 }
910 if (newcw & 0x1000) flags |= _IC_AFFINE;
911
912 *cw = (flags & ~cw_mask) | (*cw & cw_mask);
913 TRACE("x86 update cw %08x to %08x\n", flags, *cw);
914 newcw &= ~0x1f3f;
915 if (*cw & _EM_INVALID) newcw |= 0x1;
916 if (*cw & _EM_DENORMAL) newcw |= 0x2;
917 if (*cw & _EM_ZERODIVIDE) newcw |= 0x4;
918 if (*cw & _EM_OVERFLOW) newcw |= 0x8;
919 if (*cw & _EM_UNDERFLOW) newcw |= 0x10;
920 if (*cw & _EM_INEXACT) newcw |= 0x20;
921 switch (*cw & _MCW_RC)
922 {
923 case _RC_UP|_RC_DOWN: newcw |= 0xc00; break;
924 case _RC_UP: newcw |= 0x800; break;
925 case _RC_DOWN: newcw |= 0x400; break;
926 }
927 switch (*cw & _MCW_PC)
928 {
929 case _PC_64: newcw |= 0x300; break;
930 case _PC_53: newcw |= 0x200; break;
931 case _PC_24: newcw |= 0x0; break;
932 }
933 if (*cw & _IC_AFFINE) newcw |= 0x1000;
934 }
935
936 if (oldsw != newsw && (newsw & 0x3f))
937 {
938 struct {
939 WORD control_word;
940 WORD unused1;
941 WORD status_word;
942 WORD unused2;
943 WORD tag_word;
944 WORD unused3;
945 DWORD instruction_pointer;
946 WORD code_segment;
947 WORD unused4;
948 DWORD operand_addr;
949 WORD data_segment;
950 WORD unused5;
951 } fenv;
952
953 assert(cw);
954
955#ifdef _MSC_VER
956 __asm { fnstenv fenv }
957#else
958 __asm__ __volatile__( "fnstenv %0" : "=m" (fenv) );
959#endif
960 fenv.control_word = newcw;
961 fenv.status_word = newsw;
962#ifdef _MSC_VER
963 __asm { fldenv fenv }
964#else
965 __asm__ __volatile__( "fldenv %0" : : "m" (fenv) : "st", "st(1)",
966 "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)" );
967#endif
968 return;
969 }
970
971 if (oldsw != newsw)
972#ifdef _MSC_VER
973 __asm { fnclex }
974#else
975 __asm__ __volatile__( "fnclex" );
976#endif
977 if (oldcw != newcw)
978#ifdef _MSC_VER
979 __asm { fldcw newcw }
980#else
981 __asm__ __volatile__( "fldcw %0" : : "m" (newcw) );
982#endif
983#elif defined(__x86_64__)
984 _setfp_sse(cw, cw_mask, sw, sw_mask);
985#elif defined(__aarch64__)
986 ULONG_PTR old_fpsr = 0, fpsr = 0, old_fpcr = 0, fpcr = 0;
987 unsigned int flags;
988
989 cw_mask &= _MCW_EM | _MCW_RC;
990 sw_mask &= _MCW_EM;
991
992 if (sw)
993 {
994 __asm__ __volatile__( "mrs %0, fpsr" : "=r" (fpsr) );
995 old_fpsr = fpsr;
996
997 flags = 0;
998 if (fpsr & 0x1) flags |= _SW_INVALID;
999 if (fpsr & 0x2) flags |= _SW_ZERODIVIDE;
1000 if (fpsr & 0x4) flags |= _SW_OVERFLOW;
1001 if (fpsr & 0x8) flags |= _SW_UNDERFLOW;
1002 if (fpsr & 0x10) flags |= _SW_INEXACT;
1003 if (fpsr & 0x80) flags |= _SW_DENORMAL;
1004
1005 *sw = (flags & ~sw_mask) | (*sw & sw_mask);
1006 TRACE("aarch64 update sw %08x to %08x\n", flags, *sw);
1007 fpsr &= ~0x9f;
1008 if (*sw & _SW_INVALID) fpsr |= 0x1;
1009 if (*sw & _SW_ZERODIVIDE) fpsr |= 0x2;
1010 if (*sw & _SW_OVERFLOW) fpsr |= 0x4;
1011 if (*sw & _SW_UNDERFLOW) fpsr |= 0x8;
1012 if (*sw & _SW_INEXACT) fpsr |= 0x10;
1013 if (*sw & _SW_DENORMAL) fpsr |= 0x80;
1014 *sw = flags;
1015 }
1016
1017 if (cw)
1018 {
1019 __asm__ __volatile__( "mrs %0, fpcr" : "=r" (fpcr) );
1020 old_fpcr = fpcr;
1021
1022 flags = 0;
1023 if (!(fpcr & 0x100)) flags |= _EM_INVALID;
1024 if (!(fpcr & 0x200)) flags |= _EM_ZERODIVIDE;
1025 if (!(fpcr & 0x400)) flags |= _EM_OVERFLOW;
1026 if (!(fpcr & 0x800)) flags |= _EM_UNDERFLOW;
1027 if (!(fpcr & 0x1000)) flags |= _EM_INEXACT;
1028 if (!(fpcr & 0x8000)) flags |= _EM_DENORMAL;
1029 switch (fpcr & 0xc00000)
1030 {
1031 case 0x400000: flags |= _RC_UP; break;
1032 case 0x800000: flags |= _RC_DOWN; break;
1033 case 0xc00000: flags |= _RC_CHOP; break;
1034 }
1035
1036 *cw = (flags & ~cw_mask) | (*cw & cw_mask);
1037 TRACE("aarch64 update cw %08x to %08x\n", flags, *cw);
1038 fpcr &= ~0xc09f00ul;
1039 if (!(*cw & _EM_INVALID)) fpcr |= 0x100;
1040 if (!(*cw & _EM_ZERODIVIDE)) fpcr |= 0x200;
1041 if (!(*cw & _EM_OVERFLOW)) fpcr |= 0x400;
1042 if (!(*cw & _EM_UNDERFLOW)) fpcr |= 0x800;
1043 if (!(*cw & _EM_INEXACT)) fpcr |= 0x1000;
1044 if (!(*cw & _EM_DENORMAL)) fpcr |= 0x8000;
1045 switch (*cw & _MCW_RC)
1046 {
1047 case _RC_CHOP: fpcr |= 0xc00000; break;
1048 case _RC_UP: fpcr |= 0x400000; break;
1049 case _RC_DOWN: fpcr |= 0x800000; break;
1050 }
1051 }
1052
1053 /* mask exceptions if needed */
1054 if (old_fpcr != fpcr && ~(old_fpcr >> 8) & fpsr & 0x9f != fpsr & 0x9f)
1055 {
1056 ULONG_PTR mask = fpcr & ~0x9f00;
1057 __asm__ __volatile__( "msr fpcr, %0" :: "r" (mask) );
1058 }
1059
1060 if (old_fpsr != fpsr)
1061 __asm__ __volatile__( "msr fpsr, %0" :: "r" (fpsr) );
1062 if (old_fpcr != fpcr)
1063 __asm__ __volatile__( "msr fpcr, %0" :: "r" (fpcr) );
1064#elif defined(__arm__)
1065 DWORD old_fpscr, fpscr;
1066 unsigned int flags;
1067
1068 __asm__ __volatile__( "vmrs %0, fpscr" : "=r" (fpscr) );
1069 old_fpscr = fpscr;
1070
1071 cw_mask &= _MCW_EM | _MCW_RC;
1072 sw_mask &= _MCW_EM;
1073
1074 if (sw)
1075 {
1076 flags = 0;
1077 if (fpscr & 0x1) flags |= _SW_INVALID;
1078 if (fpscr & 0x2) flags |= _SW_ZERODIVIDE;
1079 if (fpscr & 0x4) flags |= _SW_OVERFLOW;
1080 if (fpscr & 0x8) flags |= _SW_UNDERFLOW;
1081 if (fpscr & 0x10) flags |= _SW_INEXACT;
1082 if (fpscr & 0x80) flags |= _SW_DENORMAL;
1083
1084 *sw = (flags & ~sw_mask) | (*sw & sw_mask);
1085 TRACE("arm update sw %08x to %08x\n", flags, *sw);
1086 fpscr &= ~0x9f;
1087 if (*sw & _SW_INVALID) fpscr |= 0x1;
1088 if (*sw & _SW_ZERODIVIDE) fpscr |= 0x2;
1089 if (*sw & _SW_OVERFLOW) fpscr |= 0x4;
1090 if (*sw & _SW_UNDERFLOW) fpscr |= 0x8;
1091 if (*sw & _SW_INEXACT) fpscr |= 0x10;
1092 if (*sw & _SW_DENORMAL) fpscr |= 0x80;
1093 *sw = flags;
1094 }
1095
1096 if (cw)
1097 {
1098 flags = 0;
1099 if (!(fpscr & 0x100)) flags |= _EM_INVALID;
1100 if (!(fpscr & 0x200)) flags |= _EM_ZERODIVIDE;
1101 if (!(fpscr & 0x400)) flags |= _EM_OVERFLOW;
1102 if (!(fpscr & 0x800)) flags |= _EM_UNDERFLOW;
1103 if (!(fpscr & 0x1000)) flags |= _EM_INEXACT;
1104 if (!(fpscr & 0x8000)) flags |= _EM_DENORMAL;
1105 switch (fpscr & 0xc00000)
1106 {
1107 case 0x400000: flags |= _RC_UP; break;
1108 case 0x800000: flags |= _RC_DOWN; break;
1109 case 0xc00000: flags |= _RC_CHOP; break;
1110 }
1111
1112 *cw = (flags & ~cw_mask) | (*cw & cw_mask);
1113 TRACE("arm update cw %08x to %08x\n", flags, *cw);
1114 fpscr &= ~0xc09f00ul;
1115 if (!(*cw & _EM_INVALID)) fpscr |= 0x100;
1116 if (!(*cw & _EM_ZERODIVIDE)) fpscr |= 0x200;
1117 if (!(*cw & _EM_OVERFLOW)) fpscr |= 0x400;
1118 if (!(*cw & _EM_UNDERFLOW)) fpscr |= 0x800;
1119 if (!(*cw & _EM_INEXACT)) fpscr |= 0x1000;
1120 if (!(*cw & _EM_DENORMAL)) fpscr |= 0x8000;
1121 switch (*cw & _MCW_RC)
1122 {
1123 case _RC_CHOP: fpscr |= 0xc00000; break;
1124 case _RC_UP: fpscr |= 0x400000; break;
1125 case _RC_DOWN: fpscr |= 0x800000; break;
1126 }
1127 }
1128
1129 if (old_fpscr != fpscr)
1130 __asm__ __volatile__( "vmsr fpscr, %0" :: "r" (fpscr) );
1131#else
1132 FIXME("not implemented\n");
1133 if (cw) *cw = 0;
1134 if (sw) *sw = 0;
1135#endif
1136}
1137
1138/**********************************************************************
1139 * _statusfp2 (MSVCR80.@)
1140 */
1141#if defined(__i386__)
1142void CDECL _statusfp2( unsigned int *x86_sw, unsigned int *sse2_sw )
1143{
1144 if (x86_sw)
1145 _setfp(NULL, 0, x86_sw, 0);
1146 if (!sse2_sw) return;
1147 if (sse2_supported)
1148 _setfp_sse(NULL, 0, sse2_sw, 0);
1149 else *sse2_sw = 0;
1150}
1151#endif
1152
1153/**********************************************************************
1154 * _statusfp (MSVCRT.@)
1155 */
1156unsigned int CDECL _statusfp(void)
1157{
1158 unsigned int flags = 0;
1159#if defined(__i386__)
1160 unsigned int x86_sw, sse2_sw;
1161
1162 _statusfp2( &x86_sw, &sse2_sw );
1163 /* FIXME: there's no definition for ambiguous status, just return all status bits for now */
1164 flags = x86_sw | sse2_sw;
1165#else
1166 _setfp(NULL, 0, &flags, 0);
1167#endif
1168 return flags;
1169}
1170
1171/*********************************************************************
1172 * _clearfp (MSVCRT.@)
1173 */
1174unsigned int CDECL _clearfp(void)
1175{
1176 unsigned int flags = 0;
1177#ifdef __i386__
1178 _setfp(NULL, 0, &flags, _MCW_EM);
1179 if (sse2_supported)
1180 {
1181 unsigned int sse_sw = 0;
1182
1183 _setfp_sse(NULL, 0, &sse_sw, _MCW_EM);
1184 flags |= sse_sw;
1185 }
1186#else
1187 _setfp(NULL, 0, &flags, _MCW_EM);
1188#endif
1189 return flags;
1190}
1191
1192/*********************************************************************
1193 * __fpecode (MSVCRT.@)
1194 */
1195int * CDECL __fpecode(void)
1196{
1197 return &msvcrt_get_thread_data()->fpecode;
1198}
1199
1200#ifndef __REACTOS__
1201/*********************************************************************
1202 * ldexp (MSVCRT.@)
1203 */
1204double CDECL ldexp(double num, int exp)
1205{
1206 double z = scalbn(num, exp);
1207
1208 if (isfinite(num) && !isfinite(z))
1209 return math_error(_OVERFLOW, "ldexp", num, exp, z);
1210 if (num && isfinite(num) && !z)
1211 return math_error(_UNDERFLOW, "ldexp", num, exp, z);
1212 return z;
1213}
1214#endif // __REACTOS__
1215
1216/*********************************************************************
1217 * _cabs (MSVCRT.@)
1218 */
1219double CDECL _cabs(struct _complex num)
1220{
1221 return sqrt(num.x * num.x + num.y * num.y);
1222}
1223
1224/*********************************************************************
1225 * _chgsign (MSVCRT.@)
1226 */
1227double CDECL _chgsign(double num)
1228{
1229 union { double f; UINT64 i; } u = { num };
1230 u.i ^= 1ull << 63;
1231 return u.f;
1232}
1233
1234/*********************************************************************
1235 * __control87_2 (MSVCR80.@)
1236 *
1237 * Not exported by native msvcrt, added in msvcr80.
1238 */
1239#ifdef __i386__
1240int CDECL __control87_2( unsigned int newval, unsigned int mask,
1241 unsigned int *x86_cw, unsigned int *sse2_cw )
1242{
1243 if (x86_cw)
1244 {
1245 *x86_cw = newval;
1246 _setfp(x86_cw, mask, NULL, 0);
1247 }
1248
1249 if (!sse2_cw) return 1;
1250
1251 if (sse2_supported)
1252 {
1253 *sse2_cw = newval;
1254 _setfp_sse(sse2_cw, mask, NULL, 0);
1255 }
1256 else *sse2_cw = 0;
1257
1258 return 1;
1259}
1260#endif
1261
1262/*********************************************************************
1263 * _control87 (MSVCRT.@)
1264 */
1265unsigned int CDECL _control87(unsigned int newval, unsigned int mask)
1266{
1267 unsigned int flags = 0;
1268#if defined(__i386__) && (_MSVCR_VER == 0 || _MSVCR_VER >= 80)
1269 unsigned int sse2_cw;
1270
1271 __control87_2( newval, mask, &flags, &sse2_cw );
1272
1273 if (sse2_supported)
1274 {
1275 if ((flags ^ sse2_cw) & (_MCW_EM | _MCW_RC)) flags |= _EM_AMBIGUOUS;
1276 flags |= sse2_cw;
1277 }
1278#else
1279 flags = newval;
1280 _setfp(&flags, mask, NULL, 0);
1281#endif
1282 return flags;
1283}
1284
1285/*********************************************************************
1286 * _controlfp (MSVCRT.@)
1287 */
1288unsigned int CDECL _controlfp(unsigned int newval, unsigned int mask)
1289{
1290 return _control87( newval, mask & ~_EM_DENORMAL );
1291}
1292
1293/*********************************************************************
1294 * _set_controlfp (MSVCRT.@)
1295 */
1296void CDECL _set_controlfp( unsigned int newval, unsigned int mask )
1297{
1298 _controlfp( newval, mask );
1299}
1300
1301/*********************************************************************
1302 * _controlfp_s (MSVCRT.@)
1303 */
1304int CDECL _controlfp_s(unsigned int *cur, unsigned int newval, unsigned int mask)
1305{
1306 static const unsigned int all_flags = (_MCW_EM | _MCW_IC | _MCW_RC |
1307 _MCW_PC | _MCW_DN);
1308 unsigned int val;
1309
1310 if (!MSVCRT_CHECK_PMT( !(newval & mask & ~all_flags) ))
1311 {
1312 if (cur) *cur = _controlfp( 0, 0 ); /* retrieve it anyway */
1313 return EINVAL;
1314 }
1315 val = _controlfp( newval, mask );
1316 if (cur) *cur = val;
1317 return 0;
1318}
1319
1320#if _MSVCR_VER >= 140 && (defined(__i386__) || defined(__x86_64__))
1321enum fenv_masks
1322{
1323 FENV_X_INVALID = 0x00100010,
1324 FENV_X_DENORMAL = 0x00200020,
1325 FENV_X_ZERODIVIDE = 0x00080008,
1326 FENV_X_OVERFLOW = 0x00040004,
1327 FENV_X_UNDERFLOW = 0x00020002,
1328 FENV_X_INEXACT = 0x00010001,
1329 FENV_X_AFFINE = 0x00004000,
1330 FENV_X_UP = 0x00800200,
1331 FENV_X_DOWN = 0x00400100,
1332 FENV_X_24 = 0x00002000,
1333 FENV_X_53 = 0x00001000,
1334 FENV_Y_INVALID = 0x10000010,
1335 FENV_Y_DENORMAL = 0x20000020,
1336 FENV_Y_ZERODIVIDE = 0x08000008,
1337 FENV_Y_OVERFLOW = 0x04000004,
1338 FENV_Y_UNDERFLOW = 0x02000002,
1339 FENV_Y_INEXACT = 0x01000001,
1340 FENV_Y_UP = 0x80000200,
1341 FENV_Y_DOWN = 0x40000100,
1342 FENV_Y_FLUSH = 0x00000400,
1343 FENV_Y_FLUSH_SAVE = 0x00000800
1344};
1345
1346/* encodes x87/sse control/status word in ulong */
1347static __msvcrt_ulong fenv_encode(unsigned int x, unsigned int y)
1348{
1349 __msvcrt_ulong ret = 0;
1350
1351#ifdef __i386__
1352 if (x & _EM_INVALID) ret |= FENV_X_INVALID;
1353 if (x & _EM_DENORMAL) ret |= FENV_X_DENORMAL;
1354 if (x & _EM_ZERODIVIDE) ret |= FENV_X_ZERODIVIDE;
1355 if (x & _EM_OVERFLOW) ret |= FENV_X_OVERFLOW;
1356 if (x & _EM_UNDERFLOW) ret |= FENV_X_UNDERFLOW;
1357 if (x & _EM_INEXACT) ret |= FENV_X_INEXACT;
1358 if (x & _IC_AFFINE) ret |= FENV_X_AFFINE;
1359 if (x & _RC_UP) ret |= FENV_X_UP;
1360 if (x & _RC_DOWN) ret |= FENV_X_DOWN;
1361 if (x & _PC_24) ret |= FENV_X_24;
1362 if (x & _PC_53) ret |= FENV_X_53;
1363#endif
1364 x &= ~(_MCW_EM | _MCW_IC | _MCW_RC | _MCW_PC);
1365
1366 if (y & _EM_INVALID) ret |= FENV_Y_INVALID;
1367 if (y & _EM_DENORMAL) ret |= FENV_Y_DENORMAL;
1368 if (y & _EM_ZERODIVIDE) ret |= FENV_Y_ZERODIVIDE;
1369 if (y & _EM_OVERFLOW) ret |= FENV_Y_OVERFLOW;
1370 if (y & _EM_UNDERFLOW) ret |= FENV_Y_UNDERFLOW;
1371 if (y & _EM_INEXACT) ret |= FENV_Y_INEXACT;
1372 if (y & _RC_UP) ret |= FENV_Y_UP;
1373 if (y & _RC_DOWN) ret |= FENV_Y_DOWN;
1374 if (y & _DN_FLUSH) ret |= FENV_Y_FLUSH;
1375 if (y & _DN_FLUSH_OPERANDS_SAVE_RESULTS) ret |= FENV_Y_FLUSH_SAVE;
1376 y &= ~(_MCW_EM | _MCW_IC | _MCW_RC | _MCW_DN);
1377
1378 if(x || y) FIXME("unsupported flags: %x, %x\n", x, y);
1379 return ret;
1380}
1381
1382/* decodes x87/sse control/status word, returns FALSE on error */
1383static BOOL fenv_decode(__msvcrt_ulong enc, unsigned int *x, unsigned int *y)
1384{
1385 *x = *y = 0;
1386 if ((enc & FENV_X_INVALID) == FENV_X_INVALID) *x |= _EM_INVALID;
1387 if ((enc & FENV_X_DENORMAL) == FENV_X_DENORMAL) *x |= _EM_DENORMAL;
1388 if ((enc & FENV_X_ZERODIVIDE) == FENV_X_ZERODIVIDE) *x |= _EM_ZERODIVIDE;
1389 if ((enc & FENV_X_OVERFLOW) == FENV_X_OVERFLOW) *x |= _EM_OVERFLOW;
1390 if ((enc & FENV_X_UNDERFLOW) == FENV_X_UNDERFLOW) *x |= _EM_UNDERFLOW;
1391 if ((enc & FENV_X_INEXACT) == FENV_X_INEXACT) *x |= _EM_INEXACT;
1392 if ((enc & FENV_X_AFFINE) == FENV_X_AFFINE) *x |= _IC_AFFINE;
1393 if ((enc & FENV_X_UP) == FENV_X_UP) *x |= _RC_UP;
1394 if ((enc & FENV_X_DOWN) == FENV_X_DOWN) *x |= _RC_DOWN;
1395 if ((enc & FENV_X_24) == FENV_X_24) *x |= _PC_24;
1396 if ((enc & FENV_X_53) == FENV_X_53) *x |= _PC_53;
1397
1398 if ((enc & FENV_Y_INVALID) == FENV_Y_INVALID) *y |= _EM_INVALID;
1399 if ((enc & FENV_Y_DENORMAL) == FENV_Y_DENORMAL) *y |= _EM_DENORMAL;
1400 if ((enc & FENV_Y_ZERODIVIDE) == FENV_Y_ZERODIVIDE) *y |= _EM_ZERODIVIDE;
1401 if ((enc & FENV_Y_OVERFLOW) == FENV_Y_OVERFLOW) *y |= _EM_OVERFLOW;
1402 if ((enc & FENV_Y_UNDERFLOW) == FENV_Y_UNDERFLOW) *y |= _EM_UNDERFLOW;
1403 if ((enc & FENV_Y_INEXACT) == FENV_Y_INEXACT) *y |= _EM_INEXACT;
1404 if ((enc & FENV_Y_UP) == FENV_Y_UP) *y |= _RC_UP;
1405 if ((enc & FENV_Y_DOWN) == FENV_Y_DOWN) *y |= _RC_DOWN;
1406 if ((enc & FENV_Y_FLUSH) == FENV_Y_FLUSH) *y |= _DN_FLUSH;
1407 if ((enc & FENV_Y_FLUSH_SAVE) == FENV_Y_FLUSH_SAVE) *y |= _DN_FLUSH_OPERANDS_SAVE_RESULTS;
1408
1409 if (fenv_encode(*x, *y) != enc)
1410 {
1411 WARN("can't decode: %lx\n", enc);
1412 return FALSE;
1413 }
1414 return TRUE;
1415}
1416#elif _MSVCR_VER >= 120
1417static __msvcrt_ulong fenv_encode(unsigned int x, unsigned int y)
1418{
1419 if (y & _EM_DENORMAL)
1420 y = (y & ~_EM_DENORMAL) | 0x20;
1421
1422 return x | y;
1423}
1424
1425static BOOL fenv_decode(__msvcrt_ulong enc, unsigned int *x, unsigned int *y)
1426{
1427 if (enc & 0x20)
1428 enc = (enc & ~0x20) | _EM_DENORMAL;
1429
1430 *x = *y = enc;
1431 return TRUE;
1432}
1433#endif
1434
1435#if _MSVCR_VER>=120
1436/*********************************************************************
1437 * fegetenv (MSVCR120.@)
1438 */
1440{
1441#if _MSVCR_VER>=140 && defined(__i386__)
1442 unsigned int x87, sse;
1443 __control87_2(0, 0, &x87, &sse);
1444 env->_Fe_ctl = fenv_encode(x87, sse);
1445 _statusfp2(&x87, &sse);
1446 env->_Fe_stat = fenv_encode(x87, sse);
1447#elif _MSVCR_VER>=140
1448 env->_Fe_ctl = fenv_encode(0, _control87(0, 0));
1449 env->_Fe_stat = fenv_encode(0, _statusfp());
1450#else
1451 env->_Fe_ctl = _controlfp(0, 0) & (_EM_INEXACT | _EM_UNDERFLOW |
1453 env->_Fe_stat = _statusfp();
1454#endif
1455 return 0;
1456}
1457
1458/*********************************************************************
1459 * feupdateenv (MSVCR120.@)
1460 */
1461int CDECL feupdateenv(const fenv_t *env)
1462{
1463 fenv_t set;
1464 fegetenv(&set);
1465 set._Fe_ctl = env->_Fe_ctl;
1466 set._Fe_stat |= env->_Fe_stat;
1467 return fesetenv(&set);
1468}
1469
1470/*********************************************************************
1471 * fetestexcept (MSVCR120.@)
1472 */
1473int CDECL fetestexcept(int flags)
1474{
1475 return _statusfp() & flags;
1476}
1477
1478/*********************************************************************
1479 * fesetexceptflag (MSVCR120.@)
1480 */
1481int CDECL fesetexceptflag(const fexcept_t *status, int excepts)
1482{
1483 fenv_t env;
1484
1485 excepts &= FE_ALL_EXCEPT;
1486 if(!excepts)
1487 return 0;
1488
1489 fegetenv(&env);
1490 env._Fe_stat &= ~fenv_encode(excepts, excepts);
1491 env._Fe_stat |= *status & fenv_encode(excepts, excepts);
1492 return fesetenv(&env);
1493}
1494
1495/*********************************************************************
1496 * feraiseexcept (MSVCR120.@)
1497 */
1498int CDECL feraiseexcept(int flags)
1499{
1500 fenv_t env;
1501
1503 fegetenv(&env);
1504 env._Fe_stat |= fenv_encode(flags, flags);
1505 return fesetenv(&env);
1506}
1507
1508/*********************************************************************
1509 * feclearexcept (MSVCR120.@)
1510 */
1511int CDECL feclearexcept(int flags)
1512{
1513 fenv_t env;
1514
1515 fegetenv(&env);
1517 env._Fe_stat &= ~fenv_encode(flags, flags);
1518 return fesetenv(&env);
1519}
1520
1521/*********************************************************************
1522 * fegetexceptflag (MSVCR120.@)
1523 */
1524int CDECL fegetexceptflag(fexcept_t *status, int excepts)
1525{
1526#if _MSVCR_VER>=140 && defined(__i386__)
1527 unsigned int x87, sse;
1528 _statusfp2(&x87, &sse);
1529 *status = fenv_encode(x87 & excepts, sse & excepts);
1530#else
1531 *status = fenv_encode(0, _statusfp() & excepts);
1532#endif
1533 return 0;
1534}
1535#endif
1536
1537#if _MSVCR_VER>=140
1538/*********************************************************************
1539 * __fpe_flt_rounds (UCRTBASE.@)
1540 */
1541int CDECL __fpe_flt_rounds(void)
1542{
1543 unsigned int fpc = _controlfp(0, 0) & _RC_CHOP;
1544
1545 TRACE("()\n");
1546
1547 switch(fpc) {
1548 case _RC_CHOP: return 0;
1549 case _RC_NEAR: return 1;
1550 case _RC_UP: return 2;
1551 default: return 3;
1552 }
1553}
1554#endif
1555
1556#if _MSVCR_VER>=120
1557
1558/*********************************************************************
1559 * fegetround (MSVCR120.@)
1560 */
1561int CDECL fegetround(void)
1562{
1563 return _controlfp(0, 0) & _MCW_RC;
1564}
1565
1566/*********************************************************************
1567 * fesetround (MSVCR120.@)
1568 */
1569int CDECL fesetround(int round_mode)
1570{
1571 if (round_mode & (~_MCW_RC))
1572 return 1;
1573 _controlfp(round_mode, _MCW_RC);
1574 return 0;
1575}
1576
1577#endif /* _MSVCR_VER>=120 */
1578
1579/*********************************************************************
1580 * _finite (MSVCRT.@)
1581 */
1582int CDECL _finite(double num)
1583{
1584 union { double f; UINT64 i; } u = { num };
1585 return (u.i & ~0ull >> 1) < 0x7ffull << 52;
1586}
1587
1588/*********************************************************************
1589 * _fpreset (MSVCRT.@)
1590 */
1591void CDECL _fpreset(void)
1592{
1593#if (defined(__GNUC__) || defined(__clang__)) && defined(__i386__)
1594 const unsigned int x86_cw = 0x27f;
1595 __asm__ __volatile__( "fninit; fldcw %0" : : "m" (x86_cw) );
1596 if (sse2_supported)
1597 {
1598 unsigned int cw = _MCW_EM, sw = 0;
1599 _setfp_sse(&cw, ~0, &sw, ~0);
1600 }
1601#else
1602 unsigned int cw = _MCW_EM, sw = 0;
1603 _setfp(&cw, ~0, &sw, ~0);
1604#endif
1605}
1606
1607#if _MSVCR_VER>=120
1608/*********************************************************************
1609 * feholdexcept (MSVCR120.@)
1610 */
1612{
1613 TRACE( "(%p)\n", env );
1614 fegetenv(env);
1616}
1617
1618/*********************************************************************
1619 * fesetenv (MSVCR120.@)
1620 */
1621int CDECL fesetenv(const fenv_t *env)
1622{
1623 unsigned int x87_cw, cw, x87_stat, stat;
1624 unsigned int mask;
1625
1626 TRACE( "(%p)\n", env );
1627
1628 if (!env->_Fe_ctl && !env->_Fe_stat) {
1629 _fpreset();
1630 return 0;
1631 }
1632
1633 if (!fenv_decode(env->_Fe_ctl, &x87_cw, &cw))
1634 return 1;
1635 if (!fenv_decode(env->_Fe_stat, &x87_stat, &stat))
1636 return 1;
1637
1638#if _MSVCR_VER >= 140
1639 mask = ~0;
1640#else
1643#endif
1644
1645#ifdef __i386__
1646 _setfp(&x87_cw, mask, &x87_stat, ~0);
1647 if (sse2_supported)
1648 _setfp_sse(&cw, mask, &stat, ~0);
1649 return 0;
1650#else
1651 _setfp(&cw, mask, &stat, ~0);
1652 return 0;
1653#endif
1654}
1655#endif
1656
1657/*********************************************************************
1658 * _isnan (MSVCRT.@)
1659 */
1660int CDECL _isnan(double num)
1661{
1662 union { double f; UINT64 i; } u = { num };
1663 return (u.i & ~0ull >> 1) > 0x7ffull << 52;
1664}
1665
1666#if _MSVCR_VER>=120
1667
1668/*********************************************************************
1669 * rint (MSVCR120.@)
1670 */
1671double CDECL MSVCRT_rint(double x)
1672{
1673 unsigned cw;
1674 double y;
1675
1676 cw = _controlfp(0, 0);
1677 if ((cw & _MCW_PC) != _PC_53)
1679 y = rint(x);
1680 if ((cw & _MCW_PC) != _PC_53)
1681 _controlfp(cw, _MCW_PC);
1682 return y;
1683}
1684
1685/*********************************************************************
1686 * _nearbyint (MSVCR120.@)
1687 *
1688 * Based on musl: src/math/nearbyteint.c
1689 */
1690double CDECL nearbyint(double x)
1691{
1692 BOOL update_cw, update_sw;
1693 unsigned int cw, sw;
1694
1695 _setfp(&cw, 0, &sw, 0);
1696 update_cw = !(cw & _EM_INEXACT);
1697 update_sw = !(sw & _SW_INEXACT);
1698 if (update_cw)
1699 {
1700 cw |= _EM_INEXACT;
1701 _setfp(&cw, _EM_INEXACT, NULL, 0);
1702 }
1703 x = MSVCRT_rint(x);
1704 if (update_cw || update_sw)
1705 {
1706 sw = 0;
1707 cw &= ~_EM_INEXACT;
1708 _setfp(update_cw ? &cw : NULL, _EM_INEXACT,
1709 update_sw ? &sw : NULL, _SW_INEXACT);
1710 }
1711 return x;
1712}
1713
1714/*********************************************************************
1715 * _nearbyintf (MSVCR120.@)
1716 *
1717 * Based on musl: src/math/nearbyteintf.c
1718 */
1719float CDECL nearbyintf(float x)
1720{
1721 BOOL update_cw, update_sw;
1722 unsigned int cw, sw;
1723
1724 _setfp(&cw, 0, &sw, 0);
1725 update_cw = !(cw & _EM_INEXACT);
1726 update_sw = !(sw & _SW_INEXACT);
1727 if (update_cw)
1728 {
1729 cw |= _EM_INEXACT;
1730 _setfp(&cw, _EM_INEXACT, NULL, 0);
1731 }
1732 x = rintf(x);
1733 if (update_cw || update_sw)
1734 {
1735 sw = 0;
1736 cw &= ~_EM_INEXACT;
1737 _setfp(update_cw ? &cw : NULL, _EM_INEXACT,
1738 update_sw ? &sw : NULL, _SW_INEXACT);
1739 }
1740 return x;
1741}
1742
1743#endif /* _MSVCR_VER>=120 */
1744
1745/*********************************************************************
1746 * _ecvt (MSVCRT.@)
1747 */
1748char * CDECL _ecvt( double number, int ndigits, int *decpt, int *sign )
1749{
1750 int prec, len;
1752 /* FIXME: check better for overflow (native supports over 300 chars) */
1753 ndigits = min( ndigits, 80 - 8); /* 8 : space for sign, dec point, "e",
1754 * 4 for exponent and one for
1755 * terminating '\0' */
1756 if (!data->efcvt_buffer)
1757 data->efcvt_buffer = malloc( 80 ); /* ought to be enough */
1758
1759 /* handle cases with zero ndigits or less */
1760 prec = ndigits;
1761 if( prec < 1) prec = 2;
1762 len = _snprintf(data->efcvt_buffer, 80, "%.*le", prec - 1, number);
1763
1764 if (data->efcvt_buffer[0] == '-') {
1765 memmove( data->efcvt_buffer, data->efcvt_buffer + 1, len-- );
1766 *sign = 1;
1767 } else *sign = 0;
1768
1769 /* take the decimal "point away */
1770 if( prec != 1)
1771 memmove( data->efcvt_buffer + 1, data->efcvt_buffer + 2, len - 1 );
1772 /* take the exponential "e" out */
1773 data->efcvt_buffer[ prec] = '\0';
1774 /* read the exponent */
1775 sscanf( data->efcvt_buffer + prec + 1, "%d", decpt);
1776 (*decpt)++;
1777 /* adjust for some border cases */
1778 if( data->efcvt_buffer[0] == '0')/* value is zero */
1779 *decpt = 0;
1780 /* handle cases with zero ndigits or less */
1781 if( ndigits < 1){
1782 if( data->efcvt_buffer[ 0] >= '5')
1783 (*decpt)++;
1784 data->efcvt_buffer[ 0] = '\0';
1785 }
1786 TRACE("out=\"%s\"\n",data->efcvt_buffer);
1787 return data->efcvt_buffer;
1788}
1789
1790/*********************************************************************
1791 * _ecvt_s (MSVCRT.@)
1792 */
1793int CDECL _ecvt_s( char *buffer, size_t length, double number, int ndigits, int *decpt, int *sign )
1794{
1795 int prec, len;
1796 char *result;
1797
1798 if (!MSVCRT_CHECK_PMT(buffer != NULL)) return EINVAL;
1799 if (!MSVCRT_CHECK_PMT(decpt != NULL)) return EINVAL;
1800 if (!MSVCRT_CHECK_PMT(sign != NULL)) return EINVAL;
1801 if (!MSVCRT_CHECK_PMT_ERR( length > 2, ERANGE )) return ERANGE;
1802 if (!MSVCRT_CHECK_PMT_ERR(ndigits < (int)length - 1, ERANGE )) return ERANGE;
1803
1804 /* handle cases with zero ndigits or less */
1805 prec = ndigits;
1806 if( prec < 1) prec = 2;
1807 result = malloc(prec + 8);
1808
1809 len = _snprintf(result, prec + 8, "%.*le", prec - 1, number);
1810 if (result[0] == '-') {
1811 memmove( result, result + 1, len-- );
1812 *sign = 1;
1813 } else *sign = 0;
1814
1815 /* take the decimal "point away */
1816 if( prec != 1)
1817 memmove( result + 1, result + 2, len - 1 );
1818 /* take the exponential "e" out */
1819 result[ prec] = '\0';
1820 /* read the exponent */
1821 sscanf( result + prec + 1, "%d", decpt);
1822 (*decpt)++;
1823 /* adjust for some border cases */
1824 if( result[0] == '0')/* value is zero */
1825 *decpt = 0;
1826 /* handle cases with zero ndigits or less */
1827 if( ndigits < 1){
1828 if( result[ 0] >= '5')
1829 (*decpt)++;
1830 result[ 0] = '\0';
1831 }
1832 memcpy( buffer, result, max(ndigits + 1, 1) );
1833 free( result );
1834 return 0;
1835}
1836
1837/***********************************************************************
1838 * _fcvt (MSVCRT.@)
1839 */
1840char * CDECL _fcvt( double number, int ndigits, int *decpt, int *sign )
1841{
1843 int stop, dec1, dec2;
1844 char *ptr1, *ptr2, *first;
1845 char buf[80]; /* ought to be enough */
1846 char decimal_separator = get_locinfo()->lconv->decimal_point[0];
1847
1848 if (!data->efcvt_buffer)
1849 data->efcvt_buffer = malloc( 80 ); /* ought to be enough */
1850
1851 stop = _snprintf(buf, 80, "%.*f", ndigits < 0 ? 0 : ndigits, number);
1852 ptr1 = buf;
1853 ptr2 = data->efcvt_buffer;
1854 first = NULL;
1855 dec1 = 0;
1856 dec2 = 0;
1857
1858 if (*ptr1 == '-') {
1859 *sign = 1;
1860 ptr1++;
1861 } else *sign = 0;
1862
1863 /* For numbers below the requested resolution, work out where
1864 the decimal point will be rather than finding it in the string */
1865 if (number < 1.0 && number > 0.0) {
1866 dec2 = log10(number + 1e-10);
1867 if (-dec2 <= ndigits) dec2 = 0;
1868 }
1869
1870 /* If requested digits is zero or less, we will need to truncate
1871 * the returned string */
1872 if (ndigits < 1) {
1873 stop += ndigits;
1874 }
1875
1876 while (*ptr1 == '0') ptr1++; /* Skip leading zeroes */
1877 while (*ptr1 != '\0' && *ptr1 != decimal_separator) {
1878 if (!first) first = ptr2;
1879 if ((ptr1 - buf) < stop) {
1880 *ptr2++ = *ptr1++;
1881 } else {
1882 ptr1++;
1883 }
1884 dec1++;
1885 }
1886
1887 if (ndigits > 0) {
1888 ptr1++;
1889 if (!first) {
1890 while (*ptr1 == '0') { /* Process leading zeroes */
1891 *ptr2++ = *ptr1++;
1892 dec1--;
1893 }
1894 }
1895 while (*ptr1 != '\0') {
1896 if (!first) first = ptr2;
1897 *ptr2++ = *ptr1++;
1898 }
1899 }
1900
1901 *ptr2 = '\0';
1902
1903 /* We never found a non-zero digit, then our number is either
1904 * smaller than the requested precision, or 0.0 */
1905 if (!first) {
1906 if (number > 0.0) {
1907 first = ptr2;
1908 } else {
1909 first = data->efcvt_buffer;
1910 dec1 = 0;
1911 }
1912 }
1913
1914 *decpt = dec2 ? dec2 : dec1;
1915 return first;
1916}
1917
1918/***********************************************************************
1919 * _fcvt_s (MSVCRT.@)
1920 */
1921int CDECL _fcvt_s(char* outbuffer, size_t size, double number, int ndigits, int *decpt, int *sign)
1922{
1923 int stop, dec1, dec2;
1924 char *ptr1, *ptr2, *first;
1925 char buf[80]; /* ought to be enough */
1926 char decimal_separator = get_locinfo()->lconv->decimal_point[0];
1927
1928 if (!outbuffer || !decpt || !sign || size == 0)
1929 {
1930 *_errno() = EINVAL;
1931 return EINVAL;
1932 }
1933
1934 stop = _snprintf(buf, 80, "%.*f", ndigits < 0 ? 0 : ndigits, number);
1935 ptr1 = buf;
1936 ptr2 = outbuffer;
1937 first = NULL;
1938 dec1 = 0;
1939 dec2 = 0;
1940
1941 if (*ptr1 == '-') {
1942 *sign = 1;
1943 ptr1++;
1944 } else *sign = 0;
1945
1946 /* For numbers below the requested resolution, work out where
1947 the decimal point will be rather than finding it in the string */
1948 if (number < 1.0 && number > 0.0) {
1949 dec2 = log10(number + 1e-10);
1950 if (-dec2 <= ndigits) dec2 = 0;
1951 }
1952
1953 /* If requested digits is zero or less, we will need to truncate
1954 * the returned string */
1955 if (ndigits < 1) {
1956 stop += ndigits;
1957 }
1958
1959 while (*ptr1 == '0') ptr1++; /* Skip leading zeroes */
1960 while (*ptr1 != '\0' && *ptr1 != decimal_separator) {
1961 if (!first) first = ptr2;
1962 if ((ptr1 - buf) < stop) {
1963 if (size > 1) {
1964 *ptr2++ = *ptr1++;
1965 size--;
1966 }
1967 } else {
1968 ptr1++;
1969 }
1970 dec1++;
1971 }
1972
1973 if (ndigits > 0) {
1974 ptr1++;
1975 if (!first) {
1976 while (*ptr1 == '0') { /* Process leading zeroes */
1977 if (number == 0.0 && size > 1) {
1978 *ptr2++ = '0';
1979 size--;
1980 }
1981 ptr1++;
1982 dec1--;
1983 }
1984 }
1985 while (*ptr1 != '\0') {
1986 if (!first) first = ptr2;
1987 if (size > 1) {
1988 *ptr2++ = *ptr1++;
1989 size--;
1990 }
1991 }
1992 }
1993
1994 *ptr2 = '\0';
1995
1996 /* We never found a non-zero digit, then our number is either
1997 * smaller than the requested precision, or 0.0 */
1998 if (!first && (number <= 0.0))
1999 dec1 = 0;
2000
2001 *decpt = dec2 ? dec2 : dec1;
2002 return 0;
2003}
2004
2005/***********************************************************************
2006 * _gcvt (MSVCRT.@)
2007 */
2008char * CDECL _gcvt( double number, int ndigit, char *buff )
2009{
2010 if(!buff) {
2011 *_errno() = EINVAL;
2012 return NULL;
2013 }
2014
2015 if(ndigit < 0) {
2016 *_errno() = ERANGE;
2017 return NULL;
2018 }
2019
2020 sprintf(buff, "%.*g", ndigit, number);
2021 return buff;
2022}
2023
2024/***********************************************************************
2025 * _gcvt_s (MSVCRT.@)
2026 */
2027int CDECL _gcvt_s(char *buff, size_t size, double number, int digits)
2028{
2029 int len;
2030
2031 if(!buff) {
2032 *_errno() = EINVAL;
2033 return EINVAL;
2034 }
2035
2036 if( digits<0 || digits>=size) {
2037 if(size)
2038 buff[0] = '\0';
2039
2040 *_errno() = ERANGE;
2041 return ERANGE;
2042 }
2043
2044 len = _scprintf("%.*g", digits, number);
2045 if(len > size) {
2046 buff[0] = '\0';
2047 *_errno() = ERANGE;
2048 return ERANGE;
2049 }
2050
2051 sprintf(buff, "%.*g", digits, number);
2052 return 0;
2053}
2054
2055#include <stdlib.h> /* div_t, ldiv_t */
2056
2057#ifndef __REACTOS__
2058/*********************************************************************
2059 * div (MSVCRT.@)
2060 * VERSION
2061 * [i386] Windows binary compatible - returns the struct in eax/edx.
2062 */
2063#ifdef __i386__
2064unsigned __int64 CDECL div(int num, int denom)
2065{
2066 union {
2067 div_t div;
2068 unsigned __int64 uint64;
2069 } ret;
2070
2071 ret.div.quot = num / denom;
2072 ret.div.rem = num % denom;
2073 return ret.uint64;
2074}
2075#else
2076/*********************************************************************
2077 * div (MSVCRT.@)
2078 * VERSION
2079 * [!i386] Non-x86 can't run win32 apps so we don't need binary compatibility
2080 */
2081div_t CDECL div(int num, int denom)
2082{
2083 div_t ret;
2084
2085 ret.quot = num / denom;
2086 ret.rem = num % denom;
2087 return ret;
2088}
2089#endif /* ifdef __i386__ */
2090
2091
2092/*********************************************************************
2093 * ldiv (MSVCRT.@)
2094 * VERSION
2095 * [i386] Windows binary compatible - returns the struct in eax/edx.
2096 */
2097#ifdef __i386__
2099{
2100 union {
2101 ldiv_t ldiv;
2102 unsigned __int64 uint64;
2103 } ret;
2104
2105 ret.ldiv.quot = num / denom;
2106 ret.ldiv.rem = num % denom;
2107 return ret.uint64;
2108}
2109#else
2110/*********************************************************************
2111 * ldiv (MSVCRT.@)
2112 * VERSION
2113 * [!i386] Non-x86 can't run win32 apps so we don't need binary compatibility
2114 */
2116{
2117 ldiv_t ret;
2118
2119 ret.quot = num / denom;
2120 ret.rem = num % denom;
2121 return ret;
2122}
2123#endif /* ifdef __i386__ */
2124#endif /* !__REACTOS__ */
2125
2126#if _MSVCR_VER>=100
2127/*********************************************************************
2128 * lldiv (MSVCR100.@)
2129 */
2131{
2132 lldiv_t ret;
2133
2134 ret.quot = num / denom;
2135 ret.rem = num % denom;
2136
2137 return ret;
2138}
2139#endif
2140
2141#ifdef __i386__
2142
2143/*********************************************************************
2144 * _adjust_fdiv (MSVCRT.@)
2145 * Used by the MSVC compiler to work around the Pentium FDIV bug.
2146 */
2147int MSVCRT__adjust_fdiv = 0;
2148
2149/***********************************************************************
2150 * _adj_fdiv_m16i (MSVCRT.@)
2151 *
2152 * NOTE
2153 * I _think_ this function is intended to work around the Pentium
2154 * fdiv bug.
2155 */
2156void __stdcall _adj_fdiv_m16i( short arg )
2157{
2158 TRACE("(): stub\n");
2159}
2160
2161/***********************************************************************
2162 * _adj_fdiv_m32 (MSVCRT.@)
2163 *
2164 * NOTE
2165 * I _think_ this function is intended to work around the Pentium
2166 * fdiv bug.
2167 */
2168void __stdcall _adj_fdiv_m32( unsigned int arg )
2169{
2170 TRACE("(): stub\n");
2171}
2172
2173/***********************************************************************
2174 * _adj_fdiv_m32i (MSVCRT.@)
2175 *
2176 * NOTE
2177 * I _think_ this function is intended to work around the Pentium
2178 * fdiv bug.
2179 */
2180void __stdcall _adj_fdiv_m32i( int arg )
2181{
2182 TRACE("(): stub\n");
2183}
2184
2185/***********************************************************************
2186 * _adj_fdiv_m64 (MSVCRT.@)
2187 *
2188 * NOTE
2189 * I _think_ this function is intended to work around the Pentium
2190 * fdiv bug.
2191 */
2192void __stdcall _adj_fdiv_m64( unsigned __int64 arg )
2193{
2194 TRACE("(): stub\n");
2195}
2196
2197/***********************************************************************
2198 * _adj_fdiv_r (MSVCRT.@)
2199 * FIXME
2200 * This function is likely to have the wrong number of arguments.
2201 *
2202 * NOTE
2203 * I _think_ this function is intended to work around the Pentium
2204 * fdiv bug.
2205 */
2206void _adj_fdiv_r(void)
2207{
2208 TRACE("(): stub\n");
2209}
2210
2211/***********************************************************************
2212 * _adj_fdivr_m16i (MSVCRT.@)
2213 *
2214 * NOTE
2215 * I _think_ this function is intended to work around the Pentium
2216 * fdiv bug.
2217 */
2218void __stdcall _adj_fdivr_m16i( short arg )
2219{
2220 TRACE("(): stub\n");
2221}
2222
2223/***********************************************************************
2224 * _adj_fdivr_m32 (MSVCRT.@)
2225 *
2226 * NOTE
2227 * I _think_ this function is intended to work around the Pentium
2228 * fdiv bug.
2229 */
2230void __stdcall _adj_fdivr_m32( unsigned int arg )
2231{
2232 TRACE("(): stub\n");
2233}
2234
2235/***********************************************************************
2236 * _adj_fdivr_m32i (MSVCRT.@)
2237 *
2238 * NOTE
2239 * I _think_ this function is intended to work around the Pentium
2240 * fdiv bug.
2241 */
2242void __stdcall _adj_fdivr_m32i( int arg )
2243{
2244 TRACE("(): stub\n");
2245}
2246
2247/***********************************************************************
2248 * _adj_fdivr_m64 (MSVCRT.@)
2249 *
2250 * NOTE
2251 * I _think_ this function is intended to work around the Pentium
2252 * fdiv bug.
2253 */
2254void __stdcall _adj_fdivr_m64( unsigned __int64 arg )
2255{
2256 TRACE("(): stub\n");
2257}
2258
2259/***********************************************************************
2260 * _adj_fpatan (MSVCRT.@)
2261 * FIXME
2262 * This function is likely to have the wrong number of arguments.
2263 *
2264 * NOTE
2265 * I _think_ this function is intended to work around the Pentium
2266 * fdiv bug.
2267 */
2268void _adj_fpatan(void)
2269{
2270 TRACE("(): stub\n");
2271}
2272
2273/***********************************************************************
2274 * _adj_fprem (MSVCRT.@)
2275 * FIXME
2276 * This function is likely to have the wrong number of arguments.
2277 *
2278 * NOTE
2279 * I _think_ this function is intended to work around the Pentium
2280 * fdiv bug.
2281 */
2282void _adj_fprem(void)
2283{
2284 TRACE("(): stub\n");
2285}
2286
2287/***********************************************************************
2288 * _adj_fprem1 (MSVCRT.@)
2289 * FIXME
2290 * This function is likely to have the wrong number of arguments.
2291 *
2292 * NOTE
2293 * I _think_ this function is intended to work around the Pentium
2294 * fdiv bug.
2295 */
2296void _adj_fprem1(void)
2297{
2298 TRACE("(): stub\n");
2299}
2300
2301/***********************************************************************
2302 * _adj_fptan (MSVCRT.@)
2303 * FIXME
2304 * This function is likely to have the wrong number of arguments.
2305 *
2306 * NOTE
2307 * I _think_ this function is intended to work around the Pentium
2308 * fdiv bug.
2309 */
2310void _adj_fptan(void)
2311{
2312 TRACE("(): stub\n");
2313}
2314
2315/***********************************************************************
2316 * _safe_fdiv (MSVCRT.@)
2317 * FIXME
2318 * This function is likely to have the wrong number of arguments.
2319 *
2320 * NOTE
2321 * I _think_ this function is intended to work around the Pentium
2322 * fdiv bug.
2323 */
2324void _safe_fdiv(void)
2325{
2326 TRACE("(): stub\n");
2327}
2328
2329/***********************************************************************
2330 * _safe_fdivr (MSVCRT.@)
2331 * FIXME
2332 * This function is likely to have the wrong number of arguments.
2333 *
2334 * NOTE
2335 * I _think_ this function is intended to work around the Pentium
2336 * fdiv bug.
2337 */
2338void _safe_fdivr(void)
2339{
2340 TRACE("(): stub\n");
2341}
2342
2343/***********************************************************************
2344 * _safe_fprem (MSVCRT.@)
2345 * FIXME
2346 * This function is likely to have the wrong number of arguments.
2347 *
2348 * NOTE
2349 * I _think_ this function is intended to work around the Pentium
2350 * fdiv bug.
2351 */
2352void _safe_fprem(void)
2353{
2354 TRACE("(): stub\n");
2355}
2356
2357/***********************************************************************
2358 * _safe_fprem1 (MSVCRT.@)
2359 *
2360 * FIXME
2361 * This function is likely to have the wrong number of arguments.
2362 *
2363 * NOTE
2364 * I _think_ this function is intended to work around the Pentium
2365 * fdiv bug.
2366 */
2367void _safe_fprem1(void)
2368{
2369 TRACE("(): stub\n");
2370}
2371
2372#ifndef __REACTOS__
2373/***********************************************************************
2374 * __libm_sse2_acos (MSVCRT.@)
2375 */
2376void __cdecl __libm_sse2_acos(void)
2377{
2378 double d;
2379 __asm__ __volatile__( "movq %%xmm0,%0" : "=m" (d) );
2380 d = acos( d );
2381 __asm__ __volatile__( "movq %0,%%xmm0" : : "m" (d) );
2382}
2383
2384/***********************************************************************
2385 * __libm_sse2_acosf (MSVCRT.@)
2386 */
2387void __cdecl __libm_sse2_acosf(void)
2388{
2389 float f;
2390 __asm__ __volatile__( "movd %%xmm0,%0" : "=g" (f) );
2391 f = acosf( f );
2392 __asm__ __volatile__( "movd %0,%%xmm0" : : "g" (f) );
2393}
2394
2395/***********************************************************************
2396 * __libm_sse2_asin (MSVCRT.@)
2397 */
2398void __cdecl __libm_sse2_asin(void)
2399{
2400 double d;
2401 __asm__ __volatile__( "movq %%xmm0,%0" : "=m" (d) );
2402 d = asin( d );
2403 __asm__ __volatile__( "movq %0,%%xmm0" : : "m" (d) );
2404}
2405
2406/***********************************************************************
2407 * __libm_sse2_asinf (MSVCRT.@)
2408 */
2409void __cdecl __libm_sse2_asinf(void)
2410{
2411 float f;
2412 __asm__ __volatile__( "movd %%xmm0,%0" : "=g" (f) );
2413 f = asinf( f );
2414 __asm__ __volatile__( "movd %0,%%xmm0" : : "g" (f) );
2415}
2416
2417/***********************************************************************
2418 * __libm_sse2_atan (MSVCRT.@)
2419 */
2420void __cdecl __libm_sse2_atan(void)
2421{
2422 double d;
2423 __asm__ __volatile__( "movq %%xmm0,%0" : "=m" (d) );
2424 d = atan( d );
2425 __asm__ __volatile__( "movq %0,%%xmm0" : : "m" (d) );
2426}
2427
2428/***********************************************************************
2429 * __libm_sse2_atan2 (MSVCRT.@)
2430 */
2431void __cdecl __libm_sse2_atan2(void)
2432{
2433 double d1, d2;
2434 __asm__ __volatile__( "movq %%xmm0,%0; movq %%xmm1,%1 " : "=m" (d1), "=m" (d2) );
2435 d1 = atan2( d1, d2 );
2436 __asm__ __volatile__( "movq %0,%%xmm0" : : "m" (d1) );
2437}
2438
2439/***********************************************************************
2440 * __libm_sse2_atanf (MSVCRT.@)
2441 */
2442void __cdecl __libm_sse2_atanf(void)
2443{
2444 float f;
2445 __asm__ __volatile__( "movd %%xmm0,%0" : "=g" (f) );
2446 f = atanf( f );
2447 __asm__ __volatile__( "movd %0,%%xmm0" : : "g" (f) );
2448}
2449
2450/***********************************************************************
2451 * __libm_sse2_cos (MSVCRT.@)
2452 */
2453void __cdecl __libm_sse2_cos(void)
2454{
2455 double d;
2456 __asm__ __volatile__( "movq %%xmm0,%0" : "=m" (d) );
2457 d = cos( d );
2458 __asm__ __volatile__( "movq %0,%%xmm0" : : "m" (d) );
2459}
2460
2461/***********************************************************************
2462 * __libm_sse2_cosf (MSVCRT.@)
2463 */
2464void __cdecl __libm_sse2_cosf(void)
2465{
2466 float f;
2467 __asm__ __volatile__( "movd %%xmm0,%0" : "=g" (f) );
2468 f = cosf( f );
2469 __asm__ __volatile__( "movd %0,%%xmm0" : : "g" (f) );
2470}
2471
2472/***********************************************************************
2473 * __libm_sse2_exp (MSVCRT.@)
2474 */
2475void __cdecl __libm_sse2_exp(void)
2476{
2477 double d;
2478 __asm__ __volatile__( "movq %%xmm0,%0" : "=m" (d) );
2479 d = exp( d );
2480 __asm__ __volatile__( "movq %0,%%xmm0" : : "m" (d) );
2481}
2482
2483/***********************************************************************
2484 * __libm_sse2_expf (MSVCRT.@)
2485 */
2486void __cdecl __libm_sse2_expf(void)
2487{
2488 float f;
2489 __asm__ __volatile__( "movd %%xmm0,%0" : "=g" (f) );
2490 f = expf( f );
2491 __asm__ __volatile__( "movd %0,%%xmm0" : : "g" (f) );
2492}
2493
2494/***********************************************************************
2495 * __libm_sse2_log (MSVCRT.@)
2496 */
2497void __cdecl __libm_sse2_log(void)
2498{
2499 double d;
2500 __asm__ __volatile__( "movq %%xmm0,%0" : "=m" (d) );
2501 d = log( d );
2502 __asm__ __volatile__( "movq %0,%%xmm0" : : "m" (d) );
2503}
2504
2505/***********************************************************************
2506 * __libm_sse2_log10 (MSVCRT.@)
2507 */
2508void __cdecl __libm_sse2_log10(void)
2509{
2510 double d;
2511 __asm__ __volatile__( "movq %%xmm0,%0" : "=m" (d) );
2512 d = log10( d );
2513 __asm__ __volatile__( "movq %0,%%xmm0" : : "m" (d) );
2514}
2515
2516/***********************************************************************
2517 * __libm_sse2_log10f (MSVCRT.@)
2518 */
2519void __cdecl __libm_sse2_log10f(void)
2520{
2521 float f;
2522 __asm__ __volatile__( "movd %%xmm0,%0" : "=g" (f) );
2523 f = log10f( f );
2524 __asm__ __volatile__( "movd %0,%%xmm0" : : "g" (f) );
2525}
2526
2527/***********************************************************************
2528 * __libm_sse2_logf (MSVCRT.@)
2529 */
2530void __cdecl __libm_sse2_logf(void)
2531{
2532 float f;
2533 __asm__ __volatile__( "movd %%xmm0,%0" : "=g" (f) );
2534 f = logf( f );
2535 __asm__ __volatile__( "movd %0,%%xmm0" : : "g" (f) );
2536}
2537
2538/***********************************************************************
2539 * __libm_sse2_pow (MSVCRT.@)
2540 */
2541void __cdecl __libm_sse2_pow(void)
2542{
2543 double d1, d2;
2544 __asm__ __volatile__( "movq %%xmm0,%0; movq %%xmm1,%1 " : "=m" (d1), "=m" (d2) );
2545 d1 = pow( d1, d2 );
2546 __asm__ __volatile__( "movq %0,%%xmm0" : : "m" (d1) );
2547}
2548
2549/***********************************************************************
2550 * __libm_sse2_powf (MSVCRT.@)
2551 */
2552void __cdecl __libm_sse2_powf(void)
2553{
2554 float f1, f2;
2555 __asm__ __volatile__( "movd %%xmm0,%0; movd %%xmm1,%1" : "=g" (f1), "=g" (f2) );
2556 f1 = powf( f1, f2 );
2557 __asm__ __volatile__( "movd %0,%%xmm0" : : "g" (f1) );
2558}
2559
2560/***********************************************************************
2561 * __libm_sse2_sin (MSVCRT.@)
2562 */
2563void __cdecl __libm_sse2_sin(void)
2564{
2565 double d;
2566 __asm__ __volatile__( "movq %%xmm0,%0" : "=m" (d) );
2567 d = sin( d );
2568 __asm__ __volatile__( "movq %0,%%xmm0" : : "m" (d) );
2569}
2570
2571/***********************************************************************
2572 * __libm_sse2_sinf (MSVCRT.@)
2573 */
2574void __cdecl __libm_sse2_sinf(void)
2575{
2576 float f;
2577 __asm__ __volatile__( "movd %%xmm0,%0" : "=g" (f) );
2578 f = sinf( f );
2579 __asm__ __volatile__( "movd %0,%%xmm0" : : "g" (f) );
2580}
2581
2582/***********************************************************************
2583 * __libm_sse2_tan (MSVCRT.@)
2584 */
2585void __cdecl __libm_sse2_tan(void)
2586{
2587 double d;
2588 __asm__ __volatile__( "movq %%xmm0,%0" : "=m" (d) );
2589 d = tan( d );
2590 __asm__ __volatile__( "movq %0,%%xmm0" : : "m" (d) );
2591}
2592
2593/***********************************************************************
2594 * __libm_sse2_tanf (MSVCRT.@)
2595 */
2596void __cdecl __libm_sse2_tanf(void)
2597{
2598 float f;
2599 __asm__ __volatile__( "movd %%xmm0,%0" : "=g" (f) );
2600 f = tanf( f );
2601 __asm__ __volatile__( "movd %0,%%xmm0" : : "g" (f) );
2602}
2603
2604/***********************************************************************
2605 * __libm_sse2_sqrt_precise (MSVCR110.@)
2606 */
2607void __cdecl __libm_sse2_sqrt_precise(void)
2608{
2609 unsigned int cw;
2610 double d;
2611
2612 __asm__ __volatile__( "movq %%xmm0,%0" : "=m" (d) );
2613 __control87_2(0, 0, NULL, &cw);
2614 if (cw & _MCW_RC)
2615 {
2616 d = sqrt(d);
2617 __asm__ __volatile__( "movq %0,%%xmm0" : : "m" (d) );
2618 return;
2619 }
2620
2621 if (!sqrt_validate(&d, FALSE))
2622 {
2623 __asm__ __volatile__( "movq %0,%%xmm0" : : "m" (d) );
2624 return;
2625 }
2626 __asm__ __volatile__( "sqrtsd %xmm0, %xmm0" );
2627}
2628#endif /* !__REACTOS__ */
2629#endif /* __i386__ */
2630
2631#if _MSVCR_VER>=120
2632
2633/*********************************************************************
2634 * lrint (MSVCR120.@)
2635 */
2636__msvcrt_long CDECL lrint(double x)
2637{
2638 double d;
2639
2640 d = MSVCRT_rint(x);
2641 if ((d < 0 && d != (double)(__msvcrt_long)d)
2642 || (d >= 0 && d != (double)(__msvcrt_ulong)d)) {
2643 *_errno() = EDOM;
2644 return 0;
2645 }
2646 return d;
2647}
2648
2649/*********************************************************************
2650 * lrintf (MSVCR120.@)
2651 */
2653{
2654 float f;
2655
2656 f = rintf(x);
2657 if ((f < 0 && f != (float)(__msvcrt_long)f)
2658 || (f >= 0 && f != (float)(__msvcrt_ulong)f)) {
2659 *_errno() = EDOM;
2660 return 0;
2661 }
2662 return f;
2663}
2664
2665/*********************************************************************
2666 * llrint (MSVCR120.@)
2667 */
2668__int64 CDECL llrint(double x)
2669{
2670 double d;
2671
2672 d = MSVCRT_rint(x);
2673 if ((d < 0 && d != (double)(__int64)d)
2674 || (d >= 0 && d != (double)(unsigned __int64)d)) {
2675 *_errno() = EDOM;
2676 return 0;
2677 }
2678 return d;
2679}
2680
2681/*********************************************************************
2682 * llrintf (MSVCR120.@)
2683 */
2684__int64 CDECL llrintf(float x)
2685{
2686 float f;
2687
2688 f = rintf(x);
2689 if ((f < 0 && f != (float)(__int64)f)
2690 || (f >= 0 && f != (float)(unsigned __int64)f)) {
2691 *_errno() = EDOM;
2692 return 0;
2693 }
2694 return f;
2695}
2696
2697/*********************************************************************
2698 * lround (MSVCR120.@)
2699 *
2700 * Copied from musl: src/math/lround.c
2701 */
2703{
2704 double d = round(x);
2705 if (d != (double)(__msvcrt_long)d) {
2706 *_errno() = EDOM;
2707 return 0;
2708 }
2709 return d;
2710}
2711
2712/*********************************************************************
2713 * lroundf (MSVCR120.@)
2714 *
2715 * Copied from musl: src/math/lroundf.c
2716 */
2718{
2719 float f = roundf(x);
2720 if (f != (float)(__msvcrt_long)f) {
2721 *_errno() = EDOM;
2722 return 0;
2723 }
2724 return f;
2725}
2726
2727/*********************************************************************
2728 * llround (MSVCR120.@)
2729 *
2730 * Copied from musl: src/math/llround.c
2731 */
2732__int64 CDECL llround(double x)
2733{
2734 double d = round(x);
2735 if (d != (double)(__int64)d) {
2736 *_errno() = EDOM;
2737 return 0;
2738 }
2739 return d;
2740}
2741
2742/*********************************************************************
2743 * llroundf (MSVCR120.@)
2744 *
2745 * Copied from musl: src/math/llroundf.c
2746 */
2747__int64 CDECL llroundf(float x)
2748{
2749 float f = roundf(x);
2750 if (f != (float)(__int64)f) {
2751 *_errno() = EDOM;
2752 return 0;
2753 }
2754 return f;
2755}
2756
2757/*********************************************************************
2758 * _dtest (MSVCR120.@)
2759 */
2760short CDECL _dtest(double *x)
2761{
2762 return _dclass(*x);
2763}
2764
2765/*********************************************************************
2766 * _fdtest (MSVCR120.@)
2767 */
2768short CDECL _fdtest(float *x)
2769{
2770 return _fdclass(*x);
2771}
2772
2773/*********************************************************************
2774 * _fdsign (MSVCR120.@)
2775 */
2776int CDECL _fdsign(float x)
2777{
2778 union { float f; UINT32 i; } u = { x };
2779 return (u.i >> 16) & 0x8000;
2780}
2781
2782/*********************************************************************
2783 * _dsign (MSVCR120.@)
2784 */
2785int CDECL _dsign(double x)
2786{
2787 union { double f; UINT64 i; } u = { x };
2788 return (u.i >> 48) & 0x8000;
2789}
2790
2791/*********************************************************************
2792 * _dpcomp (MSVCR120.@)
2793 */
2794int CDECL _dpcomp(double x, double y)
2795{
2796 if(isnan(x) || isnan(y))
2797 return 0;
2798
2799 if(x == y) return 2;
2800 return x < y ? 1 : 4;
2801}
2802
2803/*********************************************************************
2804 * _fdpcomp (MSVCR120.@)
2805 */
2806int CDECL _fdpcomp(float x, float y)
2807{
2808 return _dpcomp(x, y);
2809}
2810
2811/*********************************************************************
2812 * acosh (MSVCR120.@)
2813 */
2814double CDECL MSVCRT_acosh(double x)
2815{
2816 if (x < 1)
2817 {
2818 *_errno() = EDOM;
2820 return NAN;
2821 }
2822 return acosh( x );
2823}
2824
2825/*********************************************************************
2826 * acoshf (MSVCR120.@)
2827 */
2828float CDECL MSVCRT_acoshf(float x)
2829{
2830 if (x < 1)
2831 {
2832 *_errno() = EDOM;
2834 return NAN;
2835 }
2836 return acoshf( x );
2837}
2838
2839/*********************************************************************
2840 * atanh (MSVCR120.@)
2841 */
2842double CDECL MSVCRT_atanh(double x)
2843{
2844 if (fabs(x) > 1)
2845 {
2846 *_errno() = EDOM;
2848 return NAN;
2849 }
2850 return atanh( x );
2851}
2852
2853/*********************************************************************
2854 * atanhf (MSVCR120.@)
2855 */
2856float CDECL MSVCRT_atanhf(float x)
2857{
2858 if (fabs(x) > 1)
2859 {
2860 *_errno() = EDOM;
2862 return NAN;
2863 }
2864 return atanhf( x );
2865}
2866
2867#endif /* _MSVCR_VER>=120 */
2868
2869/*********************************************************************
2870 * _scalb (MSVCRT.@)
2871 * scalbn (MSVCR120.@)
2872 * scalbln (MSVCR120.@)
2873 */
2875{
2876 return ldexp(num, power);
2877}
2878
2879/*********************************************************************
2880 * _scalbf (MSVCRT.@)
2881 * scalbnf (MSVCR120.@)
2882 * scalblnf (MSVCR120.@)
2883 */
2885{
2886 return ldexp(num, power);
2887}
2888
2889#if _MSVCR_VER == 120 /* other versions call remainder() directly */
2890
2891/*********************************************************************
2892 * remainder (MSVCR120.@)
2893 */
2894double CDECL MSVCRT_remainder(double x, double y)
2895{
2896#ifdef __x86_64__
2897 if (isnan(x) || isnan(y)) *_errno() = EDOM;
2898#endif
2899 return remainder(x, y);
2900}
2901
2902/*********************************************************************
2903 * remainderf (MSVCR120.@)
2904 */
2905float CDECL MSVCRT_remainderf(float x, float y)
2906{
2907#ifdef __x86_64__
2908 if (isnan(x) || isnan(y)) *_errno() = EDOM;
2909#endif
2910 return remainderf(x, y);
2911}
2912
2913#endif /* _MSVCR_VER == 120 */
2914
2915#if _MSVCR_VER>=120
2916
2917/*********************************************************************
2918 * _except1 (MSVCR120.@)
2919 * TODO:
2920 * - find meaning of ignored cw and operation bits
2921 * - unk parameter
2922 */
2923double CDECL _except1(DWORD fpe, _FP_OPERATION_CODE op, double arg, double res, DWORD cw, void *unk)
2924{
2925 ULONG_PTR exception_arg;
2926 DWORD exception = 0;
2927 unsigned int fpword = 0;
2929 int raise = 0;
2930
2931 TRACE("(%lx %x %lf %lf %lx %p)\n", fpe, op, arg, res, cw, unk);
2932
2933#ifdef _WIN64
2934 cw = ((cw >> 7) & 0x3f) | ((cw >> 3) & 0xc00);
2935#endif
2936 operation = op << 5;
2937 exception_arg = (ULONG_PTR)&operation;
2938
2939 if (fpe & 0x1) { /* overflow */
2940 if ((fpe == 0x1 && (cw & 0x8)) || (fpe==0x11 && (cw & 0x28))) {
2941 /* 32-bit version also sets SW_INEXACT here */
2942 raise |= FE_OVERFLOW;
2943 if (fpe & 0x10) raise |= FE_INEXACT;
2945 } else {
2947 }
2948 } else if (fpe & 0x2) { /* underflow */
2949 if ((fpe == 0x2 && (cw & 0x10)) || (fpe==0x12 && (cw & 0x30))) {
2951 if (fpe & 0x10) raise |= FE_INEXACT;
2952 res = signbit(res) ? -0.0 : 0.0;
2953 } else {
2955 }
2956 } else if (fpe & 0x4) { /* zerodivide */
2957 if ((fpe == 0x4 && (cw & 0x4)) || (fpe==0x14 && (cw & 0x24))) {
2959 if (fpe & 0x10) raise |= FE_INEXACT;
2960 } else {
2962 }
2963 } else if (fpe & 0x8) { /* invalid */
2964 if (fpe == 0x8 && (cw & 0x1)) {
2965 raise |= FE_INVALID;
2966 } else {
2968 }
2969 } else if (fpe & 0x10) { /* inexact */
2970 if (fpe == 0x10 && (cw & 0x20)) {
2971 raise |= FE_INEXACT;
2972 } else {
2974 }
2975 }
2976
2977 if (exception)
2978 raise = 0;
2980 if (exception)
2981 RaiseException(exception, 0, 1, &exception_arg);
2982
2983 if (cw & 0x1) fpword |= _EM_INVALID;
2984 if (cw & 0x2) fpword |= _EM_DENORMAL;
2985 if (cw & 0x4) fpword |= _EM_ZERODIVIDE;
2986 if (cw & 0x8) fpword |= _EM_OVERFLOW;
2987 if (cw & 0x10) fpword |= _EM_UNDERFLOW;
2988 if (cw & 0x20) fpword |= _EM_INEXACT;
2989 switch (cw & 0xc00)
2990 {
2991 case 0xc00: fpword |= _RC_UP|_RC_DOWN; break;
2992 case 0x800: fpword |= _RC_UP; break;
2993 case 0x400: fpword |= _RC_DOWN; break;
2994 }
2995 switch (cw & 0x300)
2996 {
2997 case 0x0: fpword |= _PC_24; break;
2998 case 0x200: fpword |= _PC_53; break;
2999 case 0x300: fpword |= _PC_64; break;
3000 }
3001 if (cw & 0x1000) fpword |= _IC_AFFINE;
3002 _setfp(&fpword, _MCW_EM | _MCW_RC | _MCW_PC | _MCW_IC, NULL, 0);
3003
3004 return res;
3005}
3006
3007_Dcomplex* CDECL _Cbuild(_Dcomplex *ret, double r, double i)
3008{
3009 ret->_Val[0] = r;
3010 ret->_Val[1] = i;
3011 return ret;
3012}
3013
3014double CDECL MSVCR120_creal(_Dcomplex z)
3015{
3016 return z._Val[0];
3017}
3018
3019#endif /* _MSVCR_VER>=120 */
unsigned long long UINT64
unsigned int UINT32
#define stat
Definition: acwin.h:99
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
operation
Definition: copy.c:29
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
double CDECL _CIsinh(void)
Definition: ci.c:14
double CDECL _CIatan(void)
Definition: ci.c:54
double CDECL _CIatan2(void)
Definition: ci.c:62
double CDECL _CIasin(void)
Definition: ci.c:38
double CDECL _CIfmod(void)
Definition: ci.c:86
double CDECL _CItanh(void)
Definition: ci.c:30
double CDECL _CIcosh(void)
Definition: ci.c:22
double CDECL _CIacos(void)
Definition: ci.c:46
double CDECL _CIlog10(void)
Definition: ci.c:78
double CDECL _CIexp(void)
Definition: ci.c:70
double CDECL _CItan(void)
Definition: ci.c:6
double CDECL _CIcos(void)
Definition: cicos.c:6
double CDECL _CIlog(void)
Definition: cilog.c:6
double CDECL _CIpow(void)
Definition: cipow.c:6
double CDECL _CIsin(void)
Definition: cisin.c:6
double CDECL _CIsqrt(void)
Definition: cisqrt.c:6
Definition: _set.h:50
_Check_return_ _ACRTIMP int __cdecl _fdsign(_In_ float _X)
Definition: _fdsign.c:14
_Check_return_ _ACRTIMP int __cdecl _dpcomp(_In_ double _X, _In_ double _Y)
_Check_return_ _ACRTIMP int __cdecl _fdpcomp(_In_ float _X, _In_ float _Y)
_Check_return_ _ACRTIMP int __cdecl _dsign(_In_ double _X)
Definition: _dsign.c:14
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp:171
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define __attribute__(x)
Definition: wpp_private.h:207
UINT op
Definition: effect.c:236
#define NTSTATUS
Definition: precomp.h:19
#define CDECL
Definition: compat.h:29
VOID WINAPI RaiseException(_In_ DWORD dwExceptionCode, _In_ DWORD dwExceptionFlags, _In_ DWORD nNumberOfArguments, _In_opt_ const ULONG_PTR *lpArguments)
Definition: except.c:700
BOOL WINAPI IsProcessorFeaturePresent(IN DWORD ProcessorFeature)
Definition: sysinfo.c:169
int *CDECL _errno(void)
Definition: errno.c:215
int CDECL raise(int sig)
Definition: except.c:682
#define assert(_expr)
Definition: assert.h:32
long __msvcrt_long
Definition: corecrt.h:167
#define __cdecl
Definition: corecrt.h:121
#define __int64
Definition: corecrt.h:72
#define __stdcall
Definition: corecrt.h:120
unsigned long __msvcrt_ulong
Definition: corecrt.h:168
#define EINVAL
Definition: errno.h:44
#define EDOM
Definition: errno.h:54
#define ERANGE
Definition: errno.h:55
#define FE_ALL_EXCEPT
Definition: fenv.h:21
_ACRTIMP int __cdecl fesetenv(const fenv_t *)
_ACRTIMP int __cdecl fesetexceptflag(const fexcept_t *, int)
#define FE_UNDERFLOW
Definition: fenv.h:17
#define FE_INVALID
Definition: fenv.h:20
_ACRTIMP int __cdecl fegetround(void)
_ACRTIMP int __cdecl fegetenv(fenv_t *)
#define FE_INEXACT
Definition: fenv.h:16
_ACRTIMP int __cdecl fegetexceptflag(fexcept_t *, int)
__msvcrt_ulong fexcept_t
Definition: fenv.h:33
_ACRTIMP int __cdecl feclearexcept(int)
_ACRTIMP int __cdecl fesetround(int)
_ACRTIMP int __cdecl fetestexcept(int)
#define FE_DIVBYZERO
Definition: fenv.h:19
#define FE_OVERFLOW
Definition: fenv.h:18
_ACRTIMP int __cdecl feholdexcept(fenv_t *)
#define _FPCLASS_PZ
Definition: float.h:113
#define _FPCLASS_PD
Definition: float.h:114
#define _IC_AFFINE
Definition: float.h:77
#define _DN_SAVE_OPERANDS_FLUSH_RESULTS
Definition: float.h:89
#define _RC_UP
Definition: float.h:80
#define _MCW_EM
Definition: float.h:64
#define _SW_INEXACT
Definition: float.h:93
#define _FPCLASS_PN
Definition: float.h:115
#define _PC_64
Definition: float.h:85
#define _SW_OVERFLOW
Definition: float.h:95
#define _EM_UNDERFLOW
Definition: float.h:75
#define _FPCLASS_ND
Definition: float.h:111
#define _MCW_PC
Definition: float.h:67
#define _FPCLASS_QNAN
Definition: float.h:108
#define _SW_DENORMAL
Definition: float.h:104
#define _MCW_RC
Definition: float.h:66
#define _EM_ZERODIVIDE
Definition: float.h:73
#define _EM_INEXACT
Definition: float.h:76
#define _EM_OVERFLOW
Definition: float.h:74
#define _MCW_IC
Definition: float.h:65
#define _MCW_DN
Definition: float.h:68
#define _FPCLASS_NINF
Definition: float.h:109
#define _EM_AMBIGUOUS
Definition: float.h:90
#define _FPCLASS_NN
Definition: float.h:110
#define _FPCLASS_SNAN
Definition: float.h:107
#define _EM_INVALID
Definition: float.h:71
#define _PC_24
Definition: float.h:83
_ACRTIMP int __cdecl __fpe_flt_rounds(void)
#define _FPCLASS_NZ
Definition: float.h:112
#define _FPCLASS_PINF
Definition: float.h:116
#define _SW_ZERODIVIDE
Definition: float.h:96
#define _DN_FLUSH
Definition: float.h:87
#define _DN_FLUSH_OPERANDS_SAVE_RESULTS
Definition: float.h:88
#define _EM_DENORMAL
Definition: float.h:72
#define _RC_NEAR
Definition: float.h:82
#define _SW_UNDERFLOW
Definition: float.h:94
#define _RC_DOWN
Definition: float.h:81
#define _RC_CHOP
Definition: float.h:79
#define _SW_INVALID
Definition: float.h:97
#define _PC_53
Definition: float.h:84
_FP_OPERATION_CODE
Definition: fpieee.h:37
_ACRTIMP float __cdecl asinf(float)
Definition: asinf.c:47
_ACRTIMP float __cdecl atanf(float)
Definition: atanf.c:47
_ACRTIMP __int64 __cdecl llrint(double)
Definition: mingw_math.h:395
_ACRTIMP float __cdecl powf(float, float)
Definition: powf.c:14
#define FP_NAN
Definition: math.h:278
#define isfinite(x)
Definition: math.h:363
_ACRTIMP double __cdecl scalbn(double, int)
Definition: scalbn.c:14
#define isnan(x)
Definition: math.h:360
_ACRTIMP double __cdecl cosh(double)
Definition: cosh.c:11
#define FP_ZERO
Definition: math.h:281
_ACRTIMP double __cdecl sqrt(double)
Definition: sqrt.c:5
_ACRTIMP double __cdecl sinh(double)
Definition: sinh.c:50
_ACRTIMP double __cdecl fabs(double)
#define FP_INFINITE
Definition: math.h:277
_ACRTIMP double __cdecl tanh(double)
Definition: tanh.c:46
_ACRTIMP float __cdecl acosf(float)
Definition: acosf.c:47
_ACRTIMP double __cdecl atan(double)
Definition: atan.c:44
_ACRTIMP __msvcrt_long __cdecl lrint(double)
Definition: mingw_math.h:371
_ACRTIMP __int64 __cdecl llrintf(float)
Definition: mingw_math.h:403
_ACRTIMP float __cdecl rintf(float)
Definition: mingw_math.h:357
_ACRTIMP __msvcrt_long __cdecl lround(double)
_ACRTIMP double __cdecl sin(double)
Definition: sin.c:21
_ACRTIMP __int64 __cdecl llroundf(float)
_ACRTIMP float __cdecl cosf(float)
Definition: cosf.c:13
_ACRTIMP float __cdecl nearbyintf(float)
_ACRTIMP float __cdecl sinf(float)
Definition: sinf.c:13
_ACRTIMP short __cdecl _fdtest(float *)
_ACRTIMP __int64 __cdecl llround(double)
#define NAN
Definition: math.h:273
_ACRTIMP float __cdecl remainderf(float, float)
Definition: remainderf.c:60
_ACRTIMP double __cdecl tan(double)
Definition: tan.c:122
#define INFINITY
Definition: math.h:272
_ACRTIMP double __cdecl fmod(double, double)
_ACRTIMP float __cdecl logf(float)
Definition: logf.c:12
_ACRTIMP float __cdecl tanhf(float)
Definition: tanhf.c:49
_ACRTIMP double __cdecl remainder(double, double)
Definition: remainder.c:75
#define signbit(x)
Definition: math.h:362
_ACRTIMP float __cdecl log10f(float)
_ACRTIMP short __cdecl _dtest(double *)
_ACRTIMP double __cdecl asin(double)
Definition: asin.c:31
_ACRTIMP double __cdecl nearbyint(double)
_ACRTIMP float __cdecl roundf(float)
Definition: roundf.c:10
_ACRTIMP float __cdecl tanf(float)
Definition: tanf.c:72
_ACRTIMP float __cdecl atanhf(float)
_ACRTIMP double __cdecl cos(double)
Definition: cos.c:21
_ACRTIMP __msvcrt_long __cdecl lroundf(float)
_ACRTIMP double __cdecl atan2(double, double)
Definition: atan2.c:52
_ACRTIMP __msvcrt_long __cdecl lrintf(float)
Definition: mingw_math.h:379
_ACRTIMP double __cdecl acos(double)
Definition: acos.c:28
_ACRTIMP float __cdecl expf(float)
_ACRTIMP double __cdecl rint(double)
Definition: mingw_math.h:350
_ACRTIMP float __cdecl acoshf(float)
long long intmax_t
Definition: stdint.h:65
_ACRTIMP int __cdecl _scprintf(const char *,...) __WINE_CRT_PRINTF_ATTR(1
_ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl sscanf(const char *, const char *,...) __WINE_CRT_SCANF_ATTR(2
_ACRTIMP lldiv_t __cdecl lldiv(__int64, __int64)
_ACRTIMP __int64 __cdecl llabs(__int64)
#define SET_X87_CW(MASK)
Definition: math.c:91
int(CDECL * MSVCRT_matherr_func)(struct _exception *)
Definition: math.c:67
#define _DOMAIN
Definition: math.c:62
#define _SING
Definition: math.c:63
int CDECL _controlfp_s(unsigned int *cur, unsigned int newval, unsigned int mask)
Definition: math.c:1304
char *CDECL _gcvt(double number, int ndigit, char *buff)
Definition: math.c:2008
unsigned __int64 CDECL MSVCRT__rotr64(unsigned __int64 num, int shift)
Definition: math.c:663
__msvcrt_ulong CDECL MSVCRT__lrotr(__msvcrt_ulong num, int shift)
Definition: math.c:636
#define _UNDERFLOW
Definition: math.c:65
__msvcrt_ulong CDECL MSVCRT__lrotl(__msvcrt_ulong num, int shift)
Definition: math.c:627
static BOOL sqrtf_validate(float *x)
Definition: math.c:268
void CDECL _set_controlfp(unsigned int newval, unsigned int mask)
Definition: math.c:1296
unsigned int CDECL _statusfp(void)
Definition: math.c:1156
static BOOL sse2_enabled
Definition: math.c:72
float CDECL _chgsignf(float num)
Definition: math.c:203
#define RESET_X87_CW
Definition: math.c:104
void CDECL __setusermatherr(MSVCRT_matherr_func func)
Definition: math.c:159
double CDECL MSVCRT_asin(double x)
Definition: math.c:352
int CDECL _fpclassf(float num)
Definition: math.c:217
short CDECL _fdclass(float x)
int CDECL _matherr(struct _exception *e)
Definition: math.c:119
double CDECL MSVCRT_atan(double x)
Definition: math.c:380
double CDECL MSVCRT_tanh(double x)
Definition: math.c:464
BOOL sse2_supported
Definition: math.c:71
int CDECL _finitef(float num)
Definition: math.c:239
int *CDECL __fpecode(void)
Definition: math.c:1195
double CDECL MSVCRT_exp(double x)
Definition: math.c:391
double CDECL _scalb(double num, __msvcrt_long power)
Definition: math.c:2874
double CDECL _chgsign(double num)
Definition: math.c:1227
unsigned int CDECL _clearfp(void)
Definition: math.c:1174
static MSVCRT_matherr_func MSVCRT_default_matherr_func
Definition: math.c:69
static void _setfp(unsigned int *cw, unsigned int cw_mask, unsigned int *sw, unsigned int sw_mask)
Definition: math.c:842
div_t CDECL div(int num, int denom)
Definition: math.c:2081
static BOOL sqrt_validate(double *x, BOOL update_sw)
Definition: math.c:400
int CDECL _finite(double num)
Definition: math.c:1582
int CDECL _isnanf(float num)
Definition: math.c:248
void CDECL _fpreset(void)
Definition: math.c:1591
int CDECL _isnan(double num)
Definition: math.c:1660
double CDECL _cabs(struct _complex num)
Definition: math.c:1219
float CDECL MSVCRT_atanf(float x)
Definition: math.c:258
unsigned int CDECL _controlfp(unsigned int newval, unsigned int mask)
Definition: math.c:1288
__int64 CDECL _abs64(__int64 n)
Definition: math.c:711
static double ret_nan(BOOL update_sw)
Definition: math.c:84
ldiv_t CDECL ldiv(__msvcrt_long num, __msvcrt_long denom)
Definition: math.c:2115
unsigned int CDECL _control87(unsigned int newval, unsigned int mask)
Definition: math.c:1265
int CDECL _ecvt_s(char *buffer, size_t length, double number, int ndigits, int *decpt, int *sign)
Definition: math.c:1793
char *CDECL _ecvt(double number, int ndigits, int *decpt, int *sign)
Definition: math.c:1748
unsigned int CDECL MSVCRT__rotr(unsigned int num, int shift)
Definition: math.c:645
unsigned __int64 CDECL MSVCRT__rotl64(unsigned __int64 num, int shift)
Definition: math.c:654
double CDECL MSVCRT_sqrt(double x)
Definition: math.c:452
float CDECL MSVCRT_tanhf(float x)
Definition: math.c:319
char *CDECL _fcvt(double number, int ndigits, int *decpt, int *sign)
Definition: math.c:1840
short CDECL _dclass(double x)
unsigned int CDECL MSVCRT__rotl(unsigned int num, int shift)
Definition: math.c:618
double CDECL ldexp(double num, int exp)
Definition: math.c:1204
__msvcrt_long CDECL labs(__msvcrt_long n)
Definition: math.c:680
int CDECL _gcvt_s(char *buff, size_t size, double number, int digits)
Definition: math.c:2027
int CDECL _fcvt_s(char *outbuffer, size_t size, double number, int ndigits, int *decpt, int *sign)
Definition: math.c:1921
double math_error(int type, const char *name, double arg1, double arg2, double retval)
Definition: math.c:125
float CDECL MSVCRT_sqrtf(float x)
Definition: math.c:303
#define _OVERFLOW
Definition: math.c:64
int CDECL _fpclass(double num)
Definition: math.c:595
float CDECL _scalbf(float num, __msvcrt_long power)
Definition: math.c:2884
int CDECL _set_SSE2_enable(int flag)
Definition: math.c:168
thread_data_t *CDECL msvcrt_get_thread_data(void)
Definition: thread.c:45
#define MSVCRT_CHECK_PMT(x)
Definition: msvcrt.h:378
#define MSVCRT_CHECK_PMT_ERR(x, err)
Definition: msvcrt.h:377
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
return ret
Definition: mutex.c:146
unsigned long long uint64
Definition: platform.h:18
#define ULONG_PTR
Definition: config.h:101
static unsigned char buff[32768]
Definition: fatten.c:17
#define abs(i)
Definition: fconv.c:206
void _safe_fdiv(void)
Definition: fdivbug.c:69
void __stdcall _adj_fdivr_m32(unsigned int arg)
Definition: fdivbug.c:24
void __stdcall _adj_fdiv_m32i(int arg)
Definition: fdivbug.c:9
void __stdcall _adj_fdiv_m32(unsigned int arg)
Definition: fdivbug.c:5
void _adj_fpatan(void)
Definition: fdivbug.c:39
void _adj_fptan(void)
Definition: fdivbug.c:64
void _safe_fprem1(void)
Definition: fdivbug.c:84
void _safe_fprem(void)
Definition: fdivbug.c:79
void __stdcall _adj_fdivr_m16i(short arg)
Definition: fdivbug.c:49
void __stdcall _adj_fdivr_m64(unsigned __int64 arg)
Definition: fdivbug.c:34
void __stdcall _adj_fdivr_m32i(int arg)
Definition: fdivbug.c:29
void _safe_fdivr(void)
Definition: fdivbug.c:74
void _adj_fprem(void)
Definition: fdivbug.c:54
void __stdcall _adj_fdiv_m16i(short arg)
Definition: fdivbug.c:44
void _adj_fprem1(void)
Definition: fdivbug.c:59
void _adj_fdiv_r(void)
Definition: fdivbug.c:19
void __stdcall _adj_fdiv_m64(unsigned __int64 arg)
Definition: fdivbug.c:14
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
int __cdecl _set_FMA3_enable(int flag)
double log10(double x)
Definition: freeldr.c:190
double pow(double x, double y)
Definition: freeldr.c:178
double atanh(double x)
Definition: fun_ieee.c:63
double acosh(double x)
Definition: fun_ieee.c:54
FxCollectionEntry * cur
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLenum func
Definition: glext.h:6028
GLdouble n
Definition: glext.h:7729
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLuint GLuint GLuint GLuint arg1
Definition: glext.h:9513
const GLubyte * c
Definition: glext.h:8905
GLenum GLint GLuint mask
Definition: glext.h:6028
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:9514
GLfloat f
Definition: glext.h:7540
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
const GLint * first
Definition: glext.h:5794
GLuint GLfloat * val
Definition: glext.h:7180
GLuint64EXT * result
Definition: glext.h:11304
GLuint GLuint num
Definition: glext.h:9618
GLenum GLsizei len
Definition: glext.h:6722
GLdouble GLdouble z
Definition: glext.h:5874
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
static const int digits[]
Definition: decode.c:71
#define d
Definition: ke_i.h:81
#define e
Definition: ke_i.h:82
#define f
Definition: ke_i.h:83
#define debugstr_a
Definition: kernel32.h:31
__ATTRIBUTE_SSE2__ __m128 __libm_sse2_cosf(__m128 Xmm0)
Definition: libm_sse2.c:86
__ATTRIBUTE_SSE2__ __m128 __libm_sse2_log10f(__m128 Xmm0)
Definition: libm_sse2.c:134
__ATTRIBUTE_SSE2__ __m128d __libm_sse2_atan(__m128d Xmm0)
Definition: libm_sse2.c:55
__ATTRIBUTE_SSE2__ __m128d __libm_sse2_acos(__m128d Xmm0)
Definition: libm_sse2.c:23
__ATTRIBUTE_SSE2__ __m128d __libm_sse2_asin(__m128d Xmm0)
Definition: libm_sse2.c:39
__ATTRIBUTE_SSE2__ __m128 __libm_sse2_asinf(__m128 Xmm0)
Definition: libm_sse2.c:46
__ATTRIBUTE_SSE2__ __m128d __libm_sse2_cos(__m128d Xmm0)
Definition: libm_sse2.c:79
__ATTRIBUTE_SSE2__ __m128d __libm_sse2_pow(__m128d Xmm0, __m128d Xmm1)
Definition: libm_sse2.c:143
__ATTRIBUTE_SSE2__ __m128d __libm_sse2_tan(__m128d Xmm0)
Definition: libm_sse2.c:175
__ATTRIBUTE_SSE2__ __m128 __libm_sse2_atanf(__m128 Xmm0)
Definition: libm_sse2.c:62
__ATTRIBUTE_SSE2__ __m128 __libm_sse2_sinf(__m128 Xmm0)
Definition: libm_sse2.c:166
__ATTRIBUTE_SSE2__ __m128 __libm_sse2_expf(__m128 Xmm0)
Definition: libm_sse2.c:102
__ATTRIBUTE_SSE2__ __m128 __libm_sse2_logf(__m128 Xmm0)
Definition: libm_sse2.c:118
__ATTRIBUTE_SSE2__ __m128 __libm_sse2_powf(__m128 Xmm0, __m128 Xmm1)
Definition: libm_sse2.c:151
__ATTRIBUTE_SSE2__ __m128d __libm_sse2_atan2(__m128d Xmm0, __m128d Xmm1)
Definition: libm_sse2.c:71
__ATTRIBUTE_SSE2__ __m128 __libm_sse2_acosf(__m128 Xmm0)
Definition: libm_sse2.c:30
__ATTRIBUTE_SSE2__ __m128d __libm_sse2_exp(__m128d Xmm0)
Definition: libm_sse2.c:95
__ATTRIBUTE_SSE2__ __m128d __libm_sse2_log(__m128d Xmm0)
Definition: libm_sse2.c:111
__ATTRIBUTE_SSE2__ __m128 __libm_sse2_tanf(__m128 Xmm0)
Definition: libm_sse2.c:182
__ATTRIBUTE_SSE2__ __m128d __libm_sse2_log10(__m128d Xmm0)
Definition: libm_sse2.c:127
__ATTRIBUTE_SSE2__ __m128d __libm_sse2_sin(__m128d Xmm0)
Definition: libm_sse2.c:159
#define sign(x)
Definition: mapdesc.cc:613
#define EXCEPTION_FLT_UNDERFLOW
Definition: minwinbase.h:55
#define EXCEPTION_FLT_OVERFLOW
Definition: minwinbase.h:53
#define EXCEPTION_FLT_INEXACT_RESULT
Definition: minwinbase.h:51
#define EXCEPTION_FLT_INVALID_OPERATION
Definition: minwinbase.h:52
#define EXCEPTION_FLT_DIVIDE_BY_ZERO
Definition: minwinbase.h:50
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define sprintf
Definition: sprintf.c:45
float power
Definition: d3drm.c:3372
static unsigned int number
Definition: dsound.c:1479
void msvcrt_init_math(void)
static size_t double int ndigits
Definition: printf.c:52
static size_t double int int * decpt
Definition: printf.c:52
static unsigned long fenv_encode(unsigned int e)
Definition: misc.c:1379
#define shift
Definition: input.c:1755
DWORD exp
Definition: msg.c:16058
#define __ASM_GLOBAL_FUNC(name, code)
Definition: port.h:201
#define min(a, b)
Definition: monoChain.cc:55
#define sqrtf(x)
Definition: mymath.h:59
#define round(x)
Definition: opentype.c:47
@ sse
Definition: optimize.h:107
__asm__(".p2align 4, 0x90\n" ".seh_proc __seh2_global_filter_func\n" "__seh2_global_filter_func:\n" "\tsub %rbp, %rax\n" "\tpush %rbp\n" "\t.seh_pushreg %rbp\n" "\tsub $32, %rsp\n" "\t.seh_stackalloc 32\n" "\t.seh_endprologue\n" "\tsub %rax, %rdx\n" "\tmov %rdx, %rbp\n" "\tjmp *%r8\n" "__seh2_global_filter_func_exit:\n" "\t.p2align 4\n" "\tadd $32, %rsp\n" "\tpop %rbp\n" "\tret\n" "\t.seh_endproc")
int __cdecl feraiseexcept(int excepts)
int __cdecl feupdateenv(const fenv_t *)
intmax_t __cdecl imaxabs(intmax_t j)
Definition: inttypes.h:277
_ACRTIMP _Dcomplex __cdecl _Cbuild(_In_ double _Re, _In_ double _Im)
#define f2(x, y, z)
Definition: sha1.c:31
#define f1(x, y, z)
Definition: sha1.c:30
#define log(outFile, fmt,...)
Definition: util.h:15
#define TRACE(s)
Definition: solgame.cpp:4
Definition: math.h:42
Definition: stdlib.h:47
Definition: stdlib.h:52
Definition: fenv.h:28
Definition: name.c:39
Definition: stat.h:66
Definition: ps.c:97
#define max(a, b)
Definition: svc.c:63
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
int retval
Definition: wcstombs.cpp:91
#define __ASM_CFI(str)
Definition: asm.h:39
#define get_locinfo()
Definition: winesup.h:25
#define PF_XMMI64_INSTRUCTIONS_AVAILABLE
Definition: ketypes.h:186
#define _snprintf
Definition: xmlstorage.h:200
#define __ATTRIBUTE_SSE__
Definition: xmmintrin.h:68