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