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