|
|
1.1 root 1: /******************************************************************\
2: * *
1.1.1.3 root 3: * <math-68881.h> last modified: 23 May 1992. *
1.1 root 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 ([email protected]). *
19: * *
20: \******************************************************************/
21:
1.1.1.4 ! root 22: /* This file is NOT a part of GCC, just distributed with it. */
! 23:
1.1.1.3 root 24: /* If you find this in GCC,
25: please send bug reports to [email protected]. */
26:
1.1.1.4 ! root 27: /* Changed by Richard Stallman:
! 28: May 1993, add conditional to prevent multiple inclusion.
! 29: % inserted before a #.
1.1 root 30: New function `hypot' added.
31: Nans written in hex to avoid 0rnan.
1.1.1.3 root 32: May 1992, use %! for fpcr register. Break lines before function names.
1.1 root 33: December 1989, add parens around `&' in pow.
34: November 1990, added alternate definition of HUGE_VAL for Sun. */
35:
1.1.1.4 ! root 36: #ifndef __math_68881
! 37: #define __math_68881
! 38:
1.1 root 39: #include <errno.h>
40:
41: #ifndef HUGE_VAL
42: #ifdef __sun__
43: /* The Sun assembler fails to handle the hex constant in the usual defn. */
44: #define HUGE_VAL \
45: ({ \
46: static union { int i[2]; double d; } u = { {0x7ff00000, 0} }; \
47: u.d; \
48: })
49: #else
50: #define HUGE_VAL \
51: ({ \
52: double huge_val; \
53: \
54: __asm ("fmove%.d %#0x7ff0000000000000,%0" /* Infinity */ \
55: : "=f" (huge_val) \
56: : /* no inputs */); \
57: huge_val; \
58: })
59: #endif
60: #endif
61:
1.1.1.3 root 62: __inline static const double
63: sin (double x)
1.1 root 64: {
65: double value;
66:
67: __asm ("fsin%.x %1,%0"
68: : "=f" (value)
69: : "f" (x));
70: return value;
71: }
72:
1.1.1.3 root 73: __inline static const double
74: cos (double x)
1.1 root 75: {
76: double value;
77:
78: __asm ("fcos%.x %1,%0"
79: : "=f" (value)
80: : "f" (x));
81: return value;
82: }
83:
1.1.1.3 root 84: __inline static const double
85: tan (double x)
1.1 root 86: {
87: double value;
88:
89: __asm ("ftan%.x %1,%0"
90: : "=f" (value)
91: : "f" (x));
92: return value;
93: }
94:
1.1.1.3 root 95: __inline static const double
96: asin (double x)
1.1 root 97: {
98: double value;
99:
100: __asm ("fasin%.x %1,%0"
101: : "=f" (value)
102: : "f" (x));
103: return value;
104: }
105:
1.1.1.3 root 106: __inline static const double
107: acos (double x)
1.1 root 108: {
109: double value;
110:
111: __asm ("facos%.x %1,%0"
112: : "=f" (value)
113: : "f" (x));
114: return value;
115: }
116:
1.1.1.3 root 117: __inline static const double
118: atan (double x)
1.1 root 119: {
120: double value;
121:
122: __asm ("fatan%.x %1,%0"
123: : "=f" (value)
124: : "f" (x));
125: return value;
126: }
127:
1.1.1.3 root 128: __inline static const double
129: atan2 (double y, double x)
1.1 root 130: {
131: double pi, pi_over_2;
132:
133: __asm ("fmovecr%.x %#0,%0" /* extended precision pi */
134: : "=f" (pi)
135: : /* no inputs */ );
136: __asm ("fscale%.b %#-1,%0" /* no loss of accuracy */
137: : "=f" (pi_over_2)
138: : "0" (pi));
139: if (x > 0)
140: {
141: if (y > 0)
142: {
143: if (x > y)
144: return atan (y / x);
145: else
146: return pi_over_2 - atan (x / y);
147: }
148: else
149: {
150: if (x > -y)
151: return atan (y / x);
152: else
153: return - pi_over_2 - atan (x / y);
154: }
155: }
156: else
157: {
1.1.1.4 ! root 158: if (y < 0)
1.1 root 159: {
1.1.1.4 ! root 160: if (-x > -y)
! 161: return - pi + atan (y / x);
1.1 root 162: else
1.1.1.4 ! root 163: return - pi_over_2 - atan (x / y);
1.1 root 164: }
165: else
166: {
1.1.1.4 ! root 167: if (-x > y)
! 168: return pi + atan (y / x);
! 169: else if (y > 0)
! 170: return pi_over_2 - atan (x / y);
1.1 root 171: else
172: {
173: double value;
174:
175: errno = EDOM;
176: __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */
177: : "=f" (value)
178: : /* no inputs */);
179: return value;
180: }
181: }
182: }
183: }
184:
1.1.1.3 root 185: __inline static const double
186: sinh (double x)
1.1 root 187: {
188: double value;
189:
190: __asm ("fsinh%.x %1,%0"
191: : "=f" (value)
192: : "f" (x));
193: return value;
194: }
195:
1.1.1.3 root 196: __inline static const double
197: cosh (double x)
1.1 root 198: {
199: double value;
200:
201: __asm ("fcosh%.x %1,%0"
202: : "=f" (value)
203: : "f" (x));
204: return value;
205: }
206:
1.1.1.3 root 207: __inline static const double
208: tanh (double x)
1.1 root 209: {
210: double value;
211:
212: __asm ("ftanh%.x %1,%0"
213: : "=f" (value)
214: : "f" (x));
215: return value;
216: }
217:
1.1.1.3 root 218: __inline static const double
219: atanh (double x)
1.1 root 220: {
221: double value;
222:
223: __asm ("fatanh%.x %1,%0"
224: : "=f" (value)
225: : "f" (x));
226: return value;
227: }
228:
1.1.1.3 root 229: __inline static const double
230: exp (double x)
1.1 root 231: {
232: double value;
233:
234: __asm ("fetox%.x %1,%0"
235: : "=f" (value)
236: : "f" (x));
237: return value;
238: }
239:
1.1.1.3 root 240: __inline static const double
241: expm1 (double x)
1.1 root 242: {
243: double value;
244:
245: __asm ("fetoxm1%.x %1,%0"
246: : "=f" (value)
247: : "f" (x));
248: return value;
249: }
250:
1.1.1.3 root 251: __inline static const double
252: log (double x)
1.1 root 253: {
254: double value;
255:
256: __asm ("flogn%.x %1,%0"
257: : "=f" (value)
258: : "f" (x));
259: return value;
260: }
261:
1.1.1.3 root 262: __inline static const double
263: log1p (double x)
1.1 root 264: {
265: double value;
266:
267: __asm ("flognp1%.x %1,%0"
268: : "=f" (value)
269: : "f" (x));
270: return value;
271: }
272:
1.1.1.3 root 273: __inline static const double
274: log10 (double x)
1.1 root 275: {
276: double value;
277:
278: __asm ("flog10%.x %1,%0"
279: : "=f" (value)
280: : "f" (x));
281: return value;
282: }
283:
1.1.1.3 root 284: __inline static const double
285: sqrt (double x)
1.1 root 286: {
287: double value;
288:
289: __asm ("fsqrt%.x %1,%0"
290: : "=f" (value)
291: : "f" (x));
292: return value;
293: }
294:
1.1.1.3 root 295: __inline static const double
296: hypot (const double x, const double y)
1.1 root 297: {
298: return sqrt (x*x + y*y);
299: }
300:
1.1.1.3 root 301: __inline static const double
302: pow (const double x, const double y)
1.1 root 303: {
304: if (x > 0)
305: return exp (y * log (x));
306: else if (x == 0)
307: {
308: if (y > 0)
309: return 0.0;
310: else
311: {
312: double value;
313:
314: errno = EDOM;
1.1.1.2 root 315: __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */
1.1 root 316: : "=f" (value)
317: : /* no inputs */);
318: return value;
319: }
320: }
321: else
322: {
323: double temp;
324:
325: __asm ("fintrz%.x %1,%0"
326: : "=f" (temp) /* integer-valued float */
327: : "f" (y));
328: if (y == temp)
329: {
330: int i = (int) y;
331:
1.1.1.2 root 332: if ((i & 1) == 0) /* even */
1.1 root 333: return exp (y * log (-x));
334: else
335: return - exp (y * log (-x));
336: }
337: else
338: {
339: double value;
340:
341: errno = EDOM;
342: __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */
343: : "=f" (value)
344: : /* no inputs */);
345: return value;
346: }
347: }
348: }
349:
1.1.1.3 root 350: __inline static const double
351: fabs (double x)
1.1 root 352: {
353: double value;
354:
355: __asm ("fabs%.x %1,%0"
356: : "=f" (value)
357: : "f" (x));
358: return value;
359: }
360:
1.1.1.3 root 361: __inline static const double
362: ceil (double x)
1.1 root 363: {
364: int rounding_mode, round_up;
365: double value;
366:
1.1.1.3 root 367: __asm volatile ("fmove%.l %!,%0"
1.1 root 368: : "=dm" (rounding_mode)
369: : /* no inputs */ );
370: round_up = rounding_mode | 0x30;
1.1.1.3 root 371: __asm volatile ("fmove%.l %0,%!"
1.1 root 372: : /* no outputs */
373: : "dmi" (round_up));
374: __asm volatile ("fint%.x %1,%0"
375: : "=f" (value)
376: : "f" (x));
1.1.1.3 root 377: __asm volatile ("fmove%.l %0,%!"
1.1 root 378: : /* no outputs */
379: : "dmi" (rounding_mode));
380: return value;
381: }
382:
1.1.1.3 root 383: __inline static const double
384: floor (double x)
1.1 root 385: {
386: int rounding_mode, round_down;
387: double value;
388:
1.1.1.3 root 389: __asm volatile ("fmove%.l %!,%0"
1.1 root 390: : "=dm" (rounding_mode)
391: : /* no inputs */ );
392: round_down = (rounding_mode & ~0x10)
393: | 0x20;
1.1.1.3 root 394: __asm volatile ("fmove%.l %0,%!"
1.1 root 395: : /* no outputs */
396: : "dmi" (round_down));
397: __asm volatile ("fint%.x %1,%0"
398: : "=f" (value)
399: : "f" (x));
1.1.1.3 root 400: __asm volatile ("fmove%.l %0,%!"
1.1 root 401: : /* no outputs */
402: : "dmi" (rounding_mode));
403: return value;
404: }
405:
1.1.1.3 root 406: __inline static const double
407: rint (double x)
1.1 root 408: {
409: int rounding_mode, round_nearest;
410: double value;
411:
1.1.1.3 root 412: __asm volatile ("fmove%.l %!,%0"
1.1 root 413: : "=dm" (rounding_mode)
414: : /* no inputs */ );
415: round_nearest = rounding_mode & ~0x30;
1.1.1.3 root 416: __asm volatile ("fmove%.l %0,%!"
1.1 root 417: : /* no outputs */
418: : "dmi" (round_nearest));
419: __asm volatile ("fint%.x %1,%0"
420: : "=f" (value)
421: : "f" (x));
1.1.1.3 root 422: __asm volatile ("fmove%.l %0,%!"
1.1 root 423: : /* no outputs */
424: : "dmi" (rounding_mode));
425: return value;
426: }
427:
1.1.1.3 root 428: __inline static const double
429: fmod (double x, double y)
1.1 root 430: {
431: double value;
432:
433: __asm ("fmod%.x %2,%0"
434: : "=f" (value)
435: : "0" (x),
436: "f" (y));
437: return value;
438: }
439:
1.1.1.3 root 440: __inline static const double
441: drem (double x, double y)
1.1 root 442: {
443: double value;
444:
445: __asm ("frem%.x %2,%0"
446: : "=f" (value)
447: : "0" (x),
448: "f" (y));
449: return value;
450: }
451:
1.1.1.3 root 452: __inline static const double
453: scalb (double x, int n)
1.1 root 454: {
455: double value;
456:
457: __asm ("fscale%.l %2,%0"
458: : "=f" (value)
459: : "0" (x),
460: "dmi" (n));
461: return value;
462: }
463:
1.1.1.3 root 464: __inline static double
465: logb (double x)
1.1 root 466: {
467: double exponent;
468:
469: __asm ("fgetexp%.x %1,%0"
470: : "=f" (exponent)
471: : "f" (x));
472: return exponent;
473: }
474:
1.1.1.3 root 475: __inline static const double
476: ldexp (double x, int n)
1.1 root 477: {
478: double value;
479:
480: __asm ("fscale%.l %2,%0"
481: : "=f" (value)
482: : "0" (x),
483: "dmi" (n));
484: return value;
485: }
486:
1.1.1.3 root 487: __inline static double
488: frexp (double x, int *exp)
1.1 root 489: {
490: double float_exponent;
491: int int_exponent;
492: double mantissa;
493:
494: __asm ("fgetexp%.x %1,%0"
495: : "=f" (float_exponent) /* integer-valued float */
496: : "f" (x));
497: int_exponent = (int) float_exponent;
498: __asm ("fgetman%.x %1,%0"
499: : "=f" (mantissa) /* 1.0 <= mantissa < 2.0 */
500: : "f" (x));
501: if (mantissa != 0)
502: {
503: __asm ("fscale%.b %#-1,%0"
504: : "=f" (mantissa) /* mantissa /= 2.0 */
505: : "0" (mantissa));
506: int_exponent += 1;
507: }
508: *exp = int_exponent;
509: return mantissa;
510: }
511:
1.1.1.3 root 512: __inline static double
513: modf (double x, double *ip)
1.1 root 514: {
515: double temp;
516:
517: __asm ("fintrz%.x %1,%0"
518: : "=f" (temp) /* integer-valued float */
519: : "f" (x));
520: *ip = temp;
521: return x - temp;
522: }
523:
1.1.1.4 ! root 524: #endif /* not __math_68881 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.