|
|
1.1 root 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 ([email protected]). *
19: * *
20: \******************************************************************/
21:
22: #include <errno.h>
23:
24: #undef HUGE_VAL
25: #define HUGE_VAL \
26: ({ \
27: double huge_val; \
28: \
29: __asm ("fmove%.d %#0x7ff0000000000000,%0" /* Infinity */ \
30: : "=f" (huge_val) \
31: : /* no inputs */); \
32: huge_val; \
33: })
34:
35: __inline static const double sin (double x)
36: {
37: double value;
38:
39: __asm ("fsin%.x %1,%0"
40: : "=f" (value)
41: : "f" (x));
42: return value;
43: }
44:
45: __inline static const double cos (double x)
46: {
47: double value;
48:
49: __asm ("fcos%.x %1,%0"
50: : "=f" (value)
51: : "f" (x));
52: return value;
53: }
54:
55: __inline static const double tan (double x)
56: {
57: double value;
58:
59: __asm ("ftan%.x %1,%0"
60: : "=f" (value)
61: : "f" (x));
62: return value;
63: }
64:
65: __inline static const double asin (double x)
66: {
67: double value;
68:
69: __asm ("fasin%.x %1,%0"
70: : "=f" (value)
71: : "f" (x));
72: return value;
73: }
74:
75: __inline static const double acos (double x)
76: {
77: double value;
78:
79: __asm ("facos%.x %1,%0"
80: : "=f" (value)
81: : "f" (x));
82: return value;
83: }
84:
85: __inline static const double atan (double x)
86: {
87: double value;
88:
89: __asm ("fatan%.x %1,%0"
90: : "=f" (value)
91: : "f" (x));
92: return value;
93: }
94:
95: __inline static const double atan2 (double y, double x)
96: {
97: double pi, pi_over_2;
98:
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)
106: {
107: if (y > 0)
108: {
109: if (x > y)
110: return atan (y / x);
111: else
112: return pi_over_2 - atan (x / y);
113: }
114: else
115: {
116: if (x > -y)
117: return atan (y / x);
118: else
119: return - pi_over_2 - atan (x / y);
120: }
121: }
122: else
123: {
124: if (y > 0)
125: {
126: if (-x > y)
127: return pi + atan (y / x);
128: else
129: return pi_over_2 - atan (x / y);
130: }
131: else
132: {
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
138: {
139: double value;
140:
141: errno = EDOM;
142: __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */
143: : "=f" (value)
144: : /* no inputs */);
145: return value;
146: }
147: }
148: }
149: }
150:
151: __inline static const double sinh (double x)
152: {
153: double value;
154:
155: __asm ("fsinh%.x %1,%0"
156: : "=f" (value)
157: : "f" (x));
158: return value;
159: }
160:
161: __inline static const double cosh (double x)
162: {
163: double value;
164:
165: __asm ("fcosh%.x %1,%0"
166: : "=f" (value)
167: : "f" (x));
168: return value;
169: }
170:
171: __inline static const double tanh (double x)
172: {
173: double value;
174:
175: __asm ("ftanh%.x %1,%0"
176: : "=f" (value)
177: : "f" (x));
178: return value;
179: }
180:
181: __inline static const double atanh (double x)
182: {
183: double value;
184:
185: __asm ("fatanh%.x %1,%0"
186: : "=f" (value)
187: : "f" (x));
188: return value;
189: }
190:
191: __inline static const double exp (double x)
192: {
193: double value;
194:
195: __asm ("fetox%.x %1,%0"
196: : "=f" (value)
197: : "f" (x));
198: return value;
199: }
200:
201: __inline static const double expm1 (double x)
202: {
203: double value;
204:
205: __asm ("fetoxm1%.x %1,%0"
206: : "=f" (value)
207: : "f" (x));
208: return value;
209: }
210:
211: __inline static const double log (double x)
212: {
213: double value;
214:
215: __asm ("flogn%.x %1,%0"
216: : "=f" (value)
217: : "f" (x));
218: return value;
219: }
220:
221: __inline static const double log1p (double x)
222: {
223: double value;
224:
225: __asm ("flognp1%.x %1,%0"
226: : "=f" (value)
227: : "f" (x));
228: return value;
229: }
230:
231: __inline static const double log10 (double x)
232: {
233: double value;
234:
235: __asm ("flog10%.x %1,%0"
236: : "=f" (value)
237: : "f" (x));
238: return value;
239: }
240:
241: __inline static const double sqrt (double x)
242: {
243: double value;
244:
245: __asm ("fsqrt%.x %1,%0"
246: : "=f" (value)
247: : "f" (x));
248: return value;
249: }
250:
251: __inline static const double pow (const double x, const double y)
252: {
253: if (x > 0)
254: return exp (y * log (x));
255: else if (x == 0)
256: {
257: if (y > 0)
258: return 0.0;
259: else
260: {
261: double value;
262:
263: errno = EDOM;
264: __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */
265: : "=f" (value)
266: : /* no inputs */);
267: return value;
268: }
269: }
270: else
271: {
272: double temp;
273:
274: __asm ("fintrz%.x %1,%0"
275: : "=f" (temp) /* integer-valued float */
276: : "f" (y));
277: if (y == temp)
278: {
279: int i = (int) y;
280:
281: if (i & 1 == 0) /* even */
282: return exp (y * log (x));
283: else
284: return - exp (y * log (x));
285: }
286: else
287: {
288: double value;
289:
290: errno = EDOM;
291: __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */
292: : "=f" (value)
293: : /* no inputs */);
294: return value;
295: }
296: }
297: }
298:
299: __inline static const double fabs (double x)
300: {
301: double value;
302:
303: __asm ("fabs%.x %1,%0"
304: : "=f" (value)
305: : "f" (x));
306: return value;
307: }
308:
309: __inline static const double ceil (double x)
310: {
311: int rounding_mode, round_up;
312: double value;
313:
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;
328: }
329:
330: __inline static const double floor (double x)
331: {
332: int rounding_mode, round_down;
333: double value;
334:
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;
350: }
351:
352: __inline static const double rint (double x)
353: {
354: int rounding_mode, round_nearest;
355: double value;
356:
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;
371: }
372:
373: __inline static const double fmod (double x, double y)
374: {
375: double value;
376:
377: __asm ("fmod%.x %2,%0"
378: : "=f" (value)
379: : "0" (x),
380: "f" (y));
381: return value;
382: }
383:
384: __inline static const double drem (double x, double y)
385: {
386: double value;
387:
388: __asm ("frem%.x %2,%0"
389: : "=f" (value)
390: : "0" (x),
391: "f" (y));
392: return value;
393: }
394:
395: __inline static const double scalb (double x, int n)
396: {
397: double value;
398:
399: __asm ("fscale%.l %2,%0"
400: : "=f" (value)
401: : "0" (x),
402: "dmi" (n));
403: return value;
404: }
405:
406: __inline static double logb (double x)
407: {
408: double exponent;
409:
410: __asm ("fgetexp%.x %1,%0"
411: : "=f" (exponent)
412: : "f" (x));
413: return exponent;
414: }
415:
416: __inline static const double ldexp (double x, int n)
417: {
418: double value;
419:
420: __asm ("fscale%.l %2,%0"
421: : "=f" (value)
422: : "0" (x),
423: "dmi" (n));
424: return value;
425: }
426:
427: __inline static double frexp (double x, int *exp)
428: {
429: double float_exponent;
430: int int_exponent;
431: double mantissa;
432:
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)
441: {
442: __asm ("fscale%.b %#-1,%0"
443: : "=f" (mantissa) /* mantissa /= 2.0 */
444: : "0" (mantissa));
445: int_exponent += 1;
446: }
447: *exp = int_exponent;
448: return mantissa;
449: }
450:
451: __inline static double modf (double x, double *ip)
452: {
453: double temp;
454:
455: __asm ("fintrz%.x %1,%0"
456: : "=f" (temp) /* integer-valued float */
457: : "f" (x));
458: *ip = temp;
459: return x - temp;
460: }
461:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.