|
|
1.1 ! root 1: /* real.c - implementation of REAL_ARITHMETIC, REAL_VALUE_ATOF, ! 2: and support for XFmode IEEE extended real floating point arithmetic. ! 3: Contributed by Stephen L. Moshier ([email protected]). ! 4: ! 5: Copyright (C) 1993 Free Software Foundation, Inc. ! 6: ! 7: This file is part of GNU CC. ! 8: ! 9: GNU CC is free software; you can redistribute it and/or modify ! 10: it under the terms of the GNU General Public License as published by ! 11: the Free Software Foundation; either version 2, or (at your option) ! 12: any later version. ! 13: ! 14: GNU CC is distributed in the hope that it will be useful, ! 15: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 16: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 17: GNU General Public License for more details. ! 18: ! 19: You should have received a copy of the GNU General Public License ! 20: along with GNU CC; see the file COPYING. If not, write to ! 21: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 22: ! 23: #include <stdio.h> ! 24: #include <errno.h> ! 25: #include "config.h" ! 26: #include "tree.h" ! 27: ! 28: #ifndef errno ! 29: extern int errno; ! 30: #endif ! 31: ! 32: /* To enable support of XFmode extended real floating point, define ! 33: LONG_DOUBLE_TYPE_SIZE 96 in the tm.h file (m68k.h or i386.h). ! 34: ! 35: To support cross compilation between IEEE and VAX floating ! 36: point formats, define REAL_ARITHMETIC in the tm.h file. ! 37: ! 38: In either case the machine files (tm.h) must not contain any code ! 39: that tries to use host floating point arithmetic to convert ! 40: REAL_VALUE_TYPEs from `double' to `float', pass them to fprintf, ! 41: etc. In cross-compile situations a REAL_VALUE_TYPE may not ! 42: be intelligible to the host computer's native arithmetic. ! 43: ! 44: The emulator defaults to the host's floating point format so that ! 45: its decimal conversion functions can be used if desired (see ! 46: real.h). ! 47: ! 48: The first part of this file interfaces gcc to ieee.c, which is a ! 49: floating point arithmetic suite that was not written with gcc in ! 50: mind. The interface is followed by ieee.c itself and related ! 51: items. Avoid changing ieee.c unless you have suitable test ! 52: programs available. A special version of the PARANOIA floating ! 53: point arithmetic tester, modified for this purpose, can be found ! 54: on usc.edu : /pub/C-numanal/ieeetest.zoo. Some tutorial ! 55: information on ieee.c is given in my book: S. L. Moshier, ! 56: _Methods and Programs for Mathematical Functions_, Prentice-Hall ! 57: or Simon & Schuster Int'l, 1989. A library of XFmode elementary ! 58: transcendental functions can be obtained by ftp from ! 59: research.att.com: netlib/cephes/ldouble.shar.Z */ ! 60: ! 61: /* Type of computer arithmetic. ! 62: * Only one of DEC, MIEEE, IBMPC, or UNK should get defined. ! 63: */ ! 64: ! 65: /* `MIEEE' refers generically to big-endian IEEE floating-point data ! 66: structure. This definition should work in SFmode `float' type and ! 67: DFmode `double' type on virtually all big-endian IEEE machines. ! 68: If LONG_DOUBLE_TYPE_SIZE has been defined to be 96, then MIEEE ! 69: also invokes the particular XFmode (`long double' type) data ! 70: structure used by the Motorola 680x0 series processors. ! 71: ! 72: `IBMPC' refers generally to little-endian IEEE machines. In this ! 73: case, if LONG_DOUBLE_TYPE_SIZE has been defined to be 96, then ! 74: IBMPC also invokes the particular XFmode `long double' data ! 75: structure used by the Intel 80x86 series processors. ! 76: ! 77: `DEC' refers specifically to the Digital Equipment Corp PDP-11 ! 78: and VAX floating point data structure. This model currently ! 79: supports no type wider than DFmode. ! 80: ! 81: If LONG_DOUBLE_TYPE_SIZE = 64 (the default, unless tm.h defines it) ! 82: then `long double' and `double' are both implemented, but they ! 83: both mean DFmode. In this case, the software floating-point ! 84: support available here is activated by writing ! 85: #define REAL_ARITHMETIC ! 86: in tm.h. ! 87: ! 88: The case LONG_DOUBLE_TYPE_SIZE = 128 activates TFmode support ! 89: (Not Yet Implemented) and may deactivate XFmode since ! 90: `long double' is used to refer to both modes. */ ! 91: ! 92: /* The following converts gcc macros into the ones used by this file. */ ! 93: ! 94: /* REAL_ARITHMETIC defined means that macros in real.h are ! 95: defined to call emulator functions. */ ! 96: #ifdef REAL_ARITHMETIC ! 97: ! 98: #if TARGET_FLOAT_FORMAT == VAX_FLOAT_FORMAT ! 99: /* PDP-11, Pro350, VAX: */ ! 100: #define DEC 1 ! 101: #else /* it's not VAX */ ! 102: #if TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT ! 103: #if WORDS_BIG_ENDIAN ! 104: /* Motorola IEEE, high order words come first (Sun workstation): */ ! 105: #define MIEEE 1 ! 106: #else /* not big-endian */ ! 107: /* Intel IEEE, low order words come first: ! 108: */ ! 109: #define IBMPC 1 ! 110: #endif /* big-endian */ ! 111: #else /* it's not IEEE either */ ! 112: /* UNKnown arithmetic. We don't support this and can't go on. */ ! 113: unknown arithmetic type ! 114: #define UNK 1 ! 115: #endif /* not IEEE */ ! 116: #endif /* not VAX */ ! 117: ! 118: #else ! 119: /* REAL_ARITHMETIC not defined means that the *host's* data ! 120: structure will be used. It may differ by endian-ness from the ! 121: target machine's structure and will get its ends swapped ! 122: accordingly (but not here). Probably only the decimal <-> binary ! 123: functions in this file will actually be used in this case. */ ! 124: #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT ! 125: #define DEC 1 ! 126: #else /* it's not VAX */ ! 127: #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT ! 128: #ifdef HOST_WORDS_BIG_ENDIAN ! 129: #define MIEEE 1 ! 130: #else /* not big-endian */ ! 131: #define IBMPC 1 ! 132: #endif /* big-endian */ ! 133: #else /* it's not IEEE either */ ! 134: unknown arithmetic type ! 135: #define UNK 1 ! 136: #endif /* not IEEE */ ! 137: #endif /* not VAX */ ! 138: ! 139: #endif /* REAL_ARITHMETIC not defined */ ! 140: ! 141: /* Define INFINITY for support of infinity. ! 142: Define NANS for support of Not-a-Number's (NaN's). */ ! 143: #ifndef DEC ! 144: #define INFINITY ! 145: #define NANS ! 146: #endif ! 147: ! 148: /* Support of NaNs requires support of infinity. */ ! 149: #ifdef NANS ! 150: #ifndef INFINITY ! 151: #define INFINITY ! 152: #endif ! 153: #endif ! 154: ! 155: /* ehead.h ! 156: * ! 157: * Include file for extended precision arithmetic programs. ! 158: */ ! 159: ! 160: /* Number of 16 bit words in external e type format */ ! 161: #define NE 6 ! 162: ! 163: /* Number of 16 bit words in internal format */ ! 164: #define NI (NE+3) ! 165: ! 166: /* Array offset to exponent */ ! 167: #define E 1 ! 168: ! 169: /* Array offset to high guard word */ ! 170: #define M 2 ! 171: ! 172: /* Number of bits of precision */ ! 173: #define NBITS ((NI-4)*16) ! 174: ! 175: /* Maximum number of decimal digits in ASCII conversion ! 176: * = NBITS*log10(2) ! 177: */ ! 178: #define NDEC (NBITS*8/27) ! 179: ! 180: /* The exponent of 1.0 */ ! 181: #define EXONE (0x3fff) ! 182: ! 183: /* Find a host integer type that is at least 16 bits wide, ! 184: and another type at least twice whatever that size is. */ ! 185: ! 186: #if HOST_BITS_PER_CHAR >= 16 ! 187: #define EMUSHORT char ! 188: #define EMUSHORT_SIZE HOST_BITS_PER_CHAR ! 189: #define EMULONG_SIZE (2 * HOST_BITS_PER_CHAR) ! 190: #else ! 191: #if HOST_BITS_PER_SHORT >= 16 ! 192: #define EMUSHORT short ! 193: #define EMUSHORT_SIZE HOST_BITS_PER_SHORT ! 194: #define EMULONG_SIZE (2 * HOST_BITS_PER_SHORT) ! 195: #else ! 196: #if HOST_BITS_PER_INT >= 16 ! 197: #define EMUSHORT int ! 198: #define EMUSHORT_SIZE HOST_BITS_PER_INT ! 199: #define EMULONG_SIZE (2 * HOST_BITS_PER_INT) ! 200: #else ! 201: #if HOST_BITS_PER_LONG >= 16 ! 202: #define EMUSHORT long ! 203: #define EMUSHORT_SIZE HOST_BITS_PER_LONG ! 204: #define EMULONG_SIZE (2 * HOST_BITS_PER_LONG) ! 205: #else ! 206: /* You will have to modify this program to have a smaller unit size. */ ! 207: #define EMU_NON_COMPILE ! 208: #endif ! 209: #endif ! 210: #endif ! 211: #endif ! 212: ! 213: #if HOST_BITS_PER_SHORT >= EMULONG_SIZE ! 214: #define EMULONG short ! 215: #else ! 216: #if HOST_BITS_PER_INT >= EMULONG_SIZE ! 217: #define EMULONG int ! 218: #else ! 219: #if HOST_BITS_PER_LONG >= EMULONG_SIZE ! 220: #define EMULONG long ! 221: #else ! 222: #if HOST_BITS_PER_LONG_LONG >= EMULONG_SIZE ! 223: #define EMULONG long long int ! 224: #else ! 225: /* You will have to modify this program to have a smaller unit size. */ ! 226: #define EMU_NON_COMPILE ! 227: #endif ! 228: #endif ! 229: #endif ! 230: #endif ! 231: ! 232: ! 233: /* The host interface doesn't work if no 16-bit size exists. */ ! 234: #if EMUSHORT_SIZE != 16 ! 235: #define EMU_NON_COMPILE ! 236: #endif ! 237: ! 238: /* OK to continue compilation. */ ! 239: #ifndef EMU_NON_COMPILE ! 240: ! 241: /* Construct macros to translate between REAL_VALUE_TYPE and e type. ! 242: In GET_REAL and PUT_REAL, r and e are pointers. ! 243: A REAL_VALUE_TYPE is guaranteed to occupy contiguous locations ! 244: in memory, with no holes. */ ! 245: ! 246: #if LONG_DOUBLE_TYPE_SIZE == 96 ! 247: #define GET_REAL(r,e) bcopy (r, e, 2*NE) ! 248: #define PUT_REAL(e,r) bcopy (e, r, 2*NE) ! 249: #else /* no XFmode */ ! 250: ! 251: #ifdef REAL_ARITHMETIC ! 252: /* Emulator uses target format internally ! 253: but host stores it in host endian-ness. */ ! 254: ! 255: #if defined (HOST_WORDS_BIG_ENDIAN) == WORDS_BIG_ENDIAN ! 256: #define GET_REAL(r,e) e53toe ((r), (e)) ! 257: #define PUT_REAL(e,r) etoe53 ((e), (r)) ! 258: ! 259: #else /* endian-ness differs */ ! 260: /* emulator uses target endian-ness internally */ ! 261: #define GET_REAL(r,e) \ ! 262: do { EMUSHORT w[4]; \ ! 263: w[3] = ((EMUSHORT *) r)[0]; \ ! 264: w[2] = ((EMUSHORT *) r)[1]; \ ! 265: w[1] = ((EMUSHORT *) r)[2]; \ ! 266: w[0] = ((EMUSHORT *) r)[3]; \ ! 267: e53toe (w, (e)); } while (0) ! 268: ! 269: #define PUT_REAL(e,r) \ ! 270: do { EMUSHORT w[4]; \ ! 271: etoe53 ((e), w); \ ! 272: *((EMUSHORT *) r) = w[3]; \ ! 273: *((EMUSHORT *) r + 1) = w[2]; \ ! 274: *((EMUSHORT *) r + 2) = w[1]; \ ! 275: *((EMUSHORT *) r + 3) = w[0]; } while (0) ! 276: ! 277: #endif /* endian-ness differs */ ! 278: ! 279: #else /* not REAL_ARITHMETIC */ ! 280: ! 281: /* emulator uses host format */ ! 282: #define GET_REAL(r,e) e53toe ((r), (e)) ! 283: #define PUT_REAL(e,r) etoe53 ((e), (r)) ! 284: ! 285: #endif /* not REAL_ARITHMETIC */ ! 286: #endif /* no XFmode */ ! 287: ! 288: void warning (); ! 289: extern int extra_warnings; ! 290: int ecmp (), enormlz (), eshift (); ! 291: int eisneg (), eisinf (), eisnan (), eiisinf (), eiisnan (); ! 292: void eadd (), esub (), emul (), ediv (); ! 293: void eshup1 (), eshup8 (), eshup6 (), eshdn1 (), eshdn8 (), eshdn6 (); ! 294: void eabs (), eneg (), emov (), eclear (), einfin (), efloor (); ! 295: void eldexp (), efrexp (), eifrac (), euifrac (), ltoe (), ultoe (); ! 296: void eround (), ereal_to_decimal (), eiinfin (), einan (); ! 297: void esqrt (), elog (), eexp (), etanh (), epow (); ! 298: void asctoe (), asctoe24 (), asctoe53 (), asctoe64 (); ! 299: void etoasc (), e24toasc (), e53toasc (), e64toasc (); ! 300: void etoe64 (), etoe53 (), etoe24 (), e64toe (), e53toe (), e24toe (); ! 301: void mtherr (), make_nan (); ! 302: void enan (); ! 303: extern unsigned EMUSHORT ezero[], ehalf[], eone[], etwo[]; ! 304: extern unsigned EMUSHORT elog2[], esqrt2[]; ! 305: ! 306: /* Pack output array with 32-bit numbers obtained from ! 307: array containing 16-bit numbers, swapping ends if required. */ ! 308: void ! 309: endian (e, x, mode) ! 310: unsigned EMUSHORT e[]; ! 311: long x[]; ! 312: enum machine_mode mode; ! 313: { ! 314: unsigned long th, t; ! 315: ! 316: #if WORDS_BIG_ENDIAN ! 317: switch (mode) ! 318: { ! 319: ! 320: case XFmode: ! 321: ! 322: /* Swap halfwords in the third long. */ ! 323: th = (unsigned long) e[4] & 0xffff; ! 324: t = (unsigned long) e[5] & 0xffff; ! 325: t |= th << 16; ! 326: x[2] = (long) t; ! 327: /* fall into the double case */ ! 328: ! 329: case DFmode: ! 330: ! 331: /* swap halfwords in the second word */ ! 332: th = (unsigned long) e[2] & 0xffff; ! 333: t = (unsigned long) e[3] & 0xffff; ! 334: t |= th << 16; ! 335: x[1] = (long) t; ! 336: /* fall into the float case */ ! 337: ! 338: case SFmode: ! 339: ! 340: /* swap halfwords in the first word */ ! 341: th = (unsigned long) e[0] & 0xffff; ! 342: t = (unsigned long) e[1] & 0xffff; ! 343: t |= th << 16; ! 344: x[0] = t; ! 345: break; ! 346: ! 347: default: ! 348: abort (); ! 349: } ! 350: ! 351: #else ! 352: ! 353: /* Pack the output array without swapping. */ ! 354: ! 355: switch (mode) ! 356: { ! 357: ! 358: case XFmode: ! 359: ! 360: /* Pack the third long. ! 361: Each element of the input REAL_VALUE_TYPE array has 16 bit useful bits ! 362: in it. */ ! 363: th = (unsigned long) e[5] & 0xffff; ! 364: t = (unsigned long) e[4] & 0xffff; ! 365: t |= th << 16; ! 366: x[2] = (long) t; ! 367: /* fall into the double case */ ! 368: ! 369: case DFmode: ! 370: ! 371: /* pack the second long */ ! 372: th = (unsigned long) e[3] & 0xffff; ! 373: t = (unsigned long) e[2] & 0xffff; ! 374: t |= th << 16; ! 375: x[1] = (long) t; ! 376: /* fall into the float case */ ! 377: ! 378: case SFmode: ! 379: ! 380: /* pack the first long */ ! 381: th = (unsigned long) e[1] & 0xffff; ! 382: t = (unsigned long) e[0] & 0xffff; ! 383: t |= th << 16; ! 384: x[0] = t; ! 385: break; ! 386: ! 387: default: ! 388: abort (); ! 389: } ! 390: ! 391: #endif ! 392: } ! 393: ! 394: ! 395: /* This is the implementation of the REAL_ARITHMETIC macro. ! 396: */ ! 397: void ! 398: earith (value, icode, r1, r2) ! 399: REAL_VALUE_TYPE *value; ! 400: int icode; ! 401: REAL_VALUE_TYPE *r1; ! 402: REAL_VALUE_TYPE *r2; ! 403: { ! 404: unsigned EMUSHORT d1[NE], d2[NE], v[NE]; ! 405: enum tree_code code; ! 406: ! 407: GET_REAL (r1, d1); ! 408: GET_REAL (r2, d2); ! 409: #ifdef NANS ! 410: /* Return NaN input back to the caller. */ ! 411: if (eisnan (d1)) ! 412: { ! 413: PUT_REAL (d1, value); ! 414: return; ! 415: } ! 416: if (eisnan (d2)) ! 417: { ! 418: PUT_REAL (d2, value); ! 419: return; ! 420: } ! 421: #endif ! 422: code = (enum tree_code) icode; ! 423: switch (code) ! 424: { ! 425: case PLUS_EXPR: ! 426: eadd (d2, d1, v); ! 427: break; ! 428: ! 429: case MINUS_EXPR: ! 430: esub (d2, d1, v); /* d1 - d2 */ ! 431: break; ! 432: ! 433: case MULT_EXPR: ! 434: emul (d2, d1, v); ! 435: break; ! 436: ! 437: case RDIV_EXPR: ! 438: #ifndef REAL_INFINITY ! 439: if (ecmp (d2, ezero) == 0) ! 440: { ! 441: #ifdef NANS ! 442: enan (v); ! 443: break; ! 444: #else ! 445: abort (); ! 446: #endif ! 447: } ! 448: #endif ! 449: ediv (d2, d1, v); /* d1/d2 */ ! 450: break; ! 451: ! 452: case MIN_EXPR: /* min (d1,d2) */ ! 453: if (ecmp (d1, d2) < 0) ! 454: emov (d1, v); ! 455: else ! 456: emov (d2, v); ! 457: break; ! 458: ! 459: case MAX_EXPR: /* max (d1,d2) */ ! 460: if (ecmp (d1, d2) > 0) ! 461: emov (d1, v); ! 462: else ! 463: emov (d2, v); ! 464: break; ! 465: default: ! 466: emov (ezero, v); ! 467: break; ! 468: } ! 469: PUT_REAL (v, value); ! 470: } ! 471: ! 472: ! 473: /* Truncate REAL_VALUE_TYPE toward zero to signed HOST_WIDE_INT ! 474: * implements REAL_VALUE_RNDZINT (x) (etrunci (x)) ! 475: */ ! 476: REAL_VALUE_TYPE ! 477: etrunci (x) ! 478: REAL_VALUE_TYPE x; ! 479: { ! 480: unsigned EMUSHORT f[NE], g[NE]; ! 481: REAL_VALUE_TYPE r; ! 482: long l; ! 483: ! 484: GET_REAL (&x, g); ! 485: #ifdef NANS ! 486: if (eisnan (g)) ! 487: return (x); ! 488: #endif ! 489: eifrac (g, &l, f); ! 490: ltoe (&l, g); ! 491: PUT_REAL (g, &r); ! 492: return (r); ! 493: } ! 494: ! 495: ! 496: /* Truncate REAL_VALUE_TYPE toward zero to unsigned HOST_WIDE_INT ! 497: * implements REAL_VALUE_UNSIGNED_RNDZINT (x) (etruncui (x)) ! 498: */ ! 499: REAL_VALUE_TYPE ! 500: etruncui (x) ! 501: REAL_VALUE_TYPE x; ! 502: { ! 503: unsigned EMUSHORT f[NE], g[NE]; ! 504: REAL_VALUE_TYPE r; ! 505: unsigned long l; ! 506: ! 507: GET_REAL (&x, g); ! 508: #ifdef NANS ! 509: if (eisnan (g)) ! 510: return (x); ! 511: #endif ! 512: euifrac (g, &l, f); ! 513: ultoe (&l, g); ! 514: PUT_REAL (g, &r); ! 515: return (r); ! 516: } ! 517: ! 518: ! 519: /* This is the REAL_VALUE_ATOF function. ! 520: * It converts a decimal string to binary, rounding off ! 521: * as indicated by the machine_mode argument. Then it ! 522: * promotes the rounded value to REAL_VALUE_TYPE. ! 523: */ ! 524: REAL_VALUE_TYPE ! 525: ereal_atof (s, t) ! 526: char *s; ! 527: enum machine_mode t; ! 528: { ! 529: unsigned EMUSHORT tem[NE], e[NE]; ! 530: REAL_VALUE_TYPE r; ! 531: ! 532: switch (t) ! 533: { ! 534: case SFmode: ! 535: asctoe24 (s, tem); ! 536: e24toe (tem, e); ! 537: break; ! 538: case DFmode: ! 539: asctoe53 (s, tem); ! 540: e53toe (tem, e); ! 541: break; ! 542: case XFmode: ! 543: asctoe64 (s, tem); ! 544: e64toe (tem, e); ! 545: break; ! 546: default: ! 547: asctoe (s, e); ! 548: } ! 549: PUT_REAL (e, &r); ! 550: return (r); ! 551: } ! 552: ! 553: ! 554: /* Expansion of REAL_NEGATE. ! 555: */ ! 556: REAL_VALUE_TYPE ! 557: ereal_negate (x) ! 558: REAL_VALUE_TYPE x; ! 559: { ! 560: unsigned EMUSHORT e[NE]; ! 561: REAL_VALUE_TYPE r; ! 562: ! 563: GET_REAL (&x, e); ! 564: #ifdef NANS ! 565: if (eisnan (e)) ! 566: return (x); ! 567: #endif ! 568: eneg (e); ! 569: PUT_REAL (e, &r); ! 570: return (r); ! 571: } ! 572: ! 573: ! 574: /* Round real to int ! 575: * implements REAL_VALUE_FIX (x) (eroundi (x)) ! 576: * The type of rounding is left unspecified by real.h. ! 577: * It is implemented here as round to nearest (add .5 and chop). ! 578: */ ! 579: int ! 580: eroundi (x) ! 581: REAL_VALUE_TYPE x; ! 582: { ! 583: unsigned EMUSHORT f[NE], g[NE]; ! 584: EMULONG l; ! 585: ! 586: GET_REAL (&x, f); ! 587: #ifdef NANS ! 588: if (eisnan (f)) ! 589: { ! 590: warning ("conversion from NaN to int"); ! 591: return (-1); ! 592: } ! 593: #endif ! 594: eround (f, g); ! 595: eifrac (g, &l, f); ! 596: return ((int) l); ! 597: } ! 598: ! 599: /* Round real to nearest unsigned int ! 600: * implements REAL_VALUE_UNSIGNED_FIX (x) ((unsigned int) eroundi (x)) ! 601: * Negative input returns zero. ! 602: * The type of rounding is left unspecified by real.h. ! 603: * It is implemented here as round to nearest (add .5 and chop). ! 604: */ ! 605: unsigned int ! 606: eroundui (x) ! 607: REAL_VALUE_TYPE x; ! 608: { ! 609: unsigned EMUSHORT f[NE], g[NE]; ! 610: unsigned EMULONG l; ! 611: ! 612: GET_REAL (&x, f); ! 613: #ifdef NANS ! 614: if (eisnan (f)) ! 615: { ! 616: warning ("conversion from NaN to unsigned int"); ! 617: return (-1); ! 618: } ! 619: #endif ! 620: eround (f, g); ! 621: euifrac (g, &l, f); ! 622: return ((unsigned int)l); ! 623: } ! 624: ! 625: ! 626: /* REAL_VALUE_FROM_INT macro. ! 627: */ ! 628: void ! 629: ereal_from_int (d, i, j) ! 630: REAL_VALUE_TYPE *d; ! 631: long i, j; ! 632: { ! 633: unsigned EMUSHORT df[NE], dg[NE]; ! 634: long low, high; ! 635: int sign; ! 636: ! 637: sign = 0; ! 638: low = i; ! 639: if ((high = j) < 0) ! 640: { ! 641: sign = 1; ! 642: /* complement and add 1 */ ! 643: high = ~high; ! 644: if (low) ! 645: low = -low; ! 646: else ! 647: high += 1; ! 648: } ! 649: eldexp (eone, HOST_BITS_PER_LONG, df); ! 650: ultoe (&high, dg); ! 651: emul (dg, df, dg); ! 652: ultoe (&low, df); ! 653: eadd (df, dg, dg); ! 654: if (sign) ! 655: eneg (dg); ! 656: PUT_REAL (dg, d); ! 657: } ! 658: ! 659: ! 660: /* REAL_VALUE_FROM_UNSIGNED_INT macro. ! 661: */ ! 662: void ! 663: ereal_from_uint (d, i, j) ! 664: REAL_VALUE_TYPE *d; ! 665: unsigned long i, j; ! 666: { ! 667: unsigned EMUSHORT df[NE], dg[NE]; ! 668: unsigned long low, high; ! 669: ! 670: low = i; ! 671: high = j; ! 672: eldexp (eone, HOST_BITS_PER_LONG, df); ! 673: ultoe (&high, dg); ! 674: emul (dg, df, dg); ! 675: ultoe (&low, df); ! 676: eadd (df, dg, dg); ! 677: PUT_REAL (dg, d); ! 678: } ! 679: ! 680: ! 681: /* REAL_VALUE_TO_INT macro ! 682: */ ! 683: void ! 684: ereal_to_int (low, high, rr) ! 685: long *low, *high; ! 686: REAL_VALUE_TYPE rr; ! 687: { ! 688: unsigned EMUSHORT d[NE], df[NE], dg[NE], dh[NE]; ! 689: int s; ! 690: ! 691: GET_REAL (&rr, d); ! 692: #ifdef NANS ! 693: if (eisnan (d)) ! 694: { ! 695: warning ("conversion from NaN to int"); ! 696: *low = -1; ! 697: *high = -1; ! 698: return; ! 699: } ! 700: #endif ! 701: /* convert positive value */ ! 702: s = 0; ! 703: if (eisneg (d)) ! 704: { ! 705: eneg (d); ! 706: s = 1; ! 707: } ! 708: eldexp (eone, HOST_BITS_PER_LONG, df); ! 709: ediv (df, d, dg); /* dg = d / 2^32 is the high word */ ! 710: euifrac (dg, high, dh); ! 711: emul (df, dh, dg); /* fractional part is the low word */ ! 712: euifrac (dg, low, dh); ! 713: if (s) ! 714: { ! 715: /* complement and add 1 */ ! 716: *high = ~(*high); ! 717: if (*low) ! 718: *low = -(*low); ! 719: else ! 720: *high += 1; ! 721: } ! 722: } ! 723: ! 724: ! 725: /* REAL_VALUE_LDEXP macro. ! 726: */ ! 727: REAL_VALUE_TYPE ! 728: ereal_ldexp (x, n) ! 729: REAL_VALUE_TYPE x; ! 730: int n; ! 731: { ! 732: unsigned EMUSHORT e[NE], y[NE]; ! 733: REAL_VALUE_TYPE r; ! 734: ! 735: GET_REAL (&x, e); ! 736: #ifdef NANS ! 737: if (eisnan (e)) ! 738: return (x); ! 739: #endif ! 740: eldexp (e, n, y); ! 741: PUT_REAL (y, &r); ! 742: return (r); ! 743: } ! 744: ! 745: /* These routines are conditionally compiled because functions ! 746: * of the same names may be defined in fold-const.c. */ ! 747: #ifdef REAL_ARITHMETIC ! 748: ! 749: /* Check for infinity in a REAL_VALUE_TYPE. */ ! 750: int ! 751: target_isinf (x) ! 752: REAL_VALUE_TYPE x; ! 753: { ! 754: unsigned EMUSHORT e[NE]; ! 755: ! 756: #ifdef INFINITY ! 757: GET_REAL (&x, e); ! 758: return (eisinf (e)); ! 759: #else ! 760: return 0; ! 761: #endif ! 762: } ! 763: ! 764: ! 765: /* Check whether a REAL_VALUE_TYPE item is a NaN. */ ! 766: ! 767: int ! 768: target_isnan (x) ! 769: REAL_VALUE_TYPE x; ! 770: { ! 771: unsigned EMUSHORT e[NE]; ! 772: ! 773: #ifdef NANS ! 774: GET_REAL (&x, e); ! 775: return (eisnan (e)); ! 776: #else ! 777: return (0); ! 778: #endif ! 779: } ! 780: ! 781: ! 782: /* Check for a negative REAL_VALUE_TYPE number. ! 783: * this means strictly less than zero, not -0. ! 784: */ ! 785: ! 786: int ! 787: target_negative (x) ! 788: REAL_VALUE_TYPE x; ! 789: { ! 790: unsigned EMUSHORT e[NE]; ! 791: ! 792: GET_REAL (&x, e); ! 793: if (ecmp (e, ezero) == -1) ! 794: return (1); ! 795: return (0); ! 796: } ! 797: ! 798: /* Expansion of REAL_VALUE_TRUNCATE. ! 799: * The result is in floating point, rounded to nearest or even. ! 800: */ ! 801: REAL_VALUE_TYPE ! 802: real_value_truncate (mode, arg) ! 803: enum machine_mode mode; ! 804: REAL_VALUE_TYPE arg; ! 805: { ! 806: unsigned EMUSHORT e[NE], t[NE]; ! 807: REAL_VALUE_TYPE r; ! 808: ! 809: GET_REAL (&arg, e); ! 810: #ifdef NANS ! 811: if (eisnan (e)) ! 812: return (arg); ! 813: #endif ! 814: eclear (t); ! 815: switch (mode) ! 816: { ! 817: case XFmode: ! 818: etoe64 (e, t); ! 819: e64toe (t, t); ! 820: break; ! 821: ! 822: case DFmode: ! 823: etoe53 (e, t); ! 824: e53toe (t, t); ! 825: break; ! 826: ! 827: case SFmode: ! 828: etoe24 (e, t); ! 829: e24toe (t, t); ! 830: break; ! 831: ! 832: case SImode: ! 833: r = etrunci (e); ! 834: return (r); ! 835: ! 836: default: ! 837: abort (); ! 838: } ! 839: PUT_REAL (t, &r); ! 840: return (r); ! 841: } ! 842: ! 843: #endif /* REAL_ARITHMETIC defined */ ! 844: ! 845: /* Target values are arrays of host longs. A long is guaranteed ! 846: to be at least 32 bits wide. */ ! 847: void ! 848: etarldouble (r, l) ! 849: REAL_VALUE_TYPE r; ! 850: long l[]; ! 851: { ! 852: unsigned EMUSHORT e[NE]; ! 853: ! 854: GET_REAL (&r, e); ! 855: etoe64 (e, e); ! 856: endian (e, l, XFmode); ! 857: } ! 858: ! 859: void ! 860: etardouble (r, l) ! 861: REAL_VALUE_TYPE r; ! 862: long l[]; ! 863: { ! 864: unsigned EMUSHORT e[NE]; ! 865: ! 866: GET_REAL (&r, e); ! 867: etoe53 (e, e); ! 868: endian (e, l, DFmode); ! 869: } ! 870: ! 871: long ! 872: etarsingle (r) ! 873: REAL_VALUE_TYPE r; ! 874: { ! 875: unsigned EMUSHORT e[NE]; ! 876: unsigned long l; ! 877: ! 878: GET_REAL (&r, e); ! 879: etoe24 (e, e); ! 880: endian (e, &l, SFmode); ! 881: return ((long) l); ! 882: } ! 883: ! 884: void ! 885: ereal_to_decimal (x, s) ! 886: REAL_VALUE_TYPE x; ! 887: char *s; ! 888: { ! 889: unsigned EMUSHORT e[NE]; ! 890: ! 891: GET_REAL (&x, e); ! 892: etoasc (e, s, 20); ! 893: } ! 894: ! 895: int ! 896: ereal_cmp (x, y) ! 897: REAL_VALUE_TYPE x, y; ! 898: { ! 899: unsigned EMUSHORT ex[NE], ey[NE]; ! 900: ! 901: GET_REAL (&x, ex); ! 902: GET_REAL (&y, ey); ! 903: return (ecmp (ex, ey)); ! 904: } ! 905: ! 906: int ! 907: ereal_isneg (x) ! 908: REAL_VALUE_TYPE x; ! 909: { ! 910: unsigned EMUSHORT ex[NE]; ! 911: ! 912: GET_REAL (&x, ex); ! 913: return (eisneg (ex)); ! 914: } ! 915: ! 916: /* End of REAL_ARITHMETIC interface */ ! 917: ! 918: /* ieee.c ! 919: * ! 920: * Extended precision IEEE binary floating point arithmetic routines ! 921: * ! 922: * Numbers are stored in C language as arrays of 16-bit unsigned ! 923: * short integers. The arguments of the routines are pointers to ! 924: * the arrays. ! 925: * ! 926: * ! 927: * External e type data structure, simulates Intel 8087 chip ! 928: * temporary real format but possibly with a larger significand: ! 929: * ! 930: * NE-1 significand words (least significant word first, ! 931: * most significant bit is normally set) ! 932: * exponent (value = EXONE for 1.0, ! 933: * top bit is the sign) ! 934: * ! 935: * ! 936: * Internal data structure of a number (a "word" is 16 bits): ! 937: * ! 938: * ei[0] sign word (0 for positive, 0xffff for negative) ! 939: * ei[1] biased exponent (value = EXONE for the number 1.0) ! 940: * ei[2] high guard word (always zero after normalization) ! 941: * ei[3] ! 942: * to ei[NI-2] significand (NI-4 significand words, ! 943: * most significant word first, ! 944: * most significant bit is set) ! 945: * ei[NI-1] low guard word (0x8000 bit is rounding place) ! 946: * ! 947: * ! 948: * ! 949: * Routines for external format numbers ! 950: * ! 951: * asctoe (string, e) ASCII string to extended double e type ! 952: * asctoe64 (string, &d) ASCII string to long double ! 953: * asctoe53 (string, &d) ASCII string to double ! 954: * asctoe24 (string, &f) ASCII string to single ! 955: * asctoeg (string, e, prec) ASCII string to specified precision ! 956: * e24toe (&f, e) IEEE single precision to e type ! 957: * e53toe (&d, e) IEEE double precision to e type ! 958: * e64toe (&d, e) IEEE long double precision to e type ! 959: * eabs (e) absolute value ! 960: * eadd (a, b, c) c = b + a ! 961: * eclear (e) e = 0 ! 962: * ecmp (a, b) Returns 1 if a > b, 0 if a == b, ! 963: * -1 if a < b, -2 if either a or b is a NaN. ! 964: * ediv (a, b, c) c = b / a ! 965: * efloor (a, b) truncate to integer, toward -infinity ! 966: * efrexp (a, exp, s) extract exponent and significand ! 967: * eifrac (e, &l, frac) e to long integer and e type fraction ! 968: * euifrac (e, &l, frac) e to unsigned long integer and e type fraction ! 969: * einfin (e) set e to infinity, leaving its sign alone ! 970: * eldexp (a, n, b) multiply by 2**n ! 971: * emov (a, b) b = a ! 972: * emul (a, b, c) c = b * a ! 973: * eneg (e) e = -e ! 974: * eround (a, b) b = nearest integer value to a ! 975: * esub (a, b, c) c = b - a ! 976: * e24toasc (&f, str, n) single to ASCII string, n digits after decimal ! 977: * e53toasc (&d, str, n) double to ASCII string, n digits after decimal ! 978: * e64toasc (&d, str, n) long double to ASCII string ! 979: * etoasc (e, str, n) e to ASCII string, n digits after decimal ! 980: * etoe24 (e, &f) convert e type to IEEE single precision ! 981: * etoe53 (e, &d) convert e type to IEEE double precision ! 982: * etoe64 (e, &d) convert e type to IEEE long double precision ! 983: * ltoe (&l, e) long (32 bit) integer to e type ! 984: * ultoe (&l, e) unsigned long (32 bit) integer to e type ! 985: * eisneg (e) 1 if sign bit of e != 0, else 0 ! 986: * eisinf (e) 1 if e has maximum exponent (non-IEEE) ! 987: * or is infinite (IEEE) ! 988: * eisnan (e) 1 if e is a NaN ! 989: * ! 990: * ! 991: * Routines for internal format numbers ! 992: * ! 993: * eaddm (ai, bi) add significands, bi = bi + ai ! 994: * ecleaz (ei) ei = 0 ! 995: * ecleazs (ei) set ei = 0 but leave its sign alone ! 996: * ecmpm (ai, bi) compare significands, return 1, 0, or -1 ! 997: * edivm (ai, bi) divide significands, bi = bi / ai ! 998: * emdnorm (ai,l,s,exp) normalize and round off ! 999: * emovi (a, ai) convert external a to internal ai ! 1000: * emovo (ai, a) convert internal ai to external a ! 1001: * emovz (ai, bi) bi = ai, low guard word of bi = 0 ! 1002: * emulm (ai, bi) multiply significands, bi = bi * ai ! 1003: * enormlz (ei) left-justify the significand ! 1004: * eshdn1 (ai) shift significand and guards down 1 bit ! 1005: * eshdn8 (ai) shift down 8 bits ! 1006: * eshdn6 (ai) shift down 16 bits ! 1007: * eshift (ai, n) shift ai n bits up (or down if n < 0) ! 1008: * eshup1 (ai) shift significand and guards up 1 bit ! 1009: * eshup8 (ai) shift up 8 bits ! 1010: * eshup6 (ai) shift up 16 bits ! 1011: * esubm (ai, bi) subtract significands, bi = bi - ai ! 1012: * eiisinf (ai) 1 if infinite ! 1013: * eiisnan (ai) 1 if a NaN ! 1014: * einan (ai) set ai = NaN ! 1015: * eiinfin (ai) set ai = infinity ! 1016: * ! 1017: * ! 1018: * The result is always normalized and rounded to NI-4 word precision ! 1019: * after each arithmetic operation. ! 1020: * ! 1021: * Exception flags are NOT fully supported. ! 1022: * ! 1023: * Signaling NaN's are NOT supported; they are treated the same ! 1024: * as quiet NaN's. ! 1025: * ! 1026: * Define INFINITY for support of infinity; otherwise a ! 1027: * saturation arithmetic is implemented. ! 1028: * ! 1029: * Define NANS for support of Not-a-Number items; otherwise the ! 1030: * arithmetic will never produce a NaN output, and might be confused ! 1031: * by a NaN input. ! 1032: * If NaN's are supported, the output of `ecmp (a,b)' is -2 if ! 1033: * either a or b is a NaN. This means asking `if (ecmp (a,b) < 0)' ! 1034: * may not be legitimate. Use `if (ecmp (a,b) == -1)' for `less than' ! 1035: * if in doubt. ! 1036: * ! 1037: * Denormals are always supported here where appropriate (e.g., not ! 1038: * for conversion to DEC numbers). ! 1039: * ! 1040: */ ! 1041: ! 1042: ! 1043: /* mconf.h ! 1044: * ! 1045: * Common include file for math routines ! 1046: * ! 1047: * ! 1048: * ! 1049: * SYNOPSIS: ! 1050: * ! 1051: * #include "mconf.h" ! 1052: * ! 1053: * ! 1054: * ! 1055: * DESCRIPTION: ! 1056: * ! 1057: * This file contains definitions for error codes that are ! 1058: * passed to the common error handling routine mtherr ! 1059: * (which see). ! 1060: * ! 1061: * The file also includes a conditional assembly definition ! 1062: * for the type of computer arithmetic (Intel IEEE, DEC, Motorola ! 1063: * IEEE, or UNKnown). ! 1064: * ! 1065: * For Digital Equipment PDP-11 and VAX computers, certain ! 1066: * IBM systems, and others that use numbers with a 56-bit ! 1067: * significand, the symbol DEC should be defined. In this ! 1068: * mode, most floating point constants are given as arrays ! 1069: * of octal integers to eliminate decimal to binary conversion ! 1070: * errors that might be introduced by the compiler. ! 1071: * ! 1072: * For computers, such as IBM PC, that follow the IEEE ! 1073: * Standard for Binary Floating Point Arithmetic (ANSI/IEEE ! 1074: * Std 754-1985), the symbol IBMPC or MIEEE should be defined. ! 1075: * These numbers have 53-bit significands. In this mode, constants ! 1076: * are provided as arrays of hexadecimal 16 bit integers. ! 1077: * ! 1078: * To accommodate other types of computer arithmetic, all ! 1079: * constants are also provided in a normal decimal radix ! 1080: * which one can hope are correctly converted to a suitable ! 1081: * format by the available C language compiler. To invoke ! 1082: * this mode, the symbol UNK is defined. ! 1083: * ! 1084: * An important difference among these modes is a predefined ! 1085: * set of machine arithmetic constants for each. The numbers ! 1086: * MACHEP (the machine roundoff error), MAXNUM (largest number ! 1087: * represented), and several other parameters are preset by ! 1088: * the configuration symbol. Check the file const.c to ! 1089: * ensure that these values are correct for your computer. ! 1090: * ! 1091: * For ANSI C compatibility, define ANSIC equal to 1. Currently ! 1092: * this affects only the atan2 function and others that use it. ! 1093: */ ! 1094: ! 1095: /* Constant definitions for math error conditions. */ ! 1096: ! 1097: #define DOMAIN 1 /* argument domain error */ ! 1098: #define SING 2 /* argument singularity */ ! 1099: #define OVERFLOW 3 /* overflow range error */ ! 1100: #define UNDERFLOW 4 /* underflow range error */ ! 1101: #define TLOSS 5 /* total loss of precision */ ! 1102: #define PLOSS 6 /* partial loss of precision */ ! 1103: #define INVALID 7 /* NaN-producing operation */ ! 1104: ! 1105: /* e type constants used by high precision check routines */ ! 1106: ! 1107: /*include "ehead.h"*/ ! 1108: /* 0.0 */ ! 1109: unsigned EMUSHORT ezero[NE] = ! 1110: { ! 1111: 0, 0000000, 0000000, 0000000, 0000000, 0000000,}; ! 1112: extern unsigned EMUSHORT ezero[]; ! 1113: ! 1114: /* 5.0E-1 */ ! 1115: unsigned EMUSHORT ehalf[NE] = ! 1116: { ! 1117: 0, 0000000, 0000000, 0000000, 0100000, 0x3ffe,}; ! 1118: extern unsigned EMUSHORT ehalf[]; ! 1119: ! 1120: /* 1.0E0 */ ! 1121: unsigned EMUSHORT eone[NE] = ! 1122: { ! 1123: 0, 0000000, 0000000, 0000000, 0100000, 0x3fff,}; ! 1124: extern unsigned EMUSHORT eone[]; ! 1125: ! 1126: /* 2.0E0 */ ! 1127: unsigned EMUSHORT etwo[NE] = ! 1128: { ! 1129: 0, 0000000, 0000000, 0000000, 0100000, 0040000,}; ! 1130: extern unsigned EMUSHORT etwo[]; ! 1131: ! 1132: /* 3.2E1 */ ! 1133: unsigned EMUSHORT e32[NE] = ! 1134: { ! 1135: 0, 0000000, 0000000, 0000000, 0100000, 0040004,}; ! 1136: extern unsigned EMUSHORT e32[]; ! 1137: ! 1138: /* 6.93147180559945309417232121458176568075500134360255E-1 */ ! 1139: unsigned EMUSHORT elog2[NE] = ! 1140: { ! 1141: 0xc9e4, 0x79ab, 0150717, 0013767, 0130562, 0x3ffe,}; ! 1142: extern unsigned EMUSHORT elog2[]; ! 1143: ! 1144: /* 1.41421356237309504880168872420969807856967187537695E0 */ ! 1145: unsigned EMUSHORT esqrt2[NE] = ! 1146: { ! 1147: 0x597e, 0x6484, 0174736, 0171463, 0132404, 0x3fff,}; ! 1148: extern unsigned EMUSHORT esqrt2[]; ! 1149: ! 1150: /* 2/sqrt (PI) = ! 1151: * 1.12837916709551257389615890312154517168810125865800E0 */ ! 1152: unsigned EMUSHORT eoneopi[NE] = ! 1153: { ! 1154: 0x71d5, 0x688d, 0012333, 0135202, 0110156, 0x3fff,}; ! 1155: extern unsigned EMUSHORT eoneopi[]; ! 1156: ! 1157: /* 3.14159265358979323846264338327950288419716939937511E0 */ ! 1158: unsigned EMUSHORT epi[NE] = ! 1159: { ! 1160: 0xc4c6, 0xc234, 0020550, 0155242, 0144417, 0040000,}; ! 1161: extern unsigned EMUSHORT epi[]; ! 1162: ! 1163: /* 5.7721566490153286060651209008240243104215933593992E-1 */ ! 1164: unsigned EMUSHORT eeul[NE] = ! 1165: { ! 1166: 0xd1be, 0xc7a4, 0076660, 0063743, 0111704, 0x3ffe,}; ! 1167: extern unsigned EMUSHORT eeul[]; ! 1168: ! 1169: /* ! 1170: include "ehead.h" ! 1171: include "mconf.h" ! 1172: */ ! 1173: ! 1174: ! 1175: ! 1176: /* Control register for rounding precision. ! 1177: * This can be set to 80 (if NE=6), 64, 56, 53, or 24 bits. ! 1178: */ ! 1179: int rndprc = NBITS; ! 1180: extern int rndprc; ! 1181: ! 1182: void eaddm (), esubm (), emdnorm (), asctoeg (); ! 1183: static void toe24 (), toe53 (), toe64 (); ! 1184: void eremain (), einit (), eiremain (); ! 1185: int ecmpm (), edivm (), emulm (); ! 1186: void emovi (), emovo (), emovz (), ecleaz (), ecleazs (), eadd1 (); ! 1187: void etodec (), todec (), dectoe (); ! 1188: ! 1189: ! 1190: ! 1191: ! 1192: void ! 1193: einit () ! 1194: { ! 1195: } ! 1196: ! 1197: /* ! 1198: ; Clear out entire external format number. ! 1199: ; ! 1200: ; unsigned EMUSHORT x[]; ! 1201: ; eclear (x); ! 1202: */ ! 1203: ! 1204: void ! 1205: eclear (x) ! 1206: register unsigned EMUSHORT *x; ! 1207: { ! 1208: register int i; ! 1209: ! 1210: for (i = 0; i < NE; i++) ! 1211: *x++ = 0; ! 1212: } ! 1213: ! 1214: ! 1215: ! 1216: /* Move external format number from a to b. ! 1217: * ! 1218: * emov (a, b); ! 1219: */ ! 1220: ! 1221: void ! 1222: emov (a, b) ! 1223: register unsigned EMUSHORT *a, *b; ! 1224: { ! 1225: register int i; ! 1226: ! 1227: for (i = 0; i < NE; i++) ! 1228: *b++ = *a++; ! 1229: } ! 1230: ! 1231: ! 1232: /* ! 1233: ; Absolute value of external format number ! 1234: ; ! 1235: ; EMUSHORT x[NE]; ! 1236: ; eabs (x); ! 1237: */ ! 1238: ! 1239: void ! 1240: eabs (x) ! 1241: unsigned EMUSHORT x[]; /* x is the memory address of a short */ ! 1242: { ! 1243: ! 1244: x[NE - 1] &= 0x7fff; /* sign is top bit of last word of external format */ ! 1245: } ! 1246: ! 1247: ! 1248: ! 1249: ! 1250: /* ! 1251: ; Negate external format number ! 1252: ; ! 1253: ; unsigned EMUSHORT x[NE]; ! 1254: ; eneg (x); ! 1255: */ ! 1256: ! 1257: void ! 1258: eneg (x) ! 1259: unsigned EMUSHORT x[]; ! 1260: { ! 1261: ! 1262: #ifdef NANS ! 1263: if (eisnan (x)) ! 1264: return; ! 1265: #endif ! 1266: x[NE - 1] ^= 0x8000; /* Toggle the sign bit */ ! 1267: } ! 1268: ! 1269: ! 1270: ! 1271: /* Return 1 if external format number is negative, ! 1272: * else return zero, including when it is a NaN. ! 1273: */ ! 1274: int ! 1275: eisneg (x) ! 1276: unsigned EMUSHORT x[]; ! 1277: { ! 1278: ! 1279: #ifdef NANS ! 1280: if (eisnan (x)) ! 1281: return (0); ! 1282: #endif ! 1283: if (x[NE - 1] & 0x8000) ! 1284: return (1); ! 1285: else ! 1286: return (0); ! 1287: } ! 1288: ! 1289: ! 1290: /* Return 1 if external format number is infinity. ! 1291: * else return zero. ! 1292: */ ! 1293: int ! 1294: eisinf (x) ! 1295: unsigned EMUSHORT x[]; ! 1296: { ! 1297: ! 1298: #ifdef NANS ! 1299: if (eisnan (x)) ! 1300: return (0); ! 1301: #endif ! 1302: if ((x[NE - 1] & 0x7fff) == 0x7fff) ! 1303: return (1); ! 1304: else ! 1305: return (0); ! 1306: } ! 1307: ! 1308: ! 1309: /* Check if e-type number is not a number. ! 1310: The bit pattern is one that we defined, so we know for sure how to ! 1311: detect it. */ ! 1312: ! 1313: int ! 1314: eisnan (x) ! 1315: unsigned EMUSHORT x[]; ! 1316: { ! 1317: ! 1318: #ifdef NANS ! 1319: int i; ! 1320: /* NaN has maximum exponent */ ! 1321: if ((x[NE - 1] & 0x7fff) != 0x7fff) ! 1322: return (0); ! 1323: /* ... and non-zero significand field. */ ! 1324: for (i = 0; i < NE - 1; i++) ! 1325: { ! 1326: if (*x++ != 0) ! 1327: return (1); ! 1328: } ! 1329: #endif ! 1330: return (0); ! 1331: } ! 1332: ! 1333: /* Fill external format number with infinity pattern (IEEE) ! 1334: or largest possible number (non-IEEE). ! 1335: Before calling einfin, you should either call eclear ! 1336: or set up the sign bit by hand. */ ! 1337: ! 1338: void ! 1339: einfin (x) ! 1340: register unsigned EMUSHORT *x; ! 1341: { ! 1342: register int i; ! 1343: ! 1344: #ifdef INFINITY ! 1345: for (i = 0; i < NE - 1; i++) ! 1346: *x++ = 0; ! 1347: *x |= 32767; ! 1348: #else ! 1349: for (i = 0; i < NE - 1; i++) ! 1350: *x++ = 0xffff; ! 1351: *x |= 32766; ! 1352: if (rndprc < NBITS) ! 1353: { ! 1354: if (rndprc == 64) ! 1355: { ! 1356: *(x - 5) = 0; ! 1357: } ! 1358: if (rndprc == 53) ! 1359: { ! 1360: *(x - 4) = 0xf800; ! 1361: } ! 1362: else ! 1363: { ! 1364: *(x - 4) = 0; ! 1365: *(x - 3) = 0; ! 1366: *(x - 2) = 0xff00; ! 1367: } ! 1368: } ! 1369: #endif ! 1370: } ! 1371: ! 1372: ! 1373: /* Output an e-type NaN. ! 1374: This generates Intel's quiet NaN pattern for extended real. ! 1375: The exponent is 7fff, the leading mantissa word is c000. */ ! 1376: ! 1377: void ! 1378: enan (x) ! 1379: register unsigned EMUSHORT *x; ! 1380: { ! 1381: register int i; ! 1382: ! 1383: for (i = 0; i < NE - 2; i++) ! 1384: *x++ = 0; ! 1385: *x++ = 0xc000; ! 1386: *x = 0x7fff; ! 1387: } ! 1388: ! 1389: ! 1390: /* Move in external format number, ! 1391: * converting it to internal format. ! 1392: */ ! 1393: void ! 1394: emovi (a, b) ! 1395: unsigned EMUSHORT *a, *b; ! 1396: { ! 1397: register unsigned EMUSHORT *p, *q; ! 1398: int i; ! 1399: ! 1400: q = b; ! 1401: p = a + (NE - 1); /* point to last word of external number */ ! 1402: /* get the sign bit */ ! 1403: if (*p & 0x8000) ! 1404: *q++ = 0xffff; ! 1405: else ! 1406: *q++ = 0; ! 1407: /* get the exponent */ ! 1408: *q = *p--; ! 1409: *q++ &= 0x7fff; /* delete the sign bit */ ! 1410: #ifdef INFINITY ! 1411: if ((*(q - 1) & 0x7fff) == 0x7fff) ! 1412: { ! 1413: #ifdef NANS ! 1414: if (eisnan (a)) ! 1415: { ! 1416: *q++ = 0; ! 1417: for (i = 3; i < NI; i++) ! 1418: *q++ = *p--; ! 1419: return; ! 1420: } ! 1421: #endif ! 1422: for (i = 2; i < NI; i++) ! 1423: *q++ = 0; ! 1424: return; ! 1425: } ! 1426: #endif ! 1427: /* clear high guard word */ ! 1428: *q++ = 0; ! 1429: /* move in the significand */ ! 1430: for (i = 0; i < NE - 1; i++) ! 1431: *q++ = *p--; ! 1432: /* clear low guard word */ ! 1433: *q = 0; ! 1434: } ! 1435: ! 1436: ! 1437: /* Move internal format number out, ! 1438: * converting it to external format. ! 1439: */ ! 1440: void ! 1441: emovo (a, b) ! 1442: unsigned EMUSHORT *a, *b; ! 1443: { ! 1444: register unsigned EMUSHORT *p, *q; ! 1445: unsigned EMUSHORT i; ! 1446: ! 1447: p = a; ! 1448: q = b + (NE - 1); /* point to output exponent */ ! 1449: /* combine sign and exponent */ ! 1450: i = *p++; ! 1451: if (i) ! 1452: *q-- = *p++ | 0x8000; ! 1453: else ! 1454: *q-- = *p++; ! 1455: #ifdef INFINITY ! 1456: if (*(p - 1) == 0x7fff) ! 1457: { ! 1458: #ifdef NANS ! 1459: if (eiisnan (a)) ! 1460: { ! 1461: enan (b); ! 1462: return; ! 1463: } ! 1464: #endif ! 1465: einfin (b); ! 1466: return; ! 1467: } ! 1468: #endif ! 1469: /* skip over guard word */ ! 1470: ++p; ! 1471: /* move the significand */ ! 1472: for (i = 0; i < NE - 1; i++) ! 1473: *q-- = *p++; ! 1474: } ! 1475: ! 1476: ! 1477: ! 1478: ! 1479: /* Clear out internal format number. ! 1480: */ ! 1481: ! 1482: void ! 1483: ecleaz (xi) ! 1484: register unsigned EMUSHORT *xi; ! 1485: { ! 1486: register int i; ! 1487: ! 1488: for (i = 0; i < NI; i++) ! 1489: *xi++ = 0; ! 1490: } ! 1491: ! 1492: ! 1493: /* same, but don't touch the sign. */ ! 1494: ! 1495: void ! 1496: ecleazs (xi) ! 1497: register unsigned EMUSHORT *xi; ! 1498: { ! 1499: register int i; ! 1500: ! 1501: ++xi; ! 1502: for (i = 0; i < NI - 1; i++) ! 1503: *xi++ = 0; ! 1504: } ! 1505: ! 1506: ! 1507: ! 1508: /* Move internal format number from a to b. ! 1509: */ ! 1510: void ! 1511: emovz (a, b) ! 1512: register unsigned EMUSHORT *a, *b; ! 1513: { ! 1514: register int i; ! 1515: ! 1516: for (i = 0; i < NI - 1; i++) ! 1517: *b++ = *a++; ! 1518: /* clear low guard word */ ! 1519: *b = 0; ! 1520: } ! 1521: ! 1522: /* Generate internal format NaN. ! 1523: The explicit pattern for this is maximum exponent and ! 1524: top two significand bits set. */ ! 1525: ! 1526: void ! 1527: einan (x) ! 1528: unsigned EMUSHORT x[]; ! 1529: { ! 1530: ! 1531: ecleaz (x); ! 1532: x[E] = 0x7fff; ! 1533: x[M + 1] = 0xc000; ! 1534: } ! 1535: ! 1536: /* Return nonzero if internal format number is a NaN. */ ! 1537: ! 1538: int ! 1539: eiisnan (x) ! 1540: unsigned EMUSHORT x[]; ! 1541: { ! 1542: int i; ! 1543: ! 1544: if ((x[E] & 0x7fff) == 0x7fff) ! 1545: { ! 1546: for (i = M + 1; i < NI; i++) ! 1547: { ! 1548: if (x[i] != 0) ! 1549: return (1); ! 1550: } ! 1551: } ! 1552: return (0); ! 1553: } ! 1554: ! 1555: /* Fill internal format number with infinity pattern. ! 1556: This has maximum exponent and significand all zeros. */ ! 1557: ! 1558: void ! 1559: eiinfin (x) ! 1560: unsigned EMUSHORT x[]; ! 1561: { ! 1562: ! 1563: ecleaz (x); ! 1564: x[E] = 0x7fff; ! 1565: } ! 1566: ! 1567: /* Return nonzero if internal format number is infinite. */ ! 1568: ! 1569: int ! 1570: eiisinf (x) ! 1571: unsigned EMUSHORT x[]; ! 1572: { ! 1573: ! 1574: #ifdef NANS ! 1575: if (eiisnan (x)) ! 1576: return (0); ! 1577: #endif ! 1578: if ((x[E] & 0x7fff) == 0x7fff) ! 1579: return (1); ! 1580: return (0); ! 1581: } ! 1582: ! 1583: ! 1584: /* ! 1585: ; Compare significands of numbers in internal format. ! 1586: ; Guard words are included in the comparison. ! 1587: ; ! 1588: ; unsigned EMUSHORT a[NI], b[NI]; ! 1589: ; cmpm (a, b); ! 1590: ; ! 1591: ; for the significands: ! 1592: ; returns +1 if a > b ! 1593: ; 0 if a == b ! 1594: ; -1 if a < b ! 1595: */ ! 1596: int ! 1597: ecmpm (a, b) ! 1598: register unsigned EMUSHORT *a, *b; ! 1599: { ! 1600: int i; ! 1601: ! 1602: a += M; /* skip up to significand area */ ! 1603: b += M; ! 1604: for (i = M; i < NI; i++) ! 1605: { ! 1606: if (*a++ != *b++) ! 1607: goto difrnt; ! 1608: } ! 1609: return (0); ! 1610: ! 1611: difrnt: ! 1612: if (*(--a) > *(--b)) ! 1613: return (1); ! 1614: else ! 1615: return (-1); ! 1616: } ! 1617: ! 1618: ! 1619: /* ! 1620: ; Shift significand down by 1 bit ! 1621: */ ! 1622: ! 1623: void ! 1624: eshdn1 (x) ! 1625: register unsigned EMUSHORT *x; ! 1626: { ! 1627: register unsigned EMUSHORT bits; ! 1628: int i; ! 1629: ! 1630: x += M; /* point to significand area */ ! 1631: ! 1632: bits = 0; ! 1633: for (i = M; i < NI; i++) ! 1634: { ! 1635: if (*x & 1) ! 1636: bits |= 1; ! 1637: *x >>= 1; ! 1638: if (bits & 2) ! 1639: *x |= 0x8000; ! 1640: bits <<= 1; ! 1641: ++x; ! 1642: } ! 1643: } ! 1644: ! 1645: ! 1646: ! 1647: /* ! 1648: ; Shift significand up by 1 bit ! 1649: */ ! 1650: ! 1651: void ! 1652: eshup1 (x) ! 1653: register unsigned EMUSHORT *x; ! 1654: { ! 1655: register unsigned EMUSHORT bits; ! 1656: int i; ! 1657: ! 1658: x += NI - 1; ! 1659: bits = 0; ! 1660: ! 1661: for (i = M; i < NI; i++) ! 1662: { ! 1663: if (*x & 0x8000) ! 1664: bits |= 1; ! 1665: *x <<= 1; ! 1666: if (bits & 2) ! 1667: *x |= 1; ! 1668: bits <<= 1; ! 1669: --x; ! 1670: } ! 1671: } ! 1672: ! 1673: ! 1674: ! 1675: /* ! 1676: ; Shift significand down by 8 bits ! 1677: */ ! 1678: ! 1679: void ! 1680: eshdn8 (x) ! 1681: register unsigned EMUSHORT *x; ! 1682: { ! 1683: register unsigned EMUSHORT newbyt, oldbyt; ! 1684: int i; ! 1685: ! 1686: x += M; ! 1687: oldbyt = 0; ! 1688: for (i = M; i < NI; i++) ! 1689: { ! 1690: newbyt = *x << 8; ! 1691: *x >>= 8; ! 1692: *x |= oldbyt; ! 1693: oldbyt = newbyt; ! 1694: ++x; ! 1695: } ! 1696: } ! 1697: ! 1698: /* ! 1699: ; Shift significand up by 8 bits ! 1700: */ ! 1701: ! 1702: void ! 1703: eshup8 (x) ! 1704: register unsigned EMUSHORT *x; ! 1705: { ! 1706: int i; ! 1707: register unsigned EMUSHORT newbyt, oldbyt; ! 1708: ! 1709: x += NI - 1; ! 1710: oldbyt = 0; ! 1711: ! 1712: for (i = M; i < NI; i++) ! 1713: { ! 1714: newbyt = *x >> 8; ! 1715: *x <<= 8; ! 1716: *x |= oldbyt; ! 1717: oldbyt = newbyt; ! 1718: --x; ! 1719: } ! 1720: } ! 1721: ! 1722: /* ! 1723: ; Shift significand up by 16 bits ! 1724: */ ! 1725: ! 1726: void ! 1727: eshup6 (x) ! 1728: register unsigned EMUSHORT *x; ! 1729: { ! 1730: int i; ! 1731: register unsigned EMUSHORT *p; ! 1732: ! 1733: p = x + M; ! 1734: x += M + 1; ! 1735: ! 1736: for (i = M; i < NI - 1; i++) ! 1737: *p++ = *x++; ! 1738: ! 1739: *p = 0; ! 1740: } ! 1741: ! 1742: /* ! 1743: ; Shift significand down by 16 bits ! 1744: */ ! 1745: ! 1746: void ! 1747: eshdn6 (x) ! 1748: register unsigned EMUSHORT *x; ! 1749: { ! 1750: int i; ! 1751: register unsigned EMUSHORT *p; ! 1752: ! 1753: x += NI - 1; ! 1754: p = x + 1; ! 1755: ! 1756: for (i = M; i < NI - 1; i++) ! 1757: *(--p) = *(--x); ! 1758: ! 1759: *(--p) = 0; ! 1760: } ! 1761: ! 1762: /* ! 1763: ; Add significands ! 1764: ; x + y replaces y ! 1765: */ ! 1766: ! 1767: void ! 1768: eaddm (x, y) ! 1769: unsigned EMUSHORT *x, *y; ! 1770: { ! 1771: register unsigned EMULONG a; ! 1772: int i; ! 1773: unsigned int carry; ! 1774: ! 1775: x += NI - 1; ! 1776: y += NI - 1; ! 1777: carry = 0; ! 1778: for (i = M; i < NI; i++) ! 1779: { ! 1780: a = (unsigned EMULONG) (*x) + (unsigned EMULONG) (*y) + carry; ! 1781: if (a & 0x10000) ! 1782: carry = 1; ! 1783: else ! 1784: carry = 0; ! 1785: *y = (unsigned EMUSHORT) a; ! 1786: --x; ! 1787: --y; ! 1788: } ! 1789: } ! 1790: ! 1791: /* ! 1792: ; Subtract significands ! 1793: ; y - x replaces y ! 1794: */ ! 1795: ! 1796: void ! 1797: esubm (x, y) ! 1798: unsigned EMUSHORT *x, *y; ! 1799: { ! 1800: unsigned EMULONG a; ! 1801: int i; ! 1802: unsigned int carry; ! 1803: ! 1804: x += NI - 1; ! 1805: y += NI - 1; ! 1806: carry = 0; ! 1807: for (i = M; i < NI; i++) ! 1808: { ! 1809: a = (unsigned EMULONG) (*y) - (unsigned EMULONG) (*x) - carry; ! 1810: if (a & 0x10000) ! 1811: carry = 1; ! 1812: else ! 1813: carry = 0; ! 1814: *y = (unsigned EMUSHORT) a; ! 1815: --x; ! 1816: --y; ! 1817: } ! 1818: } ! 1819: ! 1820: ! 1821: /* Divide significands */ ! 1822: ! 1823: static unsigned EMUSHORT equot[NI]; ! 1824: ! 1825: int ! 1826: edivm (den, num) ! 1827: unsigned EMUSHORT den[], num[]; ! 1828: { ! 1829: int i; ! 1830: register unsigned EMUSHORT *p, *q; ! 1831: unsigned EMUSHORT j; ! 1832: ! 1833: p = &equot[0]; ! 1834: *p++ = num[0]; ! 1835: *p++ = num[1]; ! 1836: ! 1837: for (i = M; i < NI; i++) ! 1838: { ! 1839: *p++ = 0; ! 1840: } ! 1841: ! 1842: /* Use faster compare and subtraction if denominator ! 1843: * has only 15 bits of significance. ! 1844: */ ! 1845: p = &den[M + 2]; ! 1846: if (*p++ == 0) ! 1847: { ! 1848: for (i = M + 3; i < NI; i++) ! 1849: { ! 1850: if (*p++ != 0) ! 1851: goto fulldiv; ! 1852: } ! 1853: if ((den[M + 1] & 1) != 0) ! 1854: goto fulldiv; ! 1855: eshdn1 (num); ! 1856: eshdn1 (den); ! 1857: ! 1858: p = &den[M + 1]; ! 1859: q = &num[M + 1]; ! 1860: ! 1861: for (i = 0; i < NBITS + 2; i++) ! 1862: { ! 1863: if (*p <= *q) ! 1864: { ! 1865: *q -= *p; ! 1866: j = 1; ! 1867: } ! 1868: else ! 1869: { ! 1870: j = 0; ! 1871: } ! 1872: eshup1 (equot); ! 1873: equot[NI - 2] |= j; ! 1874: eshup1 (num); ! 1875: } ! 1876: goto divdon; ! 1877: } ! 1878: ! 1879: /* The number of quotient bits to calculate is ! 1880: * NBITS + 1 scaling guard bit + 1 roundoff bit. ! 1881: */ ! 1882: fulldiv: ! 1883: ! 1884: p = &equot[NI - 2]; ! 1885: for (i = 0; i < NBITS + 2; i++) ! 1886: { ! 1887: if (ecmpm (den, num) <= 0) ! 1888: { ! 1889: esubm (den, num); ! 1890: j = 1; /* quotient bit = 1 */ ! 1891: } ! 1892: else ! 1893: j = 0; ! 1894: eshup1 (equot); ! 1895: *p |= j; ! 1896: eshup1 (num); ! 1897: } ! 1898: ! 1899: divdon: ! 1900: ! 1901: eshdn1 (equot); ! 1902: eshdn1 (equot); ! 1903: ! 1904: /* test for nonzero remainder after roundoff bit */ ! 1905: p = &num[M]; ! 1906: j = 0; ! 1907: for (i = M; i < NI; i++) ! 1908: { ! 1909: j |= *p++; ! 1910: } ! 1911: if (j) ! 1912: j = 1; ! 1913: ! 1914: ! 1915: for (i = 0; i < NI; i++) ! 1916: num[i] = equot[i]; ! 1917: return ((int) j); ! 1918: } ! 1919: ! 1920: ! 1921: /* Multiply significands */ ! 1922: int ! 1923: emulm (a, b) ! 1924: unsigned EMUSHORT a[], b[]; ! 1925: { ! 1926: unsigned EMUSHORT *p, *q; ! 1927: int i, j, k; ! 1928: ! 1929: equot[0] = b[0]; ! 1930: equot[1] = b[1]; ! 1931: for (i = M; i < NI; i++) ! 1932: equot[i] = 0; ! 1933: ! 1934: p = &a[NI - 2]; ! 1935: k = NBITS; ! 1936: while (*p == 0) /* significand is not supposed to be all zero */ ! 1937: { ! 1938: eshdn6 (a); ! 1939: k -= 16; ! 1940: } ! 1941: if ((*p & 0xff) == 0) ! 1942: { ! 1943: eshdn8 (a); ! 1944: k -= 8; ! 1945: } ! 1946: ! 1947: q = &equot[NI - 1]; ! 1948: j = 0; ! 1949: for (i = 0; i < k; i++) ! 1950: { ! 1951: if (*p & 1) ! 1952: eaddm (b, equot); ! 1953: /* remember if there were any nonzero bits shifted out */ ! 1954: if (*q & 1) ! 1955: j |= 1; ! 1956: eshdn1 (a); ! 1957: eshdn1 (equot); ! 1958: } ! 1959: ! 1960: for (i = 0; i < NI; i++) ! 1961: b[i] = equot[i]; ! 1962: ! 1963: /* return flag for lost nonzero bits */ ! 1964: return (j); ! 1965: } ! 1966: ! 1967: ! 1968: ! 1969: /* ! 1970: * Normalize and round off. ! 1971: * ! 1972: * The internal format number to be rounded is "s". ! 1973: * Input "lost" indicates whether or not the number is exact. ! 1974: * This is the so-called sticky bit. ! 1975: * ! 1976: * Input "subflg" indicates whether the number was obtained ! 1977: * by a subtraction operation. In that case if lost is nonzero ! 1978: * then the number is slightly smaller than indicated. ! 1979: * ! 1980: * Input "exp" is the biased exponent, which may be negative. ! 1981: * the exponent field of "s" is ignored but is replaced by ! 1982: * "exp" as adjusted by normalization and rounding. ! 1983: * ! 1984: * Input "rcntrl" is the rounding control. ! 1985: */ ! 1986: ! 1987: static int rlast = -1; ! 1988: static int rw = 0; ! 1989: static unsigned EMUSHORT rmsk = 0; ! 1990: static unsigned EMUSHORT rmbit = 0; ! 1991: static unsigned EMUSHORT rebit = 0; ! 1992: static int re = 0; ! 1993: static unsigned EMUSHORT rbit[NI]; ! 1994: ! 1995: void ! 1996: emdnorm (s, lost, subflg, exp, rcntrl) ! 1997: unsigned EMUSHORT s[]; ! 1998: int lost; ! 1999: int subflg; ! 2000: EMULONG exp; ! 2001: int rcntrl; ! 2002: { ! 2003: int i, j; ! 2004: unsigned EMUSHORT r; ! 2005: ! 2006: /* Normalize */ ! 2007: j = enormlz (s); ! 2008: ! 2009: /* a blank significand could mean either zero or infinity. */ ! 2010: #ifndef INFINITY ! 2011: if (j > NBITS) ! 2012: { ! 2013: ecleazs (s); ! 2014: return; ! 2015: } ! 2016: #endif ! 2017: exp -= j; ! 2018: #ifndef INFINITY ! 2019: if (exp >= 32767L) ! 2020: goto overf; ! 2021: #else ! 2022: if ((j > NBITS) && (exp < 32767)) ! 2023: { ! 2024: ecleazs (s); ! 2025: return; ! 2026: } ! 2027: #endif ! 2028: if (exp < 0L) ! 2029: { ! 2030: if (exp > (EMULONG) (-NBITS - 1)) ! 2031: { ! 2032: j = (int) exp; ! 2033: i = eshift (s, j); ! 2034: if (i) ! 2035: lost = 1; ! 2036: } ! 2037: else ! 2038: { ! 2039: ecleazs (s); ! 2040: return; ! 2041: } ! 2042: } ! 2043: /* Round off, unless told not to by rcntrl. */ ! 2044: if (rcntrl == 0) ! 2045: goto mdfin; ! 2046: /* Set up rounding parameters if the control register changed. */ ! 2047: if (rndprc != rlast) ! 2048: { ! 2049: ecleaz (rbit); ! 2050: switch (rndprc) ! 2051: { ! 2052: default: ! 2053: case NBITS: ! 2054: rw = NI - 1; /* low guard word */ ! 2055: rmsk = 0xffff; ! 2056: rmbit = 0x8000; ! 2057: rbit[rw - 1] = 1; ! 2058: re = NI - 2; ! 2059: rebit = 1; ! 2060: break; ! 2061: case 64: ! 2062: rw = 7; ! 2063: rmsk = 0xffff; ! 2064: rmbit = 0x8000; ! 2065: rbit[rw - 1] = 1; ! 2066: re = rw - 1; ! 2067: rebit = 1; ! 2068: break; ! 2069: /* For DEC arithmetic */ ! 2070: case 56: ! 2071: rw = 6; ! 2072: rmsk = 0xff; ! 2073: rmbit = 0x80; ! 2074: rbit[rw] = 0x100; ! 2075: re = rw; ! 2076: rebit = 0x100; ! 2077: break; ! 2078: case 53: ! 2079: rw = 6; ! 2080: rmsk = 0x7ff; ! 2081: rmbit = 0x0400; ! 2082: rbit[rw] = 0x800; ! 2083: re = rw; ! 2084: rebit = 0x800; ! 2085: break; ! 2086: case 24: ! 2087: rw = 4; ! 2088: rmsk = 0xff; ! 2089: rmbit = 0x80; ! 2090: rbit[rw] = 0x100; ! 2091: re = rw; ! 2092: rebit = 0x100; ! 2093: break; ! 2094: } ! 2095: rlast = rndprc; ! 2096: } ! 2097: ! 2098: if (rndprc >= 64) ! 2099: { ! 2100: r = s[rw] & rmsk; ! 2101: if (rndprc == 64) ! 2102: { ! 2103: i = rw + 1; ! 2104: while (i < NI) ! 2105: { ! 2106: if (s[i]) ! 2107: r |= 1; ! 2108: s[i] = 0; ! 2109: ++i; ! 2110: } ! 2111: } ! 2112: } ! 2113: else ! 2114: { ! 2115: if (exp <= 0) ! 2116: eshdn1 (s); ! 2117: r = s[rw] & rmsk; ! 2118: /* These tests assume NI = 8 */ ! 2119: i = rw + 1; ! 2120: while (i < NI) ! 2121: { ! 2122: if (s[i]) ! 2123: r |= 1; ! 2124: s[i] = 0; ! 2125: ++i; ! 2126: } ! 2127: /* ! 2128: if (rndprc == 24) ! 2129: { ! 2130: if (s[5] || s[6]) ! 2131: r |= 1; ! 2132: s[5] = 0; ! 2133: s[6] = 0; ! 2134: } ! 2135: */ ! 2136: } ! 2137: s[rw] &= ~rmsk; ! 2138: if ((r & rmbit) != 0) ! 2139: { ! 2140: if (r == rmbit) ! 2141: { ! 2142: if (lost == 0) ! 2143: { /* round to even */ ! 2144: if ((s[re] & rebit) == 0) ! 2145: goto mddone; ! 2146: } ! 2147: else ! 2148: { ! 2149: if (subflg != 0) ! 2150: goto mddone; ! 2151: } ! 2152: } ! 2153: eaddm (rbit, s); ! 2154: } ! 2155: mddone: ! 2156: if ((rndprc < 64) && (exp <= 0)) ! 2157: { ! 2158: eshup1 (s); ! 2159: } ! 2160: if (s[2] != 0) ! 2161: { /* overflow on roundoff */ ! 2162: eshdn1 (s); ! 2163: exp += 1; ! 2164: } ! 2165: mdfin: ! 2166: s[NI - 1] = 0; ! 2167: if (exp >= 32767L) ! 2168: { ! 2169: #ifndef INFINITY ! 2170: overf: ! 2171: #endif ! 2172: #ifdef INFINITY ! 2173: s[1] = 32767; ! 2174: for (i = 2; i < NI - 1; i++) ! 2175: s[i] = 0; ! 2176: if (extra_warnings) ! 2177: warning ("floating point overflow"); ! 2178: #else ! 2179: s[1] = 32766; ! 2180: s[2] = 0; ! 2181: for (i = M + 1; i < NI - 1; i++) ! 2182: s[i] = 0xffff; ! 2183: s[NI - 1] = 0; ! 2184: if (rndprc < 64) ! 2185: { ! 2186: s[rw] &= ~rmsk; ! 2187: if (rndprc == 24) ! 2188: { ! 2189: s[5] = 0; ! 2190: s[6] = 0; ! 2191: } ! 2192: } ! 2193: #endif ! 2194: return; ! 2195: } ! 2196: if (exp < 0) ! 2197: s[1] = 0; ! 2198: else ! 2199: s[1] = (unsigned EMUSHORT) exp; ! 2200: } ! 2201: ! 2202: ! 2203: ! 2204: /* ! 2205: ; Subtract external format numbers. ! 2206: ; ! 2207: ; unsigned EMUSHORT a[NE], b[NE], c[NE]; ! 2208: ; esub (a, b, c); c = b - a ! 2209: */ ! 2210: ! 2211: static int subflg = 0; ! 2212: ! 2213: void ! 2214: esub (a, b, c) ! 2215: unsigned EMUSHORT *a, *b, *c; ! 2216: { ! 2217: ! 2218: #ifdef NANS ! 2219: if (eisnan (a)) ! 2220: { ! 2221: emov (a, c); ! 2222: return; ! 2223: } ! 2224: if (eisnan (b)) ! 2225: { ! 2226: emov (b, c); ! 2227: return; ! 2228: } ! 2229: /* Infinity minus infinity is a NaN. ! 2230: Test for subtracting infinities of the same sign. */ ! 2231: if (eisinf (a) && eisinf (b) ! 2232: && ((eisneg (a) ^ eisneg (b)) == 0)) ! 2233: { ! 2234: mtherr ("esub", INVALID); ! 2235: enan (c); ! 2236: return; ! 2237: } ! 2238: #endif ! 2239: subflg = 1; ! 2240: eadd1 (a, b, c); ! 2241: } ! 2242: ! 2243: ! 2244: /* ! 2245: ; Add. ! 2246: ; ! 2247: ; unsigned EMUSHORT a[NE], b[NE], c[NE]; ! 2248: ; eadd (a, b, c); c = b + a ! 2249: */ ! 2250: void ! 2251: eadd (a, b, c) ! 2252: unsigned EMUSHORT *a, *b, *c; ! 2253: { ! 2254: ! 2255: #ifdef NANS ! 2256: /* NaN plus anything is a NaN. */ ! 2257: if (eisnan (a)) ! 2258: { ! 2259: emov (a, c); ! 2260: return; ! 2261: } ! 2262: if (eisnan (b)) ! 2263: { ! 2264: emov (b, c); ! 2265: return; ! 2266: } ! 2267: /* Infinity minus infinity is a NaN. ! 2268: Test for adding infinities of opposite signs. */ ! 2269: if (eisinf (a) && eisinf (b) ! 2270: && ((eisneg (a) ^ eisneg (b)) != 0)) ! 2271: { ! 2272: mtherr ("esub", INVALID); ! 2273: enan (c); ! 2274: return; ! 2275: } ! 2276: #endif ! 2277: subflg = 0; ! 2278: eadd1 (a, b, c); ! 2279: } ! 2280: ! 2281: void ! 2282: eadd1 (a, b, c) ! 2283: unsigned EMUSHORT *a, *b, *c; ! 2284: { ! 2285: unsigned EMUSHORT ai[NI], bi[NI], ci[NI]; ! 2286: int i, lost, j, k; ! 2287: EMULONG lt, lta, ltb; ! 2288: ! 2289: #ifdef INFINITY ! 2290: if (eisinf (a)) ! 2291: { ! 2292: emov (a, c); ! 2293: if (subflg) ! 2294: eneg (c); ! 2295: return; ! 2296: } ! 2297: if (eisinf (b)) ! 2298: { ! 2299: emov (b, c); ! 2300: return; ! 2301: } ! 2302: #endif ! 2303: emovi (a, ai); ! 2304: emovi (b, bi); ! 2305: if (subflg) ! 2306: ai[0] = ~ai[0]; ! 2307: ! 2308: /* compare exponents */ ! 2309: lta = ai[E]; ! 2310: ltb = bi[E]; ! 2311: lt = lta - ltb; ! 2312: if (lt > 0L) ! 2313: { /* put the larger number in bi */ ! 2314: emovz (bi, ci); ! 2315: emovz (ai, bi); ! 2316: emovz (ci, ai); ! 2317: ltb = bi[E]; ! 2318: lt = -lt; ! 2319: } ! 2320: lost = 0; ! 2321: if (lt != 0L) ! 2322: { ! 2323: if (lt < (EMULONG) (-NBITS - 1)) ! 2324: goto done; /* answer same as larger addend */ ! 2325: k = (int) lt; ! 2326: lost = eshift (ai, k); /* shift the smaller number down */ ! 2327: } ! 2328: else ! 2329: { ! 2330: /* exponents were the same, so must compare significands */ ! 2331: i = ecmpm (ai, bi); ! 2332: if (i == 0) ! 2333: { /* the numbers are identical in magnitude */ ! 2334: /* if different signs, result is zero */ ! 2335: if (ai[0] != bi[0]) ! 2336: { ! 2337: eclear (c); ! 2338: return; ! 2339: } ! 2340: /* if same sign, result is double */ ! 2341: /* double denomalized tiny number */ ! 2342: if ((bi[E] == 0) && ((bi[3] & 0x8000) == 0)) ! 2343: { ! 2344: eshup1 (bi); ! 2345: goto done; ! 2346: } ! 2347: /* add 1 to exponent unless both are zero! */ ! 2348: for (j = 1; j < NI - 1; j++) ! 2349: { ! 2350: if (bi[j] != 0) ! 2351: { ! 2352: /* This could overflow, but let emovo take care of that. */ ! 2353: ltb += 1; ! 2354: break; ! 2355: } ! 2356: } ! 2357: bi[E] = (unsigned EMUSHORT) ltb; ! 2358: goto done; ! 2359: } ! 2360: if (i > 0) ! 2361: { /* put the larger number in bi */ ! 2362: emovz (bi, ci); ! 2363: emovz (ai, bi); ! 2364: emovz (ci, ai); ! 2365: } ! 2366: } ! 2367: if (ai[0] == bi[0]) ! 2368: { ! 2369: eaddm (ai, bi); ! 2370: subflg = 0; ! 2371: } ! 2372: else ! 2373: { ! 2374: esubm (ai, bi); ! 2375: subflg = 1; ! 2376: } ! 2377: emdnorm (bi, lost, subflg, ltb, 64); ! 2378: ! 2379: done: ! 2380: emovo (bi, c); ! 2381: } ! 2382: ! 2383: ! 2384: ! 2385: /* ! 2386: ; Divide. ! 2387: ; ! 2388: ; unsigned EMUSHORT a[NE], b[NE], c[NE]; ! 2389: ; ediv (a, b, c); c = b / a ! 2390: */ ! 2391: void ! 2392: ediv (a, b, c) ! 2393: unsigned EMUSHORT *a, *b, *c; ! 2394: { ! 2395: unsigned EMUSHORT ai[NI], bi[NI]; ! 2396: int i; ! 2397: EMULONG lt, lta, ltb; ! 2398: ! 2399: #ifdef NANS ! 2400: /* Return any NaN input. */ ! 2401: if (eisnan (a)) ! 2402: { ! 2403: emov (a, c); ! 2404: return; ! 2405: } ! 2406: if (eisnan (b)) ! 2407: { ! 2408: emov (b, c); ! 2409: return; ! 2410: } ! 2411: /* Zero over zero, or infinity over infinity, is a NaN. */ ! 2412: if (((ecmp (a, ezero) == 0) && (ecmp (b, ezero) == 0)) ! 2413: || (eisinf (a) && eisinf (b))) ! 2414: { ! 2415: mtherr ("ediv", INVALID); ! 2416: enan (c); ! 2417: return; ! 2418: } ! 2419: #endif ! 2420: /* Infinity over anything else is infinity. */ ! 2421: #ifdef INFINITY ! 2422: if (eisinf (b)) ! 2423: { ! 2424: if (eisneg (a) ^ eisneg (b)) ! 2425: *(c + (NE - 1)) = 0x8000; ! 2426: else ! 2427: *(c + (NE - 1)) = 0; ! 2428: einfin (c); ! 2429: return; ! 2430: } ! 2431: /* Anything else over infinity is zero. */ ! 2432: if (eisinf (a)) ! 2433: { ! 2434: eclear (c); ! 2435: return; ! 2436: } ! 2437: #endif ! 2438: emovi (a, ai); ! 2439: emovi (b, bi); ! 2440: lta = ai[E]; ! 2441: ltb = bi[E]; ! 2442: if (bi[E] == 0) ! 2443: { /* See if numerator is zero. */ ! 2444: for (i = 1; i < NI - 1; i++) ! 2445: { ! 2446: if (bi[i] != 0) ! 2447: { ! 2448: ltb -= enormlz (bi); ! 2449: goto dnzro1; ! 2450: } ! 2451: } ! 2452: eclear (c); ! 2453: return; ! 2454: } ! 2455: dnzro1: ! 2456: ! 2457: if (ai[E] == 0) ! 2458: { /* possible divide by zero */ ! 2459: for (i = 1; i < NI - 1; i++) ! 2460: { ! 2461: if (ai[i] != 0) ! 2462: { ! 2463: lta -= enormlz (ai); ! 2464: goto dnzro2; ! 2465: } ! 2466: } ! 2467: if (ai[0] == bi[0]) ! 2468: *(c + (NE - 1)) = 0; ! 2469: else ! 2470: *(c + (NE - 1)) = 0x8000; ! 2471: /* Divide by zero is not an invalid operation. ! 2472: It is a divide-by-zero operation! */ ! 2473: einfin (c); ! 2474: mtherr ("ediv", SING); ! 2475: return; ! 2476: } ! 2477: dnzro2: ! 2478: ! 2479: i = edivm (ai, bi); ! 2480: /* calculate exponent */ ! 2481: lt = ltb - lta + EXONE; ! 2482: emdnorm (bi, i, 0, lt, 64); ! 2483: /* set the sign */ ! 2484: if (ai[0] == bi[0]) ! 2485: bi[0] = 0; ! 2486: else ! 2487: bi[0] = 0Xffff; ! 2488: emovo (bi, c); ! 2489: } ! 2490: ! 2491: ! 2492: ! 2493: /* ! 2494: ; Multiply. ! 2495: ; ! 2496: ; unsigned EMUSHORT a[NE], b[NE], c[NE]; ! 2497: ; emul (a, b, c); c = b * a ! 2498: */ ! 2499: void ! 2500: emul (a, b, c) ! 2501: unsigned EMUSHORT *a, *b, *c; ! 2502: { ! 2503: unsigned EMUSHORT ai[NI], bi[NI]; ! 2504: int i, j; ! 2505: EMULONG lt, lta, ltb; ! 2506: ! 2507: #ifdef NANS ! 2508: /* NaN times anything is the same NaN. */ ! 2509: if (eisnan (a)) ! 2510: { ! 2511: emov (a, c); ! 2512: return; ! 2513: } ! 2514: if (eisnan (b)) ! 2515: { ! 2516: emov (b, c); ! 2517: return; ! 2518: } ! 2519: /* Zero times infinity is a NaN. */ ! 2520: if ((eisinf (a) && (ecmp (b, ezero) == 0)) ! 2521: || (eisinf (b) && (ecmp (a, ezero) == 0))) ! 2522: { ! 2523: mtherr ("emul", INVALID); ! 2524: enan (c); ! 2525: return; ! 2526: } ! 2527: #endif ! 2528: /* Infinity times anything else is infinity. */ ! 2529: #ifdef INFINITY ! 2530: if (eisinf (a) || eisinf (b)) ! 2531: { ! 2532: if (eisneg (a) ^ eisneg (b)) ! 2533: *(c + (NE - 1)) = 0x8000; ! 2534: else ! 2535: *(c + (NE - 1)) = 0; ! 2536: einfin (c); ! 2537: return; ! 2538: } ! 2539: #endif ! 2540: emovi (a, ai); ! 2541: emovi (b, bi); ! 2542: lta = ai[E]; ! 2543: ltb = bi[E]; ! 2544: if (ai[E] == 0) ! 2545: { ! 2546: for (i = 1; i < NI - 1; i++) ! 2547: { ! 2548: if (ai[i] != 0) ! 2549: { ! 2550: lta -= enormlz (ai); ! 2551: goto mnzer1; ! 2552: } ! 2553: } ! 2554: eclear (c); ! 2555: return; ! 2556: } ! 2557: mnzer1: ! 2558: ! 2559: if (bi[E] == 0) ! 2560: { ! 2561: for (i = 1; i < NI - 1; i++) ! 2562: { ! 2563: if (bi[i] != 0) ! 2564: { ! 2565: ltb -= enormlz (bi); ! 2566: goto mnzer2; ! 2567: } ! 2568: } ! 2569: eclear (c); ! 2570: return; ! 2571: } ! 2572: mnzer2: ! 2573: ! 2574: /* Multiply significands */ ! 2575: j = emulm (ai, bi); ! 2576: /* calculate exponent */ ! 2577: lt = lta + ltb - (EXONE - 1); ! 2578: emdnorm (bi, j, 0, lt, 64); ! 2579: /* calculate sign of product */ ! 2580: if (ai[0] == bi[0]) ! 2581: bi[0] = 0; ! 2582: else ! 2583: bi[0] = 0xffff; ! 2584: emovo (bi, c); ! 2585: } ! 2586: ! 2587: ! 2588: ! 2589: ! 2590: /* ! 2591: ; Convert IEEE double precision to e type ! 2592: ; double d; ! 2593: ; unsigned EMUSHORT x[N+2]; ! 2594: ; e53toe (&d, x); ! 2595: */ ! 2596: void ! 2597: e53toe (pe, y) ! 2598: unsigned EMUSHORT *pe, *y; ! 2599: { ! 2600: #ifdef DEC ! 2601: ! 2602: dectoe (pe, y); /* see etodec.c */ ! 2603: ! 2604: #else ! 2605: ! 2606: register unsigned EMUSHORT r; ! 2607: register unsigned EMUSHORT *e, *p; ! 2608: unsigned EMUSHORT yy[NI]; ! 2609: int denorm, k; ! 2610: ! 2611: e = pe; ! 2612: denorm = 0; /* flag if denormalized number */ ! 2613: ecleaz (yy); ! 2614: #ifdef IBMPC ! 2615: e += 3; ! 2616: #endif ! 2617: r = *e; ! 2618: yy[0] = 0; ! 2619: if (r & 0x8000) ! 2620: yy[0] = 0xffff; ! 2621: yy[M] = (r & 0x0f) | 0x10; ! 2622: r &= ~0x800f; /* strip sign and 4 significand bits */ ! 2623: #ifdef INFINITY ! 2624: if (r == 0x7ff0) ! 2625: { ! 2626: #ifdef NANS ! 2627: #ifdef IBMPC ! 2628: if (((pe[3] & 0xf) != 0) || (pe[2] != 0) ! 2629: || (pe[1] != 0) || (pe[0] != 0)) ! 2630: { ! 2631: enan (y); ! 2632: return; ! 2633: } ! 2634: #else ! 2635: if (((pe[0] & 0xf) != 0) || (pe[1] != 0) ! 2636: || (pe[2] != 0) || (pe[3] != 0)) ! 2637: { ! 2638: enan (y); ! 2639: return; ! 2640: } ! 2641: #endif ! 2642: #endif /* NANS */ ! 2643: eclear (y); ! 2644: einfin (y); ! 2645: if (yy[0]) ! 2646: eneg (y); ! 2647: return; ! 2648: } ! 2649: #endif /* INFINITY */ ! 2650: r >>= 4; ! 2651: /* If zero exponent, then the significand is denormalized. ! 2652: * So, take back the understood high significand bit. */ ! 2653: if (r == 0) ! 2654: { ! 2655: denorm = 1; ! 2656: yy[M] &= ~0x10; ! 2657: } ! 2658: r += EXONE - 01777; ! 2659: yy[E] = r; ! 2660: p = &yy[M + 1]; ! 2661: #ifdef IBMPC ! 2662: *p++ = *(--e); ! 2663: *p++ = *(--e); ! 2664: *p++ = *(--e); ! 2665: #endif ! 2666: #ifdef MIEEE ! 2667: ++e; ! 2668: *p++ = *e++; ! 2669: *p++ = *e++; ! 2670: *p++ = *e++; ! 2671: #endif ! 2672: eshift (yy, -5); ! 2673: if (denorm) ! 2674: { /* if zero exponent, then normalize the significand */ ! 2675: if ((k = enormlz (yy)) > NBITS) ! 2676: ecleazs (yy); ! 2677: else ! 2678: yy[E] -= (unsigned EMUSHORT) (k - 1); ! 2679: } ! 2680: emovo (yy, y); ! 2681: #endif /* not DEC */ ! 2682: } ! 2683: ! 2684: void ! 2685: e64toe (pe, y) ! 2686: unsigned EMUSHORT *pe, *y; ! 2687: { ! 2688: unsigned EMUSHORT yy[NI]; ! 2689: unsigned EMUSHORT *e, *p, *q; ! 2690: int i; ! 2691: ! 2692: e = pe; ! 2693: p = yy; ! 2694: for (i = 0; i < NE - 5; i++) ! 2695: *p++ = 0; ! 2696: #ifdef IBMPC ! 2697: for (i = 0; i < 5; i++) ! 2698: *p++ = *e++; ! 2699: #endif ! 2700: #ifdef DEC ! 2701: for (i = 0; i < 5; i++) ! 2702: *p++ = *e++; ! 2703: #endif ! 2704: #ifdef MIEEE ! 2705: p = &yy[0] + (NE - 1); ! 2706: *p-- = *e++; ! 2707: ++e; ! 2708: for (i = 0; i < 4; i++) ! 2709: *p-- = *e++; ! 2710: #endif ! 2711: p = yy; ! 2712: q = y; ! 2713: #ifdef INFINITY ! 2714: if (*p == 0x7fff) ! 2715: { ! 2716: #ifdef NANS ! 2717: #ifdef IBMPC ! 2718: for (i = 0; i < 4; i++) ! 2719: { ! 2720: if (pe[i] != 0) ! 2721: { ! 2722: enan (y); ! 2723: return; ! 2724: } ! 2725: } ! 2726: #else ! 2727: for (i = 1; i <= 4; i++) ! 2728: { ! 2729: if (pe[i] != 0) ! 2730: { ! 2731: enan (y); ! 2732: return; ! 2733: } ! 2734: } ! 2735: #endif ! 2736: #endif /* NANS */ ! 2737: eclear (y); ! 2738: einfin (y); ! 2739: if (*p & 0x8000) ! 2740: eneg (y); ! 2741: return; ! 2742: } ! 2743: #endif /* INFINITY */ ! 2744: for (i = 0; i < NE; i++) ! 2745: *q++ = *p++; ! 2746: } ! 2747: ! 2748: ! 2749: /* ! 2750: ; Convert IEEE single precision to e type ! 2751: ; float d; ! 2752: ; unsigned EMUSHORT x[N+2]; ! 2753: ; dtox (&d, x); ! 2754: */ ! 2755: void ! 2756: e24toe (pe, y) ! 2757: unsigned EMUSHORT *pe, *y; ! 2758: { ! 2759: register unsigned EMUSHORT r; ! 2760: register unsigned EMUSHORT *e, *p; ! 2761: unsigned EMUSHORT yy[NI]; ! 2762: int denorm, k; ! 2763: ! 2764: e = pe; ! 2765: denorm = 0; /* flag if denormalized number */ ! 2766: ecleaz (yy); ! 2767: #ifdef IBMPC ! 2768: e += 1; ! 2769: #endif ! 2770: #ifdef DEC ! 2771: e += 1; ! 2772: #endif ! 2773: r = *e; ! 2774: yy[0] = 0; ! 2775: if (r & 0x8000) ! 2776: yy[0] = 0xffff; ! 2777: yy[M] = (r & 0x7f) | 0200; ! 2778: r &= ~0x807f; /* strip sign and 7 significand bits */ ! 2779: #ifdef INFINITY ! 2780: if (r == 0x7f80) ! 2781: { ! 2782: #ifdef NANS ! 2783: #ifdef MIEEE ! 2784: if (((pe[0] & 0x7f) != 0) || (pe[1] != 0)) ! 2785: { ! 2786: enan (y); ! 2787: return; ! 2788: } ! 2789: #else ! 2790: if (((pe[1] & 0x7f) != 0) || (pe[0] != 0)) ! 2791: { ! 2792: enan (y); ! 2793: return; ! 2794: } ! 2795: #endif ! 2796: #endif /* NANS */ ! 2797: eclear (y); ! 2798: einfin (y); ! 2799: if (yy[0]) ! 2800: eneg (y); ! 2801: return; ! 2802: } ! 2803: #endif /* INFINITY */ ! 2804: r >>= 7; ! 2805: /* If zero exponent, then the significand is denormalized. ! 2806: * So, take back the understood high significand bit. */ ! 2807: if (r == 0) ! 2808: { ! 2809: denorm = 1; ! 2810: yy[M] &= ~0200; ! 2811: } ! 2812: r += EXONE - 0177; ! 2813: yy[E] = r; ! 2814: p = &yy[M + 1]; ! 2815: #ifdef IBMPC ! 2816: *p++ = *(--e); ! 2817: #endif ! 2818: #ifdef DEC ! 2819: *p++ = *(--e); ! 2820: #endif ! 2821: #ifdef MIEEE ! 2822: ++e; ! 2823: *p++ = *e++; ! 2824: #endif ! 2825: eshift (yy, -8); ! 2826: if (denorm) ! 2827: { /* if zero exponent, then normalize the significand */ ! 2828: if ((k = enormlz (yy)) > NBITS) ! 2829: ecleazs (yy); ! 2830: else ! 2831: yy[E] -= (unsigned EMUSHORT) (k - 1); ! 2832: } ! 2833: emovo (yy, y); ! 2834: } ! 2835: ! 2836: ! 2837: void ! 2838: etoe64 (x, e) ! 2839: unsigned EMUSHORT *x, *e; ! 2840: { ! 2841: unsigned EMUSHORT xi[NI]; ! 2842: EMULONG exp; ! 2843: int rndsav; ! 2844: ! 2845: #ifdef NANS ! 2846: if (eisnan (x)) ! 2847: { ! 2848: make_nan (e, XFmode); ! 2849: return; ! 2850: } ! 2851: #endif ! 2852: emovi (x, xi); ! 2853: /* adjust exponent for offset */ ! 2854: exp = (EMULONG) xi[E]; ! 2855: #ifdef INFINITY ! 2856: if (eisinf (x)) ! 2857: goto nonorm; ! 2858: #endif ! 2859: /* round off to nearest or even */ ! 2860: rndsav = rndprc; ! 2861: rndprc = 64; ! 2862: emdnorm (xi, 0, 0, exp, 64); ! 2863: rndprc = rndsav; ! 2864: nonorm: ! 2865: toe64 (xi, e); ! 2866: } ! 2867: ! 2868: /* move out internal format to ieee long double */ ! 2869: static void ! 2870: toe64 (a, b) ! 2871: unsigned EMUSHORT *a, *b; ! 2872: { ! 2873: register unsigned EMUSHORT *p, *q; ! 2874: unsigned EMUSHORT i; ! 2875: ! 2876: #ifdef NANS ! 2877: if (eiisnan (a)) ! 2878: { ! 2879: make_nan (b, XFmode); ! 2880: return; ! 2881: } ! 2882: #endif ! 2883: p = a; ! 2884: #ifdef MIEEE ! 2885: q = b; ! 2886: #else ! 2887: q = b + 4; /* point to output exponent */ ! 2888: #if LONG_DOUBLE_TYPE_SIZE == 96 ! 2889: /* Clear the last two bytes of 12-byte Intel format */ ! 2890: *(q+1) = 0; ! 2891: #endif ! 2892: #endif ! 2893: ! 2894: /* combine sign and exponent */ ! 2895: i = *p++; ! 2896: #ifdef MIEEE ! 2897: if (i) ! 2898: *q++ = *p++ | 0x8000; ! 2899: else ! 2900: *q++ = *p++; ! 2901: *q++ = 0; ! 2902: #else ! 2903: if (i) ! 2904: *q-- = *p++ | 0x8000; ! 2905: else ! 2906: *q-- = *p++; ! 2907: #endif ! 2908: /* skip over guard word */ ! 2909: ++p; ! 2910: /* move the significand */ ! 2911: #ifdef MIEEE ! 2912: for (i = 0; i < 4; i++) ! 2913: *q++ = *p++; ! 2914: #else ! 2915: for (i = 0; i < 4; i++) ! 2916: *q-- = *p++; ! 2917: #endif ! 2918: } ! 2919: ! 2920: ! 2921: /* ! 2922: ; e type to IEEE double precision ! 2923: ; double d; ! 2924: ; unsigned EMUSHORT x[NE]; ! 2925: ; etoe53 (x, &d); ! 2926: */ ! 2927: ! 2928: #ifdef DEC ! 2929: ! 2930: void ! 2931: etoe53 (x, e) ! 2932: unsigned EMUSHORT *x, *e; ! 2933: { ! 2934: etodec (x, e); /* see etodec.c */ ! 2935: } ! 2936: ! 2937: static void ! 2938: toe53 (x, y) ! 2939: unsigned EMUSHORT *x, *y; ! 2940: { ! 2941: todec (x, y); ! 2942: } ! 2943: ! 2944: #else ! 2945: ! 2946: void ! 2947: etoe53 (x, e) ! 2948: unsigned EMUSHORT *x, *e; ! 2949: { ! 2950: unsigned EMUSHORT xi[NI]; ! 2951: EMULONG exp; ! 2952: int rndsav; ! 2953: ! 2954: #ifdef NANS ! 2955: if (eisnan (x)) ! 2956: { ! 2957: make_nan (e, DFmode); ! 2958: return; ! 2959: } ! 2960: #endif ! 2961: emovi (x, xi); ! 2962: /* adjust exponent for offsets */ ! 2963: exp = (EMULONG) xi[E] - (EXONE - 0x3ff); ! 2964: #ifdef INFINITY ! 2965: if (eisinf (x)) ! 2966: goto nonorm; ! 2967: #endif ! 2968: /* round off to nearest or even */ ! 2969: rndsav = rndprc; ! 2970: rndprc = 53; ! 2971: emdnorm (xi, 0, 0, exp, 64); ! 2972: rndprc = rndsav; ! 2973: nonorm: ! 2974: toe53 (xi, e); ! 2975: } ! 2976: ! 2977: ! 2978: static void ! 2979: toe53 (x, y) ! 2980: unsigned EMUSHORT *x, *y; ! 2981: { ! 2982: unsigned EMUSHORT i; ! 2983: unsigned EMUSHORT *p; ! 2984: ! 2985: #ifdef NANS ! 2986: if (eiisnan (x)) ! 2987: { ! 2988: make_nan (y, DFmode); ! 2989: return; ! 2990: } ! 2991: #endif ! 2992: p = &x[0]; ! 2993: #ifdef IBMPC ! 2994: y += 3; ! 2995: #endif ! 2996: *y = 0; /* output high order */ ! 2997: if (*p++) ! 2998: *y = 0x8000; /* output sign bit */ ! 2999: ! 3000: i = *p++; ! 3001: if (i >= (unsigned int) 2047) ! 3002: { /* Saturate at largest number less than infinity. */ ! 3003: #ifdef INFINITY ! 3004: *y |= 0x7ff0; ! 3005: #ifdef IBMPC ! 3006: *(--y) = 0; ! 3007: *(--y) = 0; ! 3008: *(--y) = 0; ! 3009: #endif ! 3010: #ifdef MIEEE ! 3011: ++y; ! 3012: *y++ = 0; ! 3013: *y++ = 0; ! 3014: *y++ = 0; ! 3015: #endif ! 3016: #else ! 3017: *y |= (unsigned EMUSHORT) 0x7fef; ! 3018: #ifdef IBMPC ! 3019: *(--y) = 0xffff; ! 3020: *(--y) = 0xffff; ! 3021: *(--y) = 0xffff; ! 3022: #endif ! 3023: #ifdef MIEEE ! 3024: ++y; ! 3025: *y++ = 0xffff; ! 3026: *y++ = 0xffff; ! 3027: *y++ = 0xffff; ! 3028: #endif ! 3029: #endif ! 3030: return; ! 3031: } ! 3032: if (i == 0) ! 3033: { ! 3034: eshift (x, 4); ! 3035: } ! 3036: else ! 3037: { ! 3038: i <<= 4; ! 3039: eshift (x, 5); ! 3040: } ! 3041: i |= *p++ & (unsigned EMUSHORT) 0x0f; /* *p = xi[M] */ ! 3042: *y |= (unsigned EMUSHORT) i; /* high order output already has sign bit set */ ! 3043: #ifdef IBMPC ! 3044: *(--y) = *p++; ! 3045: *(--y) = *p++; ! 3046: *(--y) = *p; ! 3047: #endif ! 3048: #ifdef MIEEE ! 3049: ++y; ! 3050: *y++ = *p++; ! 3051: *y++ = *p++; ! 3052: *y++ = *p++; ! 3053: #endif ! 3054: } ! 3055: ! 3056: #endif /* not DEC */ ! 3057: ! 3058: ! 3059: ! 3060: /* ! 3061: ; e type to IEEE single precision ! 3062: ; float d; ! 3063: ; unsigned EMUSHORT x[N+2]; ! 3064: ; xtod (x, &d); ! 3065: */ ! 3066: void ! 3067: etoe24 (x, e) ! 3068: unsigned EMUSHORT *x, *e; ! 3069: { ! 3070: EMULONG exp; ! 3071: unsigned EMUSHORT xi[NI]; ! 3072: int rndsav; ! 3073: ! 3074: #ifdef NANS ! 3075: if (eisnan (x)) ! 3076: { ! 3077: make_nan (e, SFmode); ! 3078: return; ! 3079: } ! 3080: #endif ! 3081: emovi (x, xi); ! 3082: /* adjust exponent for offsets */ ! 3083: exp = (EMULONG) xi[E] - (EXONE - 0177); ! 3084: #ifdef INFINITY ! 3085: if (eisinf (x)) ! 3086: goto nonorm; ! 3087: #endif ! 3088: /* round off to nearest or even */ ! 3089: rndsav = rndprc; ! 3090: rndprc = 24; ! 3091: emdnorm (xi, 0, 0, exp, 64); ! 3092: rndprc = rndsav; ! 3093: nonorm: ! 3094: toe24 (xi, e); ! 3095: } ! 3096: ! 3097: static void ! 3098: toe24 (x, y) ! 3099: unsigned EMUSHORT *x, *y; ! 3100: { ! 3101: unsigned EMUSHORT i; ! 3102: unsigned EMUSHORT *p; ! 3103: ! 3104: #ifdef NANS ! 3105: if (eiisnan (x)) ! 3106: { ! 3107: make_nan (y, SFmode); ! 3108: return; ! 3109: } ! 3110: #endif ! 3111: p = &x[0]; ! 3112: #ifdef IBMPC ! 3113: y += 1; ! 3114: #endif ! 3115: #ifdef DEC ! 3116: y += 1; ! 3117: #endif ! 3118: *y = 0; /* output high order */ ! 3119: if (*p++) ! 3120: *y = 0x8000; /* output sign bit */ ! 3121: ! 3122: i = *p++; ! 3123: /* Handle overflow cases. */ ! 3124: if (i >= 255) ! 3125: { ! 3126: #ifdef INFINITY ! 3127: *y |= (unsigned EMUSHORT) 0x7f80; ! 3128: #ifdef IBMPC ! 3129: *(--y) = 0; ! 3130: #endif ! 3131: #ifdef DEC ! 3132: *(--y) = 0; ! 3133: #endif ! 3134: #ifdef MIEEE ! 3135: ++y; ! 3136: *y = 0; ! 3137: #endif ! 3138: #else /* no INFINITY */ ! 3139: *y |= (unsigned EMUSHORT) 0x7f7f; ! 3140: #ifdef IBMPC ! 3141: *(--y) = 0xffff; ! 3142: #endif ! 3143: #ifdef DEC ! 3144: *(--y) = 0xffff; ! 3145: #endif ! 3146: #ifdef MIEEE ! 3147: ++y; ! 3148: *y = 0xffff; ! 3149: #endif ! 3150: #ifdef ERANGE ! 3151: errno = ERANGE; ! 3152: #endif ! 3153: #endif /* no INFINITY */ ! 3154: return; ! 3155: } ! 3156: if (i == 0) ! 3157: { ! 3158: eshift (x, 7); ! 3159: } ! 3160: else ! 3161: { ! 3162: i <<= 7; ! 3163: eshift (x, 8); ! 3164: } ! 3165: i |= *p++ & (unsigned EMUSHORT) 0x7f; /* *p = xi[M] */ ! 3166: *y |= i; /* high order output already has sign bit set */ ! 3167: #ifdef IBMPC ! 3168: *(--y) = *p; ! 3169: #endif ! 3170: #ifdef DEC ! 3171: *(--y) = *p; ! 3172: #endif ! 3173: #ifdef MIEEE ! 3174: ++y; ! 3175: *y = *p; ! 3176: #endif ! 3177: } ! 3178: ! 3179: ! 3180: /* Compare two e type numbers. ! 3181: * ! 3182: * unsigned EMUSHORT a[NE], b[NE]; ! 3183: * ecmp (a, b); ! 3184: * ! 3185: * returns +1 if a > b ! 3186: * 0 if a == b ! 3187: * -1 if a < b ! 3188: * -2 if either a or b is a NaN. ! 3189: */ ! 3190: int ! 3191: ecmp (a, b) ! 3192: unsigned EMUSHORT *a, *b; ! 3193: { ! 3194: unsigned EMUSHORT ai[NI], bi[NI]; ! 3195: register unsigned EMUSHORT *p, *q; ! 3196: register int i; ! 3197: int msign; ! 3198: ! 3199: #ifdef NANS ! 3200: if (eisnan (a) || eisnan (b)) ! 3201: return (-2); ! 3202: #endif ! 3203: emovi (a, ai); ! 3204: p = ai; ! 3205: emovi (b, bi); ! 3206: q = bi; ! 3207: ! 3208: if (*p != *q) ! 3209: { /* the signs are different */ ! 3210: /* -0 equals + 0 */ ! 3211: for (i = 1; i < NI - 1; i++) ! 3212: { ! 3213: if (ai[i] != 0) ! 3214: goto nzro; ! 3215: if (bi[i] != 0) ! 3216: goto nzro; ! 3217: } ! 3218: return (0); ! 3219: nzro: ! 3220: if (*p == 0) ! 3221: return (1); ! 3222: else ! 3223: return (-1); ! 3224: } ! 3225: /* both are the same sign */ ! 3226: if (*p == 0) ! 3227: msign = 1; ! 3228: else ! 3229: msign = -1; ! 3230: i = NI - 1; ! 3231: do ! 3232: { ! 3233: if (*p++ != *q++) ! 3234: { ! 3235: goto diff; ! 3236: } ! 3237: } ! 3238: while (--i > 0); ! 3239: ! 3240: return (0); /* equality */ ! 3241: ! 3242: ! 3243: ! 3244: diff: ! 3245: ! 3246: if (*(--p) > *(--q)) ! 3247: return (msign); /* p is bigger */ ! 3248: else ! 3249: return (-msign); /* p is littler */ ! 3250: } ! 3251: ! 3252: ! 3253: ! 3254: ! 3255: /* Find nearest integer to x = floor (x + 0.5) ! 3256: * ! 3257: * unsigned EMUSHORT x[NE], y[NE] ! 3258: * eround (x, y); ! 3259: */ ! 3260: void ! 3261: eround (x, y) ! 3262: unsigned EMUSHORT *x, *y; ! 3263: { ! 3264: eadd (ehalf, x, y); ! 3265: efloor (y, y); ! 3266: } ! 3267: ! 3268: ! 3269: ! 3270: ! 3271: /* ! 3272: ; convert long integer to e type ! 3273: ; ! 3274: ; long l; ! 3275: ; unsigned EMUSHORT x[NE]; ! 3276: ; ltoe (&l, x); ! 3277: ; note &l is the memory address of l ! 3278: */ ! 3279: void ! 3280: ltoe (lp, y) ! 3281: long *lp; /* lp is the memory address of a long integer */ ! 3282: unsigned EMUSHORT *y; /* y is the address of a short */ ! 3283: { ! 3284: unsigned EMUSHORT yi[NI]; ! 3285: unsigned long ll; ! 3286: int k; ! 3287: ! 3288: ecleaz (yi); ! 3289: if (*lp < 0) ! 3290: { ! 3291: /* make it positive */ ! 3292: ll = (unsigned long) (-(*lp)); ! 3293: yi[0] = 0xffff; /* put correct sign in the e type number */ ! 3294: } ! 3295: else ! 3296: { ! 3297: ll = (unsigned long) (*lp); ! 3298: } ! 3299: /* move the long integer to yi significand area */ ! 3300: #if HOST_BITS_PER_LONG == 64 ! 3301: yi[M] = (unsigned EMUSHORT) (ll >> 48); ! 3302: yi[M + 1] = (unsigned EMUSHORT) (ll >> 32); ! 3303: yi[M + 2] = (unsigned EMUSHORT) (ll >> 16); ! 3304: yi[M + 3] = (unsigned EMUSHORT) ll; ! 3305: yi[E] = EXONE + 47; /* exponent if normalize shift count were 0 */ ! 3306: #else ! 3307: yi[M] = (unsigned EMUSHORT) (ll >> 16); ! 3308: yi[M + 1] = (unsigned EMUSHORT) ll; ! 3309: yi[E] = EXONE + 15; /* exponent if normalize shift count were 0 */ ! 3310: #endif ! 3311: ! 3312: if ((k = enormlz (yi)) > NBITS)/* normalize the significand */ ! 3313: ecleaz (yi); /* it was zero */ ! 3314: else ! 3315: yi[E] -= (unsigned EMUSHORT) k;/* subtract shift count from exponent */ ! 3316: emovo (yi, y); /* output the answer */ ! 3317: } ! 3318: ! 3319: /* ! 3320: ; convert unsigned long integer to e type ! 3321: ; ! 3322: ; unsigned long l; ! 3323: ; unsigned EMUSHORT x[NE]; ! 3324: ; ltox (&l, x); ! 3325: ; note &l is the memory address of l ! 3326: */ ! 3327: void ! 3328: ultoe (lp, y) ! 3329: unsigned long *lp; /* lp is the memory address of a long integer */ ! 3330: unsigned EMUSHORT *y; /* y is the address of a short */ ! 3331: { ! 3332: unsigned EMUSHORT yi[NI]; ! 3333: unsigned long ll; ! 3334: int k; ! 3335: ! 3336: ecleaz (yi); ! 3337: ll = *lp; ! 3338: ! 3339: /* move the long integer to ayi significand area */ ! 3340: #if HOST_BITS_PER_LONG == 64 ! 3341: yi[M] = (unsigned EMUSHORT) (ll >> 48); ! 3342: yi[M + 1] = (unsigned EMUSHORT) (ll >> 32); ! 3343: yi[M + 2] = (unsigned EMUSHORT) (ll >> 16); ! 3344: yi[M + 3] = (unsigned EMUSHORT) ll; ! 3345: yi[E] = EXONE + 47; /* exponent if normalize shift count were 0 */ ! 3346: #else ! 3347: yi[M] = (unsigned EMUSHORT) (ll >> 16); ! 3348: yi[M + 1] = (unsigned EMUSHORT) ll; ! 3349: yi[E] = EXONE + 15; /* exponent if normalize shift count were 0 */ ! 3350: #endif ! 3351: ! 3352: if ((k = enormlz (yi)) > NBITS)/* normalize the significand */ ! 3353: ecleaz (yi); /* it was zero */ ! 3354: else ! 3355: yi[E] -= (unsigned EMUSHORT) k; /* subtract shift count from exponent */ ! 3356: emovo (yi, y); /* output the answer */ ! 3357: } ! 3358: ! 3359: ! 3360: /* ! 3361: ; Find long integer and fractional parts ! 3362: ! 3363: ; long i; ! 3364: ; unsigned EMUSHORT x[NE], frac[NE]; ! 3365: ; xifrac (x, &i, frac); ! 3366: ! 3367: The integer output has the sign of the input. The fraction is ! 3368: the positive fractional part of abs (x). ! 3369: */ ! 3370: void ! 3371: eifrac (x, i, frac) ! 3372: unsigned EMUSHORT *x; ! 3373: long *i; ! 3374: unsigned EMUSHORT *frac; ! 3375: { ! 3376: unsigned EMUSHORT xi[NI]; ! 3377: int j, k; ! 3378: unsigned long ll; ! 3379: ! 3380: emovi (x, xi); ! 3381: k = (int) xi[E] - (EXONE - 1); ! 3382: if (k <= 0) ! 3383: { ! 3384: /* if exponent <= 0, integer = 0 and real output is fraction */ ! 3385: *i = 0L; ! 3386: emovo (xi, frac); ! 3387: return; ! 3388: } ! 3389: if (k > (HOST_BITS_PER_LONG - 1)) ! 3390: { ! 3391: /* long integer overflow: output large integer ! 3392: and correct fraction */ ! 3393: if (xi[0]) ! 3394: *i = ((unsigned long) 1) << (HOST_BITS_PER_LONG - 1); ! 3395: else ! 3396: *i = (((unsigned long) 1) << (HOST_BITS_PER_LONG - 1)) - 1; ! 3397: eshift (xi, k); ! 3398: if (extra_warnings) ! 3399: warning ("overflow on truncation to integer"); ! 3400: } ! 3401: else if (k > 16) ! 3402: { ! 3403: /* Shift more than 16 bits: first shift up k-16 mod 16, ! 3404: then shift up by 16's. */ ! 3405: j = k - ((k >> 4) << 4); ! 3406: eshift (xi, j); ! 3407: ll = xi[M]; ! 3408: k -= j; ! 3409: do ! 3410: { ! 3411: eshup6 (xi); ! 3412: ll = (ll << 16) | xi[M]; ! 3413: } ! 3414: while ((k -= 16) > 0); ! 3415: *i = ll; ! 3416: if (xi[0]) ! 3417: *i = -(*i); ! 3418: } ! 3419: else ! 3420: { ! 3421: /* shift not more than 16 bits */ ! 3422: eshift (xi, k); ! 3423: *i = (long) xi[M] & 0xffff; ! 3424: if (xi[0]) ! 3425: *i = -(*i); ! 3426: } ! 3427: xi[0] = 0; ! 3428: xi[E] = EXONE - 1; ! 3429: xi[M] = 0; ! 3430: if ((k = enormlz (xi)) > NBITS) ! 3431: ecleaz (xi); ! 3432: else ! 3433: xi[E] -= (unsigned EMUSHORT) k; ! 3434: ! 3435: emovo (xi, frac); ! 3436: } ! 3437: ! 3438: ! 3439: /* Find unsigned long integer and fractional parts. ! 3440: A negative e type input yields integer output = 0 ! 3441: but correct fraction. */ ! 3442: ! 3443: void ! 3444: euifrac (x, i, frac) ! 3445: unsigned EMUSHORT *x; ! 3446: unsigned long *i; ! 3447: unsigned EMUSHORT *frac; ! 3448: { ! 3449: unsigned long ll; ! 3450: unsigned EMUSHORT xi[NI]; ! 3451: int j, k; ! 3452: ! 3453: emovi (x, xi); ! 3454: k = (int) xi[E] - (EXONE - 1); ! 3455: if (k <= 0) ! 3456: { ! 3457: /* if exponent <= 0, integer = 0 and argument is fraction */ ! 3458: *i = 0L; ! 3459: emovo (xi, frac); ! 3460: return; ! 3461: } ! 3462: if (k > HOST_BITS_PER_LONG) ! 3463: { ! 3464: /* Long integer overflow: output large integer ! 3465: and correct fraction. ! 3466: Note, the BSD microvax compiler says that ~(0UL) ! 3467: is a syntax error. */ ! 3468: *i = ~(0L); ! 3469: eshift (xi, k); ! 3470: if (extra_warnings) ! 3471: warning ("overflow on truncation to unsigned integer"); ! 3472: } ! 3473: else if (k > 16) ! 3474: { ! 3475: /* Shift more than 16 bits: first shift up k-16 mod 16, ! 3476: then shift up by 16's. */ ! 3477: j = k - ((k >> 4) << 4); ! 3478: eshift (xi, j); ! 3479: ll = xi[M]; ! 3480: k -= j; ! 3481: do ! 3482: { ! 3483: eshup6 (xi); ! 3484: ll = (ll << 16) | xi[M]; ! 3485: } ! 3486: while ((k -= 16) > 0); ! 3487: *i = ll; ! 3488: } ! 3489: else ! 3490: { ! 3491: /* shift not more than 16 bits */ ! 3492: eshift (xi, k); ! 3493: *i = (long) xi[M] & 0xffff; ! 3494: } ! 3495: ! 3496: if (xi[0]) /* A negative value yields unsigned integer 0. */ ! 3497: *i = 0L; ! 3498: xi[0] = 0; ! 3499: xi[E] = EXONE - 1; ! 3500: xi[M] = 0; ! 3501: if ((k = enormlz (xi)) > NBITS) ! 3502: ecleaz (xi); ! 3503: else ! 3504: xi[E] -= (unsigned EMUSHORT) k; ! 3505: ! 3506: emovo (xi, frac); ! 3507: } ! 3508: ! 3509: ! 3510: ! 3511: /* ! 3512: ; Shift significand ! 3513: ; ! 3514: ; Shifts significand area up or down by the number of bits ! 3515: ; given by the variable sc. ! 3516: */ ! 3517: int ! 3518: eshift (x, sc) ! 3519: unsigned EMUSHORT *x; ! 3520: int sc; ! 3521: { ! 3522: unsigned EMUSHORT lost; ! 3523: unsigned EMUSHORT *p; ! 3524: ! 3525: if (sc == 0) ! 3526: return (0); ! 3527: ! 3528: lost = 0; ! 3529: p = x + NI - 1; ! 3530: ! 3531: if (sc < 0) ! 3532: { ! 3533: sc = -sc; ! 3534: while (sc >= 16) ! 3535: { ! 3536: lost |= *p; /* remember lost bits */ ! 3537: eshdn6 (x); ! 3538: sc -= 16; ! 3539: } ! 3540: ! 3541: while (sc >= 8) ! 3542: { ! 3543: lost |= *p & 0xff; ! 3544: eshdn8 (x); ! 3545: sc -= 8; ! 3546: } ! 3547: ! 3548: while (sc > 0) ! 3549: { ! 3550: lost |= *p & 1; ! 3551: eshdn1 (x); ! 3552: sc -= 1; ! 3553: } ! 3554: } ! 3555: else ! 3556: { ! 3557: while (sc >= 16) ! 3558: { ! 3559: eshup6 (x); ! 3560: sc -= 16; ! 3561: } ! 3562: ! 3563: while (sc >= 8) ! 3564: { ! 3565: eshup8 (x); ! 3566: sc -= 8; ! 3567: } ! 3568: ! 3569: while (sc > 0) ! 3570: { ! 3571: eshup1 (x); ! 3572: sc -= 1; ! 3573: } ! 3574: } ! 3575: if (lost) ! 3576: lost = 1; ! 3577: return ((int) lost); ! 3578: } ! 3579: ! 3580: ! 3581: ! 3582: /* ! 3583: ; normalize ! 3584: ; ! 3585: ; Shift normalizes the significand area pointed to by argument ! 3586: ; shift count (up = positive) is returned. ! 3587: */ ! 3588: int ! 3589: enormlz (x) ! 3590: unsigned EMUSHORT x[]; ! 3591: { ! 3592: register unsigned EMUSHORT *p; ! 3593: int sc; ! 3594: ! 3595: sc = 0; ! 3596: p = &x[M]; ! 3597: if (*p != 0) ! 3598: goto normdn; ! 3599: ++p; ! 3600: if (*p & 0x8000) ! 3601: return (0); /* already normalized */ ! 3602: while (*p == 0) ! 3603: { ! 3604: eshup6 (x); ! 3605: sc += 16; ! 3606: /* With guard word, there are NBITS+16 bits available. ! 3607: * return true if all are zero. ! 3608: */ ! 3609: if (sc > NBITS) ! 3610: return (sc); ! 3611: } ! 3612: /* see if high byte is zero */ ! 3613: while ((*p & 0xff00) == 0) ! 3614: { ! 3615: eshup8 (x); ! 3616: sc += 8; ! 3617: } ! 3618: /* now shift 1 bit at a time */ ! 3619: while ((*p & 0x8000) == 0) ! 3620: { ! 3621: eshup1 (x); ! 3622: sc += 1; ! 3623: if (sc > NBITS) ! 3624: { ! 3625: mtherr ("enormlz", UNDERFLOW); ! 3626: return (sc); ! 3627: } ! 3628: } ! 3629: return (sc); ! 3630: ! 3631: /* Normalize by shifting down out of the high guard word ! 3632: of the significand */ ! 3633: normdn: ! 3634: ! 3635: if (*p & 0xff00) ! 3636: { ! 3637: eshdn8 (x); ! 3638: sc -= 8; ! 3639: } ! 3640: while (*p != 0) ! 3641: { ! 3642: eshdn1 (x); ! 3643: sc -= 1; ! 3644: ! 3645: if (sc < -NBITS) ! 3646: { ! 3647: mtherr ("enormlz", OVERFLOW); ! 3648: return (sc); ! 3649: } ! 3650: } ! 3651: return (sc); ! 3652: } ! 3653: ! 3654: ! 3655: ! 3656: ! 3657: /* Convert e type number to decimal format ASCII string. ! 3658: * The constants are for 64 bit precision. ! 3659: */ ! 3660: ! 3661: #define NTEN 12 ! 3662: #define MAXP 4096 ! 3663: ! 3664: static unsigned EMUSHORT etens[NTEN + 1][NE] = ! 3665: { ! 3666: {0xc94c, 0x979a, 0x8a20, 0x5202, 0xc460, 0x7525,}, /* 10**4096 */ ! 3667: {0xa74d, 0x5de4, 0xc53d, 0x3b5d, 0x9e8b, 0x5a92,}, /* 10**2048 */ ! 3668: {0x650d, 0x0c17, 0x8175, 0x7586, 0xc976, 0x4d48,}, ! 3669: {0xcc65, 0x91c6, 0xa60e, 0xa0ae, 0xe319, 0x46a3,}, ! 3670: {0xddbc, 0xde8d, 0x9df9, 0xebfb, 0xaa7e, 0x4351,}, ! 3671: {0xc66f, 0x8cdf, 0x80e9, 0x47c9, 0x93ba, 0x41a8,}, ! 3672: {0x3cbf, 0xa6d5, 0xffcf, 0x1f49, 0xc278, 0x40d3,}, ! 3673: {0xf020, 0xb59d, 0x2b70, 0xada8, 0x9dc5, 0x4069,}, ! 3674: {0x0000, 0x0000, 0x0400, 0xc9bf, 0x8e1b, 0x4034,}, ! 3675: {0x0000, 0x0000, 0x0000, 0x2000, 0xbebc, 0x4019,}, ! 3676: {0x0000, 0x0000, 0x0000, 0x0000, 0x9c40, 0x400c,}, ! 3677: {0x0000, 0x0000, 0x0000, 0x0000, 0xc800, 0x4005,}, ! 3678: {0x0000, 0x0000, 0x0000, 0x0000, 0xa000, 0x4002,}, /* 10**1 */ ! 3679: }; ! 3680: ! 3681: static unsigned EMUSHORT emtens[NTEN + 1][NE] = ! 3682: { ! 3683: {0x2de4, 0x9fde, 0xd2ce, 0x04c8, 0xa6dd, 0x0ad8,}, /* 10**-4096 */ ! 3684: {0x4925, 0x2de4, 0x3436, 0x534f, 0xceae, 0x256b,}, /* 10**-2048 */ ! 3685: {0x87a6, 0xc0bd, 0xda57, 0x82a5, 0xa2a6, 0x32b5,}, ! 3686: {0x7133, 0xd21c, 0xdb23, 0xee32, 0x9049, 0x395a,}, ! 3687: {0xfa91, 0x1939, 0x637a, 0x4325, 0xc031, 0x3cac,}, ! 3688: {0xac7d, 0xe4a0, 0x64bc, 0x467c, 0xddd0, 0x3e55,}, ! 3689: {0x3f24, 0xe9a5, 0xa539, 0xea27, 0xa87f, 0x3f2a,}, ! 3690: {0x67de, 0x94ba, 0x4539, 0x1ead, 0xcfb1, 0x3f94,}, ! 3691: {0x4c2f, 0xe15b, 0xc44d, 0x94be, 0xe695, 0x3fc9,}, ! 3692: {0xfdc2, 0xcefc, 0x8461, 0x7711, 0xabcc, 0x3fe4,}, ! 3693: {0xd3c3, 0x652b, 0xe219, 0x1758, 0xd1b7, 0x3ff1,}, ! 3694: {0x3d71, 0xd70a, 0x70a3, 0x0a3d, 0xa3d7, 0x3ff8,}, ! 3695: {0xcccd, 0xcccc, 0xcccc, 0xcccc, 0xcccc, 0x3ffb,}, /* 10**-1 */ ! 3696: }; ! 3697: ! 3698: void ! 3699: e24toasc (x, string, ndigs) ! 3700: unsigned EMUSHORT x[]; ! 3701: char *string; ! 3702: int ndigs; ! 3703: { ! 3704: unsigned EMUSHORT w[NI]; ! 3705: ! 3706: e24toe (x, w); ! 3707: etoasc (w, string, ndigs); ! 3708: } ! 3709: ! 3710: ! 3711: void ! 3712: e53toasc (x, string, ndigs) ! 3713: unsigned EMUSHORT x[]; ! 3714: char *string; ! 3715: int ndigs; ! 3716: { ! 3717: unsigned EMUSHORT w[NI]; ! 3718: ! 3719: e53toe (x, w); ! 3720: etoasc (w, string, ndigs); ! 3721: } ! 3722: ! 3723: ! 3724: void ! 3725: e64toasc (x, string, ndigs) ! 3726: unsigned EMUSHORT x[]; ! 3727: char *string; ! 3728: int ndigs; ! 3729: { ! 3730: unsigned EMUSHORT w[NI]; ! 3731: ! 3732: e64toe (x, w); ! 3733: etoasc (w, string, ndigs); ! 3734: } ! 3735: ! 3736: ! 3737: static char wstring[80]; /* working storage for ASCII output */ ! 3738: ! 3739: void ! 3740: etoasc (x, string, ndigs) ! 3741: unsigned EMUSHORT x[]; ! 3742: char *string; ! 3743: int ndigs; ! 3744: { ! 3745: EMUSHORT digit; ! 3746: unsigned EMUSHORT y[NI], t[NI], u[NI], w[NI]; ! 3747: unsigned EMUSHORT *p, *r, *ten; ! 3748: unsigned EMUSHORT sign; ! 3749: int i, j, k, expon, rndsav; ! 3750: char *s, *ss; ! 3751: unsigned EMUSHORT m; ! 3752: ! 3753: ! 3754: rndsav = rndprc; ! 3755: ss = string; ! 3756: s = wstring; ! 3757: *ss = '\0'; ! 3758: *s = '\0'; ! 3759: #ifdef NANS ! 3760: if (eisnan (x)) ! 3761: { ! 3762: sprintf (wstring, " NaN "); ! 3763: goto bxit; ! 3764: } ! 3765: #endif ! 3766: rndprc = NBITS; /* set to full precision */ ! 3767: emov (x, y); /* retain external format */ ! 3768: if (y[NE - 1] & 0x8000) ! 3769: { ! 3770: sign = 0xffff; ! 3771: y[NE - 1] &= 0x7fff; ! 3772: } ! 3773: else ! 3774: { ! 3775: sign = 0; ! 3776: } ! 3777: expon = 0; ! 3778: ten = &etens[NTEN][0]; ! 3779: emov (eone, t); ! 3780: /* Test for zero exponent */ ! 3781: if (y[NE - 1] == 0) ! 3782: { ! 3783: for (k = 0; k < NE - 1; k++) ! 3784: { ! 3785: if (y[k] != 0) ! 3786: goto tnzro; /* denormalized number */ ! 3787: } ! 3788: goto isone; /* legal all zeros */ ! 3789: } ! 3790: tnzro: ! 3791: ! 3792: /* Test for infinity. */ ! 3793: if (y[NE - 1] == 0x7fff) ! 3794: { ! 3795: if (sign) ! 3796: sprintf (wstring, " -Infinity "); ! 3797: else ! 3798: sprintf (wstring, " Infinity "); ! 3799: goto bxit; ! 3800: } ! 3801: ! 3802: /* Test for exponent nonzero but significand denormalized. ! 3803: * This is an error condition. ! 3804: */ ! 3805: if ((y[NE - 1] != 0) && ((y[NE - 2] & 0x8000) == 0)) ! 3806: { ! 3807: mtherr ("etoasc", DOMAIN); ! 3808: sprintf (wstring, "NaN"); ! 3809: goto bxit; ! 3810: } ! 3811: ! 3812: /* Compare to 1.0 */ ! 3813: i = ecmp (eone, y); ! 3814: if (i == 0) ! 3815: goto isone; ! 3816: ! 3817: if (i == -2) ! 3818: abort (); ! 3819: ! 3820: if (i < 0) ! 3821: { /* Number is greater than 1 */ ! 3822: /* Convert significand to an integer and strip trailing decimal zeros. */ ! 3823: emov (y, u); ! 3824: u[NE - 1] = EXONE + NBITS - 1; ! 3825: ! 3826: p = &etens[NTEN - 4][0]; ! 3827: m = 16; ! 3828: do ! 3829: { ! 3830: ediv (p, u, t); ! 3831: efloor (t, w); ! 3832: for (j = 0; j < NE - 1; j++) ! 3833: { ! 3834: if (t[j] != w[j]) ! 3835: goto noint; ! 3836: } ! 3837: emov (t, u); ! 3838: expon += (int) m; ! 3839: noint: ! 3840: p += NE; ! 3841: m >>= 1; ! 3842: } ! 3843: while (m != 0); ! 3844: ! 3845: /* Rescale from integer significand */ ! 3846: u[NE - 1] += y[NE - 1] - (unsigned int) (EXONE + NBITS - 1); ! 3847: emov (u, y); ! 3848: /* Find power of 10 */ ! 3849: emov (eone, t); ! 3850: m = MAXP; ! 3851: p = &etens[0][0]; ! 3852: /* An unordered compare result shouldn't happen here. */ ! 3853: while (ecmp (ten, u) <= 0) ! 3854: { ! 3855: if (ecmp (p, u) <= 0) ! 3856: { ! 3857: ediv (p, u, u); ! 3858: emul (p, t, t); ! 3859: expon += (int) m; ! 3860: } ! 3861: m >>= 1; ! 3862: if (m == 0) ! 3863: break; ! 3864: p += NE; ! 3865: } ! 3866: } ! 3867: else ! 3868: { /* Number is less than 1.0 */ ! 3869: /* Pad significand with trailing decimal zeros. */ ! 3870: if (y[NE - 1] == 0) ! 3871: { ! 3872: while ((y[NE - 2] & 0x8000) == 0) ! 3873: { ! 3874: emul (ten, y, y); ! 3875: expon -= 1; ! 3876: } ! 3877: } ! 3878: else ! 3879: { ! 3880: emovi (y, w); ! 3881: for (i = 0; i < NDEC + 1; i++) ! 3882: { ! 3883: if ((w[NI - 1] & 0x7) != 0) ! 3884: break; ! 3885: /* multiply by 10 */ ! 3886: emovz (w, u); ! 3887: eshdn1 (u); ! 3888: eshdn1 (u); ! 3889: eaddm (w, u); ! 3890: u[1] += 3; ! 3891: while (u[2] != 0) ! 3892: { ! 3893: eshdn1 (u); ! 3894: u[1] += 1; ! 3895: } ! 3896: if (u[NI - 1] != 0) ! 3897: break; ! 3898: if (eone[NE - 1] <= u[1]) ! 3899: break; ! 3900: emovz (u, w); ! 3901: expon -= 1; ! 3902: } ! 3903: emovo (w, y); ! 3904: } ! 3905: k = -MAXP; ! 3906: p = &emtens[0][0]; ! 3907: r = &etens[0][0]; ! 3908: emov (y, w); ! 3909: emov (eone, t); ! 3910: while (ecmp (eone, w) > 0) ! 3911: { ! 3912: if (ecmp (p, w) >= 0) ! 3913: { ! 3914: emul (r, w, w); ! 3915: emul (r, t, t); ! 3916: expon += k; ! 3917: } ! 3918: k /= 2; ! 3919: if (k == 0) ! 3920: break; ! 3921: p += NE; ! 3922: r += NE; ! 3923: } ! 3924: ediv (t, eone, t); ! 3925: } ! 3926: isone: ! 3927: /* Find the first (leading) digit. */ ! 3928: emovi (t, w); ! 3929: emovz (w, t); ! 3930: emovi (y, w); ! 3931: emovz (w, y); ! 3932: eiremain (t, y); ! 3933: digit = equot[NI - 1]; ! 3934: while ((digit == 0) && (ecmp (y, ezero) != 0)) ! 3935: { ! 3936: eshup1 (y); ! 3937: emovz (y, u); ! 3938: eshup1 (u); ! 3939: eshup1 (u); ! 3940: eaddm (u, y); ! 3941: eiremain (t, y); ! 3942: digit = equot[NI - 1]; ! 3943: expon -= 1; ! 3944: } ! 3945: s = wstring; ! 3946: if (sign) ! 3947: *s++ = '-'; ! 3948: else ! 3949: *s++ = ' '; ! 3950: /* Examine number of digits requested by caller. */ ! 3951: if (ndigs < 0) ! 3952: ndigs = 0; ! 3953: if (ndigs > NDEC) ! 3954: ndigs = NDEC; ! 3955: if (digit == 10) ! 3956: { ! 3957: *s++ = '1'; ! 3958: *s++ = '.'; ! 3959: if (ndigs > 0) ! 3960: { ! 3961: *s++ = '0'; ! 3962: ndigs -= 1; ! 3963: } ! 3964: expon += 1; ! 3965: } ! 3966: else ! 3967: { ! 3968: *s++ = (char )digit + '0'; ! 3969: *s++ = '.'; ! 3970: } ! 3971: /* Generate digits after the decimal point. */ ! 3972: for (k = 0; k <= ndigs; k++) ! 3973: { ! 3974: /* multiply current number by 10, without normalizing */ ! 3975: eshup1 (y); ! 3976: emovz (y, u); ! 3977: eshup1 (u); ! 3978: eshup1 (u); ! 3979: eaddm (u, y); ! 3980: eiremain (t, y); ! 3981: *s++ = (char) equot[NI - 1] + '0'; ! 3982: } ! 3983: digit = equot[NI - 1]; ! 3984: --s; ! 3985: ss = s; ! 3986: /* round off the ASCII string */ ! 3987: if (digit > 4) ! 3988: { ! 3989: /* Test for critical rounding case in ASCII output. */ ! 3990: if (digit == 5) ! 3991: { ! 3992: emovo (y, t); ! 3993: if (ecmp (t, ezero) != 0) ! 3994: goto roun; /* round to nearest */ ! 3995: if ((*(s - 1) & 1) == 0) ! 3996: goto doexp; /* round to even */ ! 3997: } ! 3998: /* Round up and propagate carry-outs */ ! 3999: roun: ! 4000: --s; ! 4001: k = *s & 0x7f; ! 4002: /* Carry out to most significant digit? */ ! 4003: if (k == '.') ! 4004: { ! 4005: --s; ! 4006: k = *s; ! 4007: k += 1; ! 4008: *s = (char) k; ! 4009: /* Most significant digit carries to 10? */ ! 4010: if (k > '9') ! 4011: { ! 4012: expon += 1; ! 4013: *s = '1'; ! 4014: } ! 4015: goto doexp; ! 4016: } ! 4017: /* Round up and carry out from less significant digits */ ! 4018: k += 1; ! 4019: *s = (char) k; ! 4020: if (k > '9') ! 4021: { ! 4022: *s = '0'; ! 4023: goto roun; ! 4024: } ! 4025: } ! 4026: doexp: ! 4027: /* ! 4028: if (expon >= 0) ! 4029: sprintf (ss, "e+%d", expon); ! 4030: else ! 4031: sprintf (ss, "e%d", expon); ! 4032: */ ! 4033: sprintf (ss, "e%d", expon); ! 4034: bxit: ! 4035: rndprc = rndsav; ! 4036: /* copy out the working string */ ! 4037: s = string; ! 4038: ss = wstring; ! 4039: while (*ss == ' ') /* strip possible leading space */ ! 4040: ++ss; ! 4041: while ((*s++ = *ss++) != '\0') ! 4042: ; ! 4043: } ! 4044: ! 4045: ! 4046: ! 4047: ! 4048: /* ! 4049: ; ASCTOQ ! 4050: ; ASCTOQ.MAC LATEST REV: 11 JAN 84 ! 4051: ; SLM, 3 JAN 78 ! 4052: ; ! 4053: ; Convert ASCII string to quadruple precision floating point ! 4054: ; ! 4055: ; Numeric input is free field decimal number ! 4056: ; with max of 15 digits with or without ! 4057: ; decimal point entered as ASCII from teletype. ! 4058: ; Entering E after the number followed by a second ! 4059: ; number causes the second number to be interpreted ! 4060: ; as a power of 10 to be multiplied by the first number ! 4061: ; (i.e., "scientific" notation). ! 4062: ; ! 4063: ; Usage: ! 4064: ; asctoq (string, q); ! 4065: */ ! 4066: ! 4067: /* ASCII to single */ ! 4068: void ! 4069: asctoe24 (s, y) ! 4070: char *s; ! 4071: unsigned EMUSHORT *y; ! 4072: { ! 4073: asctoeg (s, y, 24); ! 4074: } ! 4075: ! 4076: ! 4077: /* ASCII to double */ ! 4078: void ! 4079: asctoe53 (s, y) ! 4080: char *s; ! 4081: unsigned EMUSHORT *y; ! 4082: { ! 4083: #ifdef DEC ! 4084: asctoeg (s, y, 56); ! 4085: #else ! 4086: asctoeg (s, y, 53); ! 4087: #endif ! 4088: } ! 4089: ! 4090: ! 4091: /* ASCII to long double */ ! 4092: void ! 4093: asctoe64 (s, y) ! 4094: char *s; ! 4095: unsigned EMUSHORT *y; ! 4096: { ! 4097: asctoeg (s, y, 64); ! 4098: } ! 4099: ! 4100: /* ASCII to super double */ ! 4101: void ! 4102: asctoe (s, y) ! 4103: char *s; ! 4104: unsigned EMUSHORT *y; ! 4105: { ! 4106: asctoeg (s, y, NBITS); ! 4107: } ! 4108: ! 4109: /* Space to make a copy of the input string: */ ! 4110: static char lstr[82]; ! 4111: ! 4112: void ! 4113: asctoeg (ss, y, oprec) ! 4114: char *ss; ! 4115: unsigned EMUSHORT *y; ! 4116: int oprec; ! 4117: { ! 4118: unsigned EMUSHORT yy[NI], xt[NI], tt[NI]; ! 4119: int esign, decflg, sgnflg, nexp, exp, prec, lost; ! 4120: int k, trail, c, rndsav; ! 4121: EMULONG lexp; ! 4122: unsigned EMUSHORT nsign, *p; ! 4123: char *sp, *s; ! 4124: ! 4125: /* Copy the input string. */ ! 4126: s = ss; ! 4127: while (*s == ' ') /* skip leading spaces */ ! 4128: ++s; ! 4129: sp = lstr; ! 4130: for (k = 0; k < 79; k++) ! 4131: { ! 4132: if ((*sp++ = *s++) == '\0') ! 4133: break; ! 4134: } ! 4135: *sp = '\0'; ! 4136: s = lstr; ! 4137: ! 4138: rndsav = rndprc; ! 4139: rndprc = NBITS; /* Set to full precision */ ! 4140: lost = 0; ! 4141: nsign = 0; ! 4142: decflg = 0; ! 4143: sgnflg = 0; ! 4144: nexp = 0; ! 4145: exp = 0; ! 4146: prec = 0; ! 4147: ecleaz (yy); ! 4148: trail = 0; ! 4149: ! 4150: nxtcom: ! 4151: k = *s - '0'; ! 4152: if ((k >= 0) && (k <= 9)) ! 4153: { ! 4154: /* Ignore leading zeros */ ! 4155: if ((prec == 0) && (decflg == 0) && (k == 0)) ! 4156: goto donchr; ! 4157: /* Identify and strip trailing zeros after the decimal point. */ ! 4158: if ((trail == 0) && (decflg != 0)) ! 4159: { ! 4160: sp = s; ! 4161: while ((*sp >= '0') && (*sp <= '9')) ! 4162: ++sp; ! 4163: /* Check for syntax error */ ! 4164: c = *sp & 0x7f; ! 4165: if ((c != 'e') && (c != 'E') && (c != '\0') ! 4166: && (c != '\n') && (c != '\r') && (c != ' ') ! 4167: && (c != ',')) ! 4168: goto error; ! 4169: --sp; ! 4170: while (*sp == '0') ! 4171: *sp-- = 'z'; ! 4172: trail = 1; ! 4173: if (*s == 'z') ! 4174: goto donchr; ! 4175: } ! 4176: /* If enough digits were given to more than fill up the yy register, ! 4177: * continuing until overflow into the high guard word yy[2] ! 4178: * guarantees that there will be a roundoff bit at the top ! 4179: * of the low guard word after normalization. ! 4180: */ ! 4181: if (yy[2] == 0) ! 4182: { ! 4183: if (decflg) ! 4184: nexp += 1; /* count digits after decimal point */ ! 4185: eshup1 (yy); /* multiply current number by 10 */ ! 4186: emovz (yy, xt); ! 4187: eshup1 (xt); ! 4188: eshup1 (xt); ! 4189: eaddm (xt, yy); ! 4190: ecleaz (xt); ! 4191: xt[NI - 2] = (unsigned EMUSHORT) k; ! 4192: eaddm (xt, yy); ! 4193: } ! 4194: else ! 4195: { ! 4196: lost |= k; ! 4197: } ! 4198: prec += 1; ! 4199: goto donchr; ! 4200: } ! 4201: ! 4202: switch (*s) ! 4203: { ! 4204: case 'z': ! 4205: break; ! 4206: case 'E': ! 4207: case 'e': ! 4208: goto expnt; ! 4209: case '.': /* decimal point */ ! 4210: if (decflg) ! 4211: goto error; ! 4212: ++decflg; ! 4213: break; ! 4214: case '-': ! 4215: nsign = 0xffff; ! 4216: if (sgnflg) ! 4217: goto error; ! 4218: ++sgnflg; ! 4219: break; ! 4220: case '+': ! 4221: if (sgnflg) ! 4222: goto error; ! 4223: ++sgnflg; ! 4224: break; ! 4225: case ',': ! 4226: case ' ': ! 4227: case '\0': ! 4228: case '\n': ! 4229: case '\r': ! 4230: goto daldone; ! 4231: case 'i': ! 4232: case 'I': ! 4233: goto infinite; ! 4234: default: ! 4235: error: ! 4236: #ifdef NANS ! 4237: einan (yy); ! 4238: #else ! 4239: mtherr ("asctoe", DOMAIN); ! 4240: eclear (yy); ! 4241: #endif ! 4242: goto aexit; ! 4243: } ! 4244: donchr: ! 4245: ++s; ! 4246: goto nxtcom; ! 4247: ! 4248: /* Exponent interpretation */ ! 4249: expnt: ! 4250: ! 4251: esign = 1; ! 4252: exp = 0; ! 4253: ++s; ! 4254: /* check for + or - */ ! 4255: if (*s == '-') ! 4256: { ! 4257: esign = -1; ! 4258: ++s; ! 4259: } ! 4260: if (*s == '+') ! 4261: ++s; ! 4262: while ((*s >= '0') && (*s <= '9')) ! 4263: { ! 4264: exp *= 10; ! 4265: exp += *s++ - '0'; ! 4266: if (exp > 4956) ! 4267: { ! 4268: if (esign < 0) ! 4269: goto zero; ! 4270: else ! 4271: goto infinite; ! 4272: } ! 4273: } ! 4274: if (esign < 0) ! 4275: exp = -exp; ! 4276: if (exp > 4932) ! 4277: { ! 4278: infinite: ! 4279: ecleaz (yy); ! 4280: yy[E] = 0x7fff; /* infinity */ ! 4281: goto aexit; ! 4282: } ! 4283: if (exp < -4956) ! 4284: { ! 4285: zero: ! 4286: ecleaz (yy); ! 4287: goto aexit; ! 4288: } ! 4289: ! 4290: daldone: ! 4291: nexp = exp - nexp; ! 4292: /* Pad trailing zeros to minimize power of 10, per IEEE spec. */ ! 4293: while ((nexp > 0) && (yy[2] == 0)) ! 4294: { ! 4295: emovz (yy, xt); ! 4296: eshup1 (xt); ! 4297: eshup1 (xt); ! 4298: eaddm (yy, xt); ! 4299: eshup1 (xt); ! 4300: if (xt[2] != 0) ! 4301: break; ! 4302: nexp -= 1; ! 4303: emovz (xt, yy); ! 4304: } ! 4305: if ((k = enormlz (yy)) > NBITS) ! 4306: { ! 4307: ecleaz (yy); ! 4308: goto aexit; ! 4309: } ! 4310: lexp = (EXONE - 1 + NBITS) - k; ! 4311: emdnorm (yy, lost, 0, lexp, 64); ! 4312: /* convert to external format */ ! 4313: ! 4314: ! 4315: /* Multiply by 10**nexp. If precision is 64 bits, ! 4316: * the maximum relative error incurred in forming 10**n ! 4317: * for 0 <= n <= 324 is 8.2e-20, at 10**180. ! 4318: * For 0 <= n <= 999, the peak relative error is 1.4e-19 at 10**947. ! 4319: * For 0 >= n >= -999, it is -1.55e-19 at 10**-435. ! 4320: */ ! 4321: lexp = yy[E]; ! 4322: if (nexp == 0) ! 4323: { ! 4324: k = 0; ! 4325: goto expdon; ! 4326: } ! 4327: esign = 1; ! 4328: if (nexp < 0) ! 4329: { ! 4330: nexp = -nexp; ! 4331: esign = -1; ! 4332: if (nexp > 4096) ! 4333: { /* Punt. Can't handle this without 2 divides. */ ! 4334: emovi (etens[0], tt); ! 4335: lexp -= tt[E]; ! 4336: k = edivm (tt, yy); ! 4337: lexp += EXONE; ! 4338: nexp -= 4096; ! 4339: } ! 4340: } ! 4341: p = &etens[NTEN][0]; ! 4342: emov (eone, xt); ! 4343: exp = 1; ! 4344: do ! 4345: { ! 4346: if (exp & nexp) ! 4347: emul (p, xt, xt); ! 4348: p -= NE; ! 4349: exp = exp + exp; ! 4350: } ! 4351: while (exp <= MAXP); ! 4352: ! 4353: emovi (xt, tt); ! 4354: if (esign < 0) ! 4355: { ! 4356: lexp -= tt[E]; ! 4357: k = edivm (tt, yy); ! 4358: lexp += EXONE; ! 4359: } ! 4360: else ! 4361: { ! 4362: lexp += tt[E]; ! 4363: k = emulm (tt, yy); ! 4364: lexp -= EXONE - 1; ! 4365: } ! 4366: ! 4367: expdon: ! 4368: ! 4369: /* Round and convert directly to the destination type */ ! 4370: if (oprec == 53) ! 4371: lexp -= EXONE - 0x3ff; ! 4372: else if (oprec == 24) ! 4373: lexp -= EXONE - 0177; ! 4374: #ifdef DEC ! 4375: else if (oprec == 56) ! 4376: lexp -= EXONE - 0201; ! 4377: #endif ! 4378: rndprc = oprec; ! 4379: emdnorm (yy, k, 0, lexp, 64); ! 4380: ! 4381: aexit: ! 4382: ! 4383: rndprc = rndsav; ! 4384: yy[0] = nsign; ! 4385: switch (oprec) ! 4386: { ! 4387: #ifdef DEC ! 4388: case 56: ! 4389: todec (yy, y); /* see etodec.c */ ! 4390: break; ! 4391: #endif ! 4392: case 53: ! 4393: toe53 (yy, y); ! 4394: break; ! 4395: case 24: ! 4396: toe24 (yy, y); ! 4397: break; ! 4398: case 64: ! 4399: toe64 (yy, y); ! 4400: break; ! 4401: case NBITS: ! 4402: emovo (yy, y); ! 4403: break; ! 4404: } ! 4405: } ! 4406: ! 4407: ! 4408: ! 4409: /* y = largest integer not greater than x ! 4410: * (truncated toward minus infinity) ! 4411: * ! 4412: * unsigned EMUSHORT x[NE], y[NE] ! 4413: * ! 4414: * efloor (x, y); ! 4415: */ ! 4416: static unsigned EMUSHORT bmask[] = ! 4417: { ! 4418: 0xffff, ! 4419: 0xfffe, ! 4420: 0xfffc, ! 4421: 0xfff8, ! 4422: 0xfff0, ! 4423: 0xffe0, ! 4424: 0xffc0, ! 4425: 0xff80, ! 4426: 0xff00, ! 4427: 0xfe00, ! 4428: 0xfc00, ! 4429: 0xf800, ! 4430: 0xf000, ! 4431: 0xe000, ! 4432: 0xc000, ! 4433: 0x8000, ! 4434: 0x0000, ! 4435: }; ! 4436: ! 4437: void ! 4438: efloor (x, y) ! 4439: unsigned EMUSHORT x[], y[]; ! 4440: { ! 4441: register unsigned EMUSHORT *p; ! 4442: int e, expon, i; ! 4443: unsigned EMUSHORT f[NE]; ! 4444: ! 4445: emov (x, f); /* leave in external format */ ! 4446: expon = (int) f[NE - 1]; ! 4447: e = (expon & 0x7fff) - (EXONE - 1); ! 4448: if (e <= 0) ! 4449: { ! 4450: eclear (y); ! 4451: goto isitneg; ! 4452: } ! 4453: /* number of bits to clear out */ ! 4454: e = NBITS - e; ! 4455: emov (f, y); ! 4456: if (e <= 0) ! 4457: return; ! 4458: ! 4459: p = &y[0]; ! 4460: while (e >= 16) ! 4461: { ! 4462: *p++ = 0; ! 4463: e -= 16; ! 4464: } ! 4465: /* clear the remaining bits */ ! 4466: *p &= bmask[e]; ! 4467: /* truncate negatives toward minus infinity */ ! 4468: isitneg: ! 4469: ! 4470: if ((unsigned EMUSHORT) expon & (unsigned EMUSHORT) 0x8000) ! 4471: { ! 4472: for (i = 0; i < NE - 1; i++) ! 4473: { ! 4474: if (f[i] != y[i]) ! 4475: { ! 4476: esub (eone, y, y); ! 4477: break; ! 4478: } ! 4479: } ! 4480: } ! 4481: } ! 4482: ! 4483: ! 4484: /* unsigned EMUSHORT x[], s[]; ! 4485: * int *exp; ! 4486: * ! 4487: * efrexp (x, exp, s); ! 4488: * ! 4489: * Returns s and exp such that s * 2**exp = x and .5 <= s < 1. ! 4490: * For example, 1.1 = 0.55 * 2**1 ! 4491: * Handles denormalized numbers properly using long integer exp. ! 4492: */ ! 4493: void ! 4494: efrexp (x, exp, s) ! 4495: unsigned EMUSHORT x[]; ! 4496: int *exp; ! 4497: unsigned EMUSHORT s[]; ! 4498: { ! 4499: unsigned EMUSHORT xi[NI]; ! 4500: EMULONG li; ! 4501: ! 4502: emovi (x, xi); ! 4503: li = (EMULONG) ((EMUSHORT) xi[1]); ! 4504: ! 4505: if (li == 0) ! 4506: { ! 4507: li -= enormlz (xi); ! 4508: } ! 4509: xi[1] = 0x3ffe; ! 4510: emovo (xi, s); ! 4511: *exp = (int) (li - 0x3ffe); ! 4512: } ! 4513: ! 4514: ! 4515: ! 4516: /* unsigned EMUSHORT x[], y[]; ! 4517: * long pwr2; ! 4518: * ! 4519: * eldexp (x, pwr2, y); ! 4520: * ! 4521: * Returns y = x * 2**pwr2. ! 4522: */ ! 4523: void ! 4524: eldexp (x, pwr2, y) ! 4525: unsigned EMUSHORT x[]; ! 4526: int pwr2; ! 4527: unsigned EMUSHORT y[]; ! 4528: { ! 4529: unsigned EMUSHORT xi[NI]; ! 4530: EMULONG li; ! 4531: int i; ! 4532: ! 4533: emovi (x, xi); ! 4534: li = xi[1]; ! 4535: li += pwr2; ! 4536: i = 0; ! 4537: emdnorm (xi, i, i, li, 64); ! 4538: emovo (xi, y); ! 4539: } ! 4540: ! 4541: ! 4542: /* c = remainder after dividing b by a ! 4543: * Least significant integer quotient bits left in equot[]. ! 4544: */ ! 4545: void ! 4546: eremain (a, b, c) ! 4547: unsigned EMUSHORT a[], b[], c[]; ! 4548: { ! 4549: unsigned EMUSHORT den[NI], num[NI]; ! 4550: ! 4551: #ifdef NANS ! 4552: if ( eisinf (b) ! 4553: || (ecmp (a, ezero) == 0) ! 4554: || eisnan (a) ! 4555: || eisnan (b)) ! 4556: { ! 4557: enan (c); ! 4558: return; ! 4559: } ! 4560: #endif ! 4561: if (ecmp (a, ezero) == 0) ! 4562: { ! 4563: mtherr ("eremain", SING); ! 4564: eclear (c); ! 4565: return; ! 4566: } ! 4567: emovi (a, den); ! 4568: emovi (b, num); ! 4569: eiremain (den, num); ! 4570: /* Sign of remainder = sign of quotient */ ! 4571: if (a[0] == b[0]) ! 4572: num[0] = 0; ! 4573: else ! 4574: num[0] = 0xffff; ! 4575: emovo (num, c); ! 4576: } ! 4577: ! 4578: void ! 4579: eiremain (den, num) ! 4580: unsigned EMUSHORT den[], num[]; ! 4581: { ! 4582: EMULONG ld, ln; ! 4583: unsigned EMUSHORT j; ! 4584: ! 4585: ld = den[E]; ! 4586: ld -= enormlz (den); ! 4587: ln = num[E]; ! 4588: ln -= enormlz (num); ! 4589: ecleaz (equot); ! 4590: while (ln >= ld) ! 4591: { ! 4592: if (ecmpm (den, num) <= 0) ! 4593: { ! 4594: esubm (den, num); ! 4595: j = 1; ! 4596: } ! 4597: else ! 4598: { ! 4599: j = 0; ! 4600: } ! 4601: eshup1 (equot); ! 4602: equot[NI - 1] |= j; ! 4603: eshup1 (num); ! 4604: ln -= 1; ! 4605: } ! 4606: emdnorm (num, 0, 0, ln, 0); ! 4607: } ! 4608: ! 4609: /* mtherr.c ! 4610: * ! 4611: * Library common error handling routine ! 4612: * ! 4613: * ! 4614: * ! 4615: * SYNOPSIS: ! 4616: * ! 4617: * char *fctnam; ! 4618: * int code; ! 4619: * void mtherr (); ! 4620: * ! 4621: * mtherr (fctnam, code); ! 4622: * ! 4623: * ! 4624: * ! 4625: * DESCRIPTION: ! 4626: * ! 4627: * This routine may be called to report one of the following ! 4628: * error conditions (in the include file mconf.h). ! 4629: * ! 4630: * Mnemonic Value Significance ! 4631: * ! 4632: * DOMAIN 1 argument domain error ! 4633: * SING 2 function singularity ! 4634: * OVERFLOW 3 overflow range error ! 4635: * UNDERFLOW 4 underflow range error ! 4636: * TLOSS 5 total loss of precision ! 4637: * PLOSS 6 partial loss of precision ! 4638: * INVALID 7 NaN - producing operation ! 4639: * EDOM 33 Unix domain error code ! 4640: * ERANGE 34 Unix range error code ! 4641: * ! 4642: * The default version of the file prints the function name, ! 4643: * passed to it by the pointer fctnam, followed by the ! 4644: * error condition. The display is directed to the standard ! 4645: * output device. The routine then returns to the calling ! 4646: * program. Users may wish to modify the program to abort by ! 4647: * calling exit under severe error conditions such as domain ! 4648: * errors. ! 4649: * ! 4650: * Since all error conditions pass control to this function, ! 4651: * the display may be easily changed, eliminated, or directed ! 4652: * to an error logging device. ! 4653: * ! 4654: * SEE ALSO: ! 4655: * ! 4656: * mconf.h ! 4657: * ! 4658: */ ! 4659: ! 4660: /* ! 4661: Cephes Math Library Release 2.0: April, 1987 ! 4662: Copyright 1984, 1987 by Stephen L. Moshier ! 4663: Direct inquiries to 30 Frost Street, Cambridge, MA 02140 ! 4664: */ ! 4665: ! 4666: /* include "mconf.h" */ ! 4667: ! 4668: /* Notice: the order of appearance of the following ! 4669: * messages is bound to the error codes defined ! 4670: * in mconf.h. ! 4671: */ ! 4672: #define NMSGS 8 ! 4673: static char *ermsg[NMSGS] = ! 4674: { ! 4675: "unknown", /* error code 0 */ ! 4676: "domain", /* error code 1 */ ! 4677: "singularity", /* et seq. */ ! 4678: "overflow", ! 4679: "underflow", ! 4680: "total loss of precision", ! 4681: "partial loss of precision", ! 4682: "invalid operation" ! 4683: }; ! 4684: ! 4685: int merror = 0; ! 4686: extern int merror; ! 4687: ! 4688: void ! 4689: mtherr (name, code) ! 4690: char *name; ! 4691: int code; ! 4692: { ! 4693: char errstr[80]; ! 4694: ! 4695: /* Display string passed by calling program, ! 4696: * which is supposed to be the name of the ! 4697: * function in which the error occurred. ! 4698: */ ! 4699: ! 4700: /* Display error message defined ! 4701: * by the code argument. ! 4702: */ ! 4703: if ((code <= 0) || (code >= NMSGS)) ! 4704: code = 0; ! 4705: sprintf (errstr, " %s %s error", name, ermsg[code]); ! 4706: if (extra_warnings) ! 4707: warning (errstr); ! 4708: /* Set global error message word */ ! 4709: merror = code + 1; ! 4710: ! 4711: /* Return to calling ! 4712: * program ! 4713: */ ! 4714: } ! 4715: ! 4716: /* Here is etodec.c . ! 4717: * ! 4718: */ ! 4719: ! 4720: /* ! 4721: ; convert DEC double precision to e type ! 4722: ; double d; ! 4723: ; EMUSHORT e[NE]; ! 4724: ; dectoe (&d, e); ! 4725: */ ! 4726: void ! 4727: dectoe (d, e) ! 4728: unsigned EMUSHORT *d; ! 4729: unsigned EMUSHORT *e; ! 4730: { ! 4731: unsigned EMUSHORT y[NI]; ! 4732: register unsigned EMUSHORT r, *p; ! 4733: ! 4734: ecleaz (y); /* start with a zero */ ! 4735: p = y; /* point to our number */ ! 4736: r = *d; /* get DEC exponent word */ ! 4737: if (*d & (unsigned int) 0x8000) ! 4738: *p = 0xffff; /* fill in our sign */ ! 4739: ++p; /* bump pointer to our exponent word */ ! 4740: r &= 0x7fff; /* strip the sign bit */ ! 4741: if (r == 0) /* answer = 0 if high order DEC word = 0 */ ! 4742: goto done; ! 4743: ! 4744: ! 4745: r >>= 7; /* shift exponent word down 7 bits */ ! 4746: r += EXONE - 0201; /* subtract DEC exponent offset */ ! 4747: /* add our e type exponent offset */ ! 4748: *p++ = r; /* to form our exponent */ ! 4749: ! 4750: r = *d++; /* now do the high order mantissa */ ! 4751: r &= 0177; /* strip off the DEC exponent and sign bits */ ! 4752: r |= 0200; /* the DEC understood high order mantissa bit */ ! 4753: *p++ = r; /* put result in our high guard word */ ! 4754: ! 4755: *p++ = *d++; /* fill in the rest of our mantissa */ ! 4756: *p++ = *d++; ! 4757: *p = *d; ! 4758: ! 4759: eshdn8 (y); /* shift our mantissa down 8 bits */ ! 4760: done: ! 4761: emovo (y, e); ! 4762: } ! 4763: ! 4764: ! 4765: ! 4766: /* ! 4767: ; convert e type to DEC double precision ! 4768: ; double d; ! 4769: ; EMUSHORT e[NE]; ! 4770: ; etodec (e, &d); ! 4771: */ ! 4772: #if 0 ! 4773: static unsigned EMUSHORT decbit[NI] = {0, 0, 0, 0, 0, 0, 0200, 0}; ! 4774: ! 4775: void ! 4776: etodec (x, d) ! 4777: unsigned EMUSHORT *x, *d; ! 4778: { ! 4779: unsigned EMUSHORT xi[NI]; ! 4780: register unsigned EMUSHORT r; ! 4781: int i, j; ! 4782: ! 4783: emovi (x, xi); ! 4784: *d = 0; ! 4785: if (xi[0] != 0) ! 4786: *d = 0100000; ! 4787: r = xi[E]; ! 4788: if (r < (EXONE - 128)) ! 4789: goto zout; ! 4790: i = xi[M + 4]; ! 4791: if ((i & 0200) != 0) ! 4792: { ! 4793: if ((i & 0377) == 0200) ! 4794: { ! 4795: if ((i & 0400) != 0) ! 4796: { ! 4797: /* check all less significant bits */ ! 4798: for (j = M + 5; j < NI; j++) ! 4799: { ! 4800: if (xi[j] != 0) ! 4801: goto yesrnd; ! 4802: } ! 4803: } ! 4804: goto nornd; ! 4805: } ! 4806: yesrnd: ! 4807: eaddm (decbit, xi); ! 4808: r -= enormlz (xi); ! 4809: } ! 4810: ! 4811: nornd: ! 4812: ! 4813: r -= EXONE; ! 4814: r += 0201; ! 4815: if (r < 0) ! 4816: { ! 4817: zout: ! 4818: *d++ = 0; ! 4819: *d++ = 0; ! 4820: *d++ = 0; ! 4821: *d++ = 0; ! 4822: return; ! 4823: } ! 4824: if (r >= 0377) ! 4825: { ! 4826: *d++ = 077777; ! 4827: *d++ = -1; ! 4828: *d++ = -1; ! 4829: *d++ = -1; ! 4830: return; ! 4831: } ! 4832: r &= 0377; ! 4833: r <<= 7; ! 4834: eshup8 (xi); ! 4835: xi[M] &= 0177; ! 4836: r |= xi[M]; ! 4837: *d++ |= r; ! 4838: *d++ = xi[M + 1]; ! 4839: *d++ = xi[M + 2]; ! 4840: *d++ = xi[M + 3]; ! 4841: } ! 4842: ! 4843: #else ! 4844: ! 4845: void ! 4846: etodec (x, d) ! 4847: unsigned EMUSHORT *x, *d; ! 4848: { ! 4849: unsigned EMUSHORT xi[NI]; ! 4850: EMULONG exp; ! 4851: int rndsav; ! 4852: ! 4853: emovi (x, xi); ! 4854: exp = (EMULONG) xi[E] - (EXONE - 0201); /* adjust exponent for offsets */ ! 4855: /* round off to nearest or even */ ! 4856: rndsav = rndprc; ! 4857: rndprc = 56; ! 4858: emdnorm (xi, 0, 0, exp, 64); ! 4859: rndprc = rndsav; ! 4860: todec (xi, d); ! 4861: } ! 4862: ! 4863: void ! 4864: todec (x, y) ! 4865: unsigned EMUSHORT *x, *y; ! 4866: { ! 4867: unsigned EMUSHORT i; ! 4868: unsigned EMUSHORT *p; ! 4869: ! 4870: p = x; ! 4871: *y = 0; ! 4872: if (*p++) ! 4873: *y = 0100000; ! 4874: i = *p++; ! 4875: if (i == 0) ! 4876: { ! 4877: *y++ = 0; ! 4878: *y++ = 0; ! 4879: *y++ = 0; ! 4880: *y++ = 0; ! 4881: return; ! 4882: } ! 4883: if (i > 0377) ! 4884: { ! 4885: *y++ |= 077777; ! 4886: *y++ = 0xffff; ! 4887: *y++ = 0xffff; ! 4888: *y++ = 0xffff; ! 4889: #ifdef ERANGE ! 4890: errno = ERANGE; ! 4891: #endif ! 4892: return; ! 4893: } ! 4894: i &= 0377; ! 4895: i <<= 7; ! 4896: eshup8 (x); ! 4897: x[M] &= 0177; ! 4898: i |= x[M]; ! 4899: *y++ |= i; ! 4900: *y++ = x[M + 1]; ! 4901: *y++ = x[M + 2]; ! 4902: *y++ = x[M + 3]; ! 4903: } ! 4904: ! 4905: #endif /* not 0 */ ! 4906: ! 4907: ! 4908: /* Output a binary NaN bit pattern in the target machine's format. */ ! 4909: ! 4910: /* If special NaN bit patterns are required, define them in tm.h ! 4911: as arrays of unsigned 16-bit shorts. Otherwise, use the default ! 4912: patterns here. */ ! 4913: #ifdef TFMODE_NAN ! 4914: TFMODE_NAN; ! 4915: #else ! 4916: #ifdef MIEEE ! 4917: unsigned EMUSHORT TFnan[8] = ! 4918: {0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}; ! 4919: #endif ! 4920: #ifdef IBMPC ! 4921: unsigned EMUSHORT TFnan[8] = {0, 0, 0, 0, 0, 0, 0x8000, 0xffff}; ! 4922: #endif ! 4923: #endif ! 4924: ! 4925: #ifdef XFMODE_NAN ! 4926: XFMODE_NAN; ! 4927: #else ! 4928: #ifdef MIEEE ! 4929: unsigned EMUSHORT XFnan[6] = {0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}; ! 4930: #endif ! 4931: #ifdef IBMPC ! 4932: unsigned EMUSHORT XFnan[6] = {0, 0, 0, 0xc000, 0xffff, 0}; ! 4933: #endif ! 4934: #endif ! 4935: ! 4936: #ifdef DFMODE_NAN ! 4937: DFMODE_NAN; ! 4938: #else ! 4939: #ifdef MIEEE ! 4940: unsigned EMUSHORT DFnan[4] = {0x7fff, 0xffff, 0xffff, 0xffff}; ! 4941: #endif ! 4942: #ifdef IBMPC ! 4943: unsigned EMUSHORT DFnan[4] = {0, 0, 0, 0xfff8}; ! 4944: #endif ! 4945: #endif ! 4946: ! 4947: #ifdef SFMODE_NAN ! 4948: SFMODE_NAN; ! 4949: #else ! 4950: #ifdef MIEEE ! 4951: unsigned EMUSHORT SFnan[2] = {0x7fff, 0xffff}; ! 4952: #endif ! 4953: #ifdef IBMPC ! 4954: unsigned EMUSHORT SFnan[2] = {0, 0xffc0}; ! 4955: #endif ! 4956: #endif ! 4957: ! 4958: ! 4959: void ! 4960: make_nan (nan, mode) ! 4961: unsigned EMUSHORT *nan; ! 4962: enum machine_mode mode; ! 4963: { ! 4964: int i, n; ! 4965: unsigned EMUSHORT *p; ! 4966: ! 4967: switch (mode) ! 4968: { ! 4969: /* Possibly the `reserved operand' patterns on a VAX can be ! 4970: used like NaN's, but probably not in the same way as IEEE. */ ! 4971: #ifndef DEC ! 4972: case TFmode: ! 4973: n = 8; ! 4974: p = TFnan; ! 4975: break; ! 4976: case XFmode: ! 4977: n = 6; ! 4978: p = XFnan; ! 4979: break; ! 4980: case DFmode: ! 4981: n = 4; ! 4982: p = DFnan; ! 4983: break; ! 4984: case SFmode: ! 4985: n = 2; ! 4986: p = SFnan; ! 4987: break; ! 4988: #endif ! 4989: default: ! 4990: abort (); ! 4991: } ! 4992: for (i=0; i < n; i++) ! 4993: *nan++ = *p++; ! 4994: } ! 4995: ! 4996: /* Convert an SFmode target `float' value to a REAL_VALUE_TYPE. ! 4997: This is the inverse of the function `etarsingle' invoked by ! 4998: REAL_VALUE_TO_TARGET_SINGLE. */ ! 4999: ! 5000: REAL_VALUE_TYPE ! 5001: ereal_from_float (f) ! 5002: unsigned long f; ! 5003: { ! 5004: REAL_VALUE_TYPE r; ! 5005: unsigned EMUSHORT s[2]; ! 5006: unsigned EMUSHORT e[NE]; ! 5007: ! 5008: /* Convert 32 bit integer to array of 16 bit pieces in target machine order. ! 5009: This is the inverse operation to what the function `endian' does. */ ! 5010: #if WORDS_BIG_ENDIAN ! 5011: s[0] = (unsigned EMUSHORT) (f >> 16); ! 5012: s[1] = (unsigned EMUSHORT) f; ! 5013: #else ! 5014: s[0] = (unsigned EMUSHORT) f; ! 5015: s[1] = (unsigned EMUSHORT) (f >> 16); ! 5016: #endif ! 5017: /* Convert and promote the target float to E-type. */ ! 5018: e24toe (s, e); ! 5019: /* Output E-type to REAL_VALUE_TYPE. */ ! 5020: PUT_REAL (e, &r); ! 5021: return r; ! 5022: } ! 5023: ! 5024: /* Convert a DFmode target `double' value to a REAL_VALUE_TYPE. ! 5025: This is the inverse of the function `etardouble' invoked by ! 5026: REAL_VALUE_TO_TARGET_DOUBLE. ! 5027: ! 5028: The DFmode is stored as an array of longs (i.e., HOST_WIDE_INTs) ! 5029: with 32 bits of the value per each long. The first element ! 5030: of the input array holds the bits that would come first in the ! 5031: target computer's memory. */ ! 5032: ! 5033: REAL_VALUE_TYPE ! 5034: ereal_from_double (d) ! 5035: unsigned long d[]; ! 5036: { ! 5037: REAL_VALUE_TYPE r; ! 5038: unsigned EMUSHORT s[4]; ! 5039: unsigned EMUSHORT e[NE]; ! 5040: ! 5041: /* Convert array of 32 bit pieces to equivalent array of 16 bit pieces. ! 5042: This is the inverse of `endian'. */ ! 5043: #if WORDS_BIG_ENDIAN ! 5044: s[0] = (unsigned EMUSHORT) (d[0] >> 16); ! 5045: s[1] = (unsigned EMUSHORT) d[0]; ! 5046: s[2] = (unsigned EMUSHORT) (d[1] >> 16); ! 5047: s[3] = (unsigned EMUSHORT) d[1]; ! 5048: #else ! 5049: s[0] = (unsigned EMUSHORT) d[0]; ! 5050: s[1] = (unsigned EMUSHORT) (d[0] >> 16); ! 5051: s[2] = (unsigned EMUSHORT) d[1]; ! 5052: s[3] = (unsigned EMUSHORT) (d[1] >> 16); ! 5053: #endif ! 5054: /* Convert target double to E-type. */ ! 5055: e53toe (s, e); ! 5056: /* Output E-type to REAL_VALUE_TYPE. */ ! 5057: PUT_REAL (e, &r); ! 5058: return r; ! 5059: } ! 5060: #endif /* EMU_NON_COMPILE not defined */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.