atof-ieee.c revision 77298
133965Sjdp/* atof_ieee.c - turn a Flonum into an IEEE floating point number
260484Sobrien   Copyright (C) 1987, 92, 93, 94, 95, 96, 97, 98, 99, 2000
338889Sjdp   Free Software Foundation, Inc.
433965Sjdp
533965Sjdp   This file is part of GAS, the GNU Assembler.
633965Sjdp
733965Sjdp   GAS is free software; you can redistribute it and/or modify
833965Sjdp   it under the terms of the GNU General Public License as published by
933965Sjdp   the Free Software Foundation; either version 2, or (at your option)
1033965Sjdp   any later version.
1133965Sjdp
1233965Sjdp   GAS is distributed in the hope that it will be useful,
1333965Sjdp   but WITHOUT ANY WARRANTY; without even the implied warranty of
1433965Sjdp   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1533965Sjdp   GNU General Public License for more details.
1633965Sjdp
1733965Sjdp   You should have received a copy of the GNU General Public License
1833965Sjdp   along with GAS; see the file COPYING.  If not, write to the Free
1933965Sjdp   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2033965Sjdp   02111-1307, USA.  */
2133965Sjdp
2233965Sjdp#include "as.h"
2333965Sjdp
2433965Sjdp/* Flonums returned here.  */
2533965Sjdpextern FLONUM_TYPE generic_floating_point_number;
2633965Sjdp
2733965Sjdpstatic int next_bits PARAMS ((int));
2833965Sjdpstatic void unget_bits PARAMS ((int));
2933965Sjdpstatic void make_invalid_floating_point_number PARAMS ((LITTLENUM_TYPE *));
3033965Sjdp
3133965Sjdpextern const char EXP_CHARS[];
3277298Sobrien/* Precision in LittleNums.  */
3333965Sjdp/* Don't count the gap in the m68k extended precision format.  */
3433965Sjdp#define MAX_PRECISION (5)
3533965Sjdp#define F_PRECISION (2)
3633965Sjdp#define D_PRECISION (4)
3733965Sjdp#define X_PRECISION (5)
3833965Sjdp#define P_PRECISION (5)
3933965Sjdp
4077298Sobrien/* Length in LittleNums of guard bits.  */
4133965Sjdp#define GUARD (2)
4233965Sjdp
4333965Sjdpstatic const unsigned long mask[] =
4433965Sjdp{
4533965Sjdp  0x00000000,
4633965Sjdp  0x00000001,
4733965Sjdp  0x00000003,
4833965Sjdp  0x00000007,
4933965Sjdp  0x0000000f,
5033965Sjdp  0x0000001f,
5133965Sjdp  0x0000003f,
5233965Sjdp  0x0000007f,
5333965Sjdp  0x000000ff,
5433965Sjdp  0x000001ff,
5533965Sjdp  0x000003ff,
5633965Sjdp  0x000007ff,
5733965Sjdp  0x00000fff,
5833965Sjdp  0x00001fff,
5933965Sjdp  0x00003fff,
6033965Sjdp  0x00007fff,
6133965Sjdp  0x0000ffff,
6233965Sjdp  0x0001ffff,
6333965Sjdp  0x0003ffff,
6433965Sjdp  0x0007ffff,
6533965Sjdp  0x000fffff,
6633965Sjdp  0x001fffff,
6733965Sjdp  0x003fffff,
6833965Sjdp  0x007fffff,
6933965Sjdp  0x00ffffff,
7033965Sjdp  0x01ffffff,
7133965Sjdp  0x03ffffff,
7233965Sjdp  0x07ffffff,
7333965Sjdp  0x0fffffff,
7433965Sjdp  0x1fffffff,
7533965Sjdp  0x3fffffff,
7633965Sjdp  0x7fffffff,
7733965Sjdp  0xffffffff,
7833965Sjdp};
7933965Sjdp
8033965Sjdpstatic int bits_left_in_littlenum;
8133965Sjdpstatic int littlenums_left;
8233965Sjdpstatic LITTLENUM_TYPE *littlenum_pointer;
8333965Sjdp
8433965Sjdpstatic int
8533965Sjdpnext_bits (number_of_bits)
8633965Sjdp     int number_of_bits;
8733965Sjdp{
8833965Sjdp  int return_value;
8933965Sjdp
9033965Sjdp  if (!littlenums_left)
9133965Sjdp    return (0);
9233965Sjdp  if (number_of_bits >= bits_left_in_littlenum)
9333965Sjdp    {
9433965Sjdp      return_value = mask[bits_left_in_littlenum] & *littlenum_pointer;
9533965Sjdp      number_of_bits -= bits_left_in_littlenum;
9633965Sjdp      return_value <<= number_of_bits;
9733965Sjdp
9833965Sjdp      if (--littlenums_left)
9933965Sjdp	{
10033965Sjdp	  bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits;
10133965Sjdp	  --littlenum_pointer;
10277298Sobrien	  return_value |=
10377298Sobrien	    (*littlenum_pointer >> bits_left_in_littlenum)
10477298Sobrien	    & mask[number_of_bits];
10533965Sjdp	}
10633965Sjdp    }
10733965Sjdp  else
10833965Sjdp    {
10933965Sjdp      bits_left_in_littlenum -= number_of_bits;
11077298Sobrien      return_value =
11177298Sobrien	mask[number_of_bits] & (*littlenum_pointer >> bits_left_in_littlenum);
11233965Sjdp    }
11377298Sobrien  return return_value;
11433965Sjdp}
11533965Sjdp
11677298Sobrien/* Num had better be less than LITTLENUM_NUMBER_OF_BITS.  */
11777298Sobrien
11833965Sjdpstatic void
11933965Sjdpunget_bits (num)
12033965Sjdp     int num;
12133965Sjdp{
12233965Sjdp  if (!littlenums_left)
12333965Sjdp    {
12433965Sjdp      ++littlenum_pointer;
12533965Sjdp      ++littlenums_left;
12633965Sjdp      bits_left_in_littlenum = num;
12733965Sjdp    }
12833965Sjdp  else if (bits_left_in_littlenum + num > LITTLENUM_NUMBER_OF_BITS)
12933965Sjdp    {
13077298Sobrien      bits_left_in_littlenum =
13177298Sobrien	num - (LITTLENUM_NUMBER_OF_BITS - bits_left_in_littlenum);
13233965Sjdp      ++littlenum_pointer;
13333965Sjdp      ++littlenums_left;
13433965Sjdp    }
13533965Sjdp  else
13633965Sjdp    bits_left_in_littlenum += num;
13733965Sjdp}
13833965Sjdp
13933965Sjdpstatic void
14033965Sjdpmake_invalid_floating_point_number (words)
14133965Sjdp     LITTLENUM_TYPE *words;
14233965Sjdp{
14360484Sobrien  as_bad (_("cannot create floating-point number"));
14477298Sobrien  /* Zero the leftmost bit.  */
14577298Sobrien  words[0] = (LITTLENUM_TYPE) ((unsigned) -1) >> 1;
14633965Sjdp  words[1] = (LITTLENUM_TYPE) -1;
14733965Sjdp  words[2] = (LITTLENUM_TYPE) -1;
14833965Sjdp  words[3] = (LITTLENUM_TYPE) -1;
14933965Sjdp  words[4] = (LITTLENUM_TYPE) -1;
15033965Sjdp  words[5] = (LITTLENUM_TYPE) -1;
15133965Sjdp}
15233965Sjdp
15377298Sobrien/* Warning: This returns 16-bit LITTLENUMs.  It is up to the caller to
15477298Sobrien   figure out any alignment problems and to conspire for the
15577298Sobrien   bytes/word to be emitted in the right order.  Bigendians beware!  */
15633965Sjdp
15733965Sjdp/* Note that atof-ieee always has X and P precisions enabled.  it is up
15833965Sjdp   to md_atof to filter them out if the target machine does not support
15933965Sjdp   them.  */
16033965Sjdp
16177298Sobrien/* Returns pointer past text consumed.  */
16277298Sobrien
16333965Sjdpchar *
16433965Sjdpatof_ieee (str, what_kind, words)
16577298Sobrien     char *str;			/* Text to convert to binary.  */
16677298Sobrien     int what_kind;		/* 'd', 'f', 'g', 'h'.  */
16777298Sobrien     LITTLENUM_TYPE *words;	/* Build the binary here.  */
16833965Sjdp{
16977298Sobrien  /* Extra bits for zeroed low-order bits.
17077298Sobrien     The 1st MAX_PRECISION are zeroed, the last contain flonum bits.  */
17133965Sjdp  static LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
17233965Sjdp  char *return_value;
17377298Sobrien  /* Number of 16-bit words in the format.  */
17433965Sjdp  int precision;
17533965Sjdp  long exponent_bits;
17633965Sjdp  FLONUM_TYPE save_gen_flonum;
17733965Sjdp
17833965Sjdp  /* We have to save the generic_floating_point_number because it
17933965Sjdp     contains storage allocation about the array of LITTLENUMs where
18033965Sjdp     the value is actually stored.  We will allocate our own array of
18133965Sjdp     littlenums below, but have to restore the global one on exit.  */
18233965Sjdp  save_gen_flonum = generic_floating_point_number;
18333965Sjdp
18433965Sjdp  return_value = str;
18533965Sjdp  generic_floating_point_number.low = bits + MAX_PRECISION;
18633965Sjdp  generic_floating_point_number.high = NULL;
18733965Sjdp  generic_floating_point_number.leader = NULL;
18833965Sjdp  generic_floating_point_number.exponent = 0;
18933965Sjdp  generic_floating_point_number.sign = '\0';
19033965Sjdp
19133965Sjdp  /* Use more LittleNums than seems necessary: the highest flonum may
19277298Sobrien     have 15 leading 0 bits, so could be useless.  */
19333965Sjdp
19433965Sjdp  memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
19533965Sjdp
19633965Sjdp  switch (what_kind)
19733965Sjdp    {
19833965Sjdp    case 'f':
19933965Sjdp    case 'F':
20033965Sjdp    case 's':
20133965Sjdp    case 'S':
20233965Sjdp      precision = F_PRECISION;
20333965Sjdp      exponent_bits = 8;
20433965Sjdp      break;
20533965Sjdp
20633965Sjdp    case 'd':
20733965Sjdp    case 'D':
20833965Sjdp    case 'r':
20933965Sjdp    case 'R':
21033965Sjdp      precision = D_PRECISION;
21133965Sjdp      exponent_bits = 11;
21233965Sjdp      break;
21333965Sjdp
21433965Sjdp    case 'x':
21533965Sjdp    case 'X':
21633965Sjdp    case 'e':
21733965Sjdp    case 'E':
21833965Sjdp      precision = X_PRECISION;
21933965Sjdp      exponent_bits = 15;
22033965Sjdp      break;
22133965Sjdp
22233965Sjdp    case 'p':
22333965Sjdp    case 'P':
22433965Sjdp
22533965Sjdp      precision = P_PRECISION;
22633965Sjdp      exponent_bits = -1;
22733965Sjdp      break;
22833965Sjdp
22933965Sjdp    default:
23033965Sjdp      make_invalid_floating_point_number (words);
23133965Sjdp      return (NULL);
23233965Sjdp    }
23333965Sjdp
23433965Sjdp  generic_floating_point_number.high
23533965Sjdp    = generic_floating_point_number.low + precision - 1 + GUARD;
23633965Sjdp
23733965Sjdp  if (atof_generic (&return_value, ".", EXP_CHARS,
23833965Sjdp		    &generic_floating_point_number))
23933965Sjdp    {
24033965Sjdp      make_invalid_floating_point_number (words);
24133965Sjdp      return (NULL);
24233965Sjdp    }
24333965Sjdp  gen_to_words (words, precision, exponent_bits);
24433965Sjdp
24533965Sjdp  /* Restore the generic_floating_point_number's storage alloc (and
24633965Sjdp     everything else).  */
24733965Sjdp  generic_floating_point_number = save_gen_flonum;
24833965Sjdp
24933965Sjdp  return return_value;
25033965Sjdp}
25133965Sjdp
25233965Sjdp/* Turn generic_floating_point_number into a real float/double/extended.  */
25377298Sobrien
25433965Sjdpint
25533965Sjdpgen_to_words (words, precision, exponent_bits)
25633965Sjdp     LITTLENUM_TYPE *words;
25733965Sjdp     int precision;
25833965Sjdp     long exponent_bits;
25933965Sjdp{
26033965Sjdp  int return_value = 0;
26133965Sjdp
26233965Sjdp  long exponent_1;
26333965Sjdp  long exponent_2;
26433965Sjdp  long exponent_3;
26533965Sjdp  long exponent_4;
26633965Sjdp  int exponent_skippage;
26733965Sjdp  LITTLENUM_TYPE word1;
26833965Sjdp  LITTLENUM_TYPE *lp;
26933965Sjdp  LITTLENUM_TYPE *words_end;
27033965Sjdp
27133965Sjdp  words_end = words + precision;
27233965Sjdp#ifdef TC_M68K
27333965Sjdp  if (precision == X_PRECISION)
27433965Sjdp    /* On the m68k the extended precision format has a gap of 16 bits
27533965Sjdp       between the exponent and the mantissa.  */
27633965Sjdp    words_end++;
27733965Sjdp#endif
27833965Sjdp
27933965Sjdp  if (generic_floating_point_number.low > generic_floating_point_number.leader)
28033965Sjdp    {
28177298Sobrien      /* 0.0e0 seen.  */
28233965Sjdp      if (generic_floating_point_number.sign == '+')
28333965Sjdp	words[0] = 0x0000;
28433965Sjdp      else
28533965Sjdp	words[0] = 0x8000;
28633965Sjdp      memset (&words[1], '\0',
28733965Sjdp	      (words_end - words - 1) * sizeof (LITTLENUM_TYPE));
28877298Sobrien      return return_value;
28933965Sjdp    }
29033965Sjdp
29177298Sobrien  /* NaN:  Do the right thing.  */
29233965Sjdp  if (generic_floating_point_number.sign == 0)
29333965Sjdp    {
29433965Sjdp      if (precision == F_PRECISION)
29533965Sjdp	{
29633965Sjdp	  words[0] = 0x7fff;
29733965Sjdp	  words[1] = 0xffff;
29833965Sjdp	}
29933965Sjdp      else if (precision == X_PRECISION)
30033965Sjdp	{
30133965Sjdp#ifdef TC_M68K
30233965Sjdp	  words[0] = 0x7fff;
30333965Sjdp	  words[1] = 0;
30433965Sjdp	  words[2] = 0xffff;
30533965Sjdp	  words[3] = 0xffff;
30633965Sjdp	  words[4] = 0xffff;
30733965Sjdp	  words[5] = 0xffff;
30877298Sobrien#else /* ! TC_M68K  */
30933965Sjdp#ifdef TC_I386
31033965Sjdp	  words[0] = 0xffff;
31133965Sjdp	  words[1] = 0xc000;
31233965Sjdp	  words[2] = 0;
31333965Sjdp	  words[3] = 0;
31433965Sjdp	  words[4] = 0;
31577298Sobrien#else /* ! TC_I386  */
31633965Sjdp	  abort ();
31777298Sobrien#endif /* ! TC_I386  */
31877298Sobrien#endif /* ! TC_M68K  */
31933965Sjdp	}
32033965Sjdp      else
32133965Sjdp	{
32233965Sjdp	  words[0] = 0x7fff;
32333965Sjdp	  words[1] = 0xffff;
32433965Sjdp	  words[2] = 0xffff;
32533965Sjdp	  words[3] = 0xffff;
32633965Sjdp	}
32733965Sjdp      return return_value;
32833965Sjdp    }
32933965Sjdp  else if (generic_floating_point_number.sign == 'P')
33033965Sjdp    {
33177298Sobrien      /* +INF:  Do the right thing.  */
33233965Sjdp      if (precision == F_PRECISION)
33333965Sjdp	{
33433965Sjdp	  words[0] = 0x7f80;
33533965Sjdp	  words[1] = 0;
33633965Sjdp	}
33733965Sjdp      else if (precision == X_PRECISION)
33833965Sjdp	{
33933965Sjdp#ifdef TC_M68K
34033965Sjdp	  words[0] = 0x7fff;
34133965Sjdp	  words[1] = 0;
34233965Sjdp	  words[2] = 0;
34333965Sjdp	  words[3] = 0;
34433965Sjdp	  words[4] = 0;
34533965Sjdp	  words[5] = 0;
34677298Sobrien#else /* ! TC_M68K  */
34733965Sjdp#ifdef TC_I386
34833965Sjdp	  words[0] = 0x7fff;
34933965Sjdp	  words[1] = 0x8000;
35033965Sjdp	  words[2] = 0;
35133965Sjdp	  words[3] = 0;
35233965Sjdp	  words[4] = 0;
35377298Sobrien#else /* ! TC_I386  */
35433965Sjdp	  abort ();
35577298Sobrien#endif /* ! TC_I386  */
35677298Sobrien#endif /* ! TC_M68K  */
35733965Sjdp	}
35833965Sjdp      else
35933965Sjdp	{
36033965Sjdp	  words[0] = 0x7ff0;
36133965Sjdp	  words[1] = 0;
36233965Sjdp	  words[2] = 0;
36333965Sjdp	  words[3] = 0;
36433965Sjdp	}
36577298Sobrien      return return_value;
36633965Sjdp    }
36733965Sjdp  else if (generic_floating_point_number.sign == 'N')
36833965Sjdp    {
36977298Sobrien      /* Negative INF.  */
37033965Sjdp      if (precision == F_PRECISION)
37133965Sjdp	{
37233965Sjdp	  words[0] = 0xff80;
37333965Sjdp	  words[1] = 0x0;
37433965Sjdp	}
37533965Sjdp      else if (precision == X_PRECISION)
37633965Sjdp	{
37733965Sjdp#ifdef TC_M68K
37833965Sjdp	  words[0] = 0xffff;
37933965Sjdp	  words[1] = 0;
38033965Sjdp	  words[2] = 0;
38133965Sjdp	  words[3] = 0;
38233965Sjdp	  words[4] = 0;
38333965Sjdp	  words[5] = 0;
38477298Sobrien#else /* ! TC_M68K  */
38533965Sjdp#ifdef TC_I386
38633965Sjdp	  words[0] = 0xffff;
38733965Sjdp	  words[1] = 0x8000;
38833965Sjdp	  words[2] = 0;
38933965Sjdp	  words[3] = 0;
39033965Sjdp	  words[4] = 0;
39177298Sobrien#else /* ! TC_I386  */
39233965Sjdp	  abort ();
39377298Sobrien#endif /* ! TC_I386  */
39477298Sobrien#endif /* ! TC_M68K  */
39533965Sjdp	}
39633965Sjdp      else
39733965Sjdp	{
39833965Sjdp	  words[0] = 0xfff0;
39933965Sjdp	  words[1] = 0x0;
40033965Sjdp	  words[2] = 0x0;
40133965Sjdp	  words[3] = 0x0;
40233965Sjdp	}
40377298Sobrien      return return_value;
40433965Sjdp    }
40577298Sobrien
40677298Sobrien  /* The floating point formats we support have:
40777298Sobrien     Bit 15 is sign bit.
40877298Sobrien     Bits 14:n are excess-whatever exponent.
40977298Sobrien     Bits n-1:0 (if any) are most significant bits of fraction.
41077298Sobrien     Bits 15:0 of the next word(s) are the next most significant bits.
41177298Sobrien
41277298Sobrien     So we need: number of bits of exponent, number of bits of
41377298Sobrien     mantissa.  */
41433965Sjdp  bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
41533965Sjdp  littlenum_pointer = generic_floating_point_number.leader;
41633965Sjdp  littlenums_left = (1
41733965Sjdp		     + generic_floating_point_number.leader
41833965Sjdp		     - generic_floating_point_number.low);
41977298Sobrien
42077298Sobrien  /* Seek (and forget) 1st significant bit.  */
42133965Sjdp  for (exponent_skippage = 0; !next_bits (1); ++exponent_skippage);;
42233965Sjdp  exponent_1 = (generic_floating_point_number.exponent
42333965Sjdp		+ generic_floating_point_number.leader
42433965Sjdp		+ 1
42533965Sjdp		- generic_floating_point_number.low);
42677298Sobrien
42733965Sjdp  /* Radix LITTLENUM_RADIX, point just higher than
42877298Sobrien     generic_floating_point_number.leader.  */
42933965Sjdp  exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
43077298Sobrien
43177298Sobrien  /* Radix 2.  */
43233965Sjdp  exponent_3 = exponent_2 - exponent_skippage;
43377298Sobrien
43477298Sobrien  /* Forget leading zeros, forget 1st bit.  */
43533965Sjdp  exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2);
43633965Sjdp
43777298Sobrien  /* Offset exponent.  */
43833965Sjdp  lp = words;
43933965Sjdp
44077298Sobrien  /* Word 1.  Sign, exponent and perhaps high bits.  */
44133965Sjdp  word1 = ((generic_floating_point_number.sign == '+')
44233965Sjdp	   ? 0
44333965Sjdp	   : (1 << (LITTLENUM_NUMBER_OF_BITS - 1)));
44433965Sjdp
44577298Sobrien  /* Assume 2's complement integers.  */
44633965Sjdp  if (exponent_4 <= 0)
44733965Sjdp    {
44833965Sjdp      int prec_bits;
44933965Sjdp      int num_bits;
45033965Sjdp
45133965Sjdp      unget_bits (1);
45233965Sjdp      num_bits = -exponent_4;
45377298Sobrien      prec_bits =
45477298Sobrien	LITTLENUM_NUMBER_OF_BITS * precision - (exponent_bits + 1 + num_bits);
45533965Sjdp#ifdef TC_I386
45633965Sjdp      if (precision == X_PRECISION && exponent_bits == 15)
45733965Sjdp	{
45833965Sjdp	  /* On the i386 a denormalized extended precision float is
45933965Sjdp	     shifted down by one, effectively decreasing the exponent
46033965Sjdp	     bias by one.  */
46133965Sjdp	  prec_bits -= 1;
46233965Sjdp	  num_bits += 1;
46333965Sjdp	}
46433965Sjdp#endif
46533965Sjdp
46633965Sjdp      if (num_bits >= LITTLENUM_NUMBER_OF_BITS - exponent_bits)
46733965Sjdp	{
46877298Sobrien	  /* Bigger than one littlenum.  */
46933965Sjdp	  num_bits -= (LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits;
47033965Sjdp	  *lp++ = word1;
47177298Sobrien	  if (num_bits + exponent_bits + 1
47277298Sobrien	      > precision * LITTLENUM_NUMBER_OF_BITS)
47333965Sjdp	    {
47477298Sobrien	      /* Exponent overflow.  */
47533965Sjdp	      make_invalid_floating_point_number (words);
47677298Sobrien	      return return_value;
47733965Sjdp	    }
47833965Sjdp#ifdef TC_M68K
47933965Sjdp	  if (precision == X_PRECISION && exponent_bits == 15)
48033965Sjdp	    *lp++ = 0;
48133965Sjdp#endif
48233965Sjdp	  while (num_bits >= LITTLENUM_NUMBER_OF_BITS)
48333965Sjdp	    {
48433965Sjdp	      num_bits -= LITTLENUM_NUMBER_OF_BITS;
48533965Sjdp	      *lp++ = 0;
48633965Sjdp	    }
48733965Sjdp	  if (num_bits)
48833965Sjdp	    *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - (num_bits));
48933965Sjdp	}
49033965Sjdp      else
49133965Sjdp	{
49233965Sjdp	  if (precision == X_PRECISION && exponent_bits == 15)
49333965Sjdp	    {
49433965Sjdp	      *lp++ = word1;
49533965Sjdp#ifdef TC_M68K
49633965Sjdp	      *lp++ = 0;
49733965Sjdp#endif
49833965Sjdp	      *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - num_bits);
49933965Sjdp	    }
50033965Sjdp	  else
50133965Sjdp	    {
50277298Sobrien	      word1 |= next_bits ((LITTLENUM_NUMBER_OF_BITS - 1)
50377298Sobrien				  - (exponent_bits + num_bits));
50433965Sjdp	      *lp++ = word1;
50533965Sjdp	    }
50633965Sjdp	}
50733965Sjdp      while (lp < words_end)
50833965Sjdp	*lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS);
50933965Sjdp
51077298Sobrien      /* Round the mantissa up, but don't change the number.  */
51133965Sjdp      if (next_bits (1))
51233965Sjdp	{
51333965Sjdp	  --lp;
51460484Sobrien	  if (prec_bits >= LITTLENUM_NUMBER_OF_BITS)
51533965Sjdp	    {
51633965Sjdp	      int n = 0;
51733965Sjdp	      int tmp_bits;
51833965Sjdp
51933965Sjdp	      n = 0;
52033965Sjdp	      tmp_bits = prec_bits;
52133965Sjdp	      while (tmp_bits > LITTLENUM_NUMBER_OF_BITS)
52233965Sjdp		{
52333965Sjdp		  if (lp[n] != (LITTLENUM_TYPE) - 1)
52433965Sjdp		    break;
52533965Sjdp		  --n;
52633965Sjdp		  tmp_bits -= LITTLENUM_NUMBER_OF_BITS;
52733965Sjdp		}
52860484Sobrien	      if (tmp_bits > LITTLENUM_NUMBER_OF_BITS
52960484Sobrien		  || (lp[n] & mask[tmp_bits]) != mask[tmp_bits]
53060484Sobrien		  || (prec_bits != (precision * LITTLENUM_NUMBER_OF_BITS
53160484Sobrien				    - exponent_bits - 1)
53260484Sobrien#ifdef TC_I386
53360484Sobrien		      /* An extended precision float with only the integer
53460484Sobrien			 bit set would be invalid.  That must be converted
53560484Sobrien			 to the smallest normalized number.  */
53660484Sobrien		      && !(precision == X_PRECISION
53760484Sobrien			   && prec_bits == (precision * LITTLENUM_NUMBER_OF_BITS
53860484Sobrien					    - exponent_bits - 2))
53960484Sobrien#endif
54060484Sobrien		      ))
54133965Sjdp		{
54233965Sjdp		  unsigned long carry;
54333965Sjdp
54433965Sjdp		  for (carry = 1; carry && (lp >= words); lp--)
54533965Sjdp		    {
54633965Sjdp		      carry = *lp + carry;
54733965Sjdp		      *lp = carry;
54833965Sjdp		      carry >>= LITTLENUM_NUMBER_OF_BITS;
54933965Sjdp		    }
55033965Sjdp		}
55138889Sjdp	      else
55238889Sjdp		{
55338889Sjdp		  /* This is an overflow of the denormal numbers.  We
55438889Sjdp                     need to forget what we have produced, and instead
55538889Sjdp                     generate the smallest normalized number.  */
55638889Sjdp		  lp = words;
55738889Sjdp		  word1 = ((generic_floating_point_number.sign == '+')
55838889Sjdp			   ? 0
55938889Sjdp			   : (1 << (LITTLENUM_NUMBER_OF_BITS - 1)));
56038889Sjdp		  word1 |= (1
56138889Sjdp			    << ((LITTLENUM_NUMBER_OF_BITS - 1)
56238889Sjdp				- exponent_bits));
56338889Sjdp		  *lp++ = word1;
56460484Sobrien#ifdef TC_I386
56560484Sobrien		  /* Set the integer bit in the extended precision format.
56660484Sobrien		     This cannot happen on the m68k where the mantissa
56760484Sobrien		     just overflows into the integer bit above.  */
56860484Sobrien		  if (precision == X_PRECISION)
56960484Sobrien		    *lp++ = 1 << (LITTLENUM_NUMBER_OF_BITS - 1);
57060484Sobrien#endif
57138889Sjdp		  while (lp < words_end)
57238889Sjdp		    *lp++ = 0;
57338889Sjdp		}
57433965Sjdp	    }
57560484Sobrien	  else
57633965Sjdp	    *lp += 1;
57733965Sjdp	}
57833965Sjdp
57933965Sjdp      return return_value;
58033965Sjdp    }
58138889Sjdp  else if ((unsigned long) exponent_4 >= mask[exponent_bits])
58233965Sjdp    {
58377298Sobrien      /* Exponent overflow.  Lose immediately.  */
58433965Sjdp
58577298Sobrien      /* We leave return_value alone: admit we read the
58677298Sobrien	 number, but return a floating exception
58777298Sobrien	 because we can't encode the number.  */
58833965Sjdp      make_invalid_floating_point_number (words);
58933965Sjdp      return return_value;
59033965Sjdp    }
59133965Sjdp  else
59233965Sjdp    {
59333965Sjdp      word1 |= (exponent_4 << ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits))
59433965Sjdp	| next_bits ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits);
59533965Sjdp    }
59633965Sjdp
59733965Sjdp  *lp++ = word1;
59833965Sjdp
59933965Sjdp  /* X_PRECISION is special: on the 68k, it has 16 bits of zero in the
60077298Sobrien     middle.  Either way, it is then followed by a 1 bit.  */
60133965Sjdp  if (exponent_bits == 15 && precision == X_PRECISION)
60233965Sjdp    {
60333965Sjdp#ifdef TC_M68K
60433965Sjdp      *lp++ = 0;
60533965Sjdp#endif
60633965Sjdp      *lp++ = (1 << (LITTLENUM_NUMBER_OF_BITS - 1)
60733965Sjdp	       | next_bits (LITTLENUM_NUMBER_OF_BITS - 1));
60833965Sjdp    }
60933965Sjdp
61077298Sobrien  /* The rest of the words are just mantissa bits.  */
61133965Sjdp  while (lp < words_end)
61233965Sjdp    *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS);
61333965Sjdp
61433965Sjdp  if (next_bits (1))
61533965Sjdp    {
61633965Sjdp      unsigned long carry;
61777298Sobrien      /* Since the NEXT bit is a 1, round UP the mantissa.
61877298Sobrien	 The cunning design of these hidden-1 floats permits
61977298Sobrien	 us to let the mantissa overflow into the exponent, and
62077298Sobrien	 it 'does the right thing'. However, we lose if the
62177298Sobrien	 highest-order bit of the lowest-order word flips.
62277298Sobrien	 Is that clear?  */
62333965Sjdp
62433965Sjdp      /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
62533965Sjdp	 Please allow at least 1 more bit in carry than is in a LITTLENUM.
62633965Sjdp	 We need that extra bit to hold a carry during a LITTLENUM carry
62733965Sjdp	 propagation. Another extra bit (kept 0) will assure us that we
62833965Sjdp	 don't get a sticky sign bit after shifting right, and that
62933965Sjdp	 permits us to propagate the carry without any masking of bits.
63033965Sjdp	 #endif */
63160484Sobrien      for (carry = 1, lp--; carry; lp--)
63233965Sjdp	{
63333965Sjdp	  carry = *lp + carry;
63433965Sjdp	  *lp = carry;
63533965Sjdp	  carry >>= LITTLENUM_NUMBER_OF_BITS;
63660484Sobrien	  if (lp == words)
63760484Sobrien	    break;
63833965Sjdp	}
63933965Sjdp      if (precision == X_PRECISION && exponent_bits == 15)
64033965Sjdp	{
64133965Sjdp	  /* Extended precision numbers have an explicit integer bit
64233965Sjdp	     that we may have to restore.  */
64333965Sjdp	  if (lp == words)
64433965Sjdp	    {
64533965Sjdp#ifdef TC_M68K
64633965Sjdp	      /* On the m68k there is a gap of 16 bits.  We must
64777298Sobrien		 explicitly propagate the carry into the exponent.  */
64833965Sjdp	      words[0] += words[1];
64933965Sjdp	      words[1] = 0;
65033965Sjdp	      lp++;
65133965Sjdp#endif
65277298Sobrien	      /* Put back the integer bit.  */
65333965Sjdp	      lp[1] |= 1 << (LITTLENUM_NUMBER_OF_BITS - 1);
65433965Sjdp	    }
65577298Sobrien	}
65633965Sjdp      if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)))
65733965Sjdp	{
65877298Sobrien	  /* We leave return_value alone: admit we read the number,
65977298Sobrien	     but return a floating exception because we can't encode
66077298Sobrien	     the number.  */
66133965Sjdp	  *words &= ~(1 << (LITTLENUM_NUMBER_OF_BITS - 1));
66277298Sobrien#if 0
66377298Sobrien	  make_invalid_floating_point_number (words);
66477298Sobrien	  return return_value;
66577298Sobrien#endif
66633965Sjdp	}
66733965Sjdp    }
66877298Sobrien  return return_value;
66933965Sjdp}
67033965Sjdp
67177298Sobrien#if 0
67277298Sobrien/* Unused.  */
67333965Sjdp/* This routine is a real kludge.  Someone really should do it better,
67433965Sjdp   but I'm too lazy, and I don't understand this stuff all too well
67533965Sjdp   anyway. (JF)  */
67677298Sobrien
67733965Sjdpstatic void
67833965Sjdpint_to_gen (x)
67933965Sjdp     long x;
68033965Sjdp{
68133965Sjdp  char buf[20];
68233965Sjdp  char *bufp;
68333965Sjdp
68433965Sjdp  sprintf (buf, "%ld", x);
68533965Sjdp  bufp = &buf[0];
68633965Sjdp  if (atof_generic (&bufp, ".", EXP_CHARS, &generic_floating_point_number))
68760484Sobrien    as_bad (_("Error converting number to floating point (Exponent overflow?)"));
68833965Sjdp}
68933965Sjdp#endif
69033965Sjdp
69133965Sjdp#ifdef TEST
69233965Sjdpchar *
69333965Sjdpprint_gen (gen)
69433965Sjdp     FLONUM_TYPE *gen;
69533965Sjdp{
69633965Sjdp  FLONUM_TYPE f;
69733965Sjdp  LITTLENUM_TYPE arr[10];
69833965Sjdp  double dv;
69933965Sjdp  float fv;
70033965Sjdp  static char sbuf[40];
70133965Sjdp
70233965Sjdp  if (gen)
70333965Sjdp    {
70433965Sjdp      f = generic_floating_point_number;
70533965Sjdp      generic_floating_point_number = *gen;
70633965Sjdp    }
70733965Sjdp  gen_to_words (&arr[0], 4, 11);
70833965Sjdp  memcpy (&dv, &arr[0], sizeof (double));
70933965Sjdp  sprintf (sbuf, "%x %x %x %x %.14G   ", arr[0], arr[1], arr[2], arr[3], dv);
71033965Sjdp  gen_to_words (&arr[0], 2, 8);
71133965Sjdp  memcpy (&fv, &arr[0], sizeof (float));
71233965Sjdp  sprintf (sbuf + strlen (sbuf), "%x %x %.12g\n", arr[0], arr[1], fv);
71333965Sjdp
71433965Sjdp  if (gen)
71577298Sobrien    generic_floating_point_number = f;
71633965Sjdp
71733965Sjdp  return (sbuf);
71833965Sjdp}
71933965Sjdp
72033965Sjdp#endif
721