1  /* Extended precision arithmetic functions for long double I/O.
2   * This program has been placed in the public domain.
3   */
4 
5 #define _DEFAULT_SOURCE
6 #include <newlib.h>
7 #include <sys/config.h>
8 
9 #ifndef _USE_GDTOA
10 #include <_ansi.h>
11 #include <string.h>
12 #include <stdlib.h>
13 #include "mprec.h"
14 
15 /* These are the externally visible entries. */
16 /* linux name:  long double _IO_strtold (char *, char **); */
17 int _ldcheck (long double *);
18 #if 0
19 void _IO_ldtostr (long double *, char *, int, int, char);
20 #endif
21 
22  /* Number of 16 bit words in external x type format */
23 #define NE 10
24 
25  /* Number of 16 bit words in internal format */
26 #define NI (NE+3)
27 
28  /* Array offset to exponent */
29 #define E 1
30 
31  /* Array offset to high guard word */
32 #define M 2
33 
34  /* Number of bits of precision */
35 #define NBITS ((NI-4)*16)
36 
37  /* Maximum number of decimal digits in ASCII conversion */
38 #define NDEC 1023
39  /* Use static stack buffer for up to 44 digits */
40 #define NDEC_SML 44
41 
42  /* The exponent of 1.0 */
43 #define EXONE (0x3fff)
44 
45  /* Maximum exponent digits - base 10 */
46 #define MAX_EXP_DIGITS 5
47 
48 /* Control structure for long double conversion including rounding precision values.
49  * rndprc can be set to 80 (if NE=6), 64, 56, 53, or 24 bits.
50  */
51 typedef struct
52 {
53   int rlast;
54   int rndprc;
55   int rw;
56   int re;
57   int outexpon;
58   unsigned short rmsk;
59   unsigned short rmbit;
60   unsigned short rebit;
61   unsigned short rbit[NI];
62   unsigned short equot[NI];
63 } LDPARMS;
64 
65 static void esub (const short unsigned int *a, const short unsigned int *b,
66 		  short unsigned int *c, LDPARMS * ldp);
67 static void emul (const short unsigned int *a, const short unsigned int *b,
68 		  short unsigned int *c, LDPARMS * ldp);
69 static void ediv (const short unsigned int *a, const short unsigned int *b,
70 		  short unsigned int *c, LDPARMS * ldp);
71 static int ecmp (const short unsigned int *a, const short unsigned int *b);
72 static int enormlz (short unsigned int *x);
73 static int eshift (short unsigned int *x, int sc);
74 static void eshup1 (register short unsigned int *x);
75 static void eshup8 (register short unsigned int *x);
76 static void eshup6 (register short unsigned int *x);
77 static void eshdn1 (register short unsigned int *x);
78 static void eshdn8 (register short unsigned int *x);
79 static void eshdn6 (register short unsigned int *x);
80 static void eneg (short unsigned int *x);
81 static void emov (register const short unsigned int *a,
82 		  register short unsigned int *b);
83 static void eclear (register short unsigned int *x);
84 static void einfin (register short unsigned int *x, register LDPARMS * ldp);
85 static void efloor (short unsigned int *x, short unsigned int *y,
86 		    LDPARMS * ldp);
87 static void etoasc (short unsigned int *x, char *string, int ndec, int ndigs,
88 		    int outformat, LDPARMS * ldp);
89 
90 union uconv
91 {
92   unsigned short pe;
93   long double d;
94 };
95 
96 #if LDBL_MANT_DIG == 24
97 static void e24toe (short unsigned int *pe, short unsigned int *y,
98 		    LDPARMS * ldp);
99 #elif LDBL_MANT_DIG == 53
100 static void e53toe (short unsigned int *pe, short unsigned int *y,
101 		    LDPARMS * ldp);
102 #elif LDBL_MANT_DIG == 64
103 static void e64toe (short unsigned int *pe, short unsigned int *y,
104 		    LDPARMS * ldp);
105 #else
106 static void e113toe (short unsigned int *pe, short unsigned int *y,
107 		     LDPARMS * ldp);
108 #endif
109 
110 /*							econst.c	*/
111 /*  e type constants used by high precision check routines */
112 
113 #if NE == 10
114 /* 0.0 */
115 static const unsigned short ezero[NE] = { 0x0000, 0x0000, 0x0000, 0x0000,
116   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
117 };
118 
119 /* 1.0E0 */
120 static const unsigned short eone[NE] = { 0x0000, 0x0000, 0x0000, 0x0000,
121   0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x3fff,
122 };
123 
124 #else
125 
126 /* 0.0 */
127 static const unsigned short ezero[NE] = {
128   0, 0000000, 0000000, 0000000, 0000000, 0000000,
129 };
130 
131 /* 1.0E0 */
132 static const unsigned short eone[NE] = {
133   0, 0000000, 0000000, 0000000, 0100000, 0x3fff,
134 };
135 
136 #endif
137 
138 /* Debugging routine for displaying errors */
139 #ifdef DEBUG
140 /* Notice: the order of appearance of the following
141  * messages is bound to the error codes defined
142  * in mconf.h.
143  */
144 static const char *const ermsg[7] = {
145   "unknown",			/* error code 0 */
146   "domain",			/* error code 1 */
147   "singularity",		/* et seq.      */
148   "overflow",
149   "underflow",
150   "total loss of precision",
151   "partial loss of precision"
152 };
153 
154 #define mtherr(name, code) printf( "\n%s %s error\n", name, ermsg[code] );
155 #else
156 #define mtherr(name, code)
157 #endif
158 
159 /*							ieee.c
160  *
161  *    Extended precision IEEE binary floating point arithmetic routines
162  *
163  * Numbers are stored in C language as arrays of 16-bit unsigned
164  * short integers.  The arguments of the routines are pointers to
165  * the arrays.
166  *
167  *
168  * External e type data structure, simulates Intel 8087 chip
169  * temporary real format but possibly with a larger significand:
170  *
171  *	NE-1 significand words	(least significant word first,
172  *				 most significant bit is normally set)
173  *	exponent		(value = EXONE for 1.0,
174  *				top bit is the sign)
175  *
176  *
177  * Internal data structure of a number (a "word" is 16 bits):
178  *
179  * ei[0]	sign word	(0 for positive, 0xffff for negative)
180  * ei[1]	biased exponent	(value = EXONE for the number 1.0)
181  * ei[2]	high guard word	(always zero after normalization)
182  * ei[3]
183  * to ei[NI-2]	significand	(NI-4 significand words,
184  *				 most significant word first,
185  *				 most significant bit is set)
186  * ei[NI-1]	low guard word	(0x8000 bit is rounding place)
187  *
188  *
189  *
190  *		Routines for external format numbers
191  *
192  *	asctoe( string, e )	ASCII string to extended double e type
193  *	asctoe64( string, &d )	ASCII string to long double
194  *	asctoe53( string, &d )	ASCII string to double
195  *	asctoe24( string, &f )	ASCII string to single
196  *	asctoeg( string, e, prec, ldp ) ASCII string to specified precision
197  *	e24toe( &f, e, ldp )	IEEE single precision to e type
198  *	e53toe( &d, e, ldp )	IEEE double precision to e type
199  *	e64toe( &d, e, ldp )	IEEE long double precision to e type
200  *	e113toe( &d, e, ldp )	IEEE long double precision to e type
201  *	eabs(e)			absolute value
202  *	eadd( a, b, c )		c = b + a
203  *	eclear(e)		e = 0
204  *	ecmp (a, b)		Returns 1 if a > b, 0 if a == b,
205  *				-1 if a < b, -2 if either a or b is a NaN.
206  *	ediv( a, b, c, ldp )	c = b / a
207  *	efloor( a, b, ldp )	truncate to integer, toward -infinity
208  *	efrexp( a, exp, s )	extract exponent and significand
209  *	eifrac( e, &l, frac )   e to long integer and e type fraction
210  *	euifrac( e, &l, frac )  e to unsigned long integer and e type fraction
211  *	einfin( e, ldp )	set e to infinity, leaving its sign alone
212  *	eldexp( a, n, b )	multiply by 2**n
213  *	emov( a, b )		b = a
214  *	emul( a, b, c, ldp )	c = b * a
215  *	eneg(e)			e = -e
216  *	eround( a, b )		b = nearest integer value to a
217  *	esub( a, b, c, ldp )	c = b - a
218  *	e24toasc( &f, str, n )	single to ASCII string, n digits after decimal
219  *	e53toasc( &d, str, n )	double to ASCII string, n digits after decimal
220  *	e64toasc( &d, str, n )	long double to ASCII string
221  *	etoasc(e,str,ndec,n,fmt,ldp)e to ASCII string, n digits after decimal
222  *	etoe24( e, &f )		convert e type to IEEE single precision
223  *	etoe53( e, &d )		convert e type to IEEE double precision
224  *	etoe64( e, &d )		convert e type to IEEE long double precision
225  *	ltoe( &l, e )		long (32 bit) integer to e type
226  *	ultoe( &l, e )		unsigned long (32 bit) integer to e type
227  *      eisneg( e )             1 if sign bit of e != 0, else 0
228  *      eisinf( e )             1 if e has maximum exponent (non-IEEE)
229  *				or is infinite (IEEE)
230  *      eisnan( e )             1 if e is a NaN
231  *	esqrt( a, b )		b = square root of a
232  *
233  *
234  *		Routines for internal format numbers
235  *
236  *	eaddm( ai, bi )		add significands, bi = bi + ai
237  *	ecleaz(ei)		ei = 0
238  *	ecleazs(ei)		set ei = 0 but leave its sign alone
239  *	ecmpm( ai, bi )		compare significands, return 1, 0, or -1
240  *	edivm( ai, bi, ldp )	divide  significands, bi = bi / ai
241  *	emdnorm(ai,l,s,exp,ldp) normalize and round off
242  *	emovi( a, ai )		convert external a to internal ai
243  *	emovo( ai, a, ldp )	convert internal ai to external a
244  *	emovz( ai, bi )		bi = ai, low guard word of bi = 0
245  *	emulm( ai, bi, ldp )	multiply significands, bi = bi * ai
246  *	enormlz(ei)		left-justify the significand
247  *	eshdn1( ai )		shift significand and guards down 1 bit
248  *	eshdn8( ai )		shift down 8 bits
249  *	eshdn6( ai )		shift down 16 bits
250  *	eshift( ai, n )		shift ai n bits up (or down if n < 0)
251  *	eshup1( ai )		shift significand and guards up 1 bit
252  *	eshup8( ai )		shift up 8 bits
253  *	eshup6( ai )		shift up 16 bits
254  *	esubm( ai, bi )		subtract significands, bi = bi - ai
255  *
256  *
257  * The result is always normalized and rounded to NI-4 word precision
258  * after each arithmetic operation.
259  *
260  * Exception flags are NOT fully supported.
261  *
262  * Define USE_INFINITY in mconf.h for support of infinity; otherwise a
263  * saturation arithmetic is implemented.
264  *
265  * Define NANS for support of Not-a-Number items; otherwise the
266  * arithmetic will never produce a NaN output, and might be confused
267  * by a NaN input.
268  * If NaN's are supported, the output of ecmp(a,b) is -2 if
269  * either a or b is a NaN. This means asking if(ecmp(a,b) < 0)
270  * may not be legitimate. Use if(ecmp(a,b) == -1) for less-than
271  * if in doubt.
272  * Signaling NaN's are NOT supported; they are treated the same
273  * as quiet NaN's.
274  *
275  * Denormals are always supported here where appropriate (e.g., not
276  * for conversion to DEC numbers).
277  */
278 
279 /*
280  * Revision history:
281  *
282  *  5 Jan 84	PDP-11 assembly language version
283  *  6 Dec 86	C language version
284  * 30 Aug 88	100 digit version, improved rounding
285  * 15 May 92    80-bit long double support
286  * 22 Nov 00    Revised to fit into newlib by Jeff Johnston <jjohnstn@redhat.com>
287  *
288  * Author:  S. L. Moshier.
289  *
290  * Copyright (c) 1984,2000 S.L. Moshier
291  *
292  * Permission to use, copy, modify, and distribute this software for any
293  * purpose without fee is hereby granted, provided that this entire notice
294  * is included in all copies of any software which is or includes a copy
295  * or modification of this software and in all copies of the supporting
296  * documentation for such software.
297  *
298  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
299  * WARRANTY.  IN PARTICULAR,  THE AUTHOR MAKES NO REPRESENTATION
300  * OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS
301  * SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
302  *
303  */
304 
305 #include <stdio.h>
306 /* #include "\usr\include\stdio.h" */
307 /*#include "ehead.h"*/
308 /*#include "mconf.h"*/
309 /*							mconf.h
310  *
311  *	Common include file for math routines
312  *
313  *
314  *
315  * SYNOPSIS:
316  *
317  * #include "mconf.h"
318  *
319  *
320  *
321  * DESCRIPTION:
322  *
323  * This file contains definitions for error codes that are
324  * passed to the common error handling routine mtherr()
325  * (which see).
326  *
327  * The file also includes a conditional assembly definition
328  * for the type of computer arithmetic (IEEE, DEC, Motorola
329  * IEEE, or UNKnown).
330  *
331  * For Digital Equipment PDP-11 and VAX computers, certain
332  * IBM systems, and others that use numbers with a 56-bit
333  * significand, the symbol DEC should be defined.  In this
334  * mode, most floating point constants are given as arrays
335  * of octal integers to eliminate decimal to binary conversion
336  * errors that might be introduced by the compiler.
337  *
338  * For computers, such as IBM PC, that follow the IEEE
339  * Standard for Binary Floating Point Arithmetic (ANSI/IEEE
340  * Std 754-1985), the symbol IBMPC should be defined.  These
341  * numbers have 53-bit significands.  In this mode, constants
342  * are provided as arrays of hexadecimal 16 bit integers.
343  *
344  * To accommodate other types of computer arithmetic, all
345  * constants are also provided in a normal decimal radix
346  * which one can hope are correctly converted to a suitable
347  * format by the available C language compiler.  To invoke
348  * this mode, the symbol UNK is defined.
349  *
350  * An important difference among these modes is a predefined
351  * set of machine arithmetic constants for each.  The numbers
352  * MACHEP (the machine roundoff error), MAXNUM (largest number
353  * represented), and several other parameters are preset by
354  * the configuration symbol.  Check the file const.c to
355  * ensure that these values are correct for your computer.
356  *
357  * For ANSI C compatibility, define ANSIC equal to 1.  Currently
358  * this affects only the atan2() function and others that use it.
359  */
360 
361 /* Constant definitions for math error conditions
362  */
363 
364 #define DOMAIN		1	/* argument domain error */
365 #define SING		2	/* argument singularity */
366 #define OVERFLOW	3	/* overflow range error */
367 #define UNDERFLOW	4	/* underflow range error */
368 #define TLOSS		5	/* total loss of precision */
369 #define PLOSS		6	/* partial loss of precision */
370 
371 #define EDOM		33
372 #define ERANGE		34
373 
374 typedef struct
375 {
376   double r;
377   double i;
378 } cmplx;
379 
380 /* Type of computer arithmetic */
381 
382 #ifndef DEC
383 #ifdef __IEEE_LITTLE_ENDIAN
384 #define IBMPC 1
385 #else /* !__IEEE_LITTLE_ENDIAN */
386 #define MIEEE 1
387 #endif /* !__IEEE_LITTLE_ENDIAN */
388 #endif /* !DEC */
389 
390 /* Define 1 for ANSI C atan2() function
391  * See atan.c and clog.c.
392  */
393 #define ANSIC 1
394 
395 /*define VOLATILE volatile*/
396 #define VOLATILE
397 
398 #define NANS
399 #define USE_INFINITY
400 
401 /* NaN's require infinity support. */
402 #ifdef NANS
403 #ifndef INFINITY
404 #define USE_INFINITY
405 #endif
406 #endif
407 
408 /* This handles 64-bit long ints. */
409 #define LONGBITS (8 * sizeof(long))
410 
411 
412 static void eaddm (short unsigned int *x, short unsigned int *y);
413 static void esubm (short unsigned int *x, short unsigned int *y);
414 static void emdnorm (short unsigned int *s, int lost, int subflg,
415 		     long int exp, int rcntrl, LDPARMS * ldp);
416 #if 0 /* Broken, unusable implementation of strtold */
417 static int asctoeg (char *ss, short unsigned int *y, int oprec,
418 		    LDPARMS * ldp);
419 #endif
420 static void enan (short unsigned int *nan, int size);
421 #if LDBL_MANT_DIG == 24
422 static void toe24 (short unsigned int *x, short unsigned int *y);
423 #elif LDBL_MANT_DIG == 53
424 static void toe53 (short unsigned int *x, short unsigned int *y);
425 #elif LDBL_MANT_DIG == 64
426 static void toe64 (short unsigned int *a, short unsigned int *b);
427 #else
428 static void toe113 (short unsigned int *a, short unsigned int *b);
429 #endif
430 static void eiremain (short unsigned int *den, short unsigned int *num,
431 		      LDPARMS * ldp);
432 static int ecmpm (register short unsigned int *a,
433 		  register short unsigned int *b);
434 static int edivm (short unsigned int *den, short unsigned int *num,
435 		  LDPARMS * ldp);
436 static int emulm (short unsigned int *a, short unsigned int *b,
437 		  LDPARMS * ldp);
438 static int eisneg (const short unsigned int *x);
439 static int eisinf (const short unsigned int *x);
440 static void emovi (const short unsigned int *a, short unsigned int *b);
441 static void emovo (short unsigned int *a, short unsigned int *b,
442 		   LDPARMS * ldp);
443 static void emovz (register short unsigned int *a,
444 		   register short unsigned int *b);
445 static void ecleaz (register short unsigned int *xi);
446 static void eadd1 (const short unsigned int *a, const short unsigned int *b,
447 		   short unsigned int *c, int subflg, LDPARMS * ldp);
448 static int eisnan (const short unsigned int *x);
449 static int eiisnan (short unsigned int *x);
450 
451 #ifdef DEC
452 static void etodec (), todec (), dectoe ();
453 #endif
454 
455 /*
456 ; Clear out entire external format number.
457 ;
458 ; unsigned short x[];
459 ; eclear( x );
460 */
461 
462 static void
eclear(register short unsigned int * x)463 eclear (register short unsigned int *x)
464 {
465   register int i;
466 
467   for (i = 0; i < NE; i++)
468     *x++ = 0;
469 }
470 
471 
472 
473 /* Move external format number from a to b.
474  *
475  * emov( a, b );
476  */
477 
478 static void
emov(register const short unsigned int * a,register short unsigned int * b)479 emov (register const short unsigned int *a, register short unsigned int *b)
480 {
481   register int i;
482 
483   for (i = 0; i < NE; i++)
484     *b++ = *a++;
485 }
486 
487 
488 /*
489 ;	Negate external format number
490 ;
491 ;	unsigned short x[NE];
492 ;	eneg( x );
493 */
494 
495 static void
eneg(short unsigned int * x)496 eneg (short unsigned int *x)
497 {
498 
499 #ifdef NANS
500   if (eisnan (x))
501     return;
502 #endif
503   x[NE - 1] ^= 0x8000;		/* Toggle the sign bit */
504 }
505 
506 
507 
508 /* Return 1 if external format number is negative,
509  * else return zero.
510  */
511 static int
eisneg(const short unsigned int * x)512 eisneg (const short unsigned int *x)
513 {
514 
515 #ifdef NANS
516   if (eisnan (x))
517     return (0);
518 #endif
519   if (x[NE - 1] & 0x8000)
520     return (1);
521   else
522     return (0);
523 }
524 
525 
526 /* Return 1 if external format number has maximum possible exponent,
527  * else return zero.
528  */
529 static int
eisinf(const short unsigned int * x)530 eisinf (const short unsigned int *x)
531 {
532 
533   if ((x[NE - 1] & 0x7fff) == 0x7fff)
534     {
535 #ifdef NANS
536       if (eisnan (x))
537 	return (0);
538 #endif
539       return (1);
540     }
541   else
542     return (0);
543 }
544 
545 /* Check if e-type number is not a number.
546  */
547 static int
eisnan(const short unsigned int * x)548 eisnan (const short unsigned int *x)
549 {
550 
551 #ifdef NANS
552   int i;
553 /* NaN has maximum exponent */
554   if ((x[NE - 1] & 0x7fff) != 0x7fff)
555     return (0);
556 /* ... and non-zero significand field. */
557   for (i = 0; i < NE - 1; i++)
558     {
559       if (*x++ != 0)
560 	return (1);
561     }
562 #endif
563   return (0);
564 }
565 
566 /*
567 ; Fill entire number, including exponent and significand, with
568 ; largest possible number.  These programs implement a saturation
569 ; value that is an ordinary, legal number.  A special value
570 ; "infinity" may also be implemented; this would require tests
571 ; for that value and implementation of special rules for arithmetic
572 ; operations involving inifinity.
573 */
574 
575 static void
einfin(register short unsigned int * x,register LDPARMS * ldp)576 einfin (register short unsigned int *x, register LDPARMS * ldp)
577 {
578   register int i;
579 
580 #ifdef USE_INFINITY
581   for (i = 0; i < NE - 1; i++)
582     *x++ = 0;
583   *x |= 32767;
584   (void) ldp;
585 #else
586   for (i = 0; i < NE - 1; i++)
587     *x++ = 0xffff;
588   *x |= 32766;
589   if (ldp->rndprc < NBITS)
590     {
591       if (ldp->rndprc == 113)
592 	{
593 	  *(x - 9) = 0;
594 	  *(x - 8) = 0;
595 	}
596       if (ldp->rndprc == 64)
597 	{
598 	  *(x - 5) = 0;
599 	}
600       if (ldp->rndprc == 53)
601 	{
602 	  *(x - 4) = 0xf800;
603 	}
604       else
605 	{
606 	  *(x - 4) = 0;
607 	  *(x - 3) = 0;
608 	  *(x - 2) = 0xff00;
609 	}
610     }
611 #endif
612 }
613 
614 /* Move in external format number,
615  * converting it to internal format.
616  */
617 static void
emovi(const short unsigned int * a,short unsigned int * b)618 emovi (const short unsigned int *a, short unsigned int *b)
619 {
620   register const unsigned short *p;
621   register unsigned short *q;
622   int i;
623 
624   q = b;
625   p = a + (NE - 1);		/* point to last word of external number */
626 /* get the sign bit */
627   if (*p & 0x8000)
628     *q++ = 0xffff;
629   else
630     *q++ = 0;
631 /* get the exponent */
632   *q = *p--;
633   *q++ &= 0x7fff;		/* delete the sign bit */
634 #ifdef USE_INFINITY
635   if ((*(q - 1) & 0x7fff) == 0x7fff)
636     {
637 #ifdef NANS
638       if (eisnan (a))
639 	{
640 	  *q++ = 0;
641 	  for (i = 3; i < NI; i++)
642 	    *q++ = *p--;
643 	  return;
644 	}
645 #endif
646       for (i = 2; i < NI; i++)
647 	*q++ = 0;
648       return;
649     }
650 #endif
651 /* clear high guard word */
652   *q++ = 0;
653 /* move in the significand */
654   for (i = 0; i < NE - 1; i++)
655     *q++ = *p--;
656 /* clear low guard word */
657   *q = 0;
658 }
659 
660 
661 /* Move internal format number out,
662  * converting it to external format.
663  */
664 static void
emovo(short unsigned int * a,short unsigned int * b,LDPARMS * ldp)665 emovo (short unsigned int *a, short unsigned int *b, LDPARMS * ldp)
666 {
667   register unsigned short *p, *q;
668   unsigned short i;
669 
670   p = a;
671   q = b + (NE - 1);		/* point to output exponent */
672 /* combine sign and exponent */
673   i = *p++;
674   if (i)
675     *q-- = *p++ | 0x8000;
676   else
677     *q-- = *p++;
678 #ifdef USE_INFINITY
679   if (*(p - 1) == 0x7fff)
680     {
681 #ifdef NANS
682       if (eiisnan (a))
683 	{
684 	  enan (b, NBITS);
685 	  return;
686 	}
687 #endif
688       einfin (b, ldp);
689       return;
690     }
691 #endif
692 /* skip over guard word */
693   ++p;
694 /* move the significand */
695   for (i = 0; i < NE - 1; i++)
696     *q-- = *p++;
697 }
698 
699 
700 /* Clear out internal format number.
701  */
702 
703 static void
ecleaz(register short unsigned int * xi)704 ecleaz (register short unsigned int *xi)
705 {
706   register int i;
707 
708   for (i = 0; i < NI; i++)
709     *xi++ = 0;
710 }
711 
712 /* same, but don't touch the sign. */
713 
714 static void
ecleazs(register short unsigned int * xi)715 ecleazs (register short unsigned int *xi)
716 {
717   register int i;
718 
719   ++xi;
720   for (i = 0; i < NI - 1; i++)
721     *xi++ = 0;
722 }
723 
724 
725 
726 
727 /* Move internal format number from a to b.
728  */
729 static void
emovz(register short unsigned int * a,register short unsigned int * b)730 emovz (register short unsigned int *a, register short unsigned int *b)
731 {
732   register int i;
733 
734   for (i = 0; i < NI - 1; i++)
735     *b++ = *a++;
736 /* clear low guard word */
737   *b = 0;
738 }
739 
740 /* Return nonzero if internal format number is a NaN.
741  */
742 
743 static int
eiisnan(short unsigned int * x)744 eiisnan (short unsigned int *x)
745 {
746   int i;
747 
748   if ((x[E] & 0x7fff) == 0x7fff)
749     {
750       for (i = M + 1; i < NI; i++)
751 	{
752 	  if (x[i] != 0)
753 	    return (1);
754 	}
755     }
756   return (0);
757 }
758 
759 #if LDBL_MANT_DIG == 64
760 
761 #ifdef USE_INFINITY
762 #ifdef IBMPC
763 
764 /* Return nonzero if internal format number is infinite. */
765 static int
eiisinf(unsigned short x[])766 eiisinf (unsigned short x[])
767 {
768 
769 #ifdef NANS
770   if (eiisnan (x))
771     return (0);
772 #endif
773   if ((x[E] & 0x7fff) == 0x7fff)
774     return (1);
775   return (0);
776 }
777 #endif
778 #endif
779 
780 #endif /* LDBL_MANT_DIG == 64 */
781 
782 /*
783 ;	Compare significands of numbers in internal format.
784 ;	Guard words are included in the comparison.
785 ;
786 ;	unsigned short a[NI], b[NI];
787 ;	cmpm( a, b );
788 ;
789 ;	for the significands:
790 ;	returns	+1 if a > b
791 ;		 0 if a == b
792 ;		-1 if a < b
793 */
794 static int
ecmpm(register short unsigned int * a,register short unsigned int * b)795 ecmpm (register short unsigned int *a, register short unsigned int *b)
796 {
797   int i;
798 
799   a += M;			/* skip up to significand area */
800   b += M;
801   for (i = M; i < NI; i++)
802     {
803       if (*a++ != *b++)
804 	goto difrnt;
805     }
806   return (0);
807 
808 difrnt:
809   if (*(--a) > *(--b))
810     return (1);
811   else
812     return (-1);
813 }
814 
815 
816 /*
817 ;	Shift significand down by 1 bit
818 */
819 
820 static void
eshdn1(register short unsigned int * x)821 eshdn1 (register short unsigned int *x)
822 {
823   register unsigned short bits;
824   int i;
825 
826   x += M;			/* point to significand area */
827 
828   bits = 0;
829   for (i = M; i < NI; i++)
830     {
831       if (*x & 1)
832 	bits |= 1;
833       *x >>= 1;
834       if (bits & 2)
835 	*x |= 0x8000;
836       bits <<= 1;
837       ++x;
838     }
839 }
840 
841 
842 
843 /*
844 ;	Shift significand up by 1 bit
845 */
846 
847 static void
eshup1(register short unsigned int * x)848 eshup1 (register short unsigned int *x)
849 {
850   register unsigned short bits;
851   int i;
852 
853   x += NI - 1;
854   bits = 0;
855 
856   for (i = M; i < NI; i++)
857     {
858       if (*x & 0x8000)
859 	bits |= 1;
860       *x <<= 1;
861       if (bits & 2)
862 	*x |= 1;
863       bits <<= 1;
864       --x;
865     }
866 }
867 
868 
869 
870 /*
871 ;	Shift significand down by 8 bits
872 */
873 
874 static void
eshdn8(register short unsigned int * x)875 eshdn8 (register short unsigned int *x)
876 {
877   register unsigned short newbyt, oldbyt;
878   int i;
879 
880   x += M;
881   oldbyt = 0;
882   for (i = M; i < NI; i++)
883     {
884       newbyt = *x << 8;
885       *x >>= 8;
886       *x |= oldbyt;
887       oldbyt = newbyt;
888       ++x;
889     }
890 }
891 
892 /*
893 ;	Shift significand up by 8 bits
894 */
895 
896 static void
eshup8(register short unsigned int * x)897 eshup8 (register short unsigned int *x)
898 {
899   int i;
900   register unsigned short newbyt, oldbyt;
901 
902   x += NI - 1;
903   oldbyt = 0;
904 
905   for (i = M; i < NI; i++)
906     {
907       newbyt = *x >> 8;
908       *x <<= 8;
909       *x |= oldbyt;
910       oldbyt = newbyt;
911       --x;
912     }
913 }
914 
915 /*
916 ;	Shift significand up by 16 bits
917 */
918 
919 static void
eshup6(register short unsigned int * x)920 eshup6 (register short unsigned int *x)
921 {
922   int i;
923   register unsigned short *p;
924 
925   p = x + M;
926   x += M + 1;
927 
928   for (i = M; i < NI - 1; i++)
929     *p++ = *x++;
930 
931   *p = 0;
932 }
933 
934 /*
935 ;	Shift significand down by 16 bits
936 */
937 
938 static void
eshdn6(register short unsigned int * x)939 eshdn6 (register short unsigned int *x)
940 {
941   int i;
942   register unsigned short *p;
943 
944   x += NI - 1;
945   p = x + 1;
946 
947   for (i = M; i < NI - 1; i++)
948     *(--p) = *(--x);
949 
950   *(--p) = 0;
951 }
952 
953 /*
954 ;	Add significands
955 ;	x + y replaces y
956 */
957 
958 static void
eaddm(short unsigned int * x,short unsigned int * y)959 eaddm (short unsigned int *x, short unsigned int *y)
960 {
961   register unsigned long a;
962   int i;
963   unsigned int carry;
964 
965   x += NI - 1;
966   y += NI - 1;
967   carry = 0;
968   for (i = M; i < NI; i++)
969     {
970       a = (unsigned long) (*x) + (unsigned long) (*y) + carry;
971       if (a & 0x10000)
972 	carry = 1;
973       else
974 	carry = 0;
975       *y = (unsigned short) a;
976       --x;
977       --y;
978     }
979 }
980 
981 /*
982 ;	Subtract significands
983 ;	y - x replaces y
984 */
985 
986 static void
esubm(short unsigned int * x,short unsigned int * y)987 esubm (short unsigned int *x, short unsigned int *y)
988 {
989   unsigned long a;
990   int i;
991   unsigned int carry;
992 
993   x += NI - 1;
994   y += NI - 1;
995   carry = 0;
996   for (i = M; i < NI; i++)
997     {
998       a = (unsigned long) (*y) - (unsigned long) (*x) - carry;
999       if (a & 0x10000)
1000 	carry = 1;
1001       else
1002 	carry = 0;
1003       *y = (unsigned short) a;
1004       --x;
1005       --y;
1006     }
1007 }
1008 
1009 
1010 /* Divide significands */
1011 
1012 
1013 /* Multiply significand of e-type number b
1014 by 16-bit quantity a, e-type result to c. */
1015 
1016 static void
m16m(short unsigned int a,short unsigned int * b,short unsigned int * c)1017 m16m (short unsigned int a, short unsigned int *b, short unsigned int *c)
1018 {
1019   register unsigned short *pp;
1020   register unsigned long carry;
1021   unsigned short *ps;
1022   unsigned short p[NI];
1023   unsigned long aa, m;
1024   int i;
1025 
1026   aa = a;
1027   pp = &p[NI - 2];
1028   *pp++ = 0;
1029   *pp = 0;
1030   ps = &b[NI - 1];
1031 
1032   for (i = M + 1; i < NI; i++)
1033     {
1034       if (*ps == 0)
1035 	{
1036 	  --ps;
1037 	  --pp;
1038 	  *(pp - 1) = 0;
1039 	}
1040       else
1041 	{
1042 	  m = (unsigned long) aa **ps--;
1043 	  carry = (m & 0xffff) + *pp;
1044 	  *pp-- = (unsigned short) carry;
1045 	  carry = (carry >> 16) + (m >> 16) + *pp;
1046 	  *pp = (unsigned short) carry;
1047 	  *(pp - 1) = carry >> 16;
1048 	}
1049     }
1050   for (i = M; i < NI; i++)
1051     c[i] = p[i];
1052 }
1053 
1054 
1055 /* Divide significands. Neither the numerator nor the denominator
1056 is permitted to have its high guard word nonzero.  */
1057 
1058 
1059 static int
edivm(short unsigned int * den,short unsigned int * num,LDPARMS * ldp)1060 edivm (short unsigned int *den, short unsigned int *num, LDPARMS * ldp)
1061 {
1062   int i;
1063   register unsigned short *p;
1064   unsigned long tnum;
1065   unsigned short j, tdenm, tquot;
1066   unsigned short tprod[NI + 1];
1067   unsigned short *equot = ldp->equot;
1068 
1069   p = &equot[0];
1070   *p++ = num[0];
1071   *p++ = num[1];
1072 
1073   for (i = M; i < NI; i++)
1074     {
1075       *p++ = 0;
1076     }
1077   eshdn1 (num);
1078   tdenm = den[M + 1];
1079   for (i = M; i < NI; i++)
1080     {
1081       /* Find trial quotient digit (the radix is 65536). */
1082       tnum = (((unsigned long) num[M]) << 16) + num[M + 1];
1083 
1084       /* Do not execute the divide instruction if it will overflow. */
1085       if ((tdenm * 0xffffUL) < tnum)
1086 	tquot = 0xffff;
1087       else
1088 	tquot = tnum / tdenm;
1089 
1090       /* Prove that the divide worked. */
1091 /*
1092 	tcheck = (unsigned long )tquot * tdenm;
1093 	if( tnum - tcheck > tdenm )
1094 		tquot = 0xffff;
1095 */
1096       /* Multiply denominator by trial quotient digit. */
1097       m16m (tquot, den, tprod);
1098       /* The quotient digit may have been overestimated. */
1099       if (ecmpm (tprod, num) > 0)
1100 	{
1101 	  tquot -= 1;
1102 	  esubm (den, tprod);
1103 	  if (ecmpm (tprod, num) > 0)
1104 	    {
1105 	      tquot -= 1;
1106 	      esubm (den, tprod);
1107 	    }
1108 	}
1109 /*
1110 	if( ecmpm( tprod, num ) > 0 )
1111 		{
1112 		eshow( "tprod", tprod );
1113 		eshow( "num  ", num );
1114 		printf( "tnum = %08lx, tden = %04x, tquot = %04x\n",
1115 			 tnum, den[M+1], tquot );
1116 		}
1117 */
1118       esubm (tprod, num);
1119 /*
1120 	if( ecmpm( num, den ) >= 0 )
1121 		{
1122 		eshow( "num  ", num );
1123 		eshow( "den  ", den );
1124 		printf( "tnum = %08lx, tden = %04x, tquot = %04x\n",
1125 			 tnum, den[M+1], tquot );
1126 		}
1127 */
1128       equot[i] = tquot;
1129       eshup6 (num);
1130     }
1131 /* test for nonzero remainder after roundoff bit */
1132   p = &num[M];
1133   j = 0;
1134   for (i = M; i < NI; i++)
1135     {
1136       j |= *p++;
1137     }
1138   if (j)
1139     j = 1;
1140 
1141   for (i = 0; i < NI; i++)
1142     num[i] = equot[i];
1143 
1144   return ((int) j);
1145 }
1146 
1147 
1148 
1149 /* Multiply significands */
1150 static int
emulm(short unsigned int * a,short unsigned int * b,LDPARMS * ldp)1151 emulm (short unsigned int *a, short unsigned int *b, LDPARMS * ldp)
1152 {
1153   unsigned short *p, *q;
1154   unsigned short pprod[NI];
1155   unsigned short j;
1156   int i;
1157   unsigned short *equot = ldp->equot;
1158 
1159   equot[0] = b[0];
1160   equot[1] = b[1];
1161   for (i = M; i < NI; i++)
1162     equot[i] = 0;
1163 
1164   j = 0;
1165   p = &a[NI - 1];
1166   q = &equot[NI - 1];
1167   for (i = M + 1; i < NI; i++)
1168     {
1169       if (*p == 0)
1170 	{
1171 	  --p;
1172 	}
1173       else
1174 	{
1175 	  m16m (*p--, b, pprod);
1176 	  eaddm (pprod, equot);
1177 	}
1178       j |= *q;
1179       eshdn6 (equot);
1180     }
1181 
1182   for (i = 0; i < NI; i++)
1183     b[i] = equot[i];
1184 
1185 /* return flag for lost nonzero bits */
1186   return ((int) j);
1187 }
1188 
1189 
1190 /*
1191 static void eshow(str, x)
1192 char *str;
1193 unsigned short *x;
1194 {
1195 int i;
1196 
1197 printf( "%s ", str );
1198 for( i=0; i<NI; i++ )
1199 	printf( "%04x ", *x++ );
1200 printf( "\n" );
1201 }
1202 */
1203 
1204 
1205 /*
1206  * Normalize and round off.
1207  *
1208  * The internal format number to be rounded is "s".
1209  * Input "lost" indicates whether the number is exact.
1210  * This is the so-called sticky bit.
1211  *
1212  * Input "subflg" indicates whether the number was obtained
1213  * by a subtraction operation.  In that case if lost is nonzero
1214  * then the number is slightly smaller than indicated.
1215  *
1216  * Input "exp" is the biased exponent, which may be negative.
1217  * the exponent field of "s" is ignored but is replaced by
1218  * "exp" as adjusted by normalization and rounding.
1219  *
1220  * Input "rcntrl" is the rounding control.
1221  */
1222 
1223 
1224 static void
emdnorm(short unsigned int * s,int lost,int subflg,long int exp,int rcntrl,LDPARMS * ldp)1225 emdnorm (short unsigned int *s, int lost, int subflg, long int exp,
1226 	 int rcntrl, LDPARMS * ldp)
1227 {
1228   int i, j;
1229   unsigned short r;
1230 
1231 /* Normalize */
1232   j = enormlz (s);
1233 
1234 /* a blank significand could mean either zero or infinity. */
1235 #ifndef USE_INFINITY
1236   if (j > NBITS)
1237     {
1238       ecleazs (s);
1239       return;
1240     }
1241 #endif
1242   exp -= j;
1243 #ifndef USE_INFINITY
1244   if (exp >= 32767L)
1245     goto overf;
1246 #else
1247   if ((j > NBITS) && (exp < 32767L))
1248     {
1249       ecleazs (s);
1250       return;
1251     }
1252 #endif
1253   if (exp < 0L)
1254     {
1255       if (exp > (long) (-NBITS - 1))
1256 	{
1257 	  j = (int) exp;
1258 	  i = eshift (s, j);
1259 	  if (i)
1260 	    lost = 1;
1261 	}
1262       else
1263 	{
1264 	  ecleazs (s);
1265 	  return;
1266 	}
1267     }
1268 /* Round off, unless told not to by rcntrl. */
1269   if (rcntrl == 0)
1270     goto mdfin;
1271 /* Set up rounding parameters if the control register changed. */
1272   if (ldp->rndprc != ldp->rlast)
1273     {
1274       ecleaz (ldp->rbit);
1275       switch (ldp->rndprc)
1276 	{
1277 	default:
1278 	case NBITS:
1279 	  ldp->rw = NI - 1;	/* low guard word */
1280 	  ldp->rmsk = 0xffff;
1281 	  ldp->rmbit = 0x8000;
1282 	  ldp->rebit = 1;
1283 	  ldp->re = ldp->rw - 1;
1284 	  break;
1285 	case 113:
1286 	  ldp->rw = 10;
1287 	  ldp->rmsk = 0x7fff;
1288 	  ldp->rmbit = 0x4000;
1289 	  ldp->rebit = 0x8000;
1290 	  ldp->re = ldp->rw;
1291 	  break;
1292 	case 64:
1293 	  ldp->rw = 7;
1294 	  ldp->rmsk = 0xffff;
1295 	  ldp->rmbit = 0x8000;
1296 	  ldp->rebit = 1;
1297 	  ldp->re = ldp->rw - 1;
1298 	  break;
1299 /* For DEC arithmetic */
1300 	case 56:
1301 	  ldp->rw = 6;
1302 	  ldp->rmsk = 0xff;
1303 	  ldp->rmbit = 0x80;
1304 	  ldp->rebit = 0x100;
1305 	  ldp->re = ldp->rw;
1306 	  break;
1307 	case 53:
1308 	  ldp->rw = 6;
1309 	  ldp->rmsk = 0x7ff;
1310 	  ldp->rmbit = 0x0400;
1311 	  ldp->rebit = 0x800;
1312 	  ldp->re = ldp->rw;
1313 	  break;
1314 	case 24:
1315 	  ldp->rw = 4;
1316 	  ldp->rmsk = 0xff;
1317 	  ldp->rmbit = 0x80;
1318 	  ldp->rebit = 0x100;
1319 	  ldp->re = ldp->rw;
1320 	  break;
1321 	}
1322       ldp->rbit[ldp->re] = ldp->rebit;
1323       ldp->rlast = ldp->rndprc;
1324     }
1325 
1326 /* Shift down 1 temporarily if the data structure has an implied
1327  * most significant bit and the number is denormal.
1328  * For rndprc = 64 or NBITS, there is no implied bit.
1329  * But Intel long double denormals lose one bit of significance even so.
1330  */
1331 #if IBMPC
1332   if ((exp <= 0) && (ldp->rndprc != NBITS))
1333 #else
1334   if ((exp <= 0) && (ldp->rndprc != 64) && (ldp->rndprc != NBITS))
1335 #endif
1336     {
1337       lost |= s[NI - 1] & 1;
1338       eshdn1 (s);
1339     }
1340 /* Clear out all bits below the rounding bit,
1341  * remembering in r if any were nonzero.
1342  */
1343   r = s[ldp->rw] & ldp->rmsk;
1344   if (ldp->rndprc < NBITS)
1345     {
1346       i = ldp->rw + 1;
1347       while (i < NI)
1348 	{
1349 	  if (s[i])
1350 	    r |= 1;
1351 	  s[i] = 0;
1352 	  ++i;
1353 	}
1354     }
1355   s[ldp->rw] &= ~ldp->rmsk;
1356   if ((r & ldp->rmbit) != 0)
1357     {
1358       if (r == ldp->rmbit)
1359 	{
1360 	  if (lost == 0)
1361 	    {			/* round to even */
1362 	      if ((s[ldp->re] & ldp->rebit) == 0)
1363 		goto mddone;
1364 	    }
1365 	  else
1366 	    {
1367 	      if (subflg != 0)
1368 		goto mddone;
1369 	    }
1370 	}
1371       eaddm (ldp->rbit, s);
1372     }
1373 mddone:
1374 #if IBMPC
1375   if ((exp <= 0) && (ldp->rndprc != NBITS))
1376 #else
1377   if ((exp <= 0) && (ldp->rndprc != 64) && (ldp->rndprc != NBITS))
1378 #endif
1379     {
1380       eshup1 (s);
1381     }
1382   if (s[2] != 0)
1383     {				/* overflow on roundoff */
1384       eshdn1 (s);
1385       exp += 1;
1386     }
1387 mdfin:
1388   s[NI - 1] = 0;
1389   if (exp >= 32767L)
1390     {
1391 #ifndef USE_INFINITY
1392     overf:
1393 #endif
1394 #ifdef USE_INFINITY
1395       s[1] = 32767;
1396       for (i = 2; i < NI - 1; i++)
1397 	s[i] = 0;
1398 #else
1399       s[1] = 32766;
1400       s[2] = 0;
1401       for (i = M + 1; i < NI - 1; i++)
1402 	s[i] = 0xffff;
1403       s[NI - 1] = 0;
1404       if ((ldp->rndprc < 64) || (ldp->rndprc == 113))
1405 	{
1406 	  s[ldp->rw] &= ~ldp->rmsk;
1407 	  if (ldp->rndprc == 24)
1408 	    {
1409 	      s[5] = 0;
1410 	      s[6] = 0;
1411 	    }
1412 	}
1413 #endif
1414       return;
1415     }
1416   if (exp < 0)
1417     s[1] = 0;
1418   else
1419     s[1] = (unsigned short) exp;
1420 }
1421 
1422 
1423 
1424 /*
1425 ;	Subtract external format numbers.
1426 ;
1427 ;	unsigned short a[NE], b[NE], c[NE];
1428 ;       LDPARMS *ldp;
1429 ;	esub( a, b, c, ldp );	 c = b - a
1430 */
1431 
1432 static void
esub(const short unsigned int * a,const short unsigned int * b,short unsigned int * c,LDPARMS * ldp)1433 esub (const short unsigned int *a, const short unsigned int *b,
1434       short unsigned int *c, LDPARMS * ldp)
1435 {
1436 
1437 #ifdef NANS
1438   if (eisnan (a))
1439     {
1440       emov (a, c);
1441       return;
1442     }
1443   if (eisnan (b))
1444     {
1445       emov (b, c);
1446       return;
1447     }
1448 /* Infinity minus infinity is a NaN.
1449  * Test for subtracting infinities of the same sign.
1450  */
1451   if (eisinf (a) && eisinf (b) && ((eisneg (a) ^ eisneg (b)) == 0))
1452     {
1453       mtherr ("esub", DOMAIN);
1454       enan (c, NBITS);
1455       return;
1456     }
1457 #endif
1458   eadd1 (a, b, c, 1, ldp);
1459 }
1460 
1461 
1462 
1463 static void
eadd1(const short unsigned int * a,const short unsigned int * b,short unsigned int * c,int subflg,LDPARMS * ldp)1464 eadd1 (const short unsigned int *a, const short unsigned int *b,
1465        short unsigned int *c, int subflg, LDPARMS * ldp)
1466 {
1467   unsigned short ai[NI], bi[NI], ci[NI];
1468   int i, lost, j, k;
1469   long lt, lta, ltb;
1470 
1471 #ifdef USE_INFINITY
1472   if (eisinf (a))
1473     {
1474       emov (a, c);
1475       if (subflg)
1476 	eneg (c);
1477       return;
1478     }
1479   if (eisinf (b))
1480     {
1481       emov (b, c);
1482       return;
1483     }
1484 #endif
1485   emovi (a, ai);
1486   emovi (b, bi);
1487   if (subflg)
1488     ai[0] = ~ai[0];
1489 
1490 /* compare exponents */
1491   lta = ai[E];
1492   ltb = bi[E];
1493   lt = lta - ltb;
1494   if (lt > 0L)
1495     {				/* put the larger number in bi */
1496       emovz (bi, ci);
1497       emovz (ai, bi);
1498       emovz (ci, ai);
1499       ltb = bi[E];
1500       lt = -lt;
1501     }
1502   lost = 0;
1503   if (lt != 0L)
1504     {
1505       if (lt < (long) (-NBITS - 1))
1506 	goto done;		/* answer same as larger addend */
1507       k = (int) lt;
1508       lost = eshift (ai, k);	/* shift the smaller number down */
1509     }
1510   else
1511     {
1512 /* exponents were the same, so must compare significands */
1513       i = ecmpm (ai, bi);
1514       if (i == 0)
1515 	{			/* the numbers are identical in magnitude */
1516 	  /* if different signs, result is zero */
1517 	  if (ai[0] != bi[0])
1518 	    {
1519 	      eclear (c);
1520 	      return;
1521 	    }
1522 	  /* if same sign, result is double */
1523 	  /* double denomalized tiny number */
1524 	  if ((bi[E] == 0) && ((bi[3] & 0x8000) == 0))
1525 	    {
1526 	      eshup1 (bi);
1527 	      goto done;
1528 	    }
1529 	  /* add 1 to exponent unless both are zero! */
1530 	  for (j = 1; j < NI - 1; j++)
1531 	    {
1532 	      if (bi[j] != 0)
1533 		{
1534 /* This could overflow, but let emovo take care of that. */
1535 		  ltb += 1;
1536 		  break;
1537 		}
1538 	    }
1539 	  bi[E] = (unsigned short) ltb;
1540 	  goto done;
1541 	}
1542       if (i > 0)
1543 	{			/* put the larger number in bi */
1544 	  emovz (bi, ci);
1545 	  emovz (ai, bi);
1546 	  emovz (ci, ai);
1547 	}
1548     }
1549   if (ai[0] == bi[0])
1550     {
1551       eaddm (ai, bi);
1552       subflg = 0;
1553     }
1554   else
1555     {
1556       esubm (ai, bi);
1557       subflg = 1;
1558     }
1559   emdnorm (bi, lost, subflg, ltb, 64, ldp);
1560 
1561 done:
1562   emovo (bi, c, ldp);
1563 }
1564 
1565 
1566 
1567 /*
1568 ;	Divide.
1569 ;
1570 ;	unsigned short a[NE], b[NE], c[NE];
1571 ;       LDPARMS *ldp;
1572 ;	ediv( a, b, c, ldp );	c = b / a
1573 */
1574 static void
ediv(const short unsigned int * a,const short unsigned int * b,short unsigned int * c,LDPARMS * ldp)1575 ediv (const short unsigned int *a, const short unsigned int *b,
1576       short unsigned int *c, LDPARMS * ldp)
1577 {
1578   unsigned short ai[NI], bi[NI];
1579   int i;
1580   long lt, lta, ltb;
1581 
1582 #ifdef NANS
1583 /* Return any NaN input. */
1584   if (eisnan (a))
1585     {
1586       emov (a, c);
1587       return;
1588     }
1589   if (eisnan (b))
1590     {
1591       emov (b, c);
1592       return;
1593     }
1594 /* Zero over zero, or infinity over infinity, is a NaN. */
1595   if (((ecmp (a, ezero) == 0) && (ecmp (b, ezero) == 0))
1596       || (eisinf (a) && eisinf (b)))
1597     {
1598       mtherr ("ediv", DOMAIN);
1599       enan (c, NBITS);
1600       return;
1601     }
1602 #endif
1603 /* Infinity over anything else is infinity. */
1604 #ifdef USE_INFINITY
1605   if (eisinf (b))
1606     {
1607       if (eisneg (a) ^ eisneg (b))
1608 	*(c + (NE - 1)) = 0x8000;
1609       else
1610 	*(c + (NE - 1)) = 0;
1611       einfin (c, ldp);
1612       return;
1613     }
1614   if (eisinf (a))
1615     {
1616       eclear (c);
1617       return;
1618     }
1619 #endif
1620   emovi (a, ai);
1621   emovi (b, bi);
1622   lta = ai[E];
1623   ltb = bi[E];
1624   if (bi[E] == 0)
1625     {				/* See if numerator is zero. */
1626       for (i = 1; i < NI - 1; i++)
1627 	{
1628 	  if (bi[i] != 0)
1629 	    {
1630 	      ltb -= enormlz (bi);
1631 	      goto dnzro1;
1632 	    }
1633 	}
1634       eclear (c);
1635       return;
1636     }
1637 dnzro1:
1638 
1639   if (ai[E] == 0)
1640     {				/* possible divide by zero */
1641       for (i = 1; i < NI - 1; i++)
1642 	{
1643 	  if (ai[i] != 0)
1644 	    {
1645 	      lta -= enormlz (ai);
1646 	      goto dnzro2;
1647 	    }
1648 	}
1649       if (ai[0] == bi[0])
1650 	*(c + (NE - 1)) = 0;
1651       else
1652 	*(c + (NE - 1)) = 0x8000;
1653       einfin (c, ldp);
1654       mtherr ("ediv", SING);
1655       return;
1656     }
1657 dnzro2:
1658 
1659   i = edivm (ai, bi, ldp);
1660 /* calculate exponent */
1661   lt = ltb - lta + EXONE;
1662   emdnorm (bi, i, 0, lt, 64, ldp);
1663 /* set the sign */
1664   if (ai[0] == bi[0])
1665     bi[0] = 0;
1666   else
1667     bi[0] = 0Xffff;
1668   emovo (bi, c, ldp);
1669 }
1670 
1671 
1672 
1673 /*
1674 ;	Multiply.
1675 ;
1676 ;	unsigned short a[NE], b[NE], c[NE];
1677 ;       LDPARMS *ldp
1678 ;	emul( a, b, c, ldp );	c = b * a
1679 */
1680 static void
emul(const short unsigned int * a,const short unsigned int * b,short unsigned int * c,LDPARMS * ldp)1681 emul (const short unsigned int *a, const short unsigned int *b,
1682       short unsigned int *c, LDPARMS * ldp)
1683 {
1684   unsigned short ai[NI], bi[NI];
1685   int i, j;
1686   long lt, lta, ltb;
1687 
1688 #ifdef NANS
1689 /* NaN times anything is the same NaN. */
1690   if (eisnan (a))
1691     {
1692       emov (a, c);
1693       return;
1694     }
1695   if (eisnan (b))
1696     {
1697       emov (b, c);
1698       return;
1699     }
1700 /* Zero times infinity is a NaN. */
1701   if ((eisinf (a) && (ecmp (b, ezero) == 0))
1702       || (eisinf (b) && (ecmp (a, ezero) == 0)))
1703     {
1704       mtherr ("emul", DOMAIN);
1705       enan (c, NBITS);
1706       return;
1707     }
1708 #endif
1709 /* Infinity times anything else is infinity. */
1710 #ifdef USE_INFINITY
1711   if (eisinf (a) || eisinf (b))
1712     {
1713       if (eisneg (a) ^ eisneg (b))
1714 	*(c + (NE - 1)) = 0x8000;
1715       else
1716 	*(c + (NE - 1)) = 0;
1717       einfin (c, ldp);
1718       return;
1719     }
1720 #endif
1721   emovi (a, ai);
1722   emovi (b, bi);
1723   lta = ai[E];
1724   ltb = bi[E];
1725   if (ai[E] == 0)
1726     {
1727       for (i = 1; i < NI - 1; i++)
1728 	{
1729 	  if (ai[i] != 0)
1730 	    {
1731 	      lta -= enormlz (ai);
1732 	      goto mnzer1;
1733 	    }
1734 	}
1735       eclear (c);
1736       return;
1737     }
1738 mnzer1:
1739 
1740   if (bi[E] == 0)
1741     {
1742       for (i = 1; i < NI - 1; i++)
1743 	{
1744 	  if (bi[i] != 0)
1745 	    {
1746 	      ltb -= enormlz (bi);
1747 	      goto mnzer2;
1748 	    }
1749 	}
1750       eclear (c);
1751       return;
1752     }
1753 mnzer2:
1754 
1755 /* Multiply significands */
1756   j = emulm (ai, bi, ldp);
1757 /* calculate exponent */
1758   lt = lta + ltb - (EXONE - 1);
1759   emdnorm (bi, j, 0, lt, 64, ldp);
1760 /* calculate sign of product */
1761   if (ai[0] == bi[0])
1762     bi[0] = 0;
1763   else
1764     bi[0] = 0xffff;
1765   emovo (bi, c, ldp);
1766 }
1767 
1768 
1769 
1770 #if LDBL_MANT_DIG > 64
1771 static void
e113toe(short unsigned int * pe,short unsigned int * y,LDPARMS * ldp)1772 e113toe (short unsigned int *pe, short unsigned int *y, LDPARMS * ldp)
1773 {
1774   register unsigned short r;
1775   unsigned short *e, *p;
1776   unsigned short yy[NI];
1777   int i;
1778 
1779   e = pe;
1780   ecleaz (yy);
1781 #ifdef IBMPC
1782   e += 7;
1783 #endif
1784   r = *e;
1785   yy[0] = 0;
1786   if (r & 0x8000)
1787     yy[0] = 0xffff;
1788   r &= 0x7fff;
1789 #ifdef USE_INFINITY
1790   if (r == 0x7fff)
1791     {
1792 #ifdef NANS
1793 #ifdef IBMPC
1794       for (i = 0; i < 7; i++)
1795 	{
1796 	  if (pe[i] != 0)
1797 	    {
1798 	      enan (y, NBITS);
1799 	      return;
1800 	    }
1801 	}
1802 #else /* !IBMPC */
1803       for (i = 1; i < 8; i++)
1804 	{
1805 	  if (pe[i] != 0)
1806 	    {
1807 	      enan (y, NBITS);
1808 	      return;
1809 	    }
1810 	}
1811 #endif /* !IBMPC */
1812 #endif /* NANS */
1813       eclear (y);
1814       einfin (y, ldp);
1815       if (*e & 0x8000)
1816 	eneg (y);
1817       return;
1818     }
1819 #endif /* INFINITY */
1820   yy[E] = r;
1821   p = &yy[M + 1];
1822 #ifdef IBMPC
1823   for (i = 0; i < 7; i++)
1824     *p++ = *(--e);
1825 #else /* IBMPC */
1826   ++e;
1827   for (i = 0; i < 7; i++)
1828     *p++ = *e++;
1829 #endif /* IBMPC */
1830 /* If denormal, remove the implied bit; else shift down 1. */
1831   if (r == 0)
1832     {
1833       yy[M] = 0;
1834     }
1835   else
1836     {
1837       yy[M] = 1;
1838       eshift (yy, -1);
1839     }
1840   emovo (yy, y, ldp);
1841 }
1842 
1843 /* move out internal format to ieee long double */
1844 static void
1845 __attribute__ ((__unused__))
toe113(short unsigned int * a,short unsigned int * b)1846 toe113 (short unsigned int *a, short unsigned int *b)
1847 {
1848   register unsigned short *p, *q;
1849   unsigned short i;
1850 
1851 #ifdef NANS
1852   if (eiisnan (a))
1853     {
1854       enan (b, 113);
1855       return;
1856     }
1857 #endif
1858   p = a;
1859 #ifdef MIEEE
1860   q = b;
1861 #else
1862   q = b + 7;			/* point to output exponent */
1863 #endif
1864 
1865 /* If not denormal, delete the implied bit. */
1866   if (a[E] != 0)
1867     {
1868       eshup1 (a);
1869     }
1870 /* combine sign and exponent */
1871   i = *p++;
1872 #ifdef MIEEE
1873   if (i)
1874     *q++ = *p++ | 0x8000;
1875   else
1876     *q++ = *p++;
1877 #else
1878   if (i)
1879     *q-- = *p++ | 0x8000;
1880   else
1881     *q-- = *p++;
1882 #endif
1883 /* skip over guard word */
1884   ++p;
1885 /* move the significand */
1886 #ifdef MIEEE
1887   for (i = 0; i < 7; i++)
1888     *q++ = *p++;
1889 #else
1890   for (i = 0; i < 7; i++)
1891     *q-- = *p++;
1892 #endif
1893 }
1894 #endif /* LDBL_MANT_DIG > 64 */
1895 
1896 
1897 #if LDBL_MANT_DIG == 64
1898 static void
e64toe(short unsigned int * pe,short unsigned int * y,LDPARMS * ldp)1899 e64toe (short unsigned int *pe, short unsigned int *y, LDPARMS * ldp)
1900 {
1901   unsigned short yy[NI];
1902   unsigned short *p, *q, *e;
1903   int i;
1904 
1905   e = pe;
1906   p = yy;
1907 
1908   for (i = 0; i < NE - 5; i++)
1909     *p++ = 0;
1910 #ifdef IBMPC
1911   for (i = 0; i < 5; i++)
1912     *p++ = *e++;
1913 #endif
1914 #ifdef DEC
1915   for (i = 0; i < 5; i++)
1916     *p++ = *e++;
1917 #endif
1918 #ifdef MIEEE
1919   p = &yy[0] + (NE - 1);
1920   *p-- = *e++;
1921   ++e;				/* MIEEE skips over 2nd short */
1922   for (i = 0; i < 4; i++)
1923     *p-- = *e++;
1924 #endif
1925 
1926 #ifdef IBMPC
1927 /* For Intel long double, shift denormal significand up 1
1928    -- but only if the top significand bit is zero.  */
1929   if ((yy[NE - 1] & 0x7fff) == 0 && (yy[NE - 2] & 0x8000) == 0)
1930     {
1931       unsigned short temp[NI + 1];
1932       emovi (yy, temp);
1933       eshup1 (temp);
1934       emovo (temp, y, ldp);
1935       return;
1936     }
1937 #endif
1938 #ifdef USE_INFINITY
1939 /* Point to the exponent field.  */
1940   p = &yy[NE - 1];
1941   if ((*p & 0x7fff) == 0x7fff)
1942     {
1943 #ifdef NANS
1944 #ifdef IBMPC
1945       for (i = 0; i < 4; i++)
1946 	{
1947 	  if ((i != 3 && pe[i] != 0)
1948 	      /* Check for Intel long double infinity pattern.  */
1949 	      || (i == 3 && pe[i] != 0x8000))
1950 	    {
1951 	      enan (y, NBITS);
1952 	      return;
1953 	    }
1954 	}
1955 #endif
1956 #ifdef MIEEE
1957       for (i = 2; i <= 5; i++)
1958 	{
1959 	  if (pe[i] != 0)
1960 	    {
1961 	      enan (y, NBITS);
1962 	      return;
1963 	    }
1964 	}
1965 #endif
1966 #endif /* NANS */
1967       eclear (y);
1968       einfin (y, ldp);
1969       if (*p & 0x8000)
1970 	eneg (y);
1971       return;
1972     }
1973 #endif /* USE_INFINITY */
1974   p = yy;
1975   q = y;
1976   for (i = 0; i < NE; i++)
1977     *q++ = *p++;
1978 }
1979 
1980 /* move out internal format to ieee long double */
1981 static void
1982 __attribute__ ((__unused__))
toe64(short unsigned int * a,short unsigned int * b)1983 toe64 (short unsigned int *a, short unsigned int *b)
1984 {
1985   register unsigned short *p, *q;
1986   unsigned short i;
1987 
1988 #ifdef NANS
1989   if (eiisnan (a))
1990     {
1991       enan (b, 64);
1992       return;
1993     }
1994 #endif
1995 #ifdef IBMPC
1996 /* Shift Intel denormal significand down 1.  */
1997   if (a[E] == 0)
1998     eshdn1 (a);
1999 #endif
2000   p = a;
2001 #ifdef MIEEE
2002   q = b;
2003 #else
2004   q = b + 4;			/* point to output exponent */
2005 /* NOTE: Intel data type is 96 bits wide, clear the last word here. */
2006   *(q + 1) = 0;
2007 #endif
2008 
2009 /* combine sign and exponent */
2010   i = *p++;
2011 #ifdef MIEEE
2012   if (i)
2013     *q++ = *p++ | 0x8000;
2014   else
2015     *q++ = *p++;
2016   *q++ = 0;			/* leave 2nd short blank */
2017 #else
2018   if (i)
2019     *q-- = *p++ | 0x8000;
2020   else
2021     *q-- = *p++;
2022 #endif
2023 /* skip over guard word */
2024   ++p;
2025 /* move the significand */
2026 #ifdef MIEEE
2027   for (i = 0; i < 4; i++)
2028     *q++ = *p++;
2029 #else
2030 #ifdef USE_INFINITY
2031 #ifdef IBMPC
2032   if (eiisinf (a))
2033     {
2034       /* Intel long double infinity.  */
2035       *q-- = 0x8000;
2036       *q-- = 0;
2037       *q-- = 0;
2038       *q = 0;
2039       return;
2040     }
2041 #endif /* IBMPC */
2042 #endif /* USE_INFINITY */
2043   for (i = 0; i < 4; i++)
2044     *q-- = *p++;
2045 #endif
2046 }
2047 
2048 #endif /* LDBL_MANT_DIG == 64 */
2049 
2050 #if LDBL_MANT_DIG == 53
2051 /*
2052 ; Convert IEEE double precision to e type
2053 ;	double d;
2054 ;	unsigned short x[N+2];
2055 ;	e53toe( &d, x );
2056 */
2057 static void
e53toe(short unsigned int * pe,short unsigned int * y,LDPARMS * ldp)2058 e53toe (short unsigned int *pe, short unsigned int *y, LDPARMS * ldp)
2059 {
2060 #ifdef DEC
2061 
2062   dectoe (pe, y);		/* see etodec.c */
2063 
2064 #else
2065 
2066   register unsigned short r;
2067   register unsigned short *p, *e;
2068   unsigned short yy[NI];
2069   int denorm, k;
2070 
2071   e = pe;
2072   denorm = 0;			/* flag if denormalized number */
2073   ecleaz (yy);
2074 #ifdef IBMPC
2075   e += 3;
2076 #endif
2077 #ifdef DEC
2078   e += 3;
2079 #endif
2080   r = *e;
2081   yy[0] = 0;
2082   if (r & 0x8000)
2083     yy[0] = 0xffff;
2084   yy[M] = (r & 0x0f) | 0x10;
2085   r &= ~0x800f;			/* strip sign and 4 significand bits */
2086 #ifdef USE_INFINITY
2087   if (r == 0x7ff0)
2088     {
2089 #ifdef NANS
2090 #ifdef IBMPC
2091       if (((pe[3] & 0xf) != 0) || (pe[2] != 0)
2092 	  || (pe[1] != 0) || (pe[0] != 0))
2093 	{
2094 	  enan (y, NBITS);
2095 	  return;
2096 	}
2097 #else /* !IBMPC */
2098       if (((pe[0] & 0xf) != 0) || (pe[1] != 0)
2099 	  || (pe[2] != 0) || (pe[3] != 0))
2100 	{
2101 	  enan (y, NBITS);
2102 	  return;
2103 	}
2104 #endif /* !IBMPC */
2105 #endif /* NANS */
2106       eclear (y);
2107       einfin (y, ldp);
2108       if (yy[0])
2109 	eneg (y);
2110       return;
2111     }
2112 #endif
2113   r >>= 4;
2114 /* If zero exponent, then the significand is denormalized.
2115  * So, take back the understood high significand bit. */
2116   if (r == 0)
2117     {
2118       denorm = 1;
2119       yy[M] &= ~0x10;
2120     }
2121   r += EXONE - 01777;
2122   yy[E] = r;
2123   p = &yy[M + 1];
2124 #ifdef IBMPC
2125   *p++ = *(--e);
2126   *p++ = *(--e);
2127   *p++ = *(--e);
2128 #else /* !IBMPC */
2129   ++e;
2130   *p++ = *e++;
2131   *p++ = *e++;
2132   *p++ = *e++;
2133 #endif /* !IBMPC */
2134   (void) eshift (yy, -5);
2135   if (denorm)
2136     {				/* if zero exponent, then normalize the significand */
2137       if ((k = enormlz (yy)) > NBITS)
2138 	ecleazs (yy);
2139       else
2140 	yy[E] -= (unsigned short) (k - 1);
2141     }
2142   emovo (yy, y, ldp);
2143 #endif /* !DEC */
2144 }
2145 
2146 /*
2147 ; e type to IEEE double precision
2148 ;	double d;
2149 ;	unsigned short x[NE];
2150 ;	etoe53( x, &d );
2151 */
2152 
2153 #ifdef DEC
2154 
2155 static void
etoe53(x,e)2156 etoe53 (x, e)
2157      unsigned short *x, *e;
2158 {
2159   etodec (x, e);		/* see etodec.c */
2160 }
2161 
2162 static void
2163 __attribute__ ((__unused__))
toe53(x,y)2164 toe53 (x, y)
2165      unsigned short *x, *y;
2166 {
2167   todec (x, y);
2168 }
2169 
2170 #else
2171 
2172 static void
2173 __attribute__ ((__unused__))
toe53(short unsigned int * x,short unsigned int * y)2174 toe53 (short unsigned int *x, short unsigned int *y)
2175 {
2176   unsigned short i;
2177   unsigned short *p;
2178 
2179 
2180 #ifdef NANS
2181   if (eiisnan (x))
2182     {
2183       enan (y, 53);
2184       return;
2185     }
2186 #endif
2187   p = &x[0];
2188 #ifdef IBMPC
2189   y += 3;
2190 #endif
2191 #ifdef DEC
2192   y += 3;
2193 #endif
2194   *y = 0;			/* output high order */
2195   if (*p++)
2196     *y = 0x8000;		/* output sign bit */
2197 
2198   i = *p++;
2199   if (i >= (unsigned int) 2047)
2200     {				/* Saturate at largest number less than infinity. */
2201 #ifdef USE_INFINITY
2202       *y |= 0x7ff0;
2203 #ifdef IBMPC
2204       *(--y) = 0;
2205       *(--y) = 0;
2206       *(--y) = 0;
2207 #else /* !IBMPC */
2208       ++y;
2209       *y++ = 0;
2210       *y++ = 0;
2211       *y++ = 0;
2212 #endif /* IBMPC */
2213 #else /* !USE_INFINITY */
2214       *y |= (unsigned short) 0x7fef;
2215 #ifdef IBMPC
2216       *(--y) = 0xffff;
2217       *(--y) = 0xffff;
2218       *(--y) = 0xffff;
2219 #else /* !IBMPC */
2220       ++y;
2221       *y++ = 0xffff;
2222       *y++ = 0xffff;
2223       *y++ = 0xffff;
2224 #endif
2225 #endif /* !USE_INFINITY */
2226       return;
2227     }
2228   if (i == 0)
2229     {
2230       (void) eshift (x, 4);
2231     }
2232   else
2233     {
2234       i <<= 4;
2235       (void) eshift (x, 5);
2236     }
2237   i |= *p++ & (unsigned short) 0x0f;	/* *p = xi[M] */
2238   *y |= (unsigned short) i;	/* high order output already has sign bit set */
2239 #ifdef IBMPC
2240   *(--y) = *p++;
2241   *(--y) = *p++;
2242   *(--y) = *p;
2243 #else /* !IBMPC */
2244   ++y;
2245   *y++ = *p++;
2246   *y++ = *p++;
2247   *y++ = *p++;
2248 #endif /* !IBMPC */
2249 }
2250 
2251 #endif /* not DEC */
2252 #endif /* LDBL_MANT_DIG == 53 */
2253 
2254 #if LDBL_MANT_DIG == 24
2255 /*
2256 ; Convert IEEE single precision to e type
2257 ;	float d;
2258 ;	unsigned short x[N+2];
2259 ;	dtox( &d, x );
2260 */
2261 void
e24toe(short unsigned int * pe,short unsigned int * y,LDPARMS * ldp)2262 e24toe (short unsigned int *pe, short unsigned int *y, LDPARMS * ldp)
2263 {
2264   register unsigned short r;
2265   register unsigned short *p, *e;
2266   unsigned short yy[NI];
2267   int denorm, k;
2268 
2269   e = pe;
2270   denorm = 0;			/* flag if denormalized number */
2271   ecleaz (yy);
2272 #ifdef IBMPC
2273   e += 1;
2274 #endif
2275 #ifdef DEC
2276   e += 1;
2277 #endif
2278   r = *e;
2279   yy[0] = 0;
2280   if (r & 0x8000)
2281     yy[0] = 0xffff;
2282   yy[M] = (r & 0x7f) | 0200;
2283   r &= ~0x807f;			/* strip sign and 7 significand bits */
2284 #ifdef USE_INFINITY
2285   if (r == 0x7f80)
2286     {
2287 #ifdef NANS
2288 #ifdef MIEEE
2289       if (((pe[0] & 0x7f) != 0) || (pe[1] != 0))
2290 	{
2291 	  enan (y, NBITS);
2292 	  return;
2293 	}
2294 #else /* !MIEEE */
2295       if (((pe[1] & 0x7f) != 0) || (pe[0] != 0))
2296 	{
2297 	  enan (y, NBITS);
2298 	  return;
2299 	}
2300 #endif /* !MIEEE */
2301 #endif /* NANS */
2302       eclear (y);
2303       einfin (y, ldp);
2304       if (yy[0])
2305 	eneg (y);
2306       return;
2307     }
2308 #endif
2309   r >>= 7;
2310 /* If zero exponent, then the significand is denormalized.
2311  * So, take back the understood high significand bit. */
2312   if (r == 0)
2313     {
2314       denorm = 1;
2315       yy[M] &= ~0200;
2316     }
2317   r += EXONE - 0177;
2318   yy[E] = r;
2319   p = &yy[M + 1];
2320 #ifdef IBMPC
2321   *p++ = *(--e);
2322 #endif
2323 #ifdef DEC
2324   *p++ = *(--e);
2325 #endif
2326 #ifdef MIEEE
2327   ++e;
2328   *p++ = *e++;
2329 #endif
2330   (void) eshift (yy, -8);
2331   if (denorm)
2332     {				/* if zero exponent, then normalize the significand */
2333       if ((k = enormlz (yy)) > NBITS)
2334 	ecleazs (yy);
2335       else
2336 	yy[E] -= (unsigned short) (k - 1);
2337     }
2338   emovo (yy, y, ldp);
2339 }
2340 
2341 static void
2342 __attribute__ ((__unused__))
toe24(short unsigned int * x,short unsigned int * y)2343 toe24 (short unsigned int *x, short unsigned int *y)
2344 {
2345   unsigned short i;
2346   unsigned short *p;
2347 
2348 #ifdef NANS
2349   if (eiisnan (x))
2350     {
2351       enan (y, 24);
2352       return;
2353     }
2354 #endif
2355   p = &x[0];
2356 #ifdef IBMPC
2357   y += 1;
2358 #endif
2359 #ifdef DEC
2360   y += 1;
2361 #endif
2362   *y = 0;			/* output high order */
2363   if (*p++)
2364     *y = 0x8000;		/* output sign bit */
2365 
2366   i = *p++;
2367   if (i >= 255)
2368     {				/* Saturate at largest number less than infinity. */
2369 #ifdef USE_INFINITY
2370       *y |= (unsigned short) 0x7f80;
2371 #ifdef IBMPC
2372       *(--y) = 0;
2373 #endif
2374 #ifdef DEC
2375       *(--y) = 0;
2376 #endif
2377 #ifdef MIEEE
2378       ++y;
2379       *y = 0;
2380 #endif
2381 #else /* !USE_INFINITY */
2382       *y |= (unsigned short) 0x7f7f;
2383 #ifdef IBMPC
2384       *(--y) = 0xffff;
2385 #endif
2386 #ifdef DEC
2387       *(--y) = 0xffff;
2388 #endif
2389 #ifdef MIEEE
2390       ++y;
2391       *y = 0xffff;
2392 #endif
2393 #endif /* !USE_INFINITY */
2394       return;
2395     }
2396   if (i == 0)
2397     {
2398       (void) eshift (x, 7);
2399     }
2400   else
2401     {
2402       i <<= 7;
2403       (void) eshift (x, 8);
2404     }
2405   i |= *p++ & (unsigned short) 0x7f;	/* *p = xi[M] */
2406   *y |= i;			/* high order output already has sign bit set */
2407 #ifdef IBMPC
2408   *(--y) = *p;
2409 #endif
2410 #ifdef DEC
2411   *(--y) = *p;
2412 #endif
2413 #ifdef MIEEE
2414   ++y;
2415   *y = *p;
2416 #endif
2417 }
2418 #endif /* LDBL_MANT_DIG == 24 */
2419 
2420 /* Compare two e type numbers.
2421  *
2422  * unsigned short a[NE], b[NE];
2423  * ecmp( a, b );
2424  *
2425  *  returns +1 if a > b
2426  *           0 if a == b
2427  *          -1 if a < b
2428  *          -2 if either a or b is a NaN.
2429  */
2430 static int
ecmp(const short unsigned int * a,const short unsigned int * b)2431 ecmp (const short unsigned int *a, const short unsigned int *b)
2432 {
2433   unsigned short ai[NI], bi[NI];
2434   register unsigned short *p, *q;
2435   register int i;
2436   int msign;
2437 
2438 #ifdef NANS
2439   if (eisnan (a) || eisnan (b))
2440     return (-2);
2441 #endif
2442   emovi (a, ai);
2443   p = ai;
2444   emovi (b, bi);
2445   q = bi;
2446 
2447   if (*p != *q)
2448     {				/* the signs are different */
2449 /* -0 equals + 0 */
2450       for (i = 1; i < NI - 1; i++)
2451 	{
2452 	  if (ai[i] != 0)
2453 	    goto nzro;
2454 	  if (bi[i] != 0)
2455 	    goto nzro;
2456 	}
2457       return (0);
2458     nzro:
2459       if (*p == 0)
2460 	return (1);
2461       else
2462 	return (-1);
2463     }
2464 /* both are the same sign */
2465   if (*p == 0)
2466     msign = 1;
2467   else
2468     msign = -1;
2469   i = NI - 1;
2470   do
2471     {
2472       if (*p++ != *q++)
2473 	{
2474 	  goto diff;
2475 	}
2476     }
2477   while (--i > 0);
2478 
2479   return (0);			/* equality */
2480 
2481 
2482 
2483 diff:
2484 
2485   if (*(--p) > *(--q))
2486     return (msign);		/* p is bigger */
2487   else
2488     return (-msign);		/* p is littler */
2489 }
2490 
2491 
2492 /*
2493 ;	Shift significand
2494 ;
2495 ;	Shifts significand area up or down by the number of bits
2496 ;	given by the variable sc.
2497 */
2498 static int
eshift(short unsigned int * x,int sc)2499 eshift (short unsigned int *x, int sc)
2500 {
2501   unsigned short lost;
2502   unsigned short *p;
2503 
2504   if (sc == 0)
2505     return (0);
2506 
2507   lost = 0;
2508   p = x + NI - 1;
2509 
2510   if (sc < 0)
2511     {
2512       sc = -sc;
2513       while (sc >= 16)
2514 	{
2515 	  lost |= *p;		/* remember lost bits */
2516 	  eshdn6 (x);
2517 	  sc -= 16;
2518 	}
2519 
2520       while (sc >= 8)
2521 	{
2522 	  lost |= *p & 0xff;
2523 	  eshdn8 (x);
2524 	  sc -= 8;
2525 	}
2526 
2527       while (sc > 0)
2528 	{
2529 	  lost |= *p & 1;
2530 	  eshdn1 (x);
2531 	  sc -= 1;
2532 	}
2533     }
2534   else
2535     {
2536       while (sc >= 16)
2537 	{
2538 	  eshup6 (x);
2539 	  sc -= 16;
2540 	}
2541 
2542       while (sc >= 8)
2543 	{
2544 	  eshup8 (x);
2545 	  sc -= 8;
2546 	}
2547 
2548       while (sc > 0)
2549 	{
2550 	  eshup1 (x);
2551 	  sc -= 1;
2552 	}
2553     }
2554   if (lost)
2555     lost = 1;
2556   return ((int) lost);
2557 }
2558 
2559 
2560 
2561 /*
2562 ;	normalize
2563 ;
2564 ; Shift normalizes the significand area pointed to by argument
2565 ; shift count (up = positive) is returned.
2566 */
2567 static int
enormlz(short unsigned int * x)2568 enormlz (short unsigned int *x)
2569 {
2570   register unsigned short *p;
2571   int sc;
2572 
2573   sc = 0;
2574   p = &x[M];
2575   if (*p != 0)
2576     goto normdn;
2577   ++p;
2578   if (*p & 0x8000)
2579     return (0);			/* already normalized */
2580   while (*p == 0)
2581     {
2582       eshup6 (x);
2583       sc += 16;
2584 /* With guard word, there are NBITS+16 bits available.
2585  * return true if all are zero.
2586  */
2587       if (sc > NBITS)
2588 	return (sc);
2589     }
2590 /* see if high byte is zero */
2591   while ((*p & 0xff00) == 0)
2592     {
2593       eshup8 (x);
2594       sc += 8;
2595     }
2596 /* now shift 1 bit at a time */
2597   while ((*p & 0x8000) == 0)
2598     {
2599       eshup1 (x);
2600       sc += 1;
2601       if (sc > (NBITS + 16))
2602 	{
2603 	  mtherr ("enormlz", UNDERFLOW);
2604 	  return (sc);
2605 	}
2606     }
2607   return (sc);
2608 
2609 /* Normalize by shifting down out of the high guard word
2610    of the significand */
2611 normdn:
2612 
2613   if (*p & 0xff00)
2614     {
2615       eshdn8 (x);
2616       sc -= 8;
2617     }
2618   while (*p != 0)
2619     {
2620       eshdn1 (x);
2621       sc -= 1;
2622 
2623       if (sc < -NBITS)
2624 	{
2625 	  mtherr ("enormlz", OVERFLOW);
2626 	  return (sc);
2627 	}
2628     }
2629   return (sc);
2630 }
2631 
2632 
2633 
2634 
2635 /* Convert e type number to decimal format ASCII string.
2636  * The constants are for 64 bit precision.
2637  */
2638 
2639 #define NTEN 12
2640 #define MAXP 4096
2641 
2642 #if NE == 10
2643 static const unsigned short etens[NTEN + 1][NE] = {
2644   {0x6576, 0x4a92, 0x804a, 0x153f,
2645    0xc94c, 0x979a, 0x8a20, 0x5202, 0xc460, 0x7525,},	/* 10**4096 */
2646   {0x6a32, 0xce52, 0x329a, 0x28ce,
2647    0xa74d, 0x5de4, 0xc53d, 0x3b5d, 0x9e8b, 0x5a92,},	/* 10**2048 */
2648   {0x526c, 0x50ce, 0xf18b, 0x3d28,
2649    0x650d, 0x0c17, 0x8175, 0x7586, 0xc976, 0x4d48,},
2650   {0x9c66, 0x58f8, 0xbc50, 0x5c54,
2651    0xcc65, 0x91c6, 0xa60e, 0xa0ae, 0xe319, 0x46a3,},
2652   {0x851e, 0xeab7, 0x98fe, 0x901b,
2653    0xddbb, 0xde8d, 0x9df9, 0xebfb, 0xaa7e, 0x4351,},
2654   {0x0235, 0x0137, 0x36b1, 0x336c,
2655    0xc66f, 0x8cdf, 0x80e9, 0x47c9, 0x93ba, 0x41a8,},
2656   {0x50f8, 0x25fb, 0xc76b, 0x6b71,
2657    0x3cbf, 0xa6d5, 0xffcf, 0x1f49, 0xc278, 0x40d3,},
2658   {0x0000, 0x0000, 0x0000, 0x0000,
2659    0xf020, 0xb59d, 0x2b70, 0xada8, 0x9dc5, 0x4069,},
2660   {0x0000, 0x0000, 0x0000, 0x0000,
2661    0x0000, 0x0000, 0x0400, 0xc9bf, 0x8e1b, 0x4034,},
2662   {0x0000, 0x0000, 0x0000, 0x0000,
2663    0x0000, 0x0000, 0x0000, 0x2000, 0xbebc, 0x4019,},
2664   {0x0000, 0x0000, 0x0000, 0x0000,
2665    0x0000, 0x0000, 0x0000, 0x0000, 0x9c40, 0x400c,},
2666   {0x0000, 0x0000, 0x0000, 0x0000,
2667    0x0000, 0x0000, 0x0000, 0x0000, 0xc800, 0x4005,},
2668   {0x0000, 0x0000, 0x0000, 0x0000,
2669    0x0000, 0x0000, 0x0000, 0x0000, 0xa000, 0x4002,},	/* 10**1 */
2670 };
2671 
2672 static const unsigned short emtens[NTEN + 1][NE] = {
2673   {0x2030, 0xcffc, 0xa1c3, 0x8123,
2674    0x2de3, 0x9fde, 0xd2ce, 0x04c8, 0xa6dd, 0x0ad8,},	/* 10**-4096 */
2675   {0x8264, 0xd2cb, 0xf2ea, 0x12d4,
2676    0x4925, 0x2de4, 0x3436, 0x534f, 0xceae, 0x256b,},	/* 10**-2048 */
2677   {0xf53f, 0xf698, 0x6bd3, 0x0158,
2678    0x87a6, 0xc0bd, 0xda57, 0x82a5, 0xa2a6, 0x32b5,},
2679   {0xe731, 0x04d4, 0xe3f2, 0xd332,
2680    0x7132, 0xd21c, 0xdb23, 0xee32, 0x9049, 0x395a,},
2681   {0xa23e, 0x5308, 0xfefb, 0x1155,
2682    0xfa91, 0x1939, 0x637a, 0x4325, 0xc031, 0x3cac,},
2683   {0xe26d, 0xdbde, 0xd05d, 0xb3f6,
2684    0xac7c, 0xe4a0, 0x64bc, 0x467c, 0xddd0, 0x3e55,},
2685   {0x2a20, 0x6224, 0x47b3, 0x98d7,
2686    0x3f23, 0xe9a5, 0xa539, 0xea27, 0xa87f, 0x3f2a,},
2687   {0x0b5b, 0x4af2, 0xa581, 0x18ed,
2688    0x67de, 0x94ba, 0x4539, 0x1ead, 0xcfb1, 0x3f94,},
2689   {0xbf71, 0xa9b3, 0x7989, 0xbe68,
2690    0x4c2e, 0xe15b, 0xc44d, 0x94be, 0xe695, 0x3fc9,},
2691   {0x3d4d, 0x7c3d, 0x36ba, 0x0d2b,
2692    0xfdc2, 0xcefc, 0x8461, 0x7711, 0xabcc, 0x3fe4,},
2693   {0xc155, 0xa4a8, 0x404e, 0x6113,
2694    0xd3c3, 0x652b, 0xe219, 0x1758, 0xd1b7, 0x3ff1,},
2695   {0xd70a, 0x70a3, 0x0a3d, 0xa3d7,
2696    0x3d70, 0xd70a, 0x70a3, 0x0a3d, 0xa3d7, 0x3ff8,},
2697   {0xcccd, 0xcccc, 0xcccc, 0xcccc,
2698    0xcccc, 0xcccc, 0xcccc, 0xcccc, 0xcccc, 0x3ffb,},	/* 10**-1 */
2699 };
2700 #else
2701 static const unsigned short etens[NTEN + 1][NE] = {
2702   {0xc94c, 0x979a, 0x8a20, 0x5202, 0xc460, 0x7525,},	/* 10**4096 */
2703   {0xa74d, 0x5de4, 0xc53d, 0x3b5d, 0x9e8b, 0x5a92,},	/* 10**2048 */
2704   {0x650d, 0x0c17, 0x8175, 0x7586, 0xc976, 0x4d48,},
2705   {0xcc65, 0x91c6, 0xa60e, 0xa0ae, 0xe319, 0x46a3,},
2706   {0xddbc, 0xde8d, 0x9df9, 0xebfb, 0xaa7e, 0x4351,},
2707   {0xc66f, 0x8cdf, 0x80e9, 0x47c9, 0x93ba, 0x41a8,},
2708   {0x3cbf, 0xa6d5, 0xffcf, 0x1f49, 0xc278, 0x40d3,},
2709   {0xf020, 0xb59d, 0x2b70, 0xada8, 0x9dc5, 0x4069,},
2710   {0x0000, 0x0000, 0x0400, 0xc9bf, 0x8e1b, 0x4034,},
2711   {0x0000, 0x0000, 0x0000, 0x2000, 0xbebc, 0x4019,},
2712   {0x0000, 0x0000, 0x0000, 0x0000, 0x9c40, 0x400c,},
2713   {0x0000, 0x0000, 0x0000, 0x0000, 0xc800, 0x4005,},
2714   {0x0000, 0x0000, 0x0000, 0x0000, 0xa000, 0x4002,},	/* 10**1 */
2715 };
2716 
2717 static const unsigned short emtens[NTEN + 1][NE] = {
2718   {0x2de4, 0x9fde, 0xd2ce, 0x04c8, 0xa6dd, 0x0ad8,},	/* 10**-4096 */
2719   {0x4925, 0x2de4, 0x3436, 0x534f, 0xceae, 0x256b,},	/* 10**-2048 */
2720   {0x87a6, 0xc0bd, 0xda57, 0x82a5, 0xa2a6, 0x32b5,},
2721   {0x7133, 0xd21c, 0xdb23, 0xee32, 0x9049, 0x395a,},
2722   {0xfa91, 0x1939, 0x637a, 0x4325, 0xc031, 0x3cac,},
2723   {0xac7d, 0xe4a0, 0x64bc, 0x467c, 0xddd0, 0x3e55,},
2724   {0x3f24, 0xe9a5, 0xa539, 0xea27, 0xa87f, 0x3f2a,},
2725   {0x67de, 0x94ba, 0x4539, 0x1ead, 0xcfb1, 0x3f94,},
2726   {0x4c2f, 0xe15b, 0xc44d, 0x94be, 0xe695, 0x3fc9,},
2727   {0xfdc2, 0xcefc, 0x8461, 0x7711, 0xabcc, 0x3fe4,},
2728   {0xd3c3, 0x652b, 0xe219, 0x1758, 0xd1b7, 0x3ff1,},
2729   {0x3d71, 0xd70a, 0x70a3, 0x0a3d, 0xa3d7, 0x3ff8,},
2730   {0xcccd, 0xcccc, 0xcccc, 0xcccc, 0xcccc, 0x3ffb,},	/* 10**-1 */
2731 };
2732 #endif
2733 
2734 
2735 
2736 /* ASCII string outputs for unix */
2737 
2738 
2739 #if 0
2740 void
2741 _IO_ldtostr (x, string, ndigs, flags, fmt)
2742      long double *x;
2743      char *string;
2744      int ndigs;
2745      int flags;
2746      char fmt;
2747 {
2748   unsigned short w[NI];
2749   char *t, *u;
2750   LDPARMS rnd;
2751   LDPARMS *ldp = &rnd;
2752 
2753   rnd.rlast = -1;
2754   rnd.rndprc = NBITS;
2755 
2756   if (sizeof (long double) == 16)
2757     e113toe ((unsigned short *) x, w, ldp);
2758   else
2759     e64toe ((unsigned short *) x, w, ldp);
2760 
2761   etoasc (w, string, ndigs, -1, ldp);
2762   if (ndigs == 0 && flags == 0)
2763     {
2764       /* Delete the decimal point unless alternate format.  */
2765       t = string;
2766       while (*t != '.')
2767 	++t;
2768       u = t + 1;
2769       while (*t != '\0')
2770 	*t++ = *u++;
2771     }
2772   if (*string == ' ')
2773     {
2774       t = string;
2775       u = t + 1;
2776       while (*t != '\0')
2777 	*t++ = *u++;
2778     }
2779   if (fmt == 'E')
2780     {
2781       t = string;
2782       while (*t != 'e')
2783 	++t;
2784       *t = 'E';
2785     }
2786 }
2787 
2788 #endif
2789 
2790 /* This routine will not return more than NDEC+1 digits. */
2791 
2792 char *
__ldtoa(long double d,int mode,int ndigits,int * decpt,int * sign,char ** rve)2793 __ldtoa (long double d, int mode, int ndigits,
2794        int *decpt, int *sign, char **rve)
2795 {
2796   unsigned short e[NI];
2797   char *s, *p;
2798   int i, k;
2799   int orig_ndigits;
2800   LDPARMS rnd;
2801   LDPARMS *ldp = &rnd;
2802   char *outstr;
2803   char outbuf_sml[NDEC_SML + MAX_EXP_DIGITS + 10];
2804   char *outbuf = outbuf_sml;
2805   union uconv du;
2806   du.d = d;
2807 
2808   orig_ndigits = ndigits;
2809   rnd.rlast = -1;
2810   rnd.rndprc = NBITS;
2811 
2812 #if LDBL_MANT_DIG == 24
2813   e24toe (&du.pe, e, ldp);
2814 #elif LDBL_MANT_DIG == 53
2815   e53toe (&du.pe, e, ldp);
2816 #elif LDBL_MANT_DIG == 64
2817   e64toe (&du.pe, e, ldp);
2818 #else
2819   e113toe (&du.pe, e, ldp);
2820 #endif
2821 
2822   if (eisneg (e))
2823     *sign = 1;
2824   else
2825     *sign = 0;
2826 /* Mode 3 is "f" format.  */
2827   if (mode != 3)
2828     ndigits -= 1;
2829 /* Mode 0 is for %.999 format, which is supposed to give a
2830    minimum length string that will convert back to the same binary value.
2831    For now, just ask for 20 digits which is enough but sometimes too many.  */
2832   if (mode == 0)
2833     ndigits = 20;
2834 
2835 /* This sanity limit must agree with the corresponding one in etoasc, to
2836    keep straight the returned value of outexpon.  Note that we use a dynamic
2837    limit now, either ndec (<= NDEC) or NDEC_SML, depending on ndigits. */
2838   __int32_t ndec;
2839   if (mode == 3) /* %f */
2840     {
2841       __int32_t expon = (e[NE - 1] & 0x7fff) - (EXONE - 1); /* exponent part */
2842       /* log2(10) approximately 485/146 */
2843       ndec = expon * 146 / 485 + ndigits;
2844     }
2845   else /* %g/%e */
2846     ndec = ndigits;
2847   if (ndec < 0)
2848     ndec = 0;
2849   if (ndec > NDEC)
2850     ndec = NDEC;
2851 
2852   /* Allocate buffer if more than NDEC_SML digits are requested. */
2853   if (ndec > NDEC_SML)
2854     {
2855       outbuf = (char *) malloc (ndec + MAX_EXP_DIGITS + 10);
2856       if (!outbuf)
2857 	{
2858 	  ndec = NDEC_SML;
2859 	  outbuf = outbuf_sml;
2860 	}
2861     }
2862 
2863   etoasc (e, outbuf, (int) ndec, ndigits, mode, ldp);
2864   s = outbuf;
2865   if (eisinf (e) || eisnan (e))
2866     {
2867       *decpt = 9999;
2868       goto stripspaces;
2869     }
2870   *decpt = ldp->outexpon + 1;
2871 
2872 /* Transform the string returned by etoasc into what the caller wants.  */
2873 
2874 /* Look for decimal point and delete it from the string. */
2875   s = outbuf;
2876   while (*s != '\0')
2877     {
2878       if (*s == '.')
2879 	goto yesdecpt;
2880       ++s;
2881     }
2882   goto nodecpt;
2883 
2884 yesdecpt:
2885 
2886 /* Delete the decimal point.  */
2887   while (*s != '\0')
2888     {
2889       *s = *(s + 1);
2890       ++s;
2891     }
2892 
2893 nodecpt:
2894 
2895 /* Back up over the exponent field. */
2896   while (*s != 'E' && s > outbuf)
2897     --s;
2898   *s = '\0';
2899 
2900 stripspaces:
2901 
2902 /* Strip leading spaces and sign. */
2903   p = outbuf;
2904   while (*p == ' ' || *p == '-')
2905     ++p;
2906 
2907 /* Find new end of string.  */
2908   s = outbuf;
2909   while ((*s++ = *p++) != '\0')
2910     ;
2911   --s;
2912 
2913 /* Strip trailing zeros.  */
2914   if (mode == 2)
2915     k = 1;
2916   else if (ndigits > ldp->outexpon)
2917     k = ndigits;
2918   else
2919     k = ldp->outexpon;
2920 
2921   while (*(s - 1) == '0' && ((s - outbuf) > k))
2922     *(--s) = '\0';
2923 
2924 /* In f format, flush small off-scale values to zero.
2925    Rounding has been taken care of by etoasc. */
2926   if (mode == 3 && ((ndigits + ldp->outexpon) < 0))
2927     {
2928       s = outbuf;
2929       *s = '\0';
2930       *decpt = 0;
2931     }
2932 
2933 /* we want to have enough space to hold the formatted result */
2934 
2935   if (mode == 3)		/* f format, account for sign + dec digits + decpt + frac */
2936     i = *decpt + orig_ndigits + 3;
2937   else				/* account for sign + max precision digs + E + exp sign + exponent */
2938     i = orig_ndigits + MAX_EXP_DIGITS + 4;
2939 
2940   outstr = __alloc_dtoa_result(i);
2941   if (!outstr)
2942     return NULL;
2943 
2944 /* Copy from internal temporary buffer to permanent buffer.  */
2945   strcpy (outstr, outbuf);
2946 
2947   if (rve)
2948     *rve = outstr + (s - outbuf);
2949 
2950   if (outbuf != outbuf_sml)
2951     free (outbuf);
2952 
2953   return outstr;
2954 }
2955 
2956 /* Routine used to tell if long double is NaN or Infinity or regular number.
2957    Returns:  0 = regular number
2958              1 = Nan
2959              2 = Infinity
2960 */
2961 int
_ldcheck(long double * d)2962 _ldcheck (long double *d)
2963 {
2964   unsigned short e[NI];
2965   LDPARMS rnd;
2966   LDPARMS *ldp = &rnd;
2967 
2968   union uconv du;
2969 
2970   rnd.rlast = -1;
2971   rnd.rndprc = NBITS;
2972   du.d = *d;
2973 #if LDBL_MANT_DIG == 24
2974   e24toe (&du.pe, e, ldp);
2975 #elif LDBL_MANT_DIG == 53
2976   e53toe (&du.pe, e, ldp);
2977 #elif LDBL_MANT_DIG == 64
2978   e64toe (&du.pe, e, ldp);
2979 #else
2980   e113toe (&du.pe, e, ldp);
2981 #endif
2982 
2983   if ((e[NE - 1] & 0x7fff) == 0x7fff)
2984     {
2985 #ifdef NANS
2986       if (eisnan (e))
2987 	return (1);
2988 #endif
2989       return (2);
2990     }
2991   else
2992     return (0);
2993 }				/* _ldcheck */
2994 
2995 static void
etoasc(short unsigned int * x,char * string,int ndec,int ndigits,int outformat,LDPARMS * ldp)2996 etoasc (short unsigned int *x, char *string, int ndec, int ndigits,
2997 	int outformat, LDPARMS * ldp)
2998 {
2999   long digit;
3000   unsigned short y[NI], t[NI], u[NI], w[NI];
3001   const unsigned short *p, *r, *ten;
3002   unsigned short sign;
3003   int i, j, k, expon, rndsav, ndigs;
3004   char *s, *ss;
3005   unsigned short m;
3006   unsigned short *equot = ldp->equot;
3007 
3008   ndigs = ndigits;
3009   rndsav = ldp->rndprc;
3010 #ifdef NANS
3011   if (eisnan (x))
3012     {
3013       sprintf (string, " NaN ");
3014       expon = 9999;
3015       goto bxit;
3016     }
3017 #endif
3018   ldp->rndprc = NBITS;		/* set to full precision */
3019   emov (x, y);			/* retain external format */
3020   if (y[NE - 1] & 0x8000)
3021     {
3022       sign = 0xffff;
3023       y[NE - 1] &= 0x7fff;
3024     }
3025   else
3026     {
3027       sign = 0;
3028     }
3029   expon = 0;
3030   ten = &etens[NTEN][0];
3031   emov (eone, t);
3032 /* Test for zero exponent */
3033   if (y[NE - 1] == 0)
3034     {
3035       for (k = 0; k < NE - 1; k++)
3036 	{
3037 	  if (y[k] != 0)
3038 	    goto tnzro;		/* denormalized number */
3039 	}
3040       goto isone;		/* legal all zeros */
3041     }
3042 tnzro:
3043 
3044 /* Test for infinity.
3045  */
3046   if (y[NE - 1] == 0x7fff)
3047     {
3048       if (sign)
3049 	sprintf (string, " -Infinity ");
3050       else
3051 	sprintf (string, " Infinity ");
3052       expon = 9999;
3053       goto bxit;
3054     }
3055 
3056 /* Test for exponent nonzero but significand denormalized.
3057  * This is an error condition.
3058  */
3059   if ((y[NE - 1] != 0) && ((y[NE - 2] & 0x8000) == 0))
3060     {
3061       mtherr ("etoasc", DOMAIN);
3062       sprintf (string, "NaN");
3063       expon = 9999;
3064       goto bxit;
3065     }
3066 
3067 /* Compare to 1.0 */
3068   i = ecmp (eone, y);
3069   if (i == 0)
3070     goto isone;
3071 
3072   if (i < 0)
3073     {				/* Number is greater than 1 */
3074 /* Convert significand to an integer and strip trailing decimal zeros. */
3075       emov (y, u);
3076       u[NE - 1] = EXONE + NBITS - 1;
3077 
3078       p = &etens[NTEN - 4][0];
3079       m = 16;
3080       do
3081 	{
3082 	  ediv (p, u, t, ldp);
3083 	  efloor (t, w, ldp);
3084 	  for (j = 0; j < NE - 1; j++)
3085 	    {
3086 	      if (t[j] != w[j])
3087 		goto noint;
3088 	    }
3089 	  emov (t, u);
3090 	  expon += (int) m;
3091 	noint:
3092 	  p += NE;
3093 	  m >>= 1;
3094 	}
3095       while (m != 0);
3096 
3097 /* Rescale from integer significand */
3098       u[NE - 1] += y[NE - 1] - (unsigned int) (EXONE + NBITS - 1);
3099       emov (u, y);
3100 /* Find power of 10 */
3101       emov (eone, t);
3102       m = MAXP;
3103       p = &etens[0][0];
3104       while (ecmp (ten, u) <= 0)
3105 	{
3106 	  if (ecmp (p, u) <= 0)
3107 	    {
3108 	      ediv (p, u, u, ldp);
3109 	      emul (p, t, t, ldp);
3110 	      expon += (int) m;
3111 	    }
3112 	  m >>= 1;
3113 	  if (m == 0)
3114 	    break;
3115 	  p += NE;
3116 	}
3117     }
3118   else
3119     {				/* Number is less than 1.0 */
3120 /* Pad significand with trailing decimal zeros. */
3121       if (y[NE - 1] == 0)
3122 	{
3123 	  while ((y[NE - 2] & 0x8000) == 0)
3124 	    {
3125 	      emul (ten, y, y, ldp);
3126 	      expon -= 1;
3127 	    }
3128 	}
3129       else
3130 	{
3131 	  emovi (y, w);
3132 	  for (i = 0; i < ndec + 1; i++)
3133 	    {
3134 	      if ((w[NI - 1] & 0x7) != 0)
3135 		break;
3136 /* multiply by 10 */
3137 	      emovz (w, u);
3138 	      eshdn1 (u);
3139 	      eshdn1 (u);
3140 	      eaddm (w, u);
3141 	      u[1] += 3;
3142 	      while (u[2] != 0)
3143 		{
3144 		  eshdn1 (u);
3145 		  u[1] += 1;
3146 		}
3147 	      if (u[NI - 1] != 0)
3148 		break;
3149 	      if (eone[NE - 1] <= u[1])
3150 		break;
3151 	      emovz (u, w);
3152 	      expon -= 1;
3153 	    }
3154 	  emovo (w, y, ldp);
3155 	}
3156       k = -MAXP;
3157       p = &emtens[0][0];
3158       r = &etens[0][0];
3159       emov (y, w);
3160       emov (eone, t);
3161       while (ecmp (eone, w) > 0)
3162 	{
3163 	  if (ecmp (p, w) >= 0)
3164 	    {
3165 	      emul (r, w, w, ldp);
3166 	      emul (r, t, t, ldp);
3167 	      expon += k;
3168 	    }
3169 	  k /= 2;
3170 	  if (k == 0)
3171 	    break;
3172 	  p += NE;
3173 	  r += NE;
3174 	}
3175       ediv (t, eone, t, ldp);
3176     }
3177 isone:
3178 /* Find the first (leading) digit. */
3179   emovi (t, w);
3180   emovz (w, t);
3181   emovi (y, w);
3182   emovz (w, y);
3183   eiremain (t, y, ldp);
3184   digit = equot[NI - 1];
3185   while ((digit == 0) && (ecmp (y, ezero) != 0))
3186     {
3187       eshup1 (y);
3188       emovz (y, u);
3189       eshup1 (u);
3190       eshup1 (u);
3191       eaddm (u, y);
3192       eiremain (t, y, ldp);
3193       digit = equot[NI - 1];
3194       expon -= 1;
3195     }
3196   s = string;
3197   if (sign)
3198     *s++ = '-';
3199   else
3200     *s++ = ' ';
3201 /* Examine number of digits requested by caller. */
3202   if (outformat == 3)
3203     ndigs += expon;
3204 /*
3205 else if( ndigs < 0 )
3206         ndigs = 0;
3207 */
3208   if (ndigs > ndec)
3209     ndigs = ndec;
3210   if (digit == 10)
3211     {
3212       *s++ = '1';
3213       *s++ = '.';
3214       if (ndigs > 0)
3215 	{
3216 	  *s++ = '0';
3217 	  ndigs -= 1;
3218 	}
3219       expon += 1;
3220       if (ndigs < 0)
3221 	{
3222 	  ss = s;
3223 	  goto doexp;
3224 	}
3225     }
3226   else
3227     {
3228       *s++ = (char) digit + '0';
3229       *s++ = '.';
3230     }
3231 /* Generate digits after the decimal point. */
3232   for (k = 0; k <= ndigs; k++)
3233     {
3234 /* multiply current number by 10, without normalizing */
3235       eshup1 (y);
3236       emovz (y, u);
3237       eshup1 (u);
3238       eshup1 (u);
3239       eaddm (u, y);
3240       eiremain (t, y, ldp);
3241       *s++ = (char) equot[NI - 1] + '0';
3242     }
3243   digit = equot[NI - 1];
3244   --s;
3245   ss = s;
3246 /* round off the ASCII string */
3247   if (digit > 4)
3248     {
3249 /* Test for critical rounding case in ASCII output. */
3250       if (digit == 5)
3251 	{
3252 	  emovo (y, t, ldp);
3253 	  if (ecmp (t, ezero) != 0)
3254 	    goto roun;		/* round to nearest */
3255 	  if (ndigs < 0 || (*(s - 1 - (*(s - 1) == '.')) & 1) == 0)
3256 	    goto doexp;		/* round to even */
3257 	}
3258 /* Round up and propagate carry-outs */
3259     roun:
3260       --s;
3261       k = *s & 0x7f;
3262 /* Carry out to most significant digit? */
3263       if (ndigs < 0)
3264 	{
3265 	  /* This will print like "1E-6". */
3266 	  *s = '1';
3267 	  expon += 1;
3268 	  goto doexp;
3269 	}
3270       else if (k == '.')
3271 	{
3272 	  --s;
3273 	  k = *s;
3274 	  k += 1;
3275 	  *s = (char) k;
3276 /* Most significant digit carries to 10? */
3277 	  if (k > '9')
3278 	    {
3279 	      expon += 1;
3280 	      *s = '1';
3281 	    }
3282 	  goto doexp;
3283 	}
3284 /* Round up and carry out from less significant digits */
3285       k += 1;
3286       *s = (char) k;
3287       if (k > '9')
3288 	{
3289 	  *s = '0';
3290 	  goto roun;
3291 	}
3292     }
3293 doexp:
3294 #ifdef __GO32__
3295   if (expon >= 0)
3296     sprintf (ss, "e+%02d", expon);
3297   else
3298     sprintf (ss, "e-%02d", -expon);
3299 #else
3300   sprintf (ss, "E%d", expon);
3301 #endif
3302 bxit:
3303   ldp->rndprc = rndsav;
3304   ldp->outexpon = expon;
3305 }
3306 
3307 
3308 #if 0 /* Broken, unusable implementation of strtold */
3309 
3310 /*
3311 ;								ASCTOQ
3312 ;		ASCTOQ.MAC		LATEST REV: 11 JAN 84
3313 ;					SLM, 3 JAN 78
3314 ;
3315 ;	Convert ASCII string to quadruple precision floating point
3316 ;
3317 ;		Numeric input is free field decimal number
3318 ;		with max of 15 digits with or without
3319 ;		decimal point entered as ASCII from teletype.
3320 ;	Entering E after the number followed by a second
3321 ;	number causes the second number to be interpreted
3322 ;	as a power of 10 to be multiplied by the first number
3323 ;	(i.e., "scientific" notation).
3324 ;
3325 ;	Usage:
3326 ;		asctoq( string, q );
3327 */
3328 
3329 long double
3330 strtold (char *s, char **se)
3331 {
3332   union uconv x;
3333   LDPARMS rnd;
3334   LDPARMS *ldp = &rnd;
3335   int lenldstr;
3336 
3337   rnd.rlast = -1;
3338   rnd.rndprc = NBITS;
3339 
3340   lenldstr = asctoeg (s, &x.pe, LDBL_MANT_DIG, ldp);
3341   if (se)
3342     *se = s + lenldstr;
3343   return x.d;
3344 }
3345 
3346 #define REASONABLE_LEN 200
3347 
3348 static int
3349 asctoeg (char *ss, short unsigned int *y, int oprec, LDPARMS * ldp)
3350 {
3351   unsigned short yy[NI], xt[NI], tt[NI];
3352   int esign, decflg, sgnflg, nexp, exp, prec, lost;
3353   int k, trail, c, rndsav;
3354   long lexp;
3355   unsigned short nsign;
3356   const unsigned short *p;
3357   char *sp, *s, *lstr;
3358   int lenldstr;
3359   int mflag = 0;
3360   char tmpstr[REASONABLE_LEN];
3361 
3362 /* Copy the input string. */
3363   c = strlen (ss) + 2;
3364   if (c <= REASONABLE_LEN)
3365     lstr = tmpstr;
3366   else
3367     {
3368       lstr = (char *) calloc (c, 1);
3369       mflag = 1;
3370     }
3371   s = ss;
3372   lenldstr = 0;
3373   while (*s == ' ')		/* skip leading spaces */
3374     {
3375       ++s;
3376       ++lenldstr;
3377     }
3378   sp = lstr;
3379   for (k = 0; k < c; k++)
3380     {
3381       if ((*sp++ = *s++) == '\0')
3382 	break;
3383     }
3384   *sp = '\0';
3385   s = lstr;
3386 
3387   rndsav = ldp->rndprc;
3388   ldp->rndprc = NBITS;		/* Set to full precision */
3389   lost = 0;
3390   nsign = 0;
3391   decflg = 0;
3392   sgnflg = 0;
3393   nexp = 0;
3394   exp = 0;
3395   prec = 0;
3396   ecleaz (yy);
3397   trail = 0;
3398 
3399 nxtcom:
3400   k = *s - '0';
3401   if ((k >= 0) && (k <= 9))
3402     {
3403 /* Ignore leading zeros */
3404       if ((prec == 0) && (decflg == 0) && (k == 0))
3405 	goto donchr;
3406 /* Identify and strip trailing zeros after the decimal point. */
3407       if ((trail == 0) && (decflg != 0))
3408 	{
3409 	  sp = s;
3410 	  while ((*sp >= '0') && (*sp <= '9'))
3411 	    ++sp;
3412 /* Check for syntax error */
3413 	  c = *sp & 0x7f;
3414 	  if ((c != 'e') && (c != 'E') && (c != '\0')
3415 	      && (c != '\n') && (c != '\r') && (c != ' ') && (c != ','))
3416 	    goto error;
3417 	  --sp;
3418 	  while (*sp == '0')
3419 	    *sp-- = 'z';
3420 	  trail = 1;
3421 	  if (*s == 'z')
3422 	    goto donchr;
3423 	}
3424 /* If enough digits were given to more than fill up the yy register,
3425  * continuing until overflow into the high guard word yy[2]
3426  * guarantees that there will be a roundoff bit at the top
3427  * of the low guard word after normalization.
3428  */
3429       if (yy[2] == 0)
3430 	{
3431 	  if (decflg)
3432 	    nexp += 1;		/* count digits after decimal point */
3433 	  eshup1 (yy);		/* multiply current number by 10 */
3434 	  emovz (yy, xt);
3435 	  eshup1 (xt);
3436 	  eshup1 (xt);
3437 	  eaddm (xt, yy);
3438 	  ecleaz (xt);
3439 	  xt[NI - 2] = (unsigned short) k;
3440 	  eaddm (xt, yy);
3441 	}
3442       else
3443 	{
3444 	  /* Mark any lost non-zero digit.  */
3445 	  lost |= k;
3446 	  /* Count lost digits before the decimal point.  */
3447 	  if (decflg == 0)
3448 	    nexp -= 1;
3449 	}
3450       prec += 1;
3451       goto donchr;
3452     }
3453 
3454   switch (*s)
3455     {
3456     case 'z':
3457       break;
3458     case 'E':
3459     case 'e':
3460       goto expnt;
3461     case '.':			/* decimal point */
3462       if (decflg)
3463 	goto error;
3464       ++decflg;
3465       break;
3466     case '-':
3467       nsign = 0xffff;
3468       if (sgnflg)
3469 	goto error;
3470       ++sgnflg;
3471       break;
3472     case '+':
3473       if (sgnflg)
3474 	goto error;
3475       ++sgnflg;
3476       break;
3477     case ',':
3478     case ' ':
3479     case '\0':
3480     case '\n':
3481     case '\r':
3482       goto daldone;
3483     case 'i':
3484     case 'I':
3485       goto infinite;
3486     default:
3487     error:
3488 #ifdef NANS
3489       enan (yy, NI * 16);
3490 #else
3491       mtherr ("asctoe", DOMAIN);
3492       ecleaz (yy);
3493 #endif
3494       goto aexit;
3495     }
3496 donchr:
3497   ++s;
3498   goto nxtcom;
3499 
3500 /* Exponent interpretation */
3501 expnt:
3502 
3503   esign = 1;
3504   exp = 0;
3505   ++s;
3506 /* check for + or - */
3507   if (*s == '-')
3508     {
3509       esign = -1;
3510       ++s;
3511     }
3512   if (*s == '+')
3513     ++s;
3514   while ((*s >= '0') && (*s <= '9'))
3515     {
3516       exp *= 10;
3517       exp += *s++ - '0';
3518       if (exp > 4977)
3519 	{
3520 	  if (esign < 0)
3521 	    goto zero;
3522 	  else
3523 	    goto infinite;
3524 	}
3525     }
3526   if (esign < 0)
3527     exp = -exp;
3528   if (exp > 4932)
3529     {
3530     infinite:
3531       ecleaz (yy);
3532       yy[E] = 0x7fff;		/* infinity */
3533       goto aexit;
3534     }
3535   if (exp < -4977)
3536     {
3537     zero:
3538       ecleaz (yy);
3539       goto aexit;
3540     }
3541 
3542 daldone:
3543   nexp = exp - nexp;
3544 /* Pad trailing zeros to minimize power of 10, per IEEE spec. */
3545   while ((nexp > 0) && (yy[2] == 0))
3546     {
3547       emovz (yy, xt);
3548       eshup1 (xt);
3549       eshup1 (xt);
3550       eaddm (yy, xt);
3551       eshup1 (xt);
3552       if (xt[2] != 0)
3553 	break;
3554       nexp -= 1;
3555       emovz (xt, yy);
3556     }
3557   if ((k = enormlz (yy)) > NBITS)
3558     {
3559       ecleaz (yy);
3560       goto aexit;
3561     }
3562   lexp = (EXONE - 1 + NBITS) - k;
3563   emdnorm (yy, lost, 0, lexp, 64, ldp);
3564 /* convert to external format */
3565 
3566 
3567 /* Multiply by 10**nexp.  If precision is 64 bits,
3568  * the maximum relative error incurred in forming 10**n
3569  * for 0 <= n <= 324 is 8.2e-20, at 10**180.
3570  * For 0 <= n <= 999, the peak relative error is 1.4e-19 at 10**947.
3571  * For 0 >= n >= -999, it is -1.55e-19 at 10**-435.
3572  */
3573   lexp = yy[E];
3574   if (nexp == 0)
3575     {
3576       k = 0;
3577       goto expdon;
3578     }
3579   esign = 1;
3580   if (nexp < 0)
3581     {
3582       nexp = -nexp;
3583       esign = -1;
3584       if (nexp > 4096)
3585 	{			/* Punt.  Can't handle this without 2 divides. */
3586 	  emovi (etens[0], tt);
3587 	  lexp -= tt[E];
3588 	  k = edivm (tt, yy, ldp);
3589 	  lexp += EXONE;
3590 	  nexp -= 4096;
3591 	}
3592     }
3593   p = &etens[NTEN][0];
3594   emov (eone, xt);
3595   exp = 1;
3596   do
3597     {
3598       if (exp & nexp)
3599 	emul (p, xt, xt, ldp);
3600       p -= NE;
3601       exp = exp + exp;
3602     }
3603   while (exp <= MAXP);
3604 
3605   emovi (xt, tt);
3606   if (esign < 0)
3607     {
3608       lexp -= tt[E];
3609       k = edivm (tt, yy, ldp);
3610       lexp += EXONE;
3611     }
3612   else
3613     {
3614       lexp += tt[E];
3615       k = emulm (tt, yy, ldp);
3616       lexp -= EXONE - 1;
3617     }
3618 
3619 expdon:
3620 
3621 /* Round and convert directly to the destination type */
3622   if (oprec == 53)
3623     lexp -= EXONE - 0x3ff;
3624   else if (oprec == 24)
3625     lexp -= EXONE - 0177;
3626 #ifdef DEC
3627   else if (oprec == 56)
3628     lexp -= EXONE - 0201;
3629 #endif
3630   ldp->rndprc = oprec;
3631   emdnorm (yy, k, 0, lexp, 64, ldp);
3632 
3633 aexit:
3634 
3635   ldp->rndprc = rndsav;
3636   yy[0] = nsign;
3637   switch (oprec)
3638     {
3639 #ifdef DEC
3640     case 56:
3641       todec (yy, y);		/* see etodec.c */
3642       break;
3643 #endif
3644 #if LDBL_MANT_DIG == 53
3645     case 53:
3646       toe53 (yy, y);
3647       break;
3648 #elif LDBL_MANT_DIG == 24
3649     case 24:
3650       toe24 (yy, y);
3651       break;
3652 #elif LDBL_MANT_DIG == 64
3653     case 64:
3654       toe64 (yy, y);
3655       break;
3656 #elif LDBL_MANT_DIG == 113
3657     case 113:
3658       toe113 (yy, y);
3659       break;
3660 #else
3661     case NBITS:
3662       emovo (yy, y, ldp);
3663       break;
3664 #endif
3665     }
3666   lenldstr += s - lstr;
3667   if (mflag)
3668     free (lstr);
3669   return lenldstr;
3670 }
3671 
3672 #endif
3673 
3674 /* y = largest integer not greater than x
3675  * (truncated toward minus infinity)
3676  *
3677  * unsigned short x[NE], y[NE]
3678  * LDPARMS *ldp
3679  *
3680  * efloor( x, y, ldp );
3681  */
3682 static const unsigned short bmask[] = {
3683   0xffff,
3684   0xfffe,
3685   0xfffc,
3686   0xfff8,
3687   0xfff0,
3688   0xffe0,
3689   0xffc0,
3690   0xff80,
3691   0xff00,
3692   0xfe00,
3693   0xfc00,
3694   0xf800,
3695   0xf000,
3696   0xe000,
3697   0xc000,
3698   0x8000,
3699   0x0000,
3700 };
3701 
3702 static void
efloor(short unsigned int * x,short unsigned int * y,LDPARMS * ldp)3703 efloor (short unsigned int *x, short unsigned int *y, LDPARMS * ldp)
3704 {
3705   register unsigned short *p;
3706   int e, expon, i;
3707   unsigned short f[NE];
3708 
3709   emov (x, f);			/* leave in external format */
3710   expon = (int) f[NE - 1];
3711   e = (expon & 0x7fff) - (EXONE - 1);
3712   if (e <= 0)
3713     {
3714       eclear (y);
3715       goto isitneg;
3716     }
3717 /* number of bits to clear out */
3718   e = NBITS - e;
3719   emov (f, y);
3720   if (e <= 0)
3721     return;
3722 
3723   p = &y[0];
3724   while (e >= 16)
3725     {
3726       *p++ = 0;
3727       e -= 16;
3728     }
3729 /* clear the remaining bits */
3730   *p &= bmask[e];
3731 /* truncate negatives toward minus infinity */
3732 isitneg:
3733 
3734   if ((unsigned short) expon & (unsigned short) 0x8000)
3735     {
3736       for (i = 0; i < NE - 1; i++)
3737 	{
3738 	  if (f[i] != y[i])
3739 	    {
3740 	      esub (eone, y, y, ldp);
3741 	      break;
3742 	    }
3743 	}
3744     }
3745 }
3746 
3747 
3748 
3749 static void
eiremain(short unsigned int * den,short unsigned int * num,LDPARMS * ldp)3750 eiremain (short unsigned int *den, short unsigned int *num, LDPARMS * ldp)
3751 {
3752   long ld, ln;
3753   unsigned short j;
3754   unsigned short *equot = ldp->equot;
3755 
3756   ld = den[E];
3757   ld -= enormlz (den);
3758   ln = num[E];
3759   ln -= enormlz (num);
3760   ecleaz (equot);
3761   while (ln >= ld)
3762     {
3763       if (ecmpm (den, num) <= 0)
3764 	{
3765 	  esubm (den, num);
3766 	  j = 1;
3767 	}
3768       else
3769 	{
3770 	  j = 0;
3771 	}
3772       eshup1 (equot);
3773       equot[NI - 1] |= j;
3774       eshup1 (num);
3775       ln -= 1;
3776     }
3777   emdnorm (num, 0, 0, ln, 0, ldp);
3778 }
3779 
3780 /* NaN bit patterns
3781  */
3782 #ifdef MIEEE
3783 #if !defined(__mips)
3784 static const unsigned short nan113[8] = {
3785   0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
3786 };
3787 
3788 static const unsigned short nan64[6] = {
3789   0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
3790 };
3791 static const unsigned short nan53[4] = { 0x7fff, 0xffff, 0xffff, 0xffff };
3792 static const unsigned short nan24[2] = { 0x7fff, 0xffff };
3793 #elif defined(__mips_nan2008)	/* __mips */
3794 static const unsigned short nan113[8] = { 0x7fff, 0x8000, 0, 0, 0, 0, 0, 0 };
3795 static const unsigned short nan64[6] = { 0x7fff, 0xc000, 0, 0, 0, 0 };
3796 static const unsigned short nan53[4] = { 0x7ff8, 0, 0, 0 };
3797 static const unsigned short nan24[2] = { 0x7fc0, 0 };
3798 #else /* __mips && !__mips_nan2008 */
3799 static const unsigned short nan113[8] = {
3800   0x7fff, 0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
3801 };
3802 
3803 static const unsigned short nan64[6] = {
3804   0x7fff, 0xbfff, 0xffff, 0xffff, 0xffff, 0xffff
3805 };
3806 static const unsigned short nan53[4] = { 0x7ff7, 0xffff, 0xffff, 0xffff };
3807 static const unsigned short nan24[2] = { 0x7fbf, 0xffff };
3808 #endif /* __mips && !__mips_nan2008 */
3809 #else /* !MIEEE */
3810 #if !defined(__mips) || defined(__mips_nan2008)
3811 static const unsigned short nan113[8] = { 0, 0, 0, 0, 0, 0, 0x8000, 0x7fff };
3812 static const unsigned short nan64[6] = { 0, 0, 0, 0, 0xc000, 0x7fff };
3813 static const unsigned short nan53[4] = { 0, 0, 0, 0x7ff8 };
3814 static const unsigned short nan24[2] = { 0, 0x7fc0 };
3815 #else /* __mips && !__mips_nan2008 */
3816 static const unsigned short nan113[8] = {
3817   0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x7fff, 0x7fff
3818 };
3819 
3820 static const unsigned short nan64[6] = {
3821   0xffff, 0xffff, 0xffff, 0xffff, 0xbfff, 0x7fff
3822 };
3823 static const unsigned short nan53[4] = { 0xffff, 0xffff, 0xffff, 0x7ff7 };
3824 static const unsigned short nan24[2] = { 0xffff, 0x7fbf };
3825 #endif /* __mips && !__mips_nan2008 */
3826 #endif /* !MIEEE */
3827 
3828 
3829 static void
enan(short unsigned int * nan,int size)3830 enan (short unsigned int *nan, int size)
3831 {
3832   int i, n;
3833   const unsigned short *p;
3834 
3835   switch (size)
3836     {
3837 #ifndef DEC
3838     case 113:
3839       n = 8;
3840       p = nan113;
3841       break;
3842 
3843     case 64:
3844       n = 6;
3845       p = nan64;
3846       break;
3847 
3848     case 53:
3849       n = 4;
3850       p = nan53;
3851       break;
3852 
3853     case 24:
3854       n = 2;
3855       p = nan24;
3856       break;
3857 
3858     case NBITS:
3859 #if !defined(__mips) || defined(__mips_nan2008)
3860       for (i = 0; i < NE - 2; i++)
3861 	*nan++ = 0;
3862       *nan++ = 0xc000;
3863 #else /* __mips && !__mips_nan2008 */
3864       for (i = 0; i < NE - 2; i++)
3865 	*nan++ = 0xffff;
3866       *nan++ = 0xbfff;
3867 #endif /* __mips && !__mips_nan2008 */
3868       *nan++ = 0x7fff;
3869       return;
3870 
3871     case NI * 16:
3872       *nan++ = 0;
3873       *nan++ = 0x7fff;
3874       *nan++ = 0;
3875 #if !defined(__mips) || defined(__mips_nan2008)
3876       *nan++ = 0xc000;
3877       for (i = 4; i < NI - 1; i++)
3878 	*nan++ = 0;
3879 #else /* __mips && !__mips_nan2008 */
3880       *nan++ = 0xbfff;
3881       for (i = 4; i < NI - 1; i++)
3882 	*nan++ = 0xffff;
3883 #endif /* __mips && !__mips_nan2008 */
3884       *nan++ = 0;
3885       return;
3886 #endif
3887     default:
3888       mtherr ("enan", DOMAIN);
3889       return;
3890     }
3891   for (i = 0; i < n; i++)
3892     *nan++ = *p++;
3893 }
3894 
3895 #endif /* !_USE_GDTOA */
3896