* mingwex/strtold.c: New file. * mingwex/wcstold.c: New file. * mingwex/ldtoa.c: New file. * mingwex/math/cephes_emath.h: New file. * mingwex/math/cephes_emath.c: New file. * mingwex/Makefile.in (DISTFILES): Add new files. (MATH_DISTFILES): Ditto. (STDLIB_OBJS): New. Define as strtold.c wcstold.c. (MATH_OBJS): Add cephes_emath.o. (LIB_OBJS): Add $(STDLIB_OBJS). * include/stdlib.h (strtold, wcstold): Add prototypes. * include/wchar.h (wcstold): Add prototype. Add missing ChangeLog entry for 2002-11-09.
		
			
				
	
	
		
			1319 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1319 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* This file is extracted from S L Moshier's  ioldoubl.c,
 | 
						|
 * modified for use in MinGW 
 | 
						|
 *
 | 
						|
 * Extended precision arithmetic functions for long double I/O.
 | 
						|
 * This program has been placed in the public domain.
 | 
						|
 */
 | 
						|
 | 
						|
   
 | 
						|
 | 
						|
/*
 | 
						|
 * Revision history:
 | 
						|
 *
 | 
						|
 *  5 Jan 84	PDP-11 assembly language version
 | 
						|
 *  6 Dec 86	C language version
 | 
						|
 * 30 Aug 88	100 digit version, improved rounding
 | 
						|
 * 15 May 92    80-bit long double support
 | 
						|
 *
 | 
						|
 * Author:  S. L. Moshier.
 | 
						|
 *
 | 
						|
 * 6 Oct 02	Modified for MinGW by inlining utility routines,
 | 
						|
 * 		removing global variables and splitting out strtold
 | 
						|
 *		from _IO_ldtoa and _IO_ldtostr.
 | 
						|
 *  
 | 
						|
 *		Danny Smith <dannysmith@users.sourceforge.net>
 | 
						|
 * 
 | 
						|
 */
 | 
						|
 | 
						|
 | 
						|
#include "cephes_emath.h"
 | 
						|
 | 
						|
/*
 | 
						|
 * The constants are for 64 bit precision.
 | 
						|
 */
 | 
						|
 | 
						|
 | 
						|
/* Move in external format number,
 | 
						|
 * converting it to internal format.
 | 
						|
 */
 | 
						|
