174066Sbp/* $NetBSD: strtorx.c,v 1.3 2008/03/21 23:13:48 christos Exp $ */
274066Sbp
374066Sbp/****************************************************************
474066Sbp
574066SbpThe author of this software is David M. Gay.
674066Sbp
774066SbpCopyright (C) 1998, 2000 by Lucent Technologies
874066SbpAll Rights Reserved
974066Sbp
1074066SbpPermission to use, copy, modify, and distribute this software and
1174066Sbpits documentation for any purpose and without fee is hereby
1274066Sbpgranted, provided that the above copyright notice appear in all
1374066Sbpcopies and that both that the copyright notice and this
1474066Sbppermission notice and warranty disclaimer appear in supporting
1574066Sbpdocumentation, and that the name of Lucent or any of its entities
1674066Sbpnot be used in advertising or publicity pertaining to
1774066Sbpdistribution of the software without specific, written prior
1874066Sbppermission.
1974066Sbp
2074066SbpLUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
2174066SbpINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
2274066SbpIN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
2374066SbpSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2474066SbpWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
2574066SbpIN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
2674066SbpARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
2774066SbpTHIS SOFTWARE.
2874066Sbp
2974066Sbp****************************************************************/
3074066Sbp
3174066Sbp/* Please send bug reports to David M. Gay (dmg at acm dot org,
3274066Sbp * with " at " changed at "@" and " dot " changed to ".").	*/
3374066Sbp
3474066Sbp#include "gdtoaimp.h"
3574066Sbp
3674066Sbp#undef _0
3774066Sbp#undef _1
3874066Sbp
3974066Sbp/* one or the other of IEEE_BIG_ENDIAN or IEEE_LITTLE_ENDIAN should be #defined */
4074066Sbp
4174066Sbp#ifdef IEEE_BIG_ENDIAN
4274066Sbp#define _0 0
4374066Sbp#define _1 1
4474066Sbp#define _2 2
4574066Sbp#define _3 3
4674066Sbp#define _4 4
4774066Sbp#endif
4874066Sbp#ifdef IEEE_LITTLE_ENDIAN
4974066Sbp#define _0 4
5074066Sbp#define _1 3
5174066Sbp#define _2 2
5274066Sbp#define _3 1
5374066Sbp#define _4 0
5484306Sru#endif
5588509Sdavidc
5684306Sru void
5774066Sbp#ifdef KR_headers
5874066SbpULtox(L, bits, expt, k) UShort *L; ULong *bits; Long expt; int k;
5974066Sbp#else
6074066SbpULtox(UShort *L, ULong *bits, Long expt, int k)
6174066Sbp#endif
6274066Sbp{
6374066Sbp	switch(k & STRTOG_Retmask) {
6474066Sbp	  case STRTOG_NoNumber:
6574066Sbp	  case STRTOG_Zero:
66231564Sed		L[0] = L[1] = L[2] = L[3] = L[4] = 0;
6774066Sbp		break;
68231564Sed
6974066Sbp	  case STRTOG_Denormal:
70231564Sed		L[_0] = 0;
7174066Sbp		goto normal_bits;
72231564Sed
7374066Sbp	  case STRTOG_Normal:
74231564Sed	  case STRTOG_NaNbits:
7574066Sbp		L[_0] = expt + 0x3fff + 63;
76231564Sed normal_bits:
7774066Sbp		L[_4] = (UShort)bits[0];
78231564Sed		L[_3] = (UShort)(bits[0] >> 16);
7974066Sbp		L[_2] = (UShort)bits[1];
8084455Sbde		L[_1] = (UShort)(bits[1] >> 16);
8174066Sbp		break;
8284455Sbde
8374066Sbp	  case STRTOG_Infinite:
8484455Sbde		L[_0] = 0x7fff;
8574066Sbp		L[_1] = 0x8000;
8674066Sbp		L[_2] = L[_3] = L[_4] = 0;
8774066Sbp		break;
8884455Sbde
8974066Sbp	  case STRTOG_NaN:
9074066Sbp		L[0] = ldus_QNAN0;
9174066Sbp		L[1] = ldus_QNAN1;
9274066Sbp		L[2] = ldus_QNAN2;
9374066Sbp		L[3] = ldus_QNAN3;
9474066Sbp		L[4] = ldus_QNAN4;
9574066Sbp	  }
9674141Sbp	if (k & STRTOG_Neg)
9774066Sbp		L[_0] |= 0x8000;
9874066Sbp	}
9974066Sbp
10074066Sbp int
10174066Sbp#ifdef KR_headers
102140932Srustrtorx(s, sp, rounding, L) CONST char *s; char **sp; int rounding; void *L;
103140932Sru#else
10474066Sbpstrtorx(CONST char *s, char **sp, int rounding, void *L)
105140932Sru#endif
106140932Sru{
10774066Sbp	static CONST FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI };
108140932Sru	CONST FPI *fpi;
109140932Sru	FPI fpi1;
11074066Sbp	ULong bits[2];
11174066Sbp	Long expt;
11274066Sbp	int k;
11374066Sbp
11474066Sbp	fpi = &fpi0;
11574066Sbp	if (rounding != FPI_Round_near) {
11674066Sbp		fpi1 = fpi0;
11774066Sbp		fpi1.rounding = rounding;
11874066Sbp		fpi = &fpi1;
11974066Sbp		}
12074066Sbp	k = strtodg(s, sp, fpi, &expt, bits);
12174066Sbp	if (k == STRTOG_NoMemory)
12274066Sbp		return k;
12374141Sbp	    ULtox((UShort*)L, bits, expt, k);
12474141Sbp	return k;
12574152Sru	}
12674066Sbp