PR rtl-optimization/88018
[official-gcc.git] / gcc / config / m68k / math-68881.h
blob6d9f8b2d4a1f8d39d47e0b02f13fac125cc48e4d
1 /******************************************************************\
2 * *
3 * <math-68881.h> last modified: 23 May 1992. *
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 /* This file is NOT a part of GCC, just distributed with it. */
24 /* If you find this in GCC,
25 please send bug reports to bug-gcc@prep.ai.mit.edu. */
27 /* Changed by Richard Stallman:
28 May 1993, add conditional to prevent multiple inclusion.
29 % inserted before a #.
30 New function `hypot' added.
31 Nans written in hex to avoid 0rnan.
32 May 1992, use %! for fpcr register. Break lines before function names.
33 December 1989, add parens around `&' in pow.
34 November 1990, added alternate definition of HUGE_VAL for Sun. */
36 /* Changed by Jim Wilson:
37 September 1993, Use #undef before HUGE_VAL instead of #ifdef/#endif. */
39 /* Changed by Ian Lance Taylor:
40 September 1994, use extern inline instead of static inline. */
42 #ifndef __math_68881
43 #define __math_68881
45 #include <errno.h>
47 #undef HUGE_VAL
48 #ifdef __sun__
49 /* The Sun assembler fails to handle the hex constant in the usual defn. */
50 #define HUGE_VAL \
51 ({ \
52 static union { int i[2]; double d; } u = { {0x7ff00000, 0} }; \
53 u.d; \
55 #else
56 #define HUGE_VAL \
57 ({ \
58 double huge_val; \
60 __asm ("fmove%.d #0x7ff0000000000000,%0" /* Infinity */ \
61 : "=f" (huge_val) \
62 : /* no inputs */); \
63 huge_val; \
65 #endif
67 __inline extern double
68 sin (double x)
70 double value;
72 __asm ("fsin%.x %1,%0"
73 : "=f" (value)
74 : "f" (x));
75 return value;
78 __inline extern double
79 cos (double x)
81 double value;
83 __asm ("fcos%.x %1,%0"
84 : "=f" (value)
85 : "f" (x));
86 return value;
89 __inline extern double
90 tan (double x)
92 double value;
94 __asm ("ftan%.x %1,%0"
95 : "=f" (value)
96 : "f" (x));
97 return value;
100 __inline extern double
101 asin (double x)
103 double value;
105 __asm ("fasin%.x %1,%0"
106 : "=f" (value)
107 : "f" (x));
108 return value;
111 __inline extern double
112 acos (double x)
114 double value;
116 __asm ("facos%.x %1,%0"
117 : "=f" (value)
118 : "f" (x));
119 return value;
122 __inline extern double
123 atan (double x)
125 double value;
127 __asm ("fatan%.x %1,%0"
128 : "=f" (value)
129 : "f" (x));
130 return value;
133 __inline extern double
134 atan2 (double y, double x)
136 double pi, pi_over_2;
138 __asm ("fmovecr%.x #0,%0" /* extended precision pi */
139 : "=f" (pi)
140 : /* no inputs */ );
141 __asm ("fscale%.b #-1,%0" /* no loss of accuracy */
142 : "=f" (pi_over_2)
143 : "0" (pi));
144 if (x > 0)
146 if (y > 0)
148 if (x > y)
149 return atan (y / x);
150 else
151 return pi_over_2 - atan (x / y);
153 else
155 if (x > -y)
156 return atan (y / x);
157 else
158 return - pi_over_2 - atan (x / y);
161 else
163 if (y < 0)
165 if (-x > -y)
166 return - pi + atan (y / x);
167 else
168 return - pi_over_2 - atan (x / y);
170 else
172 if (-x > y)
173 return pi + atan (y / x);
174 else if (y > 0)
175 return pi_over_2 - atan (x / y);
176 else
178 double value;
180 errno = EDOM;
181 __asm ("fmove%.d #0x7fffffffffffffff,%0" /* quiet NaN */
182 : "=f" (value)
183 : /* no inputs */);
184 return value;
190 __inline extern double
191 sinh (double x)
193 double value;
195 __asm ("fsinh%.x %1,%0"
196 : "=f" (value)
197 : "f" (x));
198 return value;
201 __inline extern double
202 cosh (double x)
204 double value;
206 __asm ("fcosh%.x %1,%0"
207 : "=f" (value)
208 : "f" (x));
209 return value;
212 __inline extern double
213 tanh (double x)
215 double value;
217 __asm ("ftanh%.x %1,%0"
218 : "=f" (value)
219 : "f" (x));
220 return value;
223 __inline extern double
224 atanh (double x)
226 double value;
228 __asm ("fatanh%.x %1,%0"
229 : "=f" (value)
230 : "f" (x));
231 return value;
234 __inline extern double
235 exp (double x)
237 double value;
239 __asm ("fetox%.x %1,%0"
240 : "=f" (value)
241 : "f" (x));
242 return value;
245 __inline extern double
246 expm1 (double x)
248 double value;
250 __asm ("fetoxm1%.x %1,%0"
251 : "=f" (value)
252 : "f" (x));
253 return value;
256 __inline extern double
257 log (double x)
259 double value;
261 __asm ("flogn%.x %1,%0"
262 : "=f" (value)
263 : "f" (x));
264 return value;
267 __inline extern double
268 log1p (double x)
270 double value;
272 __asm ("flognp1%.x %1,%0"
273 : "=f" (value)
274 : "f" (x));
275 return value;
278 __inline extern double
279 log10 (double x)
281 double value;
283 __asm ("flog10%.x %1,%0"
284 : "=f" (value)
285 : "f" (x));
286 return value;
289 __inline extern double
290 sqrt (double x)
292 double value;
294 __asm ("fsqrt%.x %1,%0"
295 : "=f" (value)
296 : "f" (x));
297 return value;
300 __inline extern double
301 hypot (double x, double y)
303 return sqrt (x*x + y*y);
306 __inline extern double
307 pow (double x, double y)
309 if (x > 0)
310 return exp (y * log (x));
311 else if (x == 0)
313 if (y > 0)
314 return 0.0;
315 else
317 double value;
319 errno = EDOM;
320 __asm ("fmove%.d #0x7fffffffffffffff,%0" /* quiet NaN */
321 : "=f" (value)
322 : /* no inputs */);
323 return value;
326 else
328 double temp;
330 __asm ("fintrz%.x %1,%0"
331 : "=f" (temp) /* integer-valued float */
332 : "f" (y));
333 if (y == temp)
335 int i = (int) y;
337 if ((i & 1) == 0) /* even */
338 return exp (y * log (-x));
339 else
340 return - exp (y * log (-x));
342 else
344 double value;
346 errno = EDOM;
347 __asm ("fmove%.d #0x7fffffffffffffff,%0" /* quiet NaN */
348 : "=f" (value)
349 : /* no inputs */);
350 return value;
355 __inline extern double
356 fabs (double x)
358 double value;
360 __asm ("fabs%.x %1,%0"
361 : "=f" (value)
362 : "f" (x));
363 return value;
366 __inline extern double
367 ceil (double x)
369 int rounding_mode, round_up;
370 double value;
372 __asm volatile ("fmove%.l %!,%0"
373 : "=dm" (rounding_mode)
374 : /* no inputs */ );
375 round_up = rounding_mode | 0x30;
376 __asm volatile ("fmove%.l %0,%!"
377 : /* no outputs */
378 : "dmi" (round_up));
379 __asm volatile ("fint%.x %1,%0"
380 : "=f" (value)
381 : "f" (x));
382 __asm volatile ("fmove%.l %0,%!"
383 : /* no outputs */
384 : "dmi" (rounding_mode));
385 return value;
388 __inline extern double
389 floor (double x)
391 int rounding_mode, round_down;
392 double value;
394 __asm volatile ("fmove%.l %!,%0"
395 : "=dm" (rounding_mode)
396 : /* no inputs */ );
397 round_down = (rounding_mode & ~0x10)
398 | 0x20;
399 __asm volatile ("fmove%.l %0,%!"
400 : /* no outputs */
401 : "dmi" (round_down));
402 __asm volatile ("fint%.x %1,%0"
403 : "=f" (value)
404 : "f" (x));
405 __asm volatile ("fmove%.l %0,%!"
406 : /* no outputs */
407 : "dmi" (rounding_mode));
408 return value;
411 __inline extern double
412 rint (double x)
414 int rounding_mode, round_nearest;
415 double value;
417 __asm volatile ("fmove%.l %!,%0"
418 : "=dm" (rounding_mode)
419 : /* no inputs */ );
420 round_nearest = rounding_mode & ~0x30;
421 __asm volatile ("fmove%.l %0,%!"
422 : /* no outputs */
423 : "dmi" (round_nearest));
424 __asm volatile ("fint%.x %1,%0"
425 : "=f" (value)
426 : "f" (x));
427 __asm volatile ("fmove%.l %0,%!"
428 : /* no outputs */
429 : "dmi" (rounding_mode));
430 return value;
433 __inline extern double
434 fmod (double x, double y)
436 double value;
438 __asm ("fmod%.x %2,%0"
439 : "=f" (value)
440 : "0" (x),
441 "f" (y));
442 return value;
445 __inline extern double
446 drem (double x, double y)
448 double value;
450 __asm ("frem%.x %2,%0"
451 : "=f" (value)
452 : "0" (x),
453 "f" (y));
454 return value;
457 __inline extern double
458 scalb (double x, int n)
460 double value;
462 __asm ("fscale%.l %2,%0"
463 : "=f" (value)
464 : "0" (x),
465 "dmi" (n));
466 return value;
469 __inline extern double
470 logb (double x)
472 double exponent;
474 __asm ("fgetexp%.x %1,%0"
475 : "=f" (exponent)
476 : "f" (x));
477 return exponent;
480 __inline extern double
481 ldexp (double x, int n)
483 double value;
485 __asm ("fscale%.l %2,%0"
486 : "=f" (value)
487 : "0" (x),
488 "dmi" (n));
489 return value;
492 __inline extern double
493 frexp (double x, int *exp)
495 double float_exponent;
496 int int_exponent;
497 double mantissa;
499 __asm ("fgetexp%.x %1,%0"
500 : "=f" (float_exponent) /* integer-valued float */
501 : "f" (x));
502 int_exponent = (int) float_exponent;
503 __asm ("fgetman%.x %1,%0"
504 : "=f" (mantissa) /* 1.0 <= mantissa < 2.0 */
505 : "f" (x));
506 if (mantissa != 0)
508 __asm ("fscale%.b #-1,%0"
509 : "=f" (mantissa) /* mantissa /= 2.0 */
510 : "0" (mantissa));
511 int_exponent += 1;
513 *exp = int_exponent;
514 return mantissa;
517 __inline extern double
518 modf (double x, double *ip)
520 double temp;
522 __asm ("fintrz%.x %1,%0"
523 : "=f" (temp) /* integer-valued float */
524 : "f" (x));
525 *ip = temp;
526 return x - temp;
529 #endif /* not __math_68881 */