Annotation of GNUtools/cc/real.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.