xref: /reactos/sdk/lib/crt/math/i386/ldexp.c (revision 8a978a17)
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 }
47