oops - omitted in previous delta
[official-gcc.git] / gcc / ginclude / math-3300.h
blob5d7ba28f67f6ecc4a376699c7bbb5089babf4325
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 #undef 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; \
35 __inline static const double sin (double x)
37 double value;
39 __asm ("fsin%.x %1,%0"
40 : "=f" (value)
41 : "f" (x));
42 return value;
45 __inline static const double cos (double x)
47 double value;
49 __asm ("fcos%.x %1,%0"
50 : "=f" (value)
51 : "f" (x));
52 return value;
55 __inline static const double tan (double x)
57 double value;
59 __asm ("ftan%.x %1,%0"
60 : "=f" (value)
61 : "f" (x));
62 return value;
65 __inline static const double asin (double x)
67 double value;
69 __asm ("fasin%.x %1,%0"
70 : "=f" (value)
71 : "f" (x));
72 return value;
75 __inline static const double acos (double x)
77 double value;
79 __asm ("facos%.x %1,%0"
80 : "=f" (value)
81 : "f" (x));
82 return value;
85 __inline static const double atan (double x)
87 double value;
89 __asm ("fatan%.x %1,%0"
90 : "=f" (value)
91 : "f" (x));
92 return value;
95 __inline static const double atan2 (double y, double x)
97 double pi, pi_over_2;
99 __asm ("fmovecr%.x %#0,%0" /* extended precision pi */
100 : "=f" (pi)
101 : /* no inputs */ );
102 __asm ("fscale%.b %#-1,%0" /* no loss of accuracy */
103 : "=f" (pi_over_2)
104 : "0" (pi));
105 if (x > 0)
107 if (y > 0)
109 if (x > y)
110 return atan (y / x);
111 else
112 return pi_over_2 - atan (x / y);
114 else
116 if (x > -y)
117 return atan (y / x);
118 else
119 return - pi_over_2 - atan (x / y);
122 else
124 if (y > 0)
126 if (-x > y)
127 return pi + atan (y / x);
128 else
129 return pi_over_2 - atan (x / y);
131 else
133 if (-x > -y)
134 return - pi + atan (y / x);
135 else if (y < 0)
136 return - pi_over_2 - atan (x / y);
137 else
139 double value;
141 errno = EDOM;
142 __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */
143 : "=f" (value)
144 : /* no inputs */);
145 return value;
151 __inline static const double sinh (double x)
153 double value;
155 __asm ("fsinh%.x %1,%0"
156 : "=f" (value)
157 : "f" (x));
158 return value;
161 __inline static const double cosh (double x)
163 double value;
165 __asm ("fcosh%.x %1,%0"
166 : "=f" (value)
167 : "f" (x));
168 return value;
171 __inline static const double tanh (double x)
173 double value;
175 __asm ("ftanh%.x %1,%0"
176 : "=f" (value)
177 : "f" (x));
178 return value;
181 __inline static const double atanh (double x)
183 double value;
185 __asm ("fatanh%.x %1,%0"
186 : "=f" (value)
187 : "f" (x));
188 return value;
191 __inline static const double exp (double x)
193 double value;
195 __asm ("fetox%.x %1,%0"
196 : "=f" (value)
197 : "f" (x));
198 return value;
201 __inline static const double expm1 (double x)
203 double value;
205 __asm ("fetoxm1%.x %1,%0"
206 : "=f" (value)
207 : "f" (x));
208 return value;
211 __inline static const double log (double x)
213 double value;
215 __asm ("flogn%.x %1,%0"
216 : "=f" (value)
217 : "f" (x));
218 return value;
221 __inline static const double log1p (double x)
223 double value;
225 __asm ("flognp1%.x %1,%0"
226 : "=f" (value)
227 : "f" (x));
228 return value;
231 __inline static const double log10 (double x)
233 double value;
235 __asm ("flog10%.x %1,%0"
236 : "=f" (value)
237 : "f" (x));
238 return value;
241 __inline static const double sqrt (double x)
243 double value;
245 __asm ("fsqrt%.x %1,%0"
246 : "=f" (value)
247 : "f" (x));
248 return value;
251 __inline static const double pow (const double x, const double y)
253 if (x > 0)
254 return exp (y * log (x));
255 else if (x == 0)
257 if (y > 0)
258 return 0.0;
259 else
261 double value;
263 errno = EDOM;
264 __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */
265 : "=f" (value)
266 : /* no inputs */);
267 return value;
270 else
272 double temp;
274 __asm ("fintrz%.x %1,%0"
275 : "=f" (temp) /* integer-valued float */
276 : "f" (y));
277 if (y == temp)
279 int i = (int) y;
281 if ((i & 1) == 0) /* even */
282 return exp (y * log (x));
283 else
284 return - exp (y * log (x));
286 else
288 double value;
290 errno = EDOM;
291 __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */
292 : "=f" (value)
293 : /* no inputs */);
294 return value;
299 __inline static const double fabs (double x)
301 double value;
303 __asm ("fabs%.x %1,%0"
304 : "=f" (value)
305 : "f" (x));
306 return value;
309 __inline static const double ceil (double x)
311 int rounding_mode, round_up;
312 double value;
314 __asm volatile ("fmove%.l %%fpcr,%0"
315 : "=dm" (rounding_mode)
316 : /* no inputs */ );
317 round_up = rounding_mode | 0x30;
318 __asm volatile ("fmove%.l %0,%%fpcr"
319 : /* no outputs */
320 : "dmi" (round_up));
321 __asm volatile ("fint%.x %1,%0"
322 : "=f" (value)
323 : "f" (x));
324 __asm volatile ("fmove%.l %0,%%fpcr"
325 : /* no outputs */
326 : "dmi" (rounding_mode));
327 return value;
330 __inline static const double floor (double x)
332 int rounding_mode, round_down;
333 double value;
335 __asm volatile ("fmove%.l %%fpcr,%0"
336 : "=dm" (rounding_mode)
337 : /* no inputs */ );
338 round_down = (rounding_mode & ~0x10)
339 | 0x20;
340 __asm volatile ("fmove%.l %0,%%fpcr"
341 : /* no outputs */
342 : "dmi" (round_down));
343 __asm volatile ("fint%.x %1,%0"
344 : "=f" (value)
345 : "f" (x));
346 __asm volatile ("fmove%.l %0,%%fpcr"
347 : /* no outputs */
348 : "dmi" (rounding_mode));
349 return value;
352 __inline static const double rint (double x)
354 int rounding_mode, round_nearest;
355 double value;
357 __asm volatile ("fmove%.l %%fpcr,%0"
358 : "=dm" (rounding_mode)
359 : /* no inputs */ );
360 round_nearest = rounding_mode & ~0x30;
361 __asm volatile ("fmove%.l %0,%%fpcr"
362 : /* no outputs */
363 : "dmi" (round_nearest));
364 __asm volatile ("fint%.x %1,%0"
365 : "=f" (value)
366 : "f" (x));
367 __asm volatile ("fmove%.l %0,%%fpcr"
368 : /* no outputs */
369 : "dmi" (rounding_mode));
370 return value;
373 __inline static const double fmod (double x, double y)
375 double value;
377 __asm ("fmod%.x %2,%0"
378 : "=f" (value)
379 : "0" (x),
380 "f" (y));
381 return value;
384 __inline static const double drem (double x, double y)
386 double value;
388 __asm ("frem%.x %2,%0"
389 : "=f" (value)
390 : "0" (x),
391 "f" (y));
392 return value;
395 __inline static const double scalb (double x, int n)
397 double value;
399 __asm ("fscale%.l %2,%0"
400 : "=f" (value)
401 : "0" (x),
402 "dmi" (n));
403 return value;
406 __inline static double logb (double x)
408 double exponent;
410 __asm ("fgetexp%.x %1,%0"
411 : "=f" (exponent)
412 : "f" (x));
413 return exponent;
416 __inline static const double ldexp (double x, int n)
418 double value;
420 __asm ("fscale%.l %2,%0"
421 : "=f" (value)
422 : "0" (x),
423 "dmi" (n));
424 return value;
427 __inline static double frexp (double x, int *exp)
429 double float_exponent;
430 int int_exponent;
431 double mantissa;
433 __asm ("fgetexp%.x %1,%0"
434 : "=f" (float_exponent) /* integer-valued float */
435 : "f" (x));
436 int_exponent = (int) float_exponent;
437 __asm ("fgetman%.x %1,%0"
438 : "=f" (mantissa) /* 1.0 <= mantissa < 2.0 */
439 : "f" (x));
440 if (mantissa != 0)
442 __asm ("fscale%.b %#-1,%0"
443 : "=f" (mantissa) /* mantissa /= 2.0 */
444 : "0" (mantissa));
445 int_exponent += 1;
447 *exp = int_exponent;
448 return mantissa;
451 __inline static double modf (double x, double *ip)
453 double temp;
455 __asm ("fintrz%.x %1,%0"
456 : "=f" (temp) /* integer-valued float */
457 : "f" (x));
458 *ip = temp;
459 return x - temp;