atof-ieee.c revision 60484
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[];
3233965Sjdp/* 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
4033965Sjdp/* 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
8033965Sjdp
8133965Sjdpstatic int bits_left_in_littlenum;
8233965Sjdpstatic int littlenums_left;
8333965Sjdpstatic LITTLENUM_TYPE *littlenum_pointer;
8433965Sjdp
8533965Sjdpstatic int
8633965Sjdpnext_bits (number_of_bits)
8733965Sjdp     int number_of_bits;
8833965Sjdp{
8933965Sjdp  int return_value;
9033965Sjdp
9133965Sjdp  if (!littlenums_left)
9233965Sjdp    return (0);
9333965Sjdp  if (number_of_bits >= bits_left_in_littlenum)
9433965Sjdp    {
9533965Sjdp      return_value = mask[bits_left_in_littlenum] & *littlenum_pointer;
9633965Sjdp      number_of_bits -= bits_left_in_littlenum;
9733965Sjdp      return_value <<= number_of_bits;
9833965Sjdp
9933965Sjdp      if (--littlenums_left)
10033965Sjdp	{
10133965Sjdp	  bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits;
10233965Sjdp	  --littlenum_pointer;
10333965Sjdp	  return_value |= (*littlenum_pointer >> bits_left_in_littlenum) & mask[number_of_bits];
10433965Sjdp	}
10533965Sjdp    }
10633965Sjdp  else
10733965Sjdp    {
10833965Sjdp      bits_left_in_littlenum -= number_of_bits;
10933965Sjdp      return_value = mask[number_of_bits] & (*littlenum_pointer >> bits_left_in_littlenum);
11033965Sjdp    }
11133965Sjdp  return (return_value);
11233965Sjdp}
11333965Sjdp
11433965Sjdp/* Num had better be less than LITTLENUM_NUMBER_OF_BITS */
11533965Sjdpstatic void
11633965Sjdpunget_bits (num)
11733965Sjdp     int num;
11833965Sjdp{
11933965Sjdp  if (!littlenums_left)
12033965Sjdp    {
12133965Sjdp      ++littlenum_pointer;
12233965Sjdp      ++littlenums_left;
12333965Sjdp      bits_left_in_littlenum = num;
12433965Sjdp    }
12533965Sjdp  else if (bits_left_in_littlenum + num > LITTLENUM_NUMBER_OF_BITS)
12633965Sjdp    {
12733965Sjdp      bits_left_in_littlenum = num - (LITTLENUM_NUMBER_OF_BITS - bits_left_in_littlenum);
12833965Sjdp      ++littlenum_pointer;
12933965Sjdp      ++littlenums_left;
13033965Sjdp    }
13133965Sjdp  else
13233965Sjdp    bits_left_in_littlenum += num;
13333965Sjdp}
13433965Sjdp
13533965Sjdpstatic void
13633965Sjdpmake_invalid_floating_point_number (words)
13733965Sjdp     LITTLENUM_TYPE *words;
13833965Sjdp{
13960484Sobrien  as_bad (_("cannot create floating-point number"));
14033965Sjdp  words[0] = (LITTLENUM_TYPE) ((unsigned) -1) >> 1; /* Zero the leftmost bit */
14133965Sjdp  words[1] = (LITTLENUM_TYPE) -1;
14233965Sjdp  words[2] = (LITTLENUM_TYPE) -1;
14333965Sjdp  words[3] = (LITTLENUM_TYPE) -1;
14433965Sjdp  words[4] = (LITTLENUM_TYPE) -1;
14533965Sjdp  words[5] = (LITTLENUM_TYPE) -1;
14633965Sjdp}
14733965Sjdp
14833965Sjdp/************************************************************************\
14933965Sjdp *	Warning: this returns 16-bit LITTLENUMs. It is up to the caller	*
15033965Sjdp *	to figure out any alignment problems and to conspire for the	*
15133965Sjdp *	bytes/word to be emitted in the right order. Bigendians beware!	*
15233965Sjdp *									*
15333965Sjdp\************************************************************************/
15433965Sjdp
15533965Sjdp/* Note that atof-ieee always has X and P precisions enabled.  it is up
15633965Sjdp   to md_atof to filter them out if the target machine does not support
15733965Sjdp   them.  */
15833965Sjdp
15933965Sjdp/* Returns pointer past text consumed. */
16033965Sjdpchar *
16133965Sjdpatof_ieee (str, what_kind, words)
16233965Sjdp     char *str;			/* Text to convert to binary. */
16360484Sobrien     int what_kind;		/* 'd', 'f', 'g', 'h' */
16433965Sjdp     LITTLENUM_TYPE *words;	/* Build the binary here. */
16533965Sjdp{
16633965Sjdp  /* Extra bits for zeroed low-order bits.  The 1st MAX_PRECISION are
16733965Sjdp     zeroed, the last contain flonum bits. */
16833965Sjdp  static LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
16933965Sjdp  char *return_value;
17033965Sjdp  /* Number of 16-bit words in the format. */
17133965Sjdp  int precision;
17233965Sjdp  long exponent_bits;
17333965Sjdp  FLONUM_TYPE save_gen_flonum;
17433965Sjdp
17533965Sjdp  /* We have to save the generic_floating_point_number because it
17633965Sjdp     contains storage allocation about the array of LITTLENUMs where
17733965Sjdp     the value is actually stored.  We will allocate our own array of
17833965Sjdp     littlenums below, but have to restore the global one on exit.  */
17933965Sjdp  save_gen_flonum = generic_floating_point_number;
18033965Sjdp
18133965Sjdp  return_value = str;
18233965Sjdp  generic_floating_point_number.low = bits + MAX_PRECISION;
18333965Sjdp  generic_floating_point_number.high = NULL;
18433965Sjdp  generic_floating_point_number.leader = NULL;
18533965Sjdp  generic_floating_point_number.exponent = 0;
18633965Sjdp  generic_floating_point_number.sign = '\0';
18733965Sjdp
18833965Sjdp  /* Use more LittleNums than seems necessary: the highest flonum may
18933965Sjdp     have 15 leading 0 bits, so could be useless. */
19033965Sjdp
19133965Sjdp  memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
19233965Sjdp
19333965Sjdp  switch (what_kind)
19433965Sjdp    {
19533965Sjdp    case 'f':
19633965Sjdp    case 'F':
19733965Sjdp    case 's':
19833965Sjdp    case 'S':
19933965Sjdp      precision = F_PRECISION;
20033965Sjdp      exponent_bits = 8;
20133965Sjdp      break;
20233965Sjdp
20333965Sjdp    case 'd':
20433965Sjdp    case 'D':
20533965Sjdp    case 'r':
20633965Sjdp    case 'R':
20733965Sjdp      precision = D_PRECISION;
20833965Sjdp      exponent_bits = 11;
20933965Sjdp      break;
21033965Sjdp
21133965Sjdp    case 'x':
21233965Sjdp    case 'X':
21333965Sjdp    case 'e':
21433965Sjdp    case 'E':
21533965Sjdp      precision = X_PRECISION;
21633965Sjdp      exponent_bits = 15;
21733965Sjdp      break;
21833965Sjdp
21933965Sjdp    case 'p':
22033965Sjdp    case 'P':
22133965Sjdp
22233965Sjdp      precision = P_PRECISION;
22333965Sjdp      exponent_bits = -1;
22433965Sjdp      break;
22533965Sjdp
22633965Sjdp    default:
22733965Sjdp      make_invalid_floating_point_number (words);
22833965Sjdp      return (NULL);
22933965Sjdp    }
23033965Sjdp
23133965Sjdp  generic_floating_point_number.high
23233965Sjdp    = generic_floating_point_number.low + precision - 1 + GUARD;
23333965Sjdp
23433965Sjdp  if (atof_generic (&return_value, ".", EXP_CHARS,
23533965Sjdp		    &generic_floating_point_number))
23633965Sjdp    {
23733965Sjdp      make_invalid_floating_point_number (words);
23833965Sjdp      return (NULL);
23933965Sjdp    }
24033965Sjdp  gen_to_words (words, precision, exponent_bits);
24133965Sjdp
24233965Sjdp  /* Restore the generic_floating_point_number's storage alloc (and
24333965Sjdp     everything else).  */
24433965Sjdp  generic_floating_point_number = save_gen_flonum;
24533965Sjdp
24633965Sjdp  return return_value;
24733965Sjdp}
24833965Sjdp
24933965Sjdp/* Turn generic_floating_point_number into a real float/double/extended.  */
25033965Sjdpint
25133965Sjdpgen_to_words (words, precision, exponent_bits)
25233965Sjdp     LITTLENUM_TYPE *words;
25333965Sjdp     int precision;
25433965Sjdp     long exponent_bits;
25533965Sjdp{
25633965Sjdp  int return_value = 0;
25733965Sjdp
25833965Sjdp  long exponent_1;
25933965Sjdp  long exponent_2;
26033965Sjdp  long exponent_3;
26133965Sjdp  long exponent_4;
26233965Sjdp  int exponent_skippage;
26333965Sjdp  LITTLENUM_TYPE word1;
26433965Sjdp  LITTLENUM_TYPE *lp;
26533965Sjdp  LITTLENUM_TYPE *words_end;
26633965Sjdp
26733965Sjdp  words_end = words + precision;
26833965Sjdp#ifdef TC_M68K
26933965Sjdp  if (precision == X_PRECISION)
27033965Sjdp    /* On the m68k the extended precision format has a gap of 16 bits
27133965Sjdp       between the exponent and the mantissa.  */
27233965Sjdp    words_end++;
27333965Sjdp#endif
27433965Sjdp
27533965Sjdp  if (generic_floating_point_number.low > generic_floating_point_number.leader)
27633965Sjdp    {
27733965Sjdp      /* 0.0e0 seen. */
27833965Sjdp      if (generic_floating_point_number.sign == '+')
27933965Sjdp	words[0] = 0x0000;
28033965Sjdp      else
28133965Sjdp	words[0] = 0x8000;
28233965Sjdp      memset (&words[1], '\0',
28333965Sjdp	      (words_end - words - 1) * sizeof (LITTLENUM_TYPE));
28433965Sjdp      return (return_value);
28533965Sjdp    }
28633965Sjdp
28733965Sjdp  /* NaN:  Do the right thing */
28833965Sjdp  if (generic_floating_point_number.sign == 0)
28933965Sjdp    {
29033965Sjdp      if (precision == F_PRECISION)
29133965Sjdp	{
29233965Sjdp	  words[0] = 0x7fff;
29333965Sjdp	  words[1] = 0xffff;
29433965Sjdp	}
29533965Sjdp      else if (precision == X_PRECISION)
29633965Sjdp	{
29733965Sjdp#ifdef TC_M68K
29833965Sjdp	  words[0] = 0x7fff;
29933965Sjdp	  words[1] = 0;
30033965Sjdp	  words[2] = 0xffff;
30133965Sjdp	  words[3] = 0xffff;
30233965Sjdp	  words[4] = 0xffff;
30333965Sjdp	  words[5] = 0xffff;
30433965Sjdp#else /* ! TC_M68K */
30533965Sjdp#ifdef TC_I386
30633965Sjdp	  words[0] = 0xffff;
30733965Sjdp	  words[1] = 0xc000;
30833965Sjdp	  words[2] = 0;
30933965Sjdp	  words[3] = 0;
31033965Sjdp	  words[4] = 0;
31133965Sjdp#else /* ! TC_I386 */
31233965Sjdp	  abort ();
31333965Sjdp#endif /* ! TC_I386 */
31433965Sjdp#endif /* ! TC_M68K */
31533965Sjdp	}
31633965Sjdp      else
31733965Sjdp	{
31833965Sjdp	  words[0] = 0x7fff;
31933965Sjdp	  words[1] = 0xffff;
32033965Sjdp	  words[2] = 0xffff;
32133965Sjdp	  words[3] = 0xffff;
32233965Sjdp	}
32333965Sjdp      return return_value;
32433965Sjdp    }
32533965Sjdp  else if (generic_floating_point_number.sign == 'P')
32633965Sjdp    {
32733965Sjdp      /* +INF:  Do the right thing */
32833965Sjdp      if (precision == F_PRECISION)
32933965Sjdp	{
33033965Sjdp	  words[0] = 0x7f80;
33133965Sjdp	  words[1] = 0;
33233965Sjdp	}
33333965Sjdp      else if (precision == X_PRECISION)
33433965Sjdp	{
33533965Sjdp#ifdef TC_M68K
33633965Sjdp	  words[0] = 0x7fff;
33733965Sjdp	  words[1] = 0;
33833965Sjdp	  words[2] = 0;
33933965Sjdp	  words[3] = 0;
34033965Sjdp	  words[4] = 0;
34133965Sjdp	  words[5] = 0;
34233965Sjdp#else /* ! TC_M68K */
34333965Sjdp#ifdef TC_I386
34433965Sjdp	  words[0] = 0x7fff;
34533965Sjdp	  words[1] = 0x8000;
34633965Sjdp	  words[2] = 0;
34733965Sjdp	  words[3] = 0;
34833965Sjdp	  words[4] = 0;
34933965Sjdp#else /* ! TC_I386 */
35033965Sjdp	  abort ();
35133965Sjdp#endif /* ! TC_I386 */
35233965Sjdp#endif /* ! TC_M68K */
35333965Sjdp	}
35433965Sjdp      else
35533965Sjdp	{
35633965Sjdp	  words[0] = 0x7ff0;
35733965Sjdp	  words[1] = 0;
35833965Sjdp	  words[2] = 0;
35933965Sjdp	  words[3] = 0;
36033965Sjdp	}
36133965Sjdp      return (return_value);
36233965Sjdp    }
36333965Sjdp  else if (generic_floating_point_number.sign == 'N')
36433965Sjdp    {
36533965Sjdp      /* Negative INF */
36633965Sjdp      if (precision == F_PRECISION)
36733965Sjdp	{
36833965Sjdp	  words[0] = 0xff80;
36933965Sjdp	  words[1] = 0x0;
37033965Sjdp	}
37133965Sjdp      else if (precision == X_PRECISION)
37233965Sjdp	{
37333965Sjdp#ifdef TC_M68K
37433965Sjdp	  words[0] = 0xffff;
37533965Sjdp	  words[1] = 0;
37633965Sjdp	  words[2] = 0;
37733965Sjdp	  words[3] = 0;
37833965Sjdp	  words[4] = 0;
37933965Sjdp	  words[5] = 0;
38033965Sjdp#else /* ! TC_M68K */
38133965Sjdp#ifdef TC_I386
38233965Sjdp	  words[0] = 0xffff;
38333965Sjdp	  words[1] = 0x8000;
38433965Sjdp	  words[2] = 0;
38533965Sjdp	  words[3] = 0;
38633965Sjdp	  words[4] = 0;
38733965Sjdp#else /* ! TC_I386 */
38833965Sjdp	  abort ();
38933965Sjdp#endif /* ! TC_I386 */
39033965Sjdp#endif /* ! TC_M68K */
39133965Sjdp	}
39233965Sjdp      else
39333965Sjdp	{
39433965Sjdp	  words[0] = 0xfff0;
39533965Sjdp	  words[1] = 0x0;
39633965Sjdp	  words[2] = 0x0;
39733965Sjdp	  words[3] = 0x0;
39833965Sjdp	}
39933965Sjdp      return (return_value);
40033965Sjdp    }
40133965Sjdp  /*
40233965Sjdp   * The floating point formats we support have:
40333965Sjdp   * Bit 15 is sign bit.
40433965Sjdp   * Bits 14:n are excess-whatever exponent.
40533965Sjdp   * Bits n-1:0 (if any) are most significant bits of fraction.
40633965Sjdp   * Bits 15:0 of the next word(s) are the next most significant bits.
40733965Sjdp   *
40833965Sjdp   * So we need: number of bits of exponent, number of bits of
40933965Sjdp   * mantissa.
41033965Sjdp   */
41133965Sjdp  bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
41233965Sjdp  littlenum_pointer = generic_floating_point_number.leader;
41333965Sjdp  littlenums_left = (1
41433965Sjdp		     + generic_floating_point_number.leader
41533965Sjdp		     - generic_floating_point_number.low);
41633965Sjdp  /* Seek (and forget) 1st significant bit */
41733965Sjdp  for (exponent_skippage = 0; !next_bits (1); ++exponent_skippage);;
41833965Sjdp  exponent_1 = (generic_floating_point_number.exponent
41933965Sjdp		+ generic_floating_point_number.leader
42033965Sjdp		+ 1
42133965Sjdp		- generic_floating_point_number.low);
42233965Sjdp  /* Radix LITTLENUM_RADIX, point just higher than
42333965Sjdp     generic_floating_point_number.leader. */
42433965Sjdp  exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
42533965Sjdp  /* Radix 2. */
42633965Sjdp  exponent_3 = exponent_2 - exponent_skippage;
42733965Sjdp  /* Forget leading zeros, forget 1st bit. */
42833965Sjdp  exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2);
42933965Sjdp  /* Offset exponent. */
43033965Sjdp
43133965Sjdp  lp = words;
43233965Sjdp
43333965Sjdp  /* Word 1. Sign, exponent and perhaps high bits. */
43433965Sjdp  word1 = ((generic_floating_point_number.sign == '+')
43533965Sjdp	   ? 0
43633965Sjdp	   : (1 << (LITTLENUM_NUMBER_OF_BITS - 1)));
43733965Sjdp
43833965Sjdp  /* Assume 2's complement integers. */
43933965Sjdp  if (exponent_4 <= 0)
44033965Sjdp    {
44133965Sjdp      int prec_bits;
44233965Sjdp      int num_bits;
44333965Sjdp
44433965Sjdp      unget_bits (1);
44533965Sjdp      num_bits = -exponent_4;
44633965Sjdp      prec_bits = LITTLENUM_NUMBER_OF_BITS * precision - (exponent_bits + 1 + num_bits);
44733965Sjdp#ifdef TC_I386
44833965Sjdp      if (precision == X_PRECISION && exponent_bits == 15)
44933965Sjdp	{
45033965Sjdp	  /* On the i386 a denormalized extended precision float is
45133965Sjdp	     shifted down by one, effectively decreasing the exponent
45233965Sjdp	     bias by one.  */
45333965Sjdp	  prec_bits -= 1;
45433965Sjdp	  num_bits += 1;
45533965Sjdp	}
45633965Sjdp#endif
45733965Sjdp
45833965Sjdp      if (num_bits >= LITTLENUM_NUMBER_OF_BITS - exponent_bits)
45933965Sjdp	{
46033965Sjdp	  /* Bigger than one littlenum */
46133965Sjdp	  num_bits -= (LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits;
46233965Sjdp	  *lp++ = word1;
46360484Sobrien	  if (num_bits + exponent_bits + 1 > precision * LITTLENUM_NUMBER_OF_BITS)
46433965Sjdp	    {
46533965Sjdp	      /* Exponent overflow */
46633965Sjdp	      make_invalid_floating_point_number (words);
46733965Sjdp	      return (return_value);
46833965Sjdp	    }
46933965Sjdp#ifdef TC_M68K
47033965Sjdp	  if (precision == X_PRECISION && exponent_bits == 15)
47133965Sjdp	    *lp++ = 0;
47233965Sjdp#endif
47333965Sjdp	  while (num_bits >= LITTLENUM_NUMBER_OF_BITS)
47433965Sjdp	    {
47533965Sjdp	      num_bits -= LITTLENUM_NUMBER_OF_BITS;
47633965Sjdp	      *lp++ = 0;
47733965Sjdp	    }
47833965Sjdp	  if (num_bits)
47933965Sjdp	    *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - (num_bits));
48033965Sjdp	}
48133965Sjdp      else
48233965Sjdp	{
48333965Sjdp	  if (precision == X_PRECISION && exponent_bits == 15)
48433965Sjdp	    {
48533965Sjdp	      *lp++ = word1;
48633965Sjdp#ifdef TC_M68K
48733965Sjdp	      *lp++ = 0;
48833965Sjdp#endif
48933965Sjdp	      *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - num_bits);
49033965Sjdp	    }
49133965Sjdp	  else
49233965Sjdp	    {
49333965Sjdp	      word1 |= next_bits ((LITTLENUM_NUMBER_OF_BITS - 1) - (exponent_bits + num_bits));
49433965Sjdp	      *lp++ = word1;
49533965Sjdp	    }
49633965Sjdp	}
49733965Sjdp      while (lp < words_end)
49833965Sjdp	*lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS);
49933965Sjdp
50033965Sjdp      /* Round the mantissa up, but don't change the number */
50133965Sjdp      if (next_bits (1))
50233965Sjdp	{
50333965Sjdp	  --lp;
50460484Sobrien	  if (prec_bits >= LITTLENUM_NUMBER_OF_BITS)
50533965Sjdp	    {
50633965Sjdp	      int n = 0;
50733965Sjdp	      int tmp_bits;
50833965Sjdp
50933965Sjdp	      n = 0;
51033965Sjdp	      tmp_bits = prec_bits;
51133965Sjdp	      while (tmp_bits > LITTLENUM_NUMBER_OF_BITS)
51233965Sjdp		{
51333965Sjdp		  if (lp[n] != (LITTLENUM_TYPE) - 1)
51433965Sjdp		    break;
51533965Sjdp		  --n;
51633965Sjdp		  tmp_bits -= LITTLENUM_NUMBER_OF_BITS;
51733965Sjdp		}
51860484Sobrien	      if (tmp_bits > LITTLENUM_NUMBER_OF_BITS
51960484Sobrien		  || (lp[n] & mask[tmp_bits]) != mask[tmp_bits]
52060484Sobrien		  || (prec_bits != (precision * LITTLENUM_NUMBER_OF_BITS
52160484Sobrien				    - exponent_bits - 1)
52260484Sobrien#ifdef TC_I386
52360484Sobrien		      /* An extended precision float with only the integer
52460484Sobrien			 bit set would be invalid.  That must be converted
52560484Sobrien			 to the smallest normalized number.  */
52660484Sobrien		      && !(precision == X_PRECISION
52760484Sobrien			   && prec_bits == (precision * LITTLENUM_NUMBER_OF_BITS
52860484Sobrien					    - exponent_bits - 2))
52960484Sobrien#endif
53060484Sobrien		      ))
53133965Sjdp		{
53233965Sjdp		  unsigned long carry;
53333965Sjdp
53433965Sjdp		  for (carry = 1; carry && (lp >= words); lp--)
53533965Sjdp		    {
53633965Sjdp		      carry = *lp + carry;
53733965Sjdp		      *lp = carry;
53833965Sjdp		      carry >>= LITTLENUM_NUMBER_OF_BITS;
53933965Sjdp		    }
54033965Sjdp		}
54138889Sjdp	      else
54238889Sjdp		{
54338889Sjdp		  /* This is an overflow of the denormal numbers.  We
54438889Sjdp                     need to forget what we have produced, and instead
54538889Sjdp                     generate the smallest normalized number.  */
54638889Sjdp		  lp = words;
54738889Sjdp		  word1 = ((generic_floating_point_number.sign == '+')
54838889Sjdp			   ? 0
54938889Sjdp			   : (1 << (LITTLENUM_NUMBER_OF_BITS - 1)));
55038889Sjdp		  word1 |= (1
55138889Sjdp			    << ((LITTLENUM_NUMBER_OF_BITS - 1)
55238889Sjdp				- exponent_bits));
55338889Sjdp		  *lp++ = word1;
55460484Sobrien#ifdef TC_I386
55560484Sobrien		  /* Set the integer bit in the extended precision format.
55660484Sobrien		     This cannot happen on the m68k where the mantissa
55760484Sobrien		     just overflows into the integer bit above.  */
55860484Sobrien		  if (precision == X_PRECISION)
55960484Sobrien		    *lp++ = 1 << (LITTLENUM_NUMBER_OF_BITS - 1);
56060484Sobrien#endif
56138889Sjdp		  while (lp < words_end)
56238889Sjdp		    *lp++ = 0;
56338889Sjdp		}
56433965Sjdp	    }
56560484Sobrien	  else
56633965Sjdp	    *lp += 1;
56733965Sjdp	}
56833965Sjdp
56933965Sjdp      return return_value;
57033965Sjdp    }
57138889Sjdp  else if ((unsigned long) exponent_4 >= mask[exponent_bits])
57233965Sjdp    {
57333965Sjdp      /*
57433965Sjdp       * Exponent overflow. Lose immediately.
57533965Sjdp       */
57633965Sjdp
57733965Sjdp      /*
57833965Sjdp       * We leave return_value alone: admit we read the
57933965Sjdp       * number, but return a floating exception
58033965Sjdp       * because we can't encode the number.
58133965Sjdp       */
58233965Sjdp      make_invalid_floating_point_number (words);
58333965Sjdp      return return_value;
58433965Sjdp    }
58533965Sjdp  else
58633965Sjdp    {
58733965Sjdp      word1 |= (exponent_4 << ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits))
58833965Sjdp	| next_bits ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits);
58933965Sjdp    }
59033965Sjdp
59133965Sjdp  *lp++ = word1;
59233965Sjdp
59333965Sjdp  /* X_PRECISION is special: on the 68k, it has 16 bits of zero in the
59433965Sjdp     middle.  Either way, it is then followed by a 1 bit. */
59533965Sjdp  if (exponent_bits == 15 && precision == X_PRECISION)
59633965Sjdp    {
59733965Sjdp#ifdef TC_M68K
59833965Sjdp      *lp++ = 0;
59933965Sjdp#endif
60033965Sjdp      *lp++ = (1 << (LITTLENUM_NUMBER_OF_BITS - 1)
60133965Sjdp	       | next_bits (LITTLENUM_NUMBER_OF_BITS - 1));
60233965Sjdp    }
60333965Sjdp
60433965Sjdp  /* The rest of the words are just mantissa bits. */
60533965Sjdp  while (lp < words_end)
60633965Sjdp    *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS);
60733965Sjdp
60833965Sjdp  if (next_bits (1))
60933965Sjdp    {
61033965Sjdp      unsigned long carry;
61133965Sjdp      /*
61233965Sjdp       * Since the NEXT bit is a 1, round UP the mantissa.
61333965Sjdp       * The cunning design of these hidden-1 floats permits
61433965Sjdp       * us to let the mantissa overflow into the exponent, and
61533965Sjdp       * it 'does the right thing'. However, we lose if the
61633965Sjdp       * highest-order bit of the lowest-order word flips.
61733965Sjdp       * Is that clear?
61833965Sjdp       */
61933965Sjdp
62033965Sjdp      /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
62133965Sjdp	 Please allow at least 1 more bit in carry than is in a LITTLENUM.
62233965Sjdp	 We need that extra bit to hold a carry during a LITTLENUM carry
62333965Sjdp	 propagation. Another extra bit (kept 0) will assure us that we
62433965Sjdp	 don't get a sticky sign bit after shifting right, and that
62533965Sjdp	 permits us to propagate the carry without any masking of bits.
62633965Sjdp	 #endif */
62760484Sobrien      for (carry = 1, lp--; carry; lp--)
62833965Sjdp	{
62933965Sjdp	  carry = *lp + carry;
63033965Sjdp	  *lp = carry;
63133965Sjdp	  carry >>= LITTLENUM_NUMBER_OF_BITS;
63260484Sobrien	  if (lp == words)
63360484Sobrien	    break;
63433965Sjdp	}
63533965Sjdp      if (precision == X_PRECISION && exponent_bits == 15)
63633965Sjdp	{
63733965Sjdp	  /* Extended precision numbers have an explicit integer bit
63833965Sjdp	     that we may have to restore.  */
63933965Sjdp	  if (lp == words)
64033965Sjdp	    {
64133965Sjdp#ifdef TC_M68K
64233965Sjdp	      /* On the m68k there is a gap of 16 bits.  We must
64333965Sjdp		 explicitly propagate the carry into the exponent. */
64433965Sjdp	      words[0] += words[1];
64533965Sjdp	      words[1] = 0;
64633965Sjdp	      lp++;
64733965Sjdp#endif
64833965Sjdp	      /* Put back the integer bit.  */
64933965Sjdp	      lp[1] |= 1 << (LITTLENUM_NUMBER_OF_BITS - 1);
65033965Sjdp	    }
65133965Sjdp 	}
65233965Sjdp      if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)))
65333965Sjdp	{
65433965Sjdp	  /* We leave return_value alone: admit we read the
65533965Sjdp	   * number, but return a floating exception
65633965Sjdp	   * because we can't encode the number.
65733965Sjdp	   */
65833965Sjdp	  *words &= ~(1 << (LITTLENUM_NUMBER_OF_BITS - 1));
65933965Sjdp	  /* make_invalid_floating_point_number (words); */
66033965Sjdp	  /* return return_value; */
66133965Sjdp	}
66233965Sjdp    }
66333965Sjdp  return (return_value);
66433965Sjdp}
66533965Sjdp
66633965Sjdp#if 0 /* unused */
66733965Sjdp/* This routine is a real kludge.  Someone really should do it better,
66833965Sjdp   but I'm too lazy, and I don't understand this stuff all too well
66933965Sjdp   anyway. (JF)  */
67033965Sjdpstatic void
67133965Sjdpint_to_gen (x)
67233965Sjdp     long x;
67333965Sjdp{
67433965Sjdp  char buf[20];
67533965Sjdp  char *bufp;
67633965Sjdp
67733965Sjdp  sprintf (buf, "%ld", x);
67833965Sjdp  bufp = &buf[0];
67933965Sjdp  if (atof_generic (&bufp, ".", EXP_CHARS, &generic_floating_point_number))
68060484Sobrien    as_bad (_("Error converting number to floating point (Exponent overflow?)"));
68133965Sjdp}
68233965Sjdp#endif
68333965Sjdp
68433965Sjdp#ifdef TEST
68533965Sjdpchar *
68633965Sjdpprint_gen (gen)
68733965Sjdp     FLONUM_TYPE *gen;
68833965Sjdp{
68933965Sjdp  FLONUM_TYPE f;
69033965Sjdp  LITTLENUM_TYPE arr[10];
69133965Sjdp  double dv;
69233965Sjdp  float fv;
69333965Sjdp  static char sbuf[40];
69433965Sjdp
69533965Sjdp  if (gen)
69633965Sjdp    {
69733965Sjdp      f = generic_floating_point_number;
69833965Sjdp      generic_floating_point_number = *gen;
69933965Sjdp    }
70033965Sjdp  gen_to_words (&arr[0], 4, 11);
70133965Sjdp  memcpy (&dv, &arr[0], sizeof (double));
70233965Sjdp  sprintf (sbuf, "%x %x %x %x %.14G   ", arr[0], arr[1], arr[2], arr[3], dv);
70333965Sjdp  gen_to_words (&arr[0], 2, 8);
70433965Sjdp  memcpy (&fv, &arr[0], sizeof (float));
70533965Sjdp  sprintf (sbuf + strlen (sbuf), "%x %x %.12g\n", arr[0], arr[1], fv);
70633965Sjdp
70733965Sjdp  if (gen)
70833965Sjdp    {
70933965Sjdp      generic_floating_point_number = f;
71033965Sjdp    }
71133965Sjdp
71233965Sjdp  return (sbuf);
71333965Sjdp}
71433965Sjdp
71533965Sjdp#endif
71633965Sjdp
71733965Sjdp/* end of atof-ieee.c */
718