133965Sjdp/* atof_ieee.c - turn a Flonum into an IEEE floating point number
2218822Sdim   Copyright 1987, 1992, 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2005
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
19218822Sdim   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20218822Sdim   02110-1301, USA.  */
2133965Sjdp
2233965Sjdp#include "as.h"
2333965Sjdp
2433965Sjdp/* Flonums returned here.  */
2533965Sjdpextern FLONUM_TYPE generic_floating_point_number;
2633965Sjdp
2733965Sjdpextern const char EXP_CHARS[];
2877298Sobrien/* Precision in LittleNums.  */
2933965Sjdp/* Don't count the gap in the m68k extended precision format.  */
30218822Sdim#define MAX_PRECISION  5
31218822Sdim#define F_PRECISION    2
32218822Sdim#define D_PRECISION    4
33218822Sdim#define X_PRECISION    5
34218822Sdim#define P_PRECISION    5
3533965Sjdp
3677298Sobrien/* Length in LittleNums of guard bits.  */
37218822Sdim#define GUARD          2
3833965Sjdp
3978828Sobrien#ifndef TC_LARGEST_EXPONENT_IS_NORMAL
40104834Sobrien#define TC_LARGEST_EXPONENT_IS_NORMAL(PRECISION) 0
4178828Sobrien#endif
4278828Sobrien
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
85218822Sdimnext_bits (int number_of_bits)
8633965Sjdp{
8733965Sjdp  int return_value;
8833965Sjdp
8933965Sjdp  if (!littlenums_left)
90218822Sdim    return 0;
91218822Sdim
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
119218822Sdimunget_bits (int num)
12033965Sjdp{
12133965Sjdp  if (!littlenums_left)
12233965Sjdp    {
12333965Sjdp      ++littlenum_pointer;
12433965Sjdp      ++littlenums_left;
12533965Sjdp      bits_left_in_littlenum = num;
12633965Sjdp    }
12733965Sjdp  else if (bits_left_in_littlenum + num > LITTLENUM_NUMBER_OF_BITS)
12833965Sjdp    {
12977298Sobrien      bits_left_in_littlenum =
13077298Sobrien	num - (LITTLENUM_NUMBER_OF_BITS - bits_left_in_littlenum);
13133965Sjdp      ++littlenum_pointer;
13233965Sjdp      ++littlenums_left;
13333965Sjdp    }
13433965Sjdp  else
13533965Sjdp    bits_left_in_littlenum += num;
13633965Sjdp}
13733965Sjdp
13833965Sjdpstatic void
139218822Sdimmake_invalid_floating_point_number (LITTLENUM_TYPE *words)
14033965Sjdp{
14160484Sobrien  as_bad (_("cannot create floating-point number"));
14277298Sobrien  /* Zero the leftmost bit.  */
14377298Sobrien  words[0] = (LITTLENUM_TYPE) ((unsigned) -1) >> 1;
14433965Sjdp  words[1] = (LITTLENUM_TYPE) -1;
14533965Sjdp  words[2] = (LITTLENUM_TYPE) -1;
14633965Sjdp  words[3] = (LITTLENUM_TYPE) -1;
14733965Sjdp  words[4] = (LITTLENUM_TYPE) -1;
14833965Sjdp  words[5] = (LITTLENUM_TYPE) -1;
14933965Sjdp}
15033965Sjdp
15177298Sobrien/* Warning: This returns 16-bit LITTLENUMs.  It is up to the caller to
15277298Sobrien   figure out any alignment problems and to conspire for the
15377298Sobrien   bytes/word to be emitted in the right order.  Bigendians beware!  */
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
15977298Sobrien/* Returns pointer past text consumed.  */
16077298Sobrien
16133965Sjdpchar *
162218822Sdimatof_ieee (char *str,			/* Text to convert to binary.  */
163218822Sdim	   int what_kind,		/* 'd', 'f', 'g', 'h'.  */
164218822Sdim	   LITTLENUM_TYPE *words)	/* Build the binary here.  */
16533965Sjdp{
16677298Sobrien  /* Extra bits for zeroed low-order bits.
16777298Sobrien     The 1st MAX_PRECISION are zeroed, the last contain flonum bits.  */
16833965Sjdp  static LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
16933965Sjdp  char *return_value;
17077298Sobrien  /* 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
18977298Sobrien     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);
238218822Sdim      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.  */
25077298Sobrien
25133965Sjdpint
252218822Sdimgen_to_words (LITTLENUM_TYPE *words, int precision, long exponent_bits)
25333965Sjdp{
25433965Sjdp  int return_value = 0;
25533965Sjdp
25633965Sjdp  long exponent_1;
25733965Sjdp  long exponent_2;
25833965Sjdp  long exponent_3;
25933965Sjdp  long exponent_4;
26033965Sjdp  int exponent_skippage;
26133965Sjdp  LITTLENUM_TYPE word1;
26233965Sjdp  LITTLENUM_TYPE *lp;
26333965Sjdp  LITTLENUM_TYPE *words_end;
26433965Sjdp
26533965Sjdp  words_end = words + precision;
26633965Sjdp#ifdef TC_M68K
26733965Sjdp  if (precision == X_PRECISION)
26833965Sjdp    /* On the m68k the extended precision format has a gap of 16 bits
26933965Sjdp       between the exponent and the mantissa.  */
27033965Sjdp    words_end++;
27133965Sjdp#endif
27233965Sjdp
27333965Sjdp  if (generic_floating_point_number.low > generic_floating_point_number.leader)
27433965Sjdp    {
27577298Sobrien      /* 0.0e0 seen.  */
27633965Sjdp      if (generic_floating_point_number.sign == '+')
27733965Sjdp	words[0] = 0x0000;
27833965Sjdp      else
27933965Sjdp	words[0] = 0x8000;
28033965Sjdp      memset (&words[1], '\0',
28133965Sjdp	      (words_end - words - 1) * sizeof (LITTLENUM_TYPE));
28277298Sobrien      return return_value;
28333965Sjdp    }
28433965Sjdp
28577298Sobrien  /* NaN:  Do the right thing.  */
28633965Sjdp  if (generic_floating_point_number.sign == 0)
28733965Sjdp    {
288104834Sobrien      if (TC_LARGEST_EXPONENT_IS_NORMAL (precision))
28978828Sobrien	as_warn ("NaNs are not supported by this target\n");
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;
30477298Sobrien#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;
31177298Sobrien#else /* ! TC_I386  */
31233965Sjdp	  abort ();
31377298Sobrien#endif /* ! TC_I386  */
31477298Sobrien#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    {
327104834Sobrien      if (TC_LARGEST_EXPONENT_IS_NORMAL (precision))
32878828Sobrien	as_warn ("Infinities are not supported by this target\n");
32978828Sobrien
33077298Sobrien      /* +INF:  Do the right thing.  */
33133965Sjdp      if (precision == F_PRECISION)
33233965Sjdp	{
33333965Sjdp	  words[0] = 0x7f80;
33433965Sjdp	  words[1] = 0;
33533965Sjdp	}
33633965Sjdp      else if (precision == X_PRECISION)
33733965Sjdp	{
33833965Sjdp#ifdef TC_M68K
33933965Sjdp	  words[0] = 0x7fff;
34033965Sjdp	  words[1] = 0;
34133965Sjdp	  words[2] = 0;
34233965Sjdp	  words[3] = 0;
34333965Sjdp	  words[4] = 0;
34433965Sjdp	  words[5] = 0;
34577298Sobrien#else /* ! TC_M68K  */
34633965Sjdp#ifdef TC_I386
34733965Sjdp	  words[0] = 0x7fff;
34833965Sjdp	  words[1] = 0x8000;
34933965Sjdp	  words[2] = 0;
35033965Sjdp	  words[3] = 0;
35133965Sjdp	  words[4] = 0;
35277298Sobrien#else /* ! TC_I386  */
35333965Sjdp	  abort ();
35477298Sobrien#endif /* ! TC_I386  */
35577298Sobrien#endif /* ! TC_M68K  */
35633965Sjdp	}
35733965Sjdp      else
35833965Sjdp	{
35933965Sjdp	  words[0] = 0x7ff0;
36033965Sjdp	  words[1] = 0;
36133965Sjdp	  words[2] = 0;
36233965Sjdp	  words[3] = 0;
36333965Sjdp	}
36477298Sobrien      return return_value;
36533965Sjdp    }
36633965Sjdp  else if (generic_floating_point_number.sign == 'N')
36733965Sjdp    {
368104834Sobrien      if (TC_LARGEST_EXPONENT_IS_NORMAL (precision))
36978828Sobrien	as_warn ("Infinities are not supported by this target\n");
37078828Sobrien
37177298Sobrien      /* Negative INF.  */
37233965Sjdp      if (precision == F_PRECISION)
37333965Sjdp	{
37433965Sjdp	  words[0] = 0xff80;
37533965Sjdp	  words[1] = 0x0;
37633965Sjdp	}
37733965Sjdp      else if (precision == X_PRECISION)
37833965Sjdp	{
37933965Sjdp#ifdef TC_M68K
38033965Sjdp	  words[0] = 0xffff;
38133965Sjdp	  words[1] = 0;
38233965Sjdp	  words[2] = 0;
38333965Sjdp	  words[3] = 0;
38433965Sjdp	  words[4] = 0;
38533965Sjdp	  words[5] = 0;
38677298Sobrien#else /* ! TC_M68K  */
38733965Sjdp#ifdef TC_I386
38833965Sjdp	  words[0] = 0xffff;
38933965Sjdp	  words[1] = 0x8000;
39033965Sjdp	  words[2] = 0;
39133965Sjdp	  words[3] = 0;
39233965Sjdp	  words[4] = 0;
39377298Sobrien#else /* ! TC_I386  */
39433965Sjdp	  abort ();
39577298Sobrien#endif /* ! TC_I386  */
39677298Sobrien#endif /* ! TC_M68K  */
39733965Sjdp	}
39833965Sjdp      else
39933965Sjdp	{
40033965Sjdp	  words[0] = 0xfff0;
40133965Sjdp	  words[1] = 0x0;
40233965Sjdp	  words[2] = 0x0;
40333965Sjdp	  words[3] = 0x0;
40433965Sjdp	}
40577298Sobrien      return return_value;
40633965Sjdp    }
40777298Sobrien
40877298Sobrien  /* The floating point formats we support have:
40977298Sobrien     Bit 15 is sign bit.
41077298Sobrien     Bits 14:n are excess-whatever exponent.
41177298Sobrien     Bits n-1:0 (if any) are most significant bits of fraction.
41277298Sobrien     Bits 15:0 of the next word(s) are the next most significant bits.
41377298Sobrien
41477298Sobrien     So we need: number of bits of exponent, number of bits of
41577298Sobrien     mantissa.  */
41633965Sjdp  bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
41733965Sjdp  littlenum_pointer = generic_floating_point_number.leader;
41833965Sjdp  littlenums_left = (1
41933965Sjdp		     + generic_floating_point_number.leader
42033965Sjdp		     - generic_floating_point_number.low);
42177298Sobrien
42277298Sobrien  /* Seek (and forget) 1st significant bit.  */
42333965Sjdp  for (exponent_skippage = 0; !next_bits (1); ++exponent_skippage);;
42433965Sjdp  exponent_1 = (generic_floating_point_number.exponent
42533965Sjdp		+ generic_floating_point_number.leader
42633965Sjdp		+ 1
42733965Sjdp		- generic_floating_point_number.low);
42877298Sobrien
42933965Sjdp  /* Radix LITTLENUM_RADIX, point just higher than
43077298Sobrien     generic_floating_point_number.leader.  */
43133965Sjdp  exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
43277298Sobrien
43377298Sobrien  /* Radix 2.  */
43433965Sjdp  exponent_3 = exponent_2 - exponent_skippage;
43577298Sobrien
43677298Sobrien  /* Forget leading zeros, forget 1st bit.  */
43733965Sjdp  exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2);
43833965Sjdp
43977298Sobrien  /* Offset exponent.  */
44033965Sjdp  lp = words;
44133965Sjdp
44277298Sobrien  /* Word 1.  Sign, exponent and perhaps high bits.  */
44333965Sjdp  word1 = ((generic_floating_point_number.sign == '+')
44433965Sjdp	   ? 0
44533965Sjdp	   : (1 << (LITTLENUM_NUMBER_OF_BITS - 1)));
44633965Sjdp
44777298Sobrien  /* Assume 2's complement integers.  */
44833965Sjdp  if (exponent_4 <= 0)
44933965Sjdp    {
45033965Sjdp      int prec_bits;
45133965Sjdp      int num_bits;
45233965Sjdp
45333965Sjdp      unget_bits (1);
45433965Sjdp      num_bits = -exponent_4;
45577298Sobrien      prec_bits =
45677298Sobrien	LITTLENUM_NUMBER_OF_BITS * precision - (exponent_bits + 1 + num_bits);
45733965Sjdp#ifdef TC_I386
45833965Sjdp      if (precision == X_PRECISION && exponent_bits == 15)
45933965Sjdp	{
46033965Sjdp	  /* On the i386 a denormalized extended precision float is
46133965Sjdp	     shifted down by one, effectively decreasing the exponent
46233965Sjdp	     bias by one.  */
46333965Sjdp	  prec_bits -= 1;
46433965Sjdp	  num_bits += 1;
46533965Sjdp	}
46633965Sjdp#endif
46733965Sjdp
46833965Sjdp      if (num_bits >= LITTLENUM_NUMBER_OF_BITS - exponent_bits)
46933965Sjdp	{
47077298Sobrien	  /* Bigger than one littlenum.  */
47133965Sjdp	  num_bits -= (LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits;
47233965Sjdp	  *lp++ = word1;
47377298Sobrien	  if (num_bits + exponent_bits + 1
47477298Sobrien	      > precision * LITTLENUM_NUMBER_OF_BITS)
47533965Sjdp	    {
47677298Sobrien	      /* Exponent overflow.  */
47733965Sjdp	      make_invalid_floating_point_number (words);
47877298Sobrien	      return return_value;
47933965Sjdp	    }
48033965Sjdp#ifdef TC_M68K
48133965Sjdp	  if (precision == X_PRECISION && exponent_bits == 15)
48233965Sjdp	    *lp++ = 0;
48333965Sjdp#endif
48433965Sjdp	  while (num_bits >= LITTLENUM_NUMBER_OF_BITS)
48533965Sjdp	    {
48633965Sjdp	      num_bits -= LITTLENUM_NUMBER_OF_BITS;
48733965Sjdp	      *lp++ = 0;
48833965Sjdp	    }
48933965Sjdp	  if (num_bits)
49033965Sjdp	    *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - (num_bits));
49133965Sjdp	}
49233965Sjdp      else
49333965Sjdp	{
49433965Sjdp	  if (precision == X_PRECISION && exponent_bits == 15)
49533965Sjdp	    {
49633965Sjdp	      *lp++ = word1;
49733965Sjdp#ifdef TC_M68K
49833965Sjdp	      *lp++ = 0;
49933965Sjdp#endif
50033965Sjdp	      *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - num_bits);
50133965Sjdp	    }
50233965Sjdp	  else
50333965Sjdp	    {
50477298Sobrien	      word1 |= next_bits ((LITTLENUM_NUMBER_OF_BITS - 1)
50577298Sobrien				  - (exponent_bits + num_bits));
50633965Sjdp	      *lp++ = word1;
50733965Sjdp	    }
50833965Sjdp	}
50933965Sjdp      while (lp < words_end)
51033965Sjdp	*lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS);
51133965Sjdp
51277298Sobrien      /* Round the mantissa up, but don't change the number.  */
51333965Sjdp      if (next_bits (1))
51433965Sjdp	{
51533965Sjdp	  --lp;
51660484Sobrien	  if (prec_bits >= LITTLENUM_NUMBER_OF_BITS)
51733965Sjdp	    {
51833965Sjdp	      int n = 0;
51933965Sjdp	      int tmp_bits;
52033965Sjdp
52133965Sjdp	      n = 0;
52233965Sjdp	      tmp_bits = prec_bits;
52333965Sjdp	      while (tmp_bits > LITTLENUM_NUMBER_OF_BITS)
52433965Sjdp		{
52533965Sjdp		  if (lp[n] != (LITTLENUM_TYPE) - 1)
52633965Sjdp		    break;
52733965Sjdp		  --n;
52833965Sjdp		  tmp_bits -= LITTLENUM_NUMBER_OF_BITS;
52933965Sjdp		}
53060484Sobrien	      if (tmp_bits > LITTLENUM_NUMBER_OF_BITS
53160484Sobrien		  || (lp[n] & mask[tmp_bits]) != mask[tmp_bits]
53260484Sobrien		  || (prec_bits != (precision * LITTLENUM_NUMBER_OF_BITS
53360484Sobrien				    - exponent_bits - 1)
53460484Sobrien#ifdef TC_I386
53560484Sobrien		      /* An extended precision float with only the integer
53660484Sobrien			 bit set would be invalid.  That must be converted
53760484Sobrien			 to the smallest normalized number.  */
53860484Sobrien		      && !(precision == X_PRECISION
53960484Sobrien			   && prec_bits == (precision * LITTLENUM_NUMBER_OF_BITS
54060484Sobrien					    - exponent_bits - 2))
54160484Sobrien#endif
54260484Sobrien		      ))
54333965Sjdp		{
54433965Sjdp		  unsigned long carry;
54533965Sjdp
54633965Sjdp		  for (carry = 1; carry && (lp >= words); lp--)
54733965Sjdp		    {
54833965Sjdp		      carry = *lp + carry;
54933965Sjdp		      *lp = carry;
55033965Sjdp		      carry >>= LITTLENUM_NUMBER_OF_BITS;
55133965Sjdp		    }
55233965Sjdp		}
55338889Sjdp	      else
55438889Sjdp		{
55538889Sjdp		  /* This is an overflow of the denormal numbers.  We
55638889Sjdp                     need to forget what we have produced, and instead
55738889Sjdp                     generate the smallest normalized number.  */
55838889Sjdp		  lp = words;
55938889Sjdp		  word1 = ((generic_floating_point_number.sign == '+')
56038889Sjdp			   ? 0
56138889Sjdp			   : (1 << (LITTLENUM_NUMBER_OF_BITS - 1)));
56238889Sjdp		  word1 |= (1
56338889Sjdp			    << ((LITTLENUM_NUMBER_OF_BITS - 1)
56438889Sjdp				- exponent_bits));
56538889Sjdp		  *lp++ = word1;
56660484Sobrien#ifdef TC_I386
56760484Sobrien		  /* Set the integer bit in the extended precision format.
56860484Sobrien		     This cannot happen on the m68k where the mantissa
56960484Sobrien		     just overflows into the integer bit above.  */
57060484Sobrien		  if (precision == X_PRECISION)
57160484Sobrien		    *lp++ = 1 << (LITTLENUM_NUMBER_OF_BITS - 1);
57260484Sobrien#endif
57338889Sjdp		  while (lp < words_end)
57438889Sjdp		    *lp++ = 0;
57538889Sjdp		}
57633965Sjdp	    }
57760484Sobrien	  else
57833965Sjdp	    *lp += 1;
57933965Sjdp	}
58033965Sjdp
58133965Sjdp      return return_value;
58233965Sjdp    }
58378828Sobrien  else if ((unsigned long) exponent_4 > mask[exponent_bits]
584104834Sobrien	   || (! TC_LARGEST_EXPONENT_IS_NORMAL (precision)
58578828Sobrien	       && (unsigned long) exponent_4 == mask[exponent_bits]))
58633965Sjdp    {
58777298Sobrien      /* Exponent overflow.  Lose immediately.  */
58833965Sjdp
58977298Sobrien      /* We leave return_value alone: admit we read the
59077298Sobrien	 number, but return a floating exception
59177298Sobrien	 because we can't encode the number.  */
59233965Sjdp      make_invalid_floating_point_number (words);
59333965Sjdp      return return_value;
59433965Sjdp    }
59533965Sjdp  else
59633965Sjdp    {
59733965Sjdp      word1 |= (exponent_4 << ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits))
59833965Sjdp	| next_bits ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits);
59933965Sjdp    }
60033965Sjdp
60133965Sjdp  *lp++ = word1;
60233965Sjdp
60333965Sjdp  /* X_PRECISION is special: on the 68k, it has 16 bits of zero in the
60477298Sobrien     middle.  Either way, it is then followed by a 1 bit.  */
60533965Sjdp  if (exponent_bits == 15 && precision == X_PRECISION)
60633965Sjdp    {
60733965Sjdp#ifdef TC_M68K
60833965Sjdp      *lp++ = 0;
60933965Sjdp#endif
61033965Sjdp      *lp++ = (1 << (LITTLENUM_NUMBER_OF_BITS - 1)
61133965Sjdp	       | next_bits (LITTLENUM_NUMBER_OF_BITS - 1));
61233965Sjdp    }
61333965Sjdp
61477298Sobrien  /* The rest of the words are just mantissa bits.  */
61533965Sjdp  while (lp < words_end)
61633965Sjdp    *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS);
61733965Sjdp
61833965Sjdp  if (next_bits (1))
61933965Sjdp    {
62033965Sjdp      unsigned long carry;
62177298Sobrien      /* Since the NEXT bit is a 1, round UP the mantissa.
62277298Sobrien	 The cunning design of these hidden-1 floats permits
62377298Sobrien	 us to let the mantissa overflow into the exponent, and
62477298Sobrien	 it 'does the right thing'. However, we lose if the
62577298Sobrien	 highest-order bit of the lowest-order word flips.
62677298Sobrien	 Is that clear?  */
62733965Sjdp
62833965Sjdp      /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
62933965Sjdp	 Please allow at least 1 more bit in carry than is in a LITTLENUM.
63033965Sjdp	 We need that extra bit to hold a carry during a LITTLENUM carry
63133965Sjdp	 propagation. Another extra bit (kept 0) will assure us that we
63233965Sjdp	 don't get a sticky sign bit after shifting right, and that
63333965Sjdp	 permits us to propagate the carry without any masking of bits.
63433965Sjdp	 #endif */
63560484Sobrien      for (carry = 1, lp--; carry; lp--)
63633965Sjdp	{
63733965Sjdp	  carry = *lp + carry;
63833965Sjdp	  *lp = carry;
63933965Sjdp	  carry >>= LITTLENUM_NUMBER_OF_BITS;
64060484Sobrien	  if (lp == words)
64160484Sobrien	    break;
64233965Sjdp	}
64333965Sjdp      if (precision == X_PRECISION && exponent_bits == 15)
64433965Sjdp	{
64533965Sjdp	  /* Extended precision numbers have an explicit integer bit
64633965Sjdp	     that we may have to restore.  */
64733965Sjdp	  if (lp == words)
64833965Sjdp	    {
64933965Sjdp#ifdef TC_M68K
65033965Sjdp	      /* On the m68k there is a gap of 16 bits.  We must
65177298Sobrien		 explicitly propagate the carry into the exponent.  */
65233965Sjdp	      words[0] += words[1];
65333965Sjdp	      words[1] = 0;
65433965Sjdp	      lp++;
65533965Sjdp#endif
65677298Sobrien	      /* Put back the integer bit.  */
65733965Sjdp	      lp[1] |= 1 << (LITTLENUM_NUMBER_OF_BITS - 1);
65833965Sjdp	    }
65977298Sobrien	}
66033965Sjdp      if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)))
66133965Sjdp	{
66277298Sobrien	  /* We leave return_value alone: admit we read the number,
66377298Sobrien	     but return a floating exception because we can't encode
66477298Sobrien	     the number.  */
66533965Sjdp	  *words &= ~(1 << (LITTLENUM_NUMBER_OF_BITS - 1));
66633965Sjdp	}
66733965Sjdp    }
66877298Sobrien  return return_value;
66933965Sjdp}
67033965Sjdp
67133965Sjdp#ifdef TEST
67233965Sjdpchar *
67333965Sjdpprint_gen (gen)
67433965Sjdp     FLONUM_TYPE *gen;
67533965Sjdp{
67633965Sjdp  FLONUM_TYPE f;
67733965Sjdp  LITTLENUM_TYPE arr[10];
67833965Sjdp  double dv;
67933965Sjdp  float fv;
68033965Sjdp  static char sbuf[40];
68133965Sjdp
68233965Sjdp  if (gen)
68333965Sjdp    {
68433965Sjdp      f = generic_floating_point_number;
68533965Sjdp      generic_floating_point_number = *gen;
68633965Sjdp    }
68733965Sjdp  gen_to_words (&arr[0], 4, 11);
68833965Sjdp  memcpy (&dv, &arr[0], sizeof (double));
68933965Sjdp  sprintf (sbuf, "%x %x %x %x %.14G   ", arr[0], arr[1], arr[2], arr[3], dv);
69033965Sjdp  gen_to_words (&arr[0], 2, 8);
69133965Sjdp  memcpy (&fv, &arr[0], sizeof (float));
69233965Sjdp  sprintf (sbuf + strlen (sbuf), "%x %x %.12g\n", arr[0], arr[1], fv);
69333965Sjdp
69433965Sjdp  if (gen)
69577298Sobrien    generic_floating_point_number = f;
69633965Sjdp
69733965Sjdp  return (sbuf);
69833965Sjdp}
69933965Sjdp
70033965Sjdp#endif
701