Import (slightly modified) ru.koi8-r.win.kbd:1.1 from FreeBSD (fjoe):
[dragonfly.git] / contrib / gcc / ginclude / math-68881.h
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 \******************************************************************/
21
22 /* This file is NOT a part of GCC, just distributed with it.  */
23
24 /* If you find this in GCC,
25    please send bug reports to bug-gcc@prep.ai.mit.edu.  */
26
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.  */
35
36 /* Changed by Jim Wilson:
37    September 1993, Use #undef before HUGE_VAL instead of #ifdef/#endif.  */
38
39 /* Changed by Ian Lance Taylor:
40    September 1994, use extern inline instead of static inline.  */
41
42 #ifndef __math_68881
43 #define __math_68881
44
45 #include <errno.h>
46
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;                                                                  \
54 })
55 #else
56 #define HUGE_VAL                                                        \
57 ({                                                                      \
58   double huge_val;                                                      \
59                                                                         \
60   __asm ("fmove%.d %#0x7ff0000000000000,%0"     /* Infinity */          \
61          : "=f" (huge_val)                                              \
62          : /* no inputs */);                                            \
63   huge_val;                                                             \
64 })
65 #endif
66
67 __inline extern double
68 sin (double x)
69 {
70   double value;
71
72   __asm ("fsin%.x %1,%0"
73          : "=f" (value)
74          : "f" (x));
75   return value;
76 }
77
78 __inline extern double
79 cos (double x)
80 {
81   double value;
82
83   __asm ("fcos%.x %1,%0"
84          : "=f" (value)
85          : "f" (x));
86   return value;
87 }
88
89 __inline extern double
90 tan (double x)
91 {
92   double value;
93
94   __asm ("ftan%.x %1,%0"
95          : "=f" (value)
96          : "f" (x));
97   return value;
98 }
99
100 __inline extern double
101 asin (double x)
102 {
103   double value;
104
105   __asm ("fasin%.x %1,%0"
106          : "=f" (value)
107          : "f" (x));
108   return value;
109 }
110
111 __inline extern double
112 acos (double x)
113 {
114   double value;
115
116   __asm ("facos%.x %1,%0"
117          : "=f" (value)
118          : "f" (x));
119   return value;
120 }
121
122 __inline extern double
123 atan (double x)
124 {
125   double value;
126
127   __asm ("fatan%.x %1,%0"
128          : "=f" (value)
129          : "f" (x));
130   return value;
131 }
132
133 __inline extern double
134 atan2 (double y, double x)
135 {
136   double pi, pi_over_2;
137
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)
145     {
146       if (y > 0)
147         {
148           if (x > y)
149             return atan (y / x);
150           else
151             return pi_over_2 - atan (x / y);
152         }
153       else
154         {
155           if (x > -y)
156             return atan (y / x);
157           else
158             return - pi_over_2 - atan (x / y);
159         }
160     }
161   else
162     {
163       if (y < 0)
164         {
165           if (-x > -y)
166             return - pi + atan (y / x);
167           else
168             return - pi_over_2 - atan (x / y);
169         }
170       else
171         {
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
177             {
178               double value;
179
180               errno = EDOM;
181               __asm ("fmove%.d %#0x7fffffffffffffff,%0"         /* quiet NaN */
182                      : "=f" (value)
183                      : /* no inputs */);
184               return value;
185             }
186         }
187     }
188 }
189
190 __inline extern double
191 sinh (double x)
192 {
193   double value;
194
195   __asm ("fsinh%.x %1,%0"
196          : "=f" (value)
197          : "f" (x));
198   return value;
199 }
200
201 __inline extern double
202 cosh (double x)
203 {
204   double value;
205
206   __asm ("fcosh%.x %1,%0"
207          : "=f" (value)
208          : "f" (x));
209   return value;
210 }
211
212 __inline extern double
213 tanh (double x)
214 {
215   double value;
216
217   __asm ("ftanh%.x %1,%0"
218          : "=f" (value)
219          : "f" (x));
220   return value;
221 }
222
223 __inline extern double
224 atanh (double x)
225 {
226   double value;
227
228   __asm ("fatanh%.x %1,%0"
229          : "=f" (value)
230          : "f" (x));
231   return value;
232 }
233
234 __inline extern double
235 exp (double x)
236 {
237   double value;
238
239   __asm ("fetox%.x %1,%0"
240          : "=f" (value)
241          : "f" (x));
242   return value;
243 }
244
245 __inline extern double
246 expm1 (double x)
247 {
248   double value;
249
250   __asm ("fetoxm1%.x %1,%0"
251          : "=f" (value)
252          : "f" (x));
253   return value;
254 }
255
256 __inline extern double
257 log (double x)
258 {
259   double value;
260
261   __asm ("flogn%.x %1,%0"
262          : "=f" (value)
263          : "f" (x));
264   return value;
265 }
266
267 __inline extern double
268 log1p (double x)
269 {
270   double value;
271
272   __asm ("flognp1%.x %1,%0"
273          : "=f" (value)
274          : "f" (x));
275   return value;
276 }
277
278 __inline extern double
279 log10 (double x)
280 {
281   double value;
282
283   __asm ("flog10%.x %1,%0"
284          : "=f" (value)
285          : "f" (x));
286   return value;
287 }
288
289 __inline extern double
290 sqrt (double x)
291 {
292   double value;
293
294   __asm ("fsqrt%.x %1,%0"
295          : "=f" (value)
296          : "f" (x));
297   return value;
298 }
299
300 __inline extern double
301 hypot (double x, double y)
302 {
303   return sqrt (x*x + y*y);
304 }
305
306 __inline extern double
307 pow (double x, double y)
308 {
309   if (x > 0)
310     return exp (y * log (x));
311   else if (x == 0)
312     {
313       if (y > 0)
314         return 0.0;
315       else
316         {
317           double value;
318
319           errno = EDOM;
320           __asm ("fmove%.d %#0x7fffffffffffffff,%0"             /* quiet NaN */
321                  : "=f" (value)
322                  : /* no inputs */);
323           return value;
324         }
325     }
326   else
327     {
328       double temp;
329
330       __asm ("fintrz%.x %1,%0"
331              : "=f" (temp)                      /* integer-valued float */
332              : "f" (y));
333       if (y == temp)
334         {
335           int i = (int) y;
336           
337           if ((i & 1) == 0)                     /* even */
338             return exp (y * log (-x));
339           else
340             return - exp (y * log (-x));
341         }
342       else
343         {
344           double value;
345
346           errno = EDOM;
347           __asm ("fmove%.d %#0x7fffffffffffffff,%0"             /* quiet NaN */
348                  : "=f" (value)
349                  : /* no inputs */);
350           return value;
351         }
352     }
353 }
354
355 __inline extern double
356 fabs (double x)
357 {
358   double value;
359
360   __asm ("fabs%.x %1,%0"
361          : "=f" (value)
362          : "f" (x));
363   return value;
364 }
365
366 __inline extern double
367 ceil (double x)
368 {
369   int rounding_mode, round_up;
370   double value;
371
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;
386 }
387
388 __inline extern double
389 floor (double x)
390 {
391   int rounding_mode, round_down;
392   double value;
393
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;
409 }
410
411 __inline extern double
412 rint (double x)
413 {
414   int rounding_mode, round_nearest;
415   double value;
416
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;
431 }
432
433 __inline extern double
434 fmod (double x, double y)
435 {
436   double value;
437
438   __asm ("fmod%.x %2,%0"
439          : "=f" (value)
440          : "0" (x),
441            "f" (y));
442   return value;
443 }
444
445 __inline extern double
446 drem (double x, double y)
447 {
448   double value;
449
450   __asm ("frem%.x %2,%0"
451          : "=f" (value)
452          : "0" (x),
453            "f" (y));
454   return value;
455 }
456
457 __inline extern double
458 scalb (double x, int n)
459 {
460   double value;
461
462   __asm ("fscale%.l %2,%0"
463          : "=f" (value)
464          : "0" (x),
465            "dmi" (n));
466   return value;
467 }
468
469 __inline extern double
470 logb (double x)
471 {
472   double exponent;
473
474   __asm ("fgetexp%.x %1,%0"
475          : "=f" (exponent)
476          : "f" (x));
477   return exponent;
478 }
479
480 __inline extern double
481 ldexp (double x, int n)
482 {
483   double value;
484
485   __asm ("fscale%.l %2,%0"
486          : "=f" (value)
487          : "0" (x),
488            "dmi" (n));
489   return value;
490 }
491
492 __inline extern double
493 frexp (double x, int *exp)
494 {
495   double float_exponent;
496   int int_exponent;
497   double mantissa;
498
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)
507     {
508       __asm ("fscale%.b %#-1,%0"
509              : "=f" (mantissa)          /* mantissa /= 2.0 */
510              : "0" (mantissa));
511       int_exponent += 1;
512     }
513   *exp = int_exponent;
514   return mantissa;
515 }
516
517 __inline extern double
518 modf (double x, double *ip)
519 {
520   double temp;
521
522   __asm ("fintrz%.x %1,%0"
523          : "=f" (temp)                  /* integer-valued float */
524          : "f" (x));
525   *ip = temp;
526   return x - temp;
527 }
528
529 #endif /* not __math_68881 */