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