more crt, crtdll and msvcrt cleanup
[reactos.git] / reactos / lib / rtl / math.c
1 /* COPYRIGHT: See COPYING in the top level directory
2 * Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/rtl/math.c
5 * PURPOSE: Math functions for i387.
6 * PROGRAMMER: John C. Bowman <bowman@ipp-garching.mpg.de>
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #include <rtl.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16 /* FUNCTIONS *****************************************************************/
17
18 double atan (double __x);
19 double ceil (double __x);
20 double cos (double __x);
21 double fabs (double __x);
22 double floor (double __x);
23 double log (double __x);
24 double __log2 (double __x);
25 double pow (double __x, double __y);
26 double sin (double __x);
27 double sqrt (double __x);
28 double tan (double __x);
29
30 int _fltused = 0x9875;
31
32 double atan (double __x)
33 {
34 register double __val;
35 __asm __volatile__
36 ("fld1\n\t"
37 "fpatan"
38 : "=t" (__val) : "0" (__x));
39
40 return __val;
41 }
42
43 /*
44 * @implemented
45 */
46 double ceil (double __x)
47 {
48 register double __val;
49 __volatile unsigned short int __cw, __cwtmp;
50
51 __asm __volatile ("fnstcw %0" : "=m" (__cw));
52 __cwtmp = (__cw & 0xf3ff) | 0x0800; /* rounding up */
53 __asm __volatile ("fldcw %0" : : "m" (__cwtmp));
54 __asm __volatile ("frndint" : "=t" (__val) : "0" (__x));
55 __asm __volatile ("fldcw %0" : : "m" (__cw));
56
57 return __val;
58 }
59
60 /*
61 * @implemented
62 */
63 double cos (double __x)
64 {
65 register double __val;
66 __asm __volatile__
67 ("fcos"
68 : "=t" (__val): "0" (__x));
69
70 return __val;
71 }
72
73 /*
74 * @implemented
75 */
76 double fabs (double __x)
77 {
78 register double __val;
79 __asm __volatile__
80 ("fabs"
81 : "=t" (__val) : "0" (__x));
82
83 return __val;
84 }
85
86 /*
87 * @implemented
88 */
89 double floor (double __x)
90 {
91 register double __val;
92 __volatile unsigned short int __cw, __cwtmp;
93
94 __asm __volatile ("fnstcw %0" : "=m" (__cw));
95 __cwtmp = (__cw & 0xf3ff) | 0x0400; /* rounding down */
96 __asm __volatile ("fldcw %0" : : "m" (__cwtmp));
97 __asm __volatile ("frndint" : "=t" (__val) : "0" (__x));
98 __asm __volatile ("fldcw %0" : : "m" (__cw));
99
100 return __val;
101 }
102
103 /*
104 * @implemented
105 */
106 double log (double __x)
107 {
108 register double __val;
109 __asm __volatile__
110 ("fldln2\n\t"
111 "fxch\n\t"
112 "fyl2x"
113 : "=t" (__val) : "0" (__x));
114
115 return __val;
116 }
117
118 double __log2 (double __x)
119 {
120 register double __val;
121 __asm __volatile__
122 ("fld1\n\t"
123 "fxch\n\t"
124 "fyl2x"
125 : "=t" (__val) : "0" (__x));
126
127 return __val;
128 }
129
130 /*
131 * @implemented
132 */
133 double pow (double __x, double __y)
134 {
135 register double __val, __exponent;
136 long __p = (long) __y;
137
138 if (__x == 0.0 && __y > 0.0)
139 return 0.0;
140 if (__y == (double) __p)
141 {
142 double __r = 1.0;
143 if (__p == 0)
144 return 1.0;
145 if (__p < 0)
146 {
147 __p = -__p;
148 __x = 1.0 / __x;
149 }
150 while (1)
151 {
152 if (__p & 1)
153 __r *= __x;
154 __p >>= 1;
155 if (__p == 0)
156 return __r;
157 __x *= __x;
158 }
159 /* NOTREACHED */
160 }
161 __asm __volatile__
162 ("fmul %%st(1) # y * log2(x)\n\t"
163 "fst %%st(1)\n\t"
164 "frndint # int(y * log2(x))\n\t"
165 "fxch\n\t"
166 "fsub %%st(1) # fract(y * log2(x))\n\t"
167 "f2xm1 # 2^(fract(y * log2(x))) - 1\n\t"
168 : "=t" (__val), "=u" (__exponent) : "0" (__log2 (__x)), "1" (__y));
169 __val += 1.0;
170 __asm __volatile__
171 ("fscale"
172 : "=t" (__val) : "0" (__val), "u" (__exponent));
173
174 return __val;
175 }
176
177 /*
178 * @implemented
179 */
180 double sin (double __x)
181 {
182 register double __val;
183 __asm __volatile__
184 ("fsin"
185 : "=t" (__val) : "0" (__x));
186
187 return __val;
188 }
189
190 /*
191 * @implemented
192 */
193 double sqrt (double __x)
194 {
195 register double __val;
196 __asm __volatile__
197 ("fsqrt"
198 : "=t" (__val) : "0" (__x));
199
200 return __val;
201 }
202
203 /*
204 * @implemented
205 */
206 double tan (double __x)
207 {
208 register double __val;
209 register double __val2 __attribute__ ((unused));
210 __asm __volatile__
211 ("fptan"
212 : "=t" (__val2), "=u" (__val) : "0" (__x));
213
214 return __val;
215 }