Fix the MSVC version of ldexp filling up the FPU stack and bailing out with #IND...
[reactos.git] / sdk / lib / crt / math / i386 / ldexp.c
1 /*
2 * PROJECT: ReactOS CRT
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: Implements the ldexp CRT function for IA-32 with Windows-compatible error codes.
5 * COPYRIGHT: Copyright 2010 Timo Kreuzer (timo.kreuzer@reactos.org)
6 * Copyright 2011 Pierre Schweitzer (pierre@reactos.org)
7 * Copyright 2019 Colin Finck (colin@reactos.org)
8 */
9
10 #include <precomp.h>
11
12 double ldexp (double value, int exp)
13 {
14 #ifdef __GNUC__
15 register double result;
16 #endif
17
18 /* Check for value correctness
19 * and set errno if required
20 */
21 if (_isnan(value))
22 {
23 errno = EDOM;
24 }
25
26 #ifdef __GNUC__
27 asm ("fscale"
28 : "=t" (result)
29 : "0" (value), "u" ((double)exp)
30 : "1");
31 return result;
32 #else /* !__GNUC__ */
33 __asm
34 {
35 fild exp
36 fld value
37 fscale
38 fstp st(1)
39 }
40
41 /* "fstp st(1)" has copied st(0) to st(1), then popped the FPU stack,
42 * so that the value is again in st(0) now. Effectively, we have reduced
43 * the FPU stack by one element while preserving st(0).
44 * st(0) is also the register used for returning a double value. */
45 #endif /* !__GNUC__ */
46 }