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