indent with astyle v1.15.3: --style=ansi -c -s3 -S --convert-tabs
[reactos.git] / reactos / lib / ntdll / rtl / math.c
1 /* Math functions for i387.
2 Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by John C. Bowman <bowman@ipp-garching.mpg.de>, 1995.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
10
11 The GNU C 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 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public
17 License along with the GNU C Library; see the file COPYING.LIB. If not,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20 #include <ntdll.h>
21 #define NDEBUG
22 #include <debug.h>
23
24 double atan (double __x);
25 double ceil (double __x);
26 double cos (double __x);
27 double fabs (double __x);
28 double floor (double __x);
29 double log (double __x);
30 double __log2 (double __x);
31 double pow (double __x, double __y);
32 double sin (double __x);
33 double sqrt (double __x);
34 double tan (double __x);
35
36 int _fltused = 0x9875;
37
38 double atan (double __x)
39 {
40 register double __value;
41 __asm __volatile__
42 ("fld1\n\t"
43 "fpatan"
44 : "=t" (__value) : "0" (__x));
45
46 return __value;
47 }
48
49 /*
50 * @implemented
51 */
52 double ceil (double __x)
53 {
54 register double __value;
55 __volatile unsigned short int __cw, __cwtmp;
56
57 __asm __volatile ("fnstcw %0" : "=m" (__cw));
58 __cwtmp = (__cw & 0xf3ff) | 0x0800; /* rounding up */
59 __asm __volatile ("fldcw %0" : : "m" (__cwtmp));
60 __asm __volatile ("frndint" : "=t" (__value) : "0" (__x));
61 __asm __volatile ("fldcw %0" : : "m" (__cw));
62
63 return __value;
64 }
65
66 /*
67 * @implemented
68 */
69 double cos (double __x)
70 {
71 register double __value;
72 __asm __volatile__
73 ("fcos"
74 : "=t" (__value): "0" (__x));
75
76 return __value;
77 }
78
79 /*
80 * @implemented
81 */
82 double fabs (double __x)
83 {
84 register double __value;
85 __asm __volatile__
86 ("fabs"
87 : "=t" (__value) : "0" (__x));
88
89 return __value;
90 }
91
92 /*
93 * @implemented
94 */
95 double floor (double __x)
96 {
97 register double __value;
98 __volatile unsigned short int __cw, __cwtmp;
99
100 __asm __volatile ("fnstcw %0" : "=m" (__cw));
101 __cwtmp = (__cw & 0xf3ff) | 0x0400; /* rounding down */
102 __asm __volatile ("fldcw %0" : : "m" (__cwtmp));
103 __asm __volatile ("frndint" : "=t" (__value) : "0" (__x));
104 __asm __volatile ("fldcw %0" : : "m" (__cw));
105
106 return __value;
107 }
108
109 /*
110 * @implemented
111 */
112 double log (double __x)
113 {
114 register double __value;
115 __asm __volatile__
116 ("fldln2\n\t"
117 "fxch\n\t"
118 "fyl2x"
119 : "=t" (__value) : "0" (__x));
120
121 return __value;
122 }
123
124 double __log2 (double __x)
125 {
126 register double __value;
127 __asm __volatile__
128 ("fld1\n\t"
129 "fxch\n\t"
130 "fyl2x"
131 : "=t" (__value) : "0" (__x));
132
133 return __value;
134 }
135
136 /*
137 * @implemented
138 */
139 double pow (double __x, double __y)
140 {
141 register double __value, __exponent;
142 long __p = (long) __y;
143
144 if (__x == 0.0 && __y > 0.0)
145 return 0.0;
146 if (__y == (double) __p)
147 {
148 double __r = 1.0;
149 if (__p == 0)
150 return 1.0;
151 if (__p < 0)
152 {
153 __p = -__p;
154 __x = 1.0 / __x;
155 }
156 while (1)
157 {
158 if (__p & 1)
159 __r *= __x;
160 __p >>= 1;
161 if (__p == 0)
162 return __r;
163 __x *= __x;
164 }
165 /* NOTREACHED */
166 }
167 __asm __volatile__
168 ("fmul %%st(1) # y * log2(x)\n\t"
169 "fst %%st(1)\n\t"
170 "frndint # int(y * log2(x))\n\t"
171 "fxch\n\t"
172 "fsub %%st(1) # fract(y * log2(x))\n\t"
173 "f2xm1 # 2^(fract(y * log2(x))) - 1\n\t"
174 : "=t" (__value), "=u" (__exponent) : "0" (__log2 (__x)), "1" (__y));
175 __value += 1.0;
176 __asm __volatile__
177 ("fscale"
178 : "=t" (__value) : "0" (__value), "u" (__exponent));
179
180 return __value;
181 }
182
183 /*
184 * @implemented
185 */
186 double sin (double __x)
187 {
188 register double __value;
189 __asm __volatile__
190 ("fsin"
191 : "=t" (__value) : "0" (__x));
192
193 return __value;
194 }
195
196 /*
197 * @implemented
198 */
199 double sqrt (double __x)
200 {
201 register double __value;
202 __asm __volatile__
203 ("fsqrt"
204 : "=t" (__value) : "0" (__x));
205
206 return __value;
207 }
208
209 /*
210 * @implemented
211 */
212 double tan (double __x)
213 {
214 register double __value;
215 register double __value2 __attribute__ ((unused));
216 __asm __volatile__
217 ("fptan"
218 : "=t" (__value2), "=u" (__value) : "0" (__x));
219
220 return __value;
221 }