void __emovi(const short unsigned int * __restrict__ a,
 | 
						|
		  short unsigned int * __restrict__ b)
 | 
						|
{
 | 
						|
register const unsigned short *p;
 | 
						|
register unsigned short *q;
 | 
						|
int i;
 | 
						|
 | 
						|
q = b;
 | 
						|
p = a + (NE-1);	/* point to last word of external number */
 | 
						|
/* get the sign bit */
 | 
						|
if( *p & 0x8000 )
 | 
						|
	*q++ = 0xffff;
 | 
						|
else
 | 
						|
	*q++ = 0;
 | 
						|
/* get the exponent */
 | 
						|
*q = *p--;
 | 
						|
*q++ &= 0x7fff;	/* delete the sign bit */
 | 
						|
#ifdef INFINITY
 | 
						|
if( (*(q-1) & 0x7fff) == 0x7fff )
 | 
						|
	{
 | 
						|
#ifdef NANS
 | 
						|
	if( __eisnan(a) )
 | 
						|
		{
 | 
						|
		*q++ = 0;
 | 
						|
		for( i=3; i<NI; i++ )
 | 
						|
			*q++ = *p--;
 | 
						|
		return;
 | 
						|
		}
 | 
						|
#endif
 | 
						|
	for( i=2; i<NI; i++ )
 | 
						|
		*q++ = 0;
 | 
						|
	return;
 | 
						|
	}
 | 
						|
#endif
 | 
						|
/* clear high guard word */
 | 
						|
*q++ = 0;
 | 
						|
/* move in the significand */
 | 
						|
for( i=0; i<NE-1; i++ )
 | 
						|
	*q++ = *p--;
 | 
						|
/* clear low guard word */
 | 
						|
*q = 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
;	Add significands
 | 
						|
;	x + y replaces y
 | 
						|
*/
 | 
						|
 | 
						|
void __eaddm(const short unsigned int * __restrict__ x,
 | 
						|
		  short unsigned int * __restrict__ y)
 | 
						|
{
 | 
						|
register unsigned long a;
 | 
						|
int i;
 | 
						|
unsigned int carry;
 | 
						|
 | 
						|
x += NI-1;
 | 
						|
y += NI-1;
 | 
						|
carry = 0;
 | 
						|
for( i=M; i<NI; i++ )
 | 
						|
	{
 | 
						|
	a = (unsigned long )(*x) + (unsigned long )(*y) + carry;
 | 
						|
	if( a & 0x10000 )
 | 
						|
		carry = 1;
 | 
						|
	else
 | 
						|
		carry = 0;
 | 
						|
	*y = (unsigned short )a;
 | 
						|
	--x;
 | 
						|
	--y;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
;	Subtract significands
 | 
						|
;	y - x replaces y
 | 
						|
*/
 | 
						|
 | 
						|
void __esubm(const short unsigned int * __restrict__ x,
 | 
						|
		  short unsigned int * __restrict__ y)
 | 
						|
{
 | 
						|
unsigned long a;
 | 
						|
int i;
 | 
						|
unsigned int carry;
 | 
						|
 | 
						|
x += NI-1;
 | 
						|
y += NI-1;
 | 
						|
carry = 0;
 | 
						|
for( i=M; i<NI; i++ )
 | 
						|
	{
 | 
						|
	a = (unsigned long )(*y) - (unsigned long )(*x) - carry;
 | 
						|
	if( a & 0x10000 )
 | 
						|
		carry = 1;
 | 
						|
	else
 | 
						|
		carry = 0;
 | 
						|
	*y = (unsigned short )a;
 | 
						|
	--x;
 | 
						|
	--y;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/* Multiply significand of e-type number b
 | 
						|
by 16-bit quantity a, e-type result to c. */
 | 
						|
 | 
						|
static void __m16m(short unsigned int a,
 | 
						|
		 short unsigned int *  __restrict__ b,
 | 
						|
		 short unsigned int *  __restrict__ c)
 | 
						|
{
 | 
						|
register unsigned short *pp;
 | 
						|
register unsigned long carry;
 | 
						|
unsigned short *ps;
 | 
						|
unsigned short p[NI];
 | 
						|
unsigned long aa, m;
 | 
						|
int i;
 | 
						|
 | 
						|
aa = a;
 | 
						|
pp = &p[NI-2];
 | 
						|
*pp++ = 0;
 | 
						|
*pp = 0;
 | 
						|
ps = &b[NI-1];
 | 
						|
 | 
						|
for( i=M+1; i<NI; i++ )
 | 
						|
	{
 | 
						|
	if( *ps == 0 )
 | 
						|
		{
 | 
						|
		--ps;
 | 
						|
		--pp;
 | 
						|
		*(pp-1) = 0;
 | 
						|
		}
 | 
						|
	else
 | 
						|
		{
 | 
						|
		m = (unsigned long) aa * *ps--;
 | 
						|
		carry = (m & 0xffff) + *pp;
 | 
						|
		*pp-- = (unsigned short )carry;
 | 
						|
		carry = (carry >> 16) + (m >> 16) + *pp;
 | 
						|
		*pp = (unsigned short )carry;
 | 
						|
		*(pp-1) = carry >> 16;
 | 
						|
		}
 | 
						|
	}
 | 
						|
for( i=M; i<NI; i++ )
 | 
						|
	c[i] = p[i];
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/* Divide significands. Neither the numerator nor the denominator
 | 
						|
is permitted to have its high guard word nonzero.  */
 | 
						|
 | 
						|
 | 
						|
int __edivm(short unsigned int * __restrict__ den,
 | 
						|
		 short unsigned int * __restrict__ num)
 | 
						|
{
 | 
						|
int i;
 | 
						|
register unsigned short *p;
 | 
						|
unsigned long tnum;
 | 
						|
unsigned short j, tdenm, tquot;
 | 
						|
unsigned short tprod[NI+1];
 | 
						|
unsigned short equot[NI];
 | 
						|
 | 
						|
p = &equot[0];
 | 
						|
*p++ = num[0];
 | 
						|
*p++ = num[1];
 | 
						|
 | 
						|
for( i=M; i<NI; i++ )
 | 
						|
	{
 | 
						|
	*p++ = 0;
 | 
						|
	}
 | 
						|
__eshdn1( num );
 | 
						|
tdenm = den[M+1];
 | 
						|
for( i=M; i<NI; i++ )
 | 
						|
	{
 | 
						|
	/* Find trial quotient digit (the radix is 65536). */
 | 
						|
	tnum = (((unsigned long) num[M]) << 16) + num[M+1];
 | 
						|
 | 
						|
	/* Do not execute the divide instruction if it will overflow. */
 | 
						|
        if( (tdenm * 0xffffUL) < tnum )
 | 
						|
		tquot = 0xffff;
 | 
						|
	else
 | 
						|
		tquot = tnum / tdenm;
 | 
						|
 | 
						|
		/* Prove that the divide worked. */
 | 
						|
/*
 | 
						|
	tcheck = (unsigned long )tquot * tdenm;
 | 
						|
	if( tnum - tcheck > tdenm )
 | 
						|
		tquot = 0xffff;
 | 
						|
*/
 | 
						|
	/* Multiply denominator by trial quotient digit. */
 | 
						|
	__m16m( tquot, den, tprod );
 | 
						|
	/* The quotient digit may have been overestimated. */
 | 
						|
	if( __ecmpm( tprod, num ) > 0 )
 | 
						|
		{
 | 
						|
		tquot -= 1;
 | 
						|
		__esubm( den, tprod );
 | 
						|
		if( __ecmpm( tprod, num ) > 0 )
 | 
						|
			{
 | 
						|
			tquot -= 1;
 | 
						|
			__esubm( den, tprod );
 | 
						|
			}
 | 
						|
		}
 | 
						|
	__esubm( tprod, num );
 | 
						|
	equot[i] = tquot;
 | 
						|
	__eshup6(num);
 | 
						|
	}
 | 
						|
/* test for nonzero remainder after roundoff bit */
 | 
						|
p = &num[M];
 | 
						|
j = 0;
 | 
						|
for( i=M; i<NI; i++ )
 | 
						|
	{
 | 
						|
	j |= *p++;
 | 
						|
	}
 | 
						|
if( j )
 | 
						|
	j = 1;
 | 
						|
 | 
						|
for( i=0; i<NI; i++ )
 | 
						|
	num[i] = equot[i];
 | 
						|
 | 
						|
return( (int )j );
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
/* Multiply significands */
 | 
						|
int __emulm(const short unsigned int * __restrict__ a,
 | 
						|
		 short unsigned int * __restrict__ b)
 | 
						|
{
 | 
						|
const unsigned short *p;
 | 
						|
unsigned short *q;
 | 
						|
unsigned short pprod[NI];
 | 
						|
unsigned short equot[NI];
 | 
						|
unsigned short j;
 | 
						|
int i;
 | 
						|
 | 
						|
equot[0] = b[0];
 | 
						|
equot[1] = b[1];
 | 
						|
for( i=M; i<NI; i++ )
 | 
						|
	equot[i] = 0;
 | 
						|
 | 
						|
j = 0;
 | 
						|
p = &a[NI-1];
 | 
						|
q = &equot[NI-1];
 | 
						|
for( i=M+1; i<NI; i++ )
 | 
						|
	{
 | 
						|
	if( *p == 0 )
 | 
						|
		{
 | 
						|
		--p;
 | 
						|
		}
 | 
						|
	else
 | 
						|
		{
 | 
						|
		__m16m( *p--, b, pprod );
 | 
						|
		__eaddm(pprod, equot);
 | 
						|
		}
 | 
						|
	j |= *q;
 | 
						|
	__eshdn6(equot);
 | 
						|
	}
 | 
						|
 | 
						|
for( i=0; i<NI; i++ )
 | 
						|
	b[i] = equot[i];
 | 
						|
 | 
						|
/* return flag for lost nonzero bits */
 | 
						|
return( (int)j );
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Normalize and round off.
 | 
						|
 *
 | 
						|
 * The internal format number to be rounded is "s".
 | 
						|
 * Input "lost" indicates whether the number is exact.
 | 
						|
 * This is the so-called sticky bit.
 | 
						|
 *
 | 
						|
 * Input "subflg" indicates whether the number was obtained
 | 
						|
 * by a subtraction operation.  In that case if lost is nonzero
 | 
						|
 * then the number is slightly smaller than indicated.
 | 
						|
 *
 | 
						|
 * Input "exp" is the biased exponent, which may be negative.
 | 
						|
 * the exponent field of "s" is ignored but is replaced by
 | 
						|
 * "exp" as adjusted by normalization and rounding.
 | 
						|
 *
 | 
						|
 * Input "rcntrl" is the rounding control.
 | 
						|
 *
 | 
						|
 * Input "rnprc" is precison control (64 or NBITS).
 | 
						|
 */
 | 
						|
 | 
						|
void __emdnorm(short unsigned int *s, int lost, int subflg, long int exp, int rcntrl, int rndprc)
 | 
						|
{
 | 
						|
int i, j;
 | 
						|
unsigned short r;
 | 
						|
int rw = NI-1; /* low guard word */
 | 
						|
int re = NI-2;
 | 
						|
const unsigned short rmsk = 0xffff;
 | 
						|
const unsigned short rmbit = 0x8000;
 | 
						|
#if NE == 6
 | 
						|
unsigned short rbit[NI] = {0,0,0,0,0,0,0,1,0};
 | 
						|
#else
 | 
						|
unsigned short rbit[NI] = {0,0,0,0,0,0,0,0,0,0,0,1,0};
 | 
						|
#endif
 | 
						|
 | 
						|
/* Normalize */
 | 
						|
j = __enormlz( s );
 | 
						|
 | 
						|
/* a blank significand could mean either zero or infinity. */
 | 
						|
#ifndef INFINITY
 | 
						|
if( j > NBITS )
 | 
						|
	{
 | 
						|
	__ecleazs( s );
 | 
						|
	return;
 | 
						|
	}
 | 
						|
#endif
 | 
						|
exp -= j;
 | 
						|
#ifndef INFINITY
 | 
						|
if( exp >= 32767L )
 | 
						|
	goto overf;
 | 
						|
#else
 | 
						|
if( (j > NBITS) && (exp < 32767L) )
 | 
						|
	{
 | 
						|
	__ecleazs( s );
 | 
						|
	return;
 | 
						|
	}
 | 
						|
#endif
 | 
						|
if( exp < 0L )
 | 
						|
	{
 | 
						|
	if( exp > (long )(-NBITS-1) )
 | 
						|
		{
 | 
						|
		j = (int )exp;
 | 
						|
		i = __eshift( s, j );
 | 
						|
		if( i )
 | 
						|
			lost = 1;
 | 
						|
		}
 | 
						|
	else
 | 
						|
		{
 | 
						|
		__ecleazs( s );
 | 
						|
		return;
 | 
						|
		}
 | 
						|
	}
 | 
						|
/* Round off, unless told not to by rcntrl. */
 | 
						|
if( rcntrl == 0 )
 | 
						|
	goto mdfin;
 | 
						|
if (rndprc == 64)
 | 
						|
  {
 | 
						|
    rw = 7;
 | 
						|
    re = 6;
 | 
						|
    rbit[NI-2] = 0;
 | 
						|
    rbit[6] = 1;
 | 
						|
  }
 | 
						|
 | 
						|
/* Shift down 1 temporarily if the data structure has an implied
 | 
						|
 * most significant bit and the number is denormal.
 | 
						|
 * For rndprc = 64 or NBITS, there is no implied bit.
 | 
						|
 * But Intel long double denormals lose one bit of significance even so.
 | 
						|
 */
 | 
						|
#if IBMPC
 | 
						|
if( (exp <= 0) && (rndprc != NBITS) )
 | 
						|
#else
 | 
						|
if( (exp <= 0) && (rndprc != 64) && (rndprc != NBITS) )
 | 
						|
#endif
 | 
						|
	{
 | 
						|
	lost |= s[NI-1] & 1;
 | 
						|
	__eshdn1(s);
 | 
						|
	}
 | 
						|
/* Clear out all bits below the rounding bit,
 | 
						|
 * remembering in r if any were nonzero.
 | 
						|
 */
 | 
						|
r = s[rw] & rmsk;
 | 
						|
if( rndprc < NBITS )
 | 
						|
	{
 | 
						|
	i = rw + 1;
 | 
						|
	while( i < NI )
 | 
						|
		{
 | 
						|
		if( s[i] )
 | 
						|
			r |= 1;
 | 
						|
		s[i] = 0;
 | 
						|
		++i;
 | 
						|
		}
 | 
						|
	}
 | 
						|
s[rw] &= ~rmsk;
 | 
						|
if( (r & rmbit) != 0 )
 | 
						|
	{
 | 
						|
	if( r == rmbit )
 | 
						|
		{
 | 
						|
		if( lost == 0 )
 | 
						|
			{ /* round to even */
 | 
						|
			if( (s[re] & 1) == 0 )
 | 
						|
				goto mddone;
 | 
						|
			}
 | 
						|
		else
 | 
						|
			{
 | 
						|
			if( subflg != 0 )
 | 
						|
				goto mddone;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	__eaddm( rbit, s );
 | 
						|
	}
 | 
						|
mddone:
 | 
						|
#if IBMPC
 | 
						|
if( (exp <= 0) && (rndprc != NBITS) )
 | 
						|
#else
 | 
						|
if( (exp <= 0) && (rndprc != 64) && (rndprc != NBITS) )
 | 
						|
#endif
 | 
						|
	{
 | 
						|
	__eshup1(s);
 | 
						|
	}
 | 
						|
if( s[2] != 0 )
 | 
						|
	{ /* overflow on roundoff */
 | 
						|
	__eshdn1(s);
 | 
						|
	exp += 1;
 | 
						|
	}
 | 
						|
mdfin:
 | 
						|
s[NI-1] = 0;
 | 
						|
if( exp >= 32767L )
 | 
						|
	{
 | 
						|
#ifndef INFINITY
 | 
						|
overf:
 | 
						|
#endif
 | 
						|
#ifdef INFINITY
 | 
						|
	s[1] = 32767;
 | 
						|
	for( i=2; i<NI-1; i++ )
 | 
						|
		s[i] = 0;
 | 
						|
#else
 | 
						|
	s[1] = 32766;
 | 
						|
	s[2] = 0;
 | 
						|
	for( i=M+1; i<NI-1; i++ )
 | 
						|
		s[i] = 0xffff;
 | 
						|
	s[NI-1] = 0;
 | 
						|
	if( (rndprc < 64) || (rndprc == 113) )
 | 
						|
		s[rw] &= ~rmsk;
 | 
						|
#endif
 | 
						|
	return;
 | 
						|
	}
 | 
						|
if( exp < 0 )
 | 
						|
	s[1] = 0;
 | 
						|
else
 | 
						|
	s[1] = (unsigned short )exp;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
;	Multiply.
 | 
						|
;
 | 
						|
;	unsigned short a[NE], b[NE], c[NE];
 | 
						|
;	emul( a, b, c );	c = b * a
 | 
						|
*/
 | 
						|
void __emul(const short unsigned int *a,
 | 
						|
		 const short unsigned int *b,
 | 
						|
		 short unsigned int *c)
 | 
						|
{
 | 
						|
unsigned short ai[NI], bi[NI];
 | 
						|
int i, j;
 | 
						|
long lt, lta, ltb;
 | 
						|
 | 
						|
#ifdef NANS
 | 
						|
/* NaN times anything is the same NaN. */
 | 
						|
if( __eisnan(a) )
 | 
						|
	{
 | 
						|
	__emov(a,c);
 | 
						|
	return;
 | 
						|
	}
 | 
						|
if( __eisnan(b) )
 | 
						|
	{
 | 
						|
	__emov(b,c);
 | 
						|
	return;
 | 
						|
	}
 | 
						|
/* Zero times infinity is a NaN. */
 | 
						|
if( (__eisinf(a) && __eiiszero(b))
 | 
						|
	|| (__eisinf(b) && __eiiszero(a)) )
 | 
						|
	{
 | 
						|
	mtherr( "emul", DOMAIN );
 | 
						|
	__enan_NBITS( c );
 | 
						|
	return;
 | 
						|
	}
 | 
						|
#endif
 | 
						|
/* Infinity times anything else is infinity. */
 | 
						|
#ifdef INFINITY
 | 
						|
if( __eisinf(a) || __eisinf(b) )
 | 
						|
	{
 | 
						|
	if( __eisneg(a) ^ __eisneg(b) )
 | 
						|
		*(c+(NE-1)) = 0x8000;
 | 
						|
	else
 | 
						|
		*(c+(NE-1)) = 0;
 | 
						|
	__einfin(c);
 | 
						|
	return;
 | 
						|
	}
 | 
						|
#endif
 | 
						|
__emovi( a, ai );
 | 
						|
__emovi( b, bi );
 | 
						|
lta = ai[E];
 | 
						|
ltb = bi[E];
 | 
						|
if( ai[E] == 0 )
 | 
						|
	{
 | 
						|
	for( i=1; i<NI-1; i++ )
 | 
						|
		{
 | 
						|
		if( ai[i] != 0 )
 | 
						|
			{
 | 
						|
			lta -= __enormlz( ai );
 | 
						|
			goto mnzer1;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	__eclear(c);
 | 
						|
	return;
 | 
						|
	}
 | 
						|
mnzer1:
 | 
						|
 | 
						|
if( bi[E] == 0 )
 | 
						|
	{
 | 
						|
	for( i=1; i<NI-1; i++ )
 | 
						|
		{
 | 
						|
		if( bi[i] != 0 )
 | 
						|
			{
 | 
						|
			ltb -= __enormlz( bi );
 | 
						|
			goto mnzer2;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	__eclear(c);
 | 
						|
	return;
 | 
						|
	}
 | 
						|
mnzer2:
 | 
						|
 | 
						|
/* Multiply significands */
 | 
						|
j = __emulm( ai, bi );
 | 
						|
/* calculate exponent */
 | 
						|
lt = lta + ltb - (EXONE - 1);
 | 
						|
__emdnorm( bi, j, 0, lt, 64, NBITS );
 | 
						|
/* calculate sign of product */
 | 
						|
if( ai[0] == bi[0] )
 | 
						|
	bi[0] = 0;
 | 
						|
else
 | 
						|
	bi[0] = 0xffff;
 | 
						|
__emovo( bi, c );
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/* move out internal format to ieee long double */
 | 
						|
void __toe64(short unsigned int *a, short unsigned int *b)
 | 
						|
{
 | 
						|
register unsigned short *p, *q;
 | 
						|
unsigned short i;
 | 
						|
 | 
						|
#ifdef NANS
 | 
						|
if( __eiisnan(a) )
 | 
						|
	{
 | 
						|
	__enan_64( b );
 | 
						|
	return;
 | 
						|
	}
 | 
						|
#endif
 | 
						|
#ifdef IBMPC
 | 
						|
/* Shift Intel denormal significand down 1.  */
 | 
						|
if( a[E] == 0 )
 | 
						|
  __eshdn1(a);
 | 
						|
#endif
 | 
						|
p = a;
 | 
						|
#ifdef MIEEE
 | 
						|
q = b;
 | 
						|
#else
 | 
						|
q = b + 4; /* point to output exponent */
 | 
						|
#if 1
 | 
						|
/* NOTE: if data type is 96 bits wide, clear the last word here. */
 | 
						|
*(q+1)= 0;
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
/* combine sign and exponent */
 | 
						|
i = *p++;
 | 
						|
#ifdef MIEEE
 | 
						|
if( i )
 | 
						|
	*q++ = *p++ | 0x8000;
 | 
						|
else
 | 
						|
	*q++ = *p++;
 | 
						|
*q++ = 0;
 | 
						|
#else
 | 
						|
if( i )
 | 
						|
	*q-- = *p++ | 0x8000;
 | 
						|
else
 | 
						|
	*q-- = *p++;
 | 
						|
#endif
 | 
						|
/* skip over guard word */
 | 
						|
++p;
 | 
						|
/* move the significand */
 | 
						|
#ifdef MIEEE
 | 
						|
for( i=0; i<4; i++ )
 | 
						|
	*q++ = *p++;
 | 
						|
#else
 | 
						|
#ifdef INFINITY
 | 
						|
if (__eiisinf (a))
 | 
						|
        {
 | 
						|
	/* Intel long double infinity.  */
 | 
						|
	*q-- = 0x8000;
 | 
						|
	*q-- = 0;
 | 
						|
	*q-- = 0;
 | 
						|
	*q = 0;
 | 
						|
	return;
 | 
						|
	}
 | 
						|
#endif
 | 
						|
for( i=0; i<4; i++ )
 | 
						|
	*q-- = *p++;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/* Compare two e type numbers.
 | 
						|
 *
 | 
						|
 * unsigned short a[NE], b[NE];
 | 
						|
 * ecmp( a, b );
 | 
						|
 *
 | 
						|
 *  returns +1 if a > b
 | 
						|
 *           0 if a == b
 | 
						|
 *          -1 if a < b
 | 
						|
 *          -2 if either a or b is a NaN.
 | 
						|
 */
 | 
						|
int __ecmp(const short unsigned int * __restrict__ a,
 | 
						|
		const short unsigned int *  __restrict__ b)
 | 
						|
{
 | 
						|
unsigned short ai[NI], bi[NI];
 | 
						|
register unsigned short *p, *q;
 | 
						|
register int i;
 | 
						|
int msign;
 | 
						|
 | 
						|
#ifdef NANS
 | 
						|
if (__eisnan (a)  || __eisnan (b))
 | 
						|
	return( -2 );
 | 
						|
#endif
 | 
						|
__emovi( a, ai );
 | 
						|
p = ai;
 | 
						|
__emovi( b, bi );
 | 
						|
q = bi;
 | 
						|
 | 
						|
if( *p != *q )
 | 
						|
	{ /* the signs are different */
 | 
						|
/* -0 equals + 0 */
 | 
						|
	for( i=1; i<NI-1; i++ )
 | 
						|
		{
 | 
						|
		if( ai[i] != 0 )
 | 
						|
			goto nzro;
 | 
						|
		if( bi[i] != 0 )
 | 
						|
			goto nzro;
 | 
						|
		}
 | 
						|
	return(0);
 | 
						|
nzro:
 | 
						|
	if( *p == 0 )
 | 
						|
		return( 1 );
 | 
						|
	else
 | 
						|
		return( -1 );
 | 
						|
	}
 | 
						|
/* both are the same sign */
 | 
						|
if( *p == 0 )
 | 
						|
	msign = 1;
 | 
						|
else
 | 
						|
	msign = -1;
 | 
						|
i = NI-1;
 | 
						|
do
 | 
						|
	{
 | 
						|
	if( *p++ != *q++ )
 | 
						|
		{
 | 
						|
		goto diff;
 | 
						|
		}
 | 
						|
	}
 | 
						|
while( --i > 0 );
 | 
						|
 | 
						|
return(0);	/* equality */
 | 
						|
 | 
						|
 | 
						|
 | 
						|
diff:
 | 
						|
 | 
						|
if( *(--p) > *(--q) )
 | 
						|
	return( msign );		/* p is bigger */
 | 
						|
else
 | 
						|
	return( -msign );	/* p is littler */
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
;	Shift significand
 | 
						|
;
 | 
						|
;	Shifts significand area up or down by the number of bits
 | 
						|
;	given by the variable sc.
 | 
						|
*/
 | 
						|
int __eshift(short unsigned int *x, int sc)
 | 
						|
{
 | 
						|
unsigned short lost;
 | 
						|
unsigned short *p;
 | 
						|
 | 
						|
if( sc == 0 )
 | 
						|
	return( 0 );
 | 
						|
 | 
						|
lost = 0;
 | 
						|
p = x + NI-1;
 | 
						|
 | 
						|
if( sc < 0 )
 | 
						|
	{
 | 
						|
	sc = -sc;
 | 
						|
	while( sc >= 16 )
 | 
						|
		{
 | 
						|
		lost |= *p;	/* remember lost bits */
 | 
						|
		__eshdn6(x);
 | 
						|
		sc -= 16;
 | 
						|
		}
 | 
						|
 | 
						|
	while( sc >= 8 )
 | 
						|
		{
 | 
						|
		lost |= *p & 0xff;
 | 
						|
		__eshdn8(x);
 | 
						|
		sc -= 8;
 | 
						|
		}
 | 
						|
 | 
						|
	while( sc > 0 )
 | 
						|
		{
 | 
						|
		lost |= *p & 1;
 | 
						|
		__eshdn1(x);
 | 
						|
		sc -= 1;
 | 
						|
		}
 | 
						|
	}
 | 
						|
else
 | 
						|
	{
 | 
						|
	while( sc >= 16 )
 | 
						|
		{
 | 
						|
		__eshup6(x);
 | 
						|
		sc -= 16;
 | 
						|
		}
 | 
						|
 | 
						|
	while( sc >= 8 )
 | 
						|
		{
 | 
						|
		__eshup8(x);
 | 
						|
		sc -= 8;
 | 
						|
		}
 | 
						|
 | 
						|
	while( sc > 0 )
 | 
						|
		{
 | 
						|
		__eshup1(x);
 | 
						|
		sc -= 1;
 | 
						|
		}
 | 
						|
	}
 | 
						|
if( lost )
 | 
						|
	lost = 1;
 | 
						|
return( (int )lost );
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
;	normalize
 | 
						|
;
 | 
						|
; Shift normalizes the significand area pointed to by argument
 | 
						|
; shift count (up = positive) is returned.
 | 
						|
*/
 | 
						|
int __enormlz(short unsigned int *x)
 | 
						|
{
 | 
						|
register unsigned short *p;
 | 
						|
int sc;
 | 
						|
 | 
						|
sc = 0;
 | 
						|
p = &x[M];
 | 
						|
if( *p != 0 )
 | 
						|
	goto normdn;
 | 
						|
++p;
 | 
						|
if( *p & 0x8000 )
 | 
						|
	return( 0 );	/* already normalized */
 | 
						|
while( *p == 0 )
 | 
						|
	{
 | 
						|
	__eshup6(x);
 | 
						|
	sc += 16;
 | 
						|
/* With guard word, there are NBITS+16 bits available.
 | 
						|
 * return true if all are zero.
 | 
						|
 */
 | 
						|
	if( sc > NBITS )
 | 
						|
		return( sc );
 | 
						|
	}
 | 
						|
/* see if high byte is zero */
 | 
						|
while( (*p & 0xff00) == 0 )
 | 
						|
	{
 | 
						|
	__eshup8(x);
 | 
						|
	sc += 8;
 | 
						|
	}
 | 
						|
/* now shift 1 bit at a time */
 | 
						|
while( (*p  & 0x8000) == 0)
 | 
						|
	{
 | 
						|
	__eshup1(x);
 | 
						|
	sc += 1;
 | 
						|
	if( sc > (NBITS+16) )
 | 
						|
		{
 | 
						|
		mtherr( "enormlz", UNDERFLOW );
 | 
						|
		return( sc );
 | 
						|
		}
 | 
						|
	}
 | 
						|
return( sc );
 | 
						|
 | 
						|
/* Normalize by shifting down out of the high guard word
 | 
						|
   of the significand */
 | 
						|
normdn:
 | 
						|
 | 
						|
if( *p & 0xff00 )
 | 
						|
	{
 | 
						|
	__eshdn8(x);
 | 
						|
	sc -= 8;
 | 
						|
	}
 | 
						|
while( *p != 0 )
 | 
						|
	{
 | 
						|
	__eshdn1(x);
 | 
						|
	sc -= 1;
 | 
						|
 | 
						|
	if( sc < -NBITS )
 | 
						|
		{
 | 
						|
		mtherr( "enormlz", OVERFLOW );
 | 
						|
		return( sc );
 | 
						|
		}
 | 
						|
	}
 | 
						|
return( sc );
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/* Move internal format number out,
 | 
						|
 * converting it to external format.
 | 
						|
 */
 | 
						|
void __emovo(const short unsigned int * __restrict__ a,
 | 
						|
		  short unsigned int * __restrict__ b)
 | 
						|
{
 | 
						|
register const unsigned short *p;
 | 
						|
register unsigned short *q;
 | 
						|
unsigned short i;
 | 
						|
 | 
						|
p = a;
 | 
						|
q = b + (NE-1); /* point to output exponent */
 | 
						|
/* combine sign and exponent */
 | 
						|
i = *p++;
 | 
						|
if( i )
 | 
						|
	*q-- = *p++ | 0x8000;
 | 
						|
else
 | 
						|
	*q-- = *p++;
 | 
						|
#ifdef INFINITY
 | 
						|
if( *(p-1) == 0x7fff )
 | 
						|
	{
 | 
						|
#ifdef NANS
 | 
						|
	if( __eiisnan(a) )
 | 
						|
		{
 | 
						|
		__enan_NBITS( b );
 | 
						|
		return;
 | 
						|
		}
 | 
						|
#endif
 | 
						|
	__einfin(b);
 | 
						|
	return;
 | 
						|
	}
 | 
						|
#endif
 | 
						|
/* skip over guard word */
 | 
						|
++p;
 | 
						|
/* move the significand */
 | 
						|
for( i=0; i<NE-1; i++ )
 | 
						|
	*q-- = *p++;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#if USE_LDTOA
 | 
						|
 | 
						|
 | 
						|
void __eiremain(short unsigned int *den, short unsigned int *num,
 | 
						|
	 short unsigned int *equot )
 | 
						|
{
 | 
						|
long ld, ln;
 | 
						|
unsigned short j;
 | 
						|
 | 
						|
ld = den[E];
 | 
						|
ld -= __enormlz( den );
 | 
						|
ln = num[E];
 | 
						|
ln -= __enormlz( num );
 | 
						|
__ecleaz( equot );
 | 
						|
while( ln >= ld )
 | 
						|
	{
 | 
						|
	if( __ecmpm(den,num) <= 0 )
 | 
						|
		{
 | 
						|
		__esubm(den, num);
 | 
						|
		j = 1;
 | 
						|
		}
 | 
						|
	else
 | 
						|
		{
 | 
						|
		j = 0;
 | 
						|
		}
 | 
						|
	__eshup1(equot);
 | 
						|
	equot[NI-1] |= j;
 | 
						|
	__eshup1(num);
 | 
						|
	ln -= 1;
 | 
						|
	}
 | 
						|
__emdnorm( num, 0, 0, ln, 0, NBITS );
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void __eadd1(const short unsigned int *  __restrict__ a,
 | 
						|
		  const short unsigned int *  __restrict__ b,
 | 
						|
		  short unsigned int *  __restrict__ c,
 | 
						|
		  int subflg)
 | 
						|
{
 | 
						|
unsigned short ai[NI], bi[NI], ci[NI];
 | 
						|
int i, lost, j, k;
 | 
						|
long lt, lta, ltb;
 | 
						|
 | 
						|
#ifdef INFINITY
 | 
						|
if( __eisinf(a) )
 | 
						|
	{
 | 
						|
	__emov(a,c);
 | 
						|
	if( subflg )
 | 
						|
		__eneg(c);
 | 
						|
	return;
 | 
						|
	}
 | 
						|
if( __eisinf(b) )
 | 
						|
	{
 | 
						|
	__emov(b,c);
 | 
						|
	return;
 | 
						|
	}
 | 
						|
#endif
 | 
						|
__emovi( a, ai );
 | 
						|
__emovi( b, bi );
 | 
						|
if( sub )
 | 
						|
	ai[0] = ~ai[0];
 | 
						|
 | 
						|
/* compare exponents */
 | 
						|
lta = ai[E];
 | 
						|
ltb = bi[E];
 | 
						|
lt = lta - ltb;
 | 
						|
if( lt > 0L )
 | 
						|
	{	/* put the larger number in bi */
 | 
						|
	__emovz( bi, ci );
 | 
						|
	__emovz( ai, bi );
 | 
						|
	__emovz( ci, ai );
 | 
						|
	ltb = bi[E];
 | 
						|
	lt = -lt;
 | 
						|
	}
 | 
						|
lost = 0;
 | 
						|
if( lt != 0L )
 | 
						|
	{
 | 
						|
	if( lt < (long )(-NBITS-1) )
 | 
						|
		goto done;	/* answer same as larger addend */
 | 
						|
	k = (int )lt;
 | 
						|
	lost = __eshift( ai, k ); /* shift the smaller number down */
 | 
						|
	}
 | 
						|
else
 | 
						|
	{
 | 
						|
/* exponents were the same, so must compare significands */
 | 
						|
	i = __ecmpm( ai, bi );
 | 
						|
	if( i == 0 )
 | 
						|
		{ /* the numbers are identical in magnitude */
 | 
						|
		/* if different signs, result is zero */
 | 
						|
		if( ai[0] != bi[0] )
 | 
						|
			{
 | 
						|
			__eclear(c);
 | 
						|
			return;
 | 
						|
			}
 | 
						|
		/* if same sign, result is double */
 | 
						|
		/* double denomalized tiny number */
 | 
						|
		if( (bi[E] == 0) && ((bi[3] & 0x8000) == 0) )
 | 
						|
			{
 | 
						|
			__eshup1( bi );
 | 
						|
			goto done;
 | 
						|
			}
 | 
						|
		/* add 1 to exponent unless both are zero! */
 | 
						|
		for( j=1; j<NI-1; j++ )
 | 
						|
			{
 | 
						|
			if( bi[j] != 0 )
 | 
						|
				{
 | 
						|
/* This could overflow, but let emovo take care of that. */
 | 
						|
				ltb += 1;
 | 
						|
				break;
 | 
						|
				}
 | 
						|
			}
 | 
						|
		bi[E] = (unsigned short )ltb;
 | 
						|
		goto done;
 | 
						|
		}
 | 
						|
	if( i > 0 )
 | 
						|
		{	/* put the larger number in bi */
 | 
						|
		__emovz( bi, ci );
 | 
						|
		__emovz( ai, bi );
 | 
						|
		__emovz( ci, ai );
 | 
						|
		}
 | 
						|
	}
 | 
						|
if( ai[0] == bi[0] )
 | 
						|
	{
 | 
						|
	__eaddm( ai, bi );
 | 
						|
	subflg = 0;
 | 
						|
	}
 | 
						|
else
 | 
						|
	{
 | 
						|
	__esubm( ai, bi );
 | 
						|
	subflg = 1;
 | 
						|
	}
 | 
						|
__emdnorm( bi, lost, subflg, ltb, 64, NBITS);
 | 
						|
 | 
						|
done:
 | 
						|
__emovo( bi, c );
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/* y = largest integer not greater than x
 | 
						|
 * (truncated toward minus infinity)
 | 
						|
 *
 | 
						|
 * unsigned short x[NE], y[NE]
 | 
						|
 *
 | 
						|
 * efloor( x, y );
 | 
						|
 */
 | 
						|
 | 
						|
 | 
						|
void __efloor(short unsigned int *x, short unsigned int *y)
 | 
						|
{
 | 
						|
register unsigned short *p;
 | 
						|
int e, expon, i;
 | 
						|
unsigned short f[NE];
 | 
						|
const unsigned short bmask[] = {
 | 
						|
0xffff,
 | 
						|
0xfffe,
 | 
						|
0xfffc,
 | 
						|
0xfff8,
 | 
						|
0xfff0,
 | 
						|
0xffe0,
 | 
						|
0xffc0,
 | 
						|
0xff80,
 | 
						|
0xff00,
 | 
						|
0xfe00,
 | 
						|
0xfc00,
 | 
						|
0xf800,
 | 
						|
0xf000,
 | 
						|
0xe000,
 | 
						|
0xc000,
 | 
						|
0x8000,
 | 
						|
0x0000,
 | 
						|
};
 | 
						|
 | 
						|
__emov( x, f ); /* leave in external format */
 | 
						|
expon = (int )f[NE-1];
 | 
						|
e = (expon & 0x7fff) - (EXONE - 1);
 | 
						|
if( e <= 0 )
 | 
						|
	{
 | 
						|
	__eclear(y);
 | 
						|
	goto isitneg;
 | 
						|
	}
 | 
						|
/* number of bits to clear out */
 | 
						|
e = NBITS - e;
 | 
						|
__emov( f, y );
 | 
						|
if( e <= 0 )
 | 
						|
	return;
 | 
						|
 | 
						|
p = &y[0];
 | 
						|
while( e >= 16 )
 | 
						|
	{
 | 
						|
	*p++ = 0;
 | 
						|
	e -= 16;
 | 
						|
	}
 | 
						|
/* clear the remaining bits */
 | 
						|
*p &= bmask[e];
 | 
						|
/* truncate negatives toward minus infinity */
 | 
						|
isitneg:
 | 
						|
 | 
						|
if( (unsigned short )expon & (unsigned short )0x8000 )
 | 
						|
	{
 | 
						|
	for( i=0; i<NE-1; i++ )
 | 
						|
		{
 | 
						|
		if( f[i] != y[i] )
 | 
						|
			{
 | 
						|
			__esub( __eone, y, y );
 | 
						|
			break;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
;	Subtract external format numbers.
 | 
						|
;
 | 
						|
;	unsigned short a[NE], b[NE], c[NE];
 | 
						|
;	esub( a, b, c );	 c = b - a
 | 
						|
*/
 | 
						|
 | 
						|
 | 
						|
void __esub(const short unsigned int *  a,
 | 
						|
		 const short unsigned int *  b,
 | 
						|
		 short unsigned int *  c)
 | 
						|
{
 | 
						|
 | 
						|
#ifdef NANS
 | 
						|
if( __eisnan(a) )
 | 
						|
	{
 | 
						|
	__emov (a, c);
 | 
						|
	return;
 | 
						|
	}
 | 
						|
if( __eisnan(b) )
 | 
						|
	{
 | 
						|
	__emov(b,c);
 | 
						|
	return;
 | 
						|
	}
 | 
						|
/* Infinity minus infinity is a NaN.
 | 
						|
 * Test for subtracting infinities of the same sign.
 | 
						|
 */
 | 
						|
if( __eisinf(a) && __eisinf(b) && ((__eisneg (a) ^ __eisneg (b)) == 0))
 | 
						|
	{
 | 
						|
	mtherr( "esub", DOMAIN );
 | 
						|
	__enan_NBITS( c );
 | 
						|
	return;
 | 
						|
	}
 | 
						|
#endif
 | 
						|
__eadd1( a, b, c, 1 );
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
;	Divide.
 | 
						|
;
 | 
						|
;	unsigned short a[NI], b[NI], c[NI];
 | 
						|
;	ediv( a, b, c );	c = b / a
 | 
						|
*/
 | 
						|
 | 
						|
void __ediv(const short unsigned int *a,
 | 
						|
		 const short unsigned int *b,
 | 
						|
		 short unsigned int *c)
 | 
						|
{
 | 
						|
unsigned short ai[NI], bi[NI];
 | 
						|
int i;
 | 
						|
long lt, lta, ltb;
 | 
						|
 | 
						|
#ifdef NANS
 | 
						|
/* Return any NaN input. */
 | 
						|
if( __eisnan(a) )
 | 
						|
	{
 | 
						|
	__emov(a,c);
 | 
						|
	return;
 | 
						|
	}
 | 
						|
if( __eisnan(b) )
 | 
						|
	{
 | 
						|
	__emov(b,c);
 | 
						|
	return;
 | 
						|
	}
 | 
						|
/* Zero over zero, or infinity over infinity, is a NaN. */
 | 
						|
if( (__eiszero(a) && __eiszero(b))
 | 
						|
	|| (__eisinf (a) && __eisinf (b)) )
 | 
						|
	{
 | 
						|
	mtherr( "ediv", DOMAIN );
 | 
						|
	__enan_NBITS( c );
 | 
						|
	return;
 | 
						|
	}
 | 
						|
#endif
 | 
						|
/* Infinity over anything else is infinity. */
 | 
						|
#ifdef INFINITY
 | 
						|
if( __eisinf(b) )
 | 
						|
	{
 | 
						|
	if( __eisneg(a) ^ __eisneg(b) )
 | 
						|
		*(c+(NE-1)) = 0x8000;
 | 
						|
	else
 | 
						|
		*(c+(NE-1)) = 0;
 | 
						|
	__einfin(c);
 | 
						|
	return;
 | 
						|
	}
 | 
						|
if( __eisinf(a) )
 | 
						|
	{
 | 
						|
	__eclear(c);
 | 
						|
	return;
 | 
						|
	}
 | 
						|
#endif
 | 
						|
__emovi( a, ai );
 | 
						|
__emovi( b, bi );
 | 
						|
lta = ai[E];
 | 
						|
ltb = bi[E];
 | 
						|
if( bi[E] == 0 )
 | 
						|
	{ /* See if numerator is zero. */
 | 
						|
	for( i=1; i<NI-1; i++ )
 | 
						|
		{
 | 
						|
		if( bi[i] != 0 )
 | 
						|
			{
 | 
						|
			ltb -= __enormlz( bi );
 | 
						|
			goto dnzro1;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	__eclear(c);
 | 
						|
	return;
 | 
						|
	}
 | 
						|
dnzro1:
 | 
						|
 | 
						|
if( ai[E] == 0 )
 | 
						|
	{	/* possible divide by zero */
 | 
						|
	for( i=1; i<NI-1; i++ )
 | 
						|
		{
 | 
						|
		if( ai[i] != 0 )
 | 
						|
			{
 | 
						|
			lta -= __enormlz( ai );
 | 
						|
			goto dnzro2;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	if( ai[0] == bi[0] )
 | 
						|
		*(c+(NE-1)) = 0;
 | 
						|
	else
 | 
						|
		*(c+(NE-1)) = 0x8000;
 | 
						|
	__einfin(c);
 | 
						|
	mtherr( "ediv", SING );
 | 
						|
	return;
 | 
						|
	}
 | 
						|
dnzro2:
 | 
						|
 | 
						|
i = __edivm( ai, bi );
 | 
						|
/* calculate exponent */
 | 
						|
lt = ltb - lta + EXONE;
 | 
						|
__emdnorm( bi, i, 0, lt, 64, NBITS );
 | 
						|
/* set the sign */
 | 
						|
if( ai[0] == bi[0] )
 | 
						|
	bi[0] = 0;
 | 
						|
else
 | 
						|
	bi[0] = 0Xffff;
 | 
						|
__emovo( bi, c );
 | 
						|
}
 | 
						|
 | 
						|
void __e64toe(short unsigned int *pe, short unsigned int *y)
 | 
						|
{
 | 
						|
unsigned short yy[NI];
 | 
						|
unsigned short *p, *q, *e;
 | 
						|
int i;
 | 
						|
 | 
						|
e = pe;
 | 
						|
p = yy;
 | 
						|
for( i=0; i<NE-5; i++ )
 | 
						|
	*p++ = 0;
 | 
						|
#ifdef IBMPC
 | 
						|
for( i=0; i<5; i++ )
 | 
						|
	*p++ = *e++;
 | 
						|
#endif
 | 
						|
#ifdef DEC
 | 
						|
for( i=0; i<5; i++ )
 | 
						|
	*p++ = *e++;
 | 
						|
#endif
 | 
						|
#ifdef MIEEE
 | 
						|
p = &yy[0] + (NE-1);
 | 
						|
*p-- = *e++;
 | 
						|
++e;
 | 
						|
for( i=0; i<4; i++ )
 | 
						|
	*p-- = *e++;
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef IBMPC
 | 
						|
/* For Intel long double, shift denormal significand up 1
 | 
						|
   -- but only if the top significand bit is zero.  */
 | 
						|
if((yy[NE-1] & 0x7fff) == 0 && (yy[NE-2] & 0x8000) == 0)
 | 
						|
  {
 | 
						|
    unsigned short temp[NI+1];
 | 
						|
    __emovi(yy, temp);
 | 
						|
    __eshup1(temp);
 | 
						|
    __emovo(temp,y);
 | 
						|
    return;
 | 
						|
  }
 | 
						|
#endif
 | 
						|
#ifdef INFINITY
 | 
						|
/* Point to the exponent field.  */
 | 
						|
p = &yy[NE-1];
 | 
						|
if( *p == 0x7fff )
 | 
						|
	{
 | 
						|
#ifdef NANS
 | 
						|
#ifdef IBMPC
 | 
						|
	for( i=0; i<4; i++ )
 | 
						|
		{
 | 
						|
		if((i != 3 && pe[i] != 0)
 | 
						|
		   /* Check for Intel long double infinity pattern.  */
 | 
						|
		   || (i == 3 && pe[i] != 0x8000))
 | 
						|
			{
 | 
						|
			__enan_NBITS( y );
 | 
						|
			return;
 | 
						|
			}
 | 
						|
		}
 | 
						|
#else
 | 
						|
	for( i=1; i<=4; i++ )
 | 
						|
		{
 | 
						|
		if( pe[i] != 0 )
 | 
						|
			{
 | 
						|
			__enan_NBITS( y );
 | 
						|
			return;
 | 
						|
			}
 | 
						|
		}
 | 
						|
#endif
 | 
						|
#endif /* NANS */
 | 
						|
	__eclear( y );
 | 
						|
	__einfin( y );
 | 
						|
	if( *p & 0x8000 )
 | 
						|
		__eneg(y);
 | 
						|
	return;
 | 
						|
	}
 | 
						|
#endif
 | 
						|
p = yy;
 | 
						|
q = y;
 | 
						|
for( i=0; i<NE; i++ )
 | 
						|
	*q++ = *p++;
 | 
						|
}
 | 
						|
 | 
						|
#endif /* USE_LDTOA */ 
 |