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