:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / 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
21
22 double atan (double __x);
23 double ceil (double __x);
24 double cos (double __x);
25 double fabs (double __x);
26 double floor (double __x);
27 long _ftol (double fl);
28 double log (double __x);
29 double __log2 (double __x);
30 double pow (double __x, double __y);
31 double sin (double __x);
32 double sqrt (double __x);
33 double tan (double __x);
34
35
36 double atan (double __x)
37 {
38   register double __value;
39   __asm __volatile__
40     ("fld1\n\t"
41      "fpatan"
42      : "=t" (__value) : "0" (__x));
43
44   return __value;
45 }
46
47 double ceil (double __x)
48 {
49   register double __value;
50   __volatile unsigned short int __cw, __cwtmp;
51
52   __asm __volatile ("fnstcw %0" : "=m" (__cw));
53   __cwtmp = (__cw & 0xf3ff) | 0x0800; /* rounding up */
54   __asm __volatile ("fldcw %0" : : "m" (__cwtmp));
55   __asm __volatile ("frndint" : "=t" (__value) : "0" (__x));
56   __asm __volatile ("fldcw %0" : : "m" (__cw));
57
58   return __value;
59 }
60
61 double cos (double __x)
62 {
63   register double __value;
64   __asm __volatile__
65     ("fcos"
66      : "=t" (__value): "0" (__x));
67
68   return __value;
69 }
70
71 double fabs (double __x)
72 {
73   register double __value;
74   __asm __volatile__
75     ("fabs"
76      : "=t" (__value) : "0" (__x));
77
78   return __value;
79 }
80
81 double floor (double __x)
82 {
83   register double __value;
84   __volatile unsigned short int __cw, __cwtmp;
85
86   __asm __volatile ("fnstcw %0" : "=m" (__cw));
87   __cwtmp = (__cw & 0xf3ff) | 0x0400; /* rounding down */
88   __asm __volatile ("fldcw %0" : : "m" (__cwtmp));
89   __asm __volatile ("frndint" : "=t" (__value) : "0" (__x));
90   __asm __volatile ("fldcw %0" : : "m" (__cw));
91
92   return __value;
93 }
94
95 long _ftol (double fl)
96 {
97   return (long)fl;
98 }
99
100 double log (double __x)
101 {
102   register double __value;
103   __asm __volatile__
104     ("fldln2\n\t"
105      "fxch\n\t"
106      "fyl2x"
107      : "=t" (__value) : "0" (__x));
108
109   return __value;
110 }
111
112 double __log2 (double __x)
113 {
114   register double __value;
115   __asm __volatile__
116     ("fld1\n\t"
117      "fxch\n\t"
118      "fyl2x"
119      : "=t" (__value) : "0" (__x));
120
121   return __value;
122 }
123
124 double pow (double __x, double __y)
125 {
126   register double __value, __exponent;
127   long __p = (long) __y;
128
129   if (__x == 0.0 && __y > 0.0)
130     return 0.0;
131   if (__y == (double) __p)
132     {
133       double __r = 1.0;
134       if (__p == 0)
135         return 1.0;
136       if (__p < 0)
137         {
138           __p = -__p;
139           __x = 1.0 / __x;
140         }
141       while (1)
142         {
143           if (__p & 1)
144             __r *= __x;
145           __p >>= 1;
146           if (__p == 0)
147             return __r;
148           __x *= __x;
149         }
150       /* NOTREACHED */
151     }
152   __asm __volatile__
153     ("fmul      %%st(1)         # y * log2(x)\n\t"
154      "fst       %%st(1)\n\t"
155      "frndint                   # int(y * log2(x))\n\t"
156      "fxch\n\t"
157      "fsub      %%st(1)         # fract(y * log2(x))\n\t"
158      "f2xm1                     # 2^(fract(y * log2(x))) - 1\n\t"
159      : "=t" (__value), "=u" (__exponent) :  "0" (__log2 (__x)), "1" (__y));
160   __value += 1.0;
161   __asm __volatile__
162     ("fscale"
163      : "=t" (__value) : "0" (__value), "u" (__exponent));
164
165   return __value;
166 }
167
168 double sin (double __x)
169 {
170   register double __value;
171   __asm __volatile__
172     ("fsin"
173      : "=t" (__value) : "0" (__x));
174
175   return __value;
176 }
177
178 double sqrt (double __x)
179 {
180   register double __value;
181   __asm __volatile__
182     ("fsqrt"
183      : "=t" (__value) : "0" (__x));
184
185   return __value;
186 }
187
188 double tan (double __x)
189 {
190   register double __value;
191   register double __value2 __attribute__ ((unused));
192   __asm __volatile__
193     ("fptan"
194      : "=t" (__value2), "=u" (__value) : "0" (__x));
195
196   return __value;
197 }