|
|
1.1 root 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 ([email protected]). *
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 [email protected]. */
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:
1.1.1.2 ! root 39: /* Changed by Ian Lance Taylor:
! 40: September 1994, use extern inline instead of static inline. */
! 41:
1.1 root 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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.