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