OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [m68k/] [math-68881.h] - Blame information for rev 801

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 709 jeremybenn
/******************************************************************\
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 (self@bayes.arc.nasa.gov).            *
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 bug-gcc@prep.ai.mit.edu.  */
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
/* Changed by Ian Lance Taylor:
40
   September 1994, use extern inline instead of static inline.  */
41
 
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 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.