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

unix.superglobalmegacorp.com

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