Initial revision
[official-gcc.git] / gcc / ginclude / math-3300.h
blob0edd8d67915e257c6228033fd1e658f33cb0c851
1 /******************************************************************\
2 * *
3 * <math-68881.h> last modified: 18 May 1989. *
4 * *
5 * Copyright (C) 1989 by Matthew Self. *
6 * You may freely distribute verbatim copies of this software *
7 * provided that this copyright notice is retained in all copies. *
8 * You may distribute modifications to this software under the *
9 * conditions above if you also clearly note such modifications *
10 * with their author and date. *
11 * *
12 * Note: errno is not set to EDOM when domain errors occur for *
13 * most of these functions. Rather, it is assumed that the *
14 * 68881's OPERR exception will be enabled and handled *
15 * appropriately by the operating system. Similarly, overflow *
16 * and underflow do not set errno to ERANGE. *
17 * *
18 * Send bugs to Matthew Self (self@bayes.arc.nasa.gov). *
19 * *
20 \******************************************************************/
22 #include <errno.h>
24 #ifndef HUGE_VAL
25 #define HUGE_VAL \
26 ({ \
27 double huge_val; \
29 __asm ("fmove%.d %#0x7ff0000000000000,%0" /* Infinity */ \
30 : "=f" (huge_val) \
31 : /* no inputs */); \
32 huge_val; \
34 #endif
36 __inline static const double sin (double x)
38 double value;
40 __asm ("fsin%.x %1,%0"
41 : "=f" (value)
42 : "f" (x));
43 return value;
46 __inline static const double cos (double x)
48 double value;
50 __asm ("fcos%.x %1,%0"
51 : "=f" (value)
52 : "f" (x));
53 return value;
56 __inline static const double tan (double x)
58 double value;
60 __asm ("ftan%.x %1,%0"
61 : "=f" (value)
62 : "f" (x));
63 return value;
66 __inline static const double asin (double x)
68 double value;
70 __asm ("fasin%.x %1,%0"
71 : "=f" (value)
72 : "f" (x));
73 return value;
76 __inline static const double acos (double x)
78 double value;
80 __asm ("facos%.x %1,%0"
81 : "=f" (value)
82 : "f" (x));
83 return value;
86 __inline static const double atan (double x)
88 double value;
90 __asm ("fatan%.x %1,%0"
91 : "=f" (value)
92 : "f" (x));
93 return value;
96 __inline static const double atan2 (double y, double x)
98 double pi, pi_over_2;
100 __asm ("fmovecr%.x %#0,%0" /* extended precision pi */
101 : "=f" (pi)
102 : /* no inputs */ );
103 __asm ("fscale%.b %#-1,%0" /* no loss of accuracy */
104 : "=f" (pi_over_2)
105 : "0" (pi));
106 if (x > 0)
108 if (y > 0)
110 if (x > y)
111 return atan (y / x);
112 else
113 return pi_over_2 - atan (x / y);
115 else
117 if (x > -y)
118 return atan (y / x);
119 else
120 return - pi_over_2 - atan (x / y);
123 else
125 if (y > 0)
127 if (-x > y)
128 return pi + atan (y / x);
129 else
130 return pi_over_2 - atan (x / y);
132 else
134 if (-x > -y)
135 return - pi + atan (y / x);
136 else if (y < 0)
137 return - pi_over_2 - atan (x / y);
138 else
140 double value;
142 errno = EDOM;
143 __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */
144 : "=f" (value)
145 : /* no inputs */);
146 return value;
152 __inline static const double sinh (double x)
154 double value;
156 __asm ("fsinh%.x %1,%0"
157 : "=f" (value)
158 : "f" (x));
159 return value;
162 __inline static const double cosh (double x)
164 double value;
166 __asm ("fcosh%.x %1,%0"
167 : "=f" (value)
168 : "f" (x));
169 return value;
172 __inline static const double tanh (double x)
174 double value;
176 __asm ("ftanh%.x %1,%0"
177 : "=f" (value)
178 : "f" (x));
179 return value;
182 __inline static const double atanh (double x)
184 double value;
186 __asm ("fatanh%.x %1,%0"
187 : "=f" (value)
188 : "f" (x));
189 return value;
192 __inline static const double exp (double x)
194 double value;
196 __asm ("fetox%.x %1,%0"
197 : "=f" (value)
198 : "f" (x));
199 return value;
202 __inline static const double expm1 (double x)
204 double value;
206 __asm ("fetoxm1%.x %1,%0"
207 : "=f" (value)
208 : "f" (x));
209 return value;
212 __inline static const double log (double x)
214 double value;
216 __asm ("flogn%.x %1,%0"
217 : "=f" (value)
218 : "f" (x));
219 return value;
222 __inline static const double log1p (double x)
224 double value;
226 __asm ("flognp1%.x %1,%0"
227 : "=f" (value)
228 : "f" (x));
229 return value;
232 __inline static const double log10 (double x)
234 double value;
236 __asm ("flog10%.x %1,%0"
237 : "=f" (value)
238 : "f" (x));
239 return value;
242 __inline static const double sqrt (double x)
244 double value;
246 __asm ("fsqrt%.x %1,%0"
247 : "=f" (value)
248 : "f" (x));
249 return value;
252 __inline static const double pow (const double x, const double y)
254 if (x > 0)
255 return exp (y * log (x));
256 else if (x == 0)
258 if (y > 0)
259 return 0.0;
260 else
262 double value;
264 errno = EDOM;
265 __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */
266 : "=f" (value)
267 : /* no inputs */);
268 return value;
271 else
273 double temp;
275 __asm ("fintrz%.x %1,%0"
276 : "=f" (temp) /* integer-valued float */
277 : "f" (y));
278 if (y == temp)
280 int i = (int) y;
282 if (i & 1 == 0) /* even */
283 return exp (y * log (x));
284 else
285 return - exp (y * log (x));
287 else
289 double value;
291 errno = EDOM;
292 __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */
293 : "=f" (value)
294 : /* no inputs */);
295 return value;
300 __inline static const double fabs (double x)
302 double value;
304 __asm ("fabs%.x %1,%0"
305 : "=f" (value)
306 : "f" (x));
307 return value;
310 __inline static const double ceil (double x)
312 int rounding_mode, round_up;
313 double value;
315 __asm volatile ("fmove%.l %%fpcr,%0"
316 : "=dm" (rounding_mode)
317 : /* no inputs */ );
318 round_up = rounding_mode | 0x30;
319 __asm volatile ("fmove%.l %0,%%fpcr"
320 : /* no outputs */
321 : "dmi" (round_up));
322 __asm volatile ("fint%.x %1,%0"
323 : "=f" (value)
324 : "f" (x));
325 __asm volatile ("fmove%.l %0,%%fpcr"
326 : /* no outputs */
327 : "dmi" (rounding_mode));
328 return value;
331 __inline static const double floor (double x)
333 int rounding_mode, round_down;
334 double value;
336 __asm volatile ("fmove%.l %%fpcr,%0"
337 : "=dm" (rounding_mode)
338 : /* no inputs */ );
339 round_down = (rounding_mode & ~0x10)
340 | 0x20;
341 __asm volatile ("fmove%.l %0,%%fpcr"
342 : /* no outputs */
343 : "dmi" (round_down));
344 __asm volatile ("fint%.x %1,%0"
345 : "=f" (value)
346 : "f" (x));
347 __asm volatile ("fmove%.l %0,%%fpcr"
348 : /* no outputs */
349 : "dmi" (rounding_mode));
350 return value;
353 __inline static const double rint (double x)
355 int rounding_mode, round_nearest;
356 double value;
358 __asm volatile ("fmove%.l %%fpcr,%0"
359 : "=dm" (rounding_mode)
360 : /* no inputs */ );
361 round_nearest = rounding_mode & ~0x30;
362 __asm volatile ("fmove%.l %0,%%fpcr"
363 : /* no outputs */
364 : "dmi" (round_nearest));
365 __asm volatile ("fint%.x %1,%0"
366 : "=f" (value)
367 : "f" (x));
368 __asm volatile ("fmove%.l %0,%%fpcr"
369 : /* no outputs */
370 : "dmi" (rounding_mode));
371 return value;
374 __inline static const double fmod (double x, double y)
376 double value;
378 __asm ("fmod%.x %2,%0"
379 : "=f" (value)
380 : "0" (x),
381 "f" (y));
382 return value;
385 __inline static const double drem (double x, double y)
387 double value;
389 __asm ("frem%.x %2,%0"
390 : "=f" (value)
391 : "0" (x),
392 "f" (y));
393 return value;
396 __inline static const double scalb (double x, int n)
398 double value;
400 __asm ("fscale%.l %2,%0"
401 : "=f" (value)
402 : "0" (x),
403 "dmi" (n));
404 return value;
407 __inline static double logb (double x)
409 double exponent;
411 __asm ("fgetexp%.x %1,%0"
412 : "=f" (exponent)
413 : "f" (x));
414 return exponent;
417 __inline static const double ldexp (double x, int n)
419 double value;
421 __asm ("fscale%.l %2,%0"
422 : "=f" (value)
423 : "0" (x),
424 "dmi" (n));
425 return value;
428 __inline static double frexp (double x, int *exp)
430 double float_exponent;
431 int int_exponent;
432 double mantissa;
434 __asm ("fgetexp%.x %1,%0"
435 : "=f" (float_exponent) /* integer-valued float */
436 : "f" (x));
437 int_exponent = (int) float_exponent;
438 __asm ("fgetman%.x %1,%0"
439 : "=f" (mantissa) /* 1.0 <= mantissa < 2.0 */
440 : "f" (x));
441 if (mantissa != 0)
443 __asm ("fscale%.b %#-1,%0"
444 : "=f" (mantissa) /* mantissa /= 2.0 */
445 : "0" (mantissa));
446 int_exponent += 1;
448 *exp = int_exponent;
449 return mantissa;
452 __inline static double modf (double x, double *ip)
454 double temp;
456 __asm ("fintrz%.x %1,%0"
457 : "=f" (temp) /* integer-valued float */
458 : "f" (x));
459 *ip = temp;
460 return x - temp;