|
|
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.