134351Sjb/* atof_vax.c - turn a Flonum into a VAX floating point number 2218822Sdim Copyright 1987, 1992, 1993, 1995, 1997, 1999, 2000, 2005, 2007 369180Sobrien Free Software Foundation, Inc. 434351Sjb 534351Sjb This file is part of GAS, the GNU Assembler. 634351Sjb 734351Sjb GAS is free software; you can redistribute it and/or modify 834351Sjb it under the terms of the GNU General Public License as published by 934351Sjb the Free Software Foundation; either version 2, or (at your option) 1034351Sjb any later version. 1134351Sjb 1234351Sjb GAS is distributed in the hope that it will be useful, 1334351Sjb but WITHOUT ANY WARRANTY; without even the implied warranty of 1434351Sjb MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1534351Sjb GNU General Public License for more details. 1634351Sjb 1734351Sjb You should have received a copy of the GNU General Public License 1834351Sjb 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. */ 2134351Sjb 2234351Sjb#include "as.h" 2334351Sjb 2494536Sobrien/* Precision in LittleNums. */ 25218822Sdim#define MAX_PRECISION 8 26218822Sdim#define H_PRECISION 8 27218822Sdim#define G_PRECISION 4 28218822Sdim#define D_PRECISION 4 29218822Sdim#define F_PRECISION 2 3034351Sjb 3194536Sobrien/* Length in LittleNums of guard bits. */ 32218822Sdim#define GUARD 2 3334351Sjb 34218822Sdimint flonum_gen2vax (int, FLONUM_TYPE *, LITTLENUM_TYPE *); 3534351Sjb 3694536Sobrien/* Number of chars in flonum type 'letter'. */ 37218822Sdim 38218822Sdimstatic unsigned int 39218822Sdimatof_vax_sizeof (int letter) 4034351Sjb{ 4134351Sjb int return_value; 4234351Sjb 43218822Sdim /* Permitting uppercase letters is probably a bad idea. 44218822Sdim Please use only lower-cased letters in case the upper-cased 45218822Sdim ones become unsupported! */ 4634351Sjb switch (letter) 4734351Sjb { 4834351Sjb case 'f': 4934351Sjb case 'F': 5034351Sjb return_value = 4; 5134351Sjb break; 5234351Sjb 5334351Sjb case 'd': 5434351Sjb case 'D': 5534351Sjb case 'g': 5634351Sjb case 'G': 5734351Sjb return_value = 8; 5834351Sjb break; 5934351Sjb 6034351Sjb case 'h': 6134351Sjb case 'H': 6234351Sjb return_value = 16; 6334351Sjb break; 6434351Sjb 6534351Sjb default: 6634351Sjb return_value = 0; 6734351Sjb break; 6834351Sjb } 6934351Sjb 70218822Sdim return return_value; 71218822Sdim} 72218822Sdim 7334351Sjbstatic const long mask[] = 7434351Sjb{ 7534351Sjb 0x00000000, 7634351Sjb 0x00000001, 7734351Sjb 0x00000003, 7834351Sjb 0x00000007, 7934351Sjb 0x0000000f, 8034351Sjb 0x0000001f, 8134351Sjb 0x0000003f, 8234351Sjb 0x0000007f, 8334351Sjb 0x000000ff, 8434351Sjb 0x000001ff, 8534351Sjb 0x000003ff, 8634351Sjb 0x000007ff, 8734351Sjb 0x00000fff, 8834351Sjb 0x00001fff, 8934351Sjb 0x00003fff, 9034351Sjb 0x00007fff, 9134351Sjb 0x0000ffff, 9234351Sjb 0x0001ffff, 9334351Sjb 0x0003ffff, 9434351Sjb 0x0007ffff, 9534351Sjb 0x000fffff, 9634351Sjb 0x001fffff, 9734351Sjb 0x003fffff, 9834351Sjb 0x007fffff, 9934351Sjb 0x00ffffff, 10034351Sjb 0x01ffffff, 10134351Sjb 0x03ffffff, 10234351Sjb 0x07ffffff, 10334351Sjb 0x0fffffff, 10434351Sjb 0x1fffffff, 10534351Sjb 0x3fffffff, 10634351Sjb 0x7fffffff, 10734351Sjb 0xffffffff 10834351Sjb}; 10934351Sjb 11034351Sjb 111218822Sdim/* Shared between flonum_gen2vax and next_bits. */ 11234351Sjbstatic int bits_left_in_littlenum; 11334351Sjbstatic LITTLENUM_TYPE *littlenum_pointer; 11434351Sjbstatic LITTLENUM_TYPE *littlenum_end; 11534351Sjb 11634351Sjbstatic int 117218822Sdimnext_bits (int number_of_bits) 11834351Sjb{ 11934351Sjb int return_value; 12034351Sjb 12134351Sjb if (littlenum_pointer < littlenum_end) 12234351Sjb return 0; 12334351Sjb if (number_of_bits >= bits_left_in_littlenum) 12434351Sjb { 12534351Sjb return_value = mask[bits_left_in_littlenum] & *littlenum_pointer; 12634351Sjb number_of_bits -= bits_left_in_littlenum; 12734351Sjb return_value <<= number_of_bits; 12834351Sjb bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits; 12934351Sjb littlenum_pointer--; 13034351Sjb if (littlenum_pointer >= littlenum_end) 13134351Sjb return_value |= ((*littlenum_pointer) >> (bits_left_in_littlenum)) & mask[number_of_bits]; 13234351Sjb } 13334351Sjb else 13434351Sjb { 13534351Sjb bits_left_in_littlenum -= number_of_bits; 13634351Sjb return_value = mask[number_of_bits] & ((*littlenum_pointer) >> bits_left_in_littlenum); 13734351Sjb } 138218822Sdim return return_value; 13934351Sjb} 14034351Sjb 14134351Sjbstatic void 142218822Sdimmake_invalid_floating_point_number (LITTLENUM_TYPE *words) 14334351Sjb{ 144218822Sdim *words = 0x8000; /* Floating Reserved Operand Code. */ 14534351Sjb} 146218822Sdim 14734351Sjb 14894536Sobrienstatic int /* 0 means letter is OK. */ 149218822Sdimwhat_kind_of_float (int letter, /* In: lowercase please. What kind of float? */ 150218822Sdim int *precisionP, /* Number of 16-bit words in the float. */ 151218822Sdim long *exponent_bitsP) /* Number of exponent bits. */ 15234351Sjb{ 153218822Sdim int retval; 15434351Sjb 15534351Sjb retval = 0; 15634351Sjb switch (letter) 15734351Sjb { 15834351Sjb case 'f': 15934351Sjb *precisionP = F_PRECISION; 16034351Sjb *exponent_bitsP = 8; 16134351Sjb break; 16234351Sjb 16334351Sjb case 'd': 16434351Sjb *precisionP = D_PRECISION; 16534351Sjb *exponent_bitsP = 8; 16634351Sjb break; 16734351Sjb 16834351Sjb case 'g': 16934351Sjb *precisionP = G_PRECISION; 17034351Sjb *exponent_bitsP = 11; 17134351Sjb break; 17234351Sjb 17334351Sjb case 'h': 17434351Sjb *precisionP = H_PRECISION; 17534351Sjb *exponent_bitsP = 15; 17634351Sjb break; 17734351Sjb 17834351Sjb default: 17934351Sjb retval = 69; 18034351Sjb break; 18134351Sjb } 182218822Sdim return retval; 18334351Sjb} 18434351Sjb 185218822Sdim/* Warning: this returns 16-bit LITTLENUMs, because that is 186218822Sdim what the VAX thinks in. It is up to the caller to figure 187218822Sdim out any alignment problems and to conspire for the bytes/word 188218822Sdim to be emitted in the right order. Bigendians beware! */ 18934351Sjb 190218822Sdimstatic char * 191218822Sdimatof_vax (char *str, /* Text to convert to binary. */ 192218822Sdim int what_kind, /* 'd', 'f', 'g', 'h' */ 193218822Sdim LITTLENUM_TYPE *words) /* Build the binary here. */ 19434351Sjb{ 19534351Sjb FLONUM_TYPE f; 19634351Sjb LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD]; 197218822Sdim /* Extra bits for zeroed low-order bits. 198218822Sdim The 1st MAX_PRECISION are zeroed, 199218822Sdim the last contain flonum bits. */ 20034351Sjb char *return_value; 20194536Sobrien int precision; /* Number of 16-bit words in the format. */ 20234351Sjb long exponent_bits; 20334351Sjb 20434351Sjb return_value = str; 20534351Sjb f.low = bits + MAX_PRECISION; 20634351Sjb f.high = NULL; 20734351Sjb f.leader = NULL; 20834351Sjb f.exponent = 0; 20934351Sjb f.sign = '\0'; 21034351Sjb 21134351Sjb if (what_kind_of_float (what_kind, &precision, &exponent_bits)) 21234351Sjb { 213218822Sdim return_value = NULL; 21434351Sjb make_invalid_floating_point_number (words); 21534351Sjb } 21634351Sjb 21734351Sjb if (return_value) 21834351Sjb { 21934351Sjb memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION); 22034351Sjb 221218822Sdim /* Use more LittleNums than seems 222218822Sdim necessary: the highest flonum may have 223218822Sdim 15 leading 0 bits, so could be useless. */ 22434351Sjb f.high = f.low + precision - 1 + GUARD; 22534351Sjb 22634351Sjb if (atof_generic (&return_value, ".", "eE", &f)) 22734351Sjb { 22834351Sjb make_invalid_floating_point_number (words); 229218822Sdim return_value = NULL; 23034351Sjb } 231218822Sdim else if (flonum_gen2vax (what_kind, &f, words)) 232218822Sdim return_value = NULL; 23334351Sjb } 234218822Sdim 235218822Sdim return return_value; 236218822Sdim} 23734351Sjb 238218822Sdim/* In: a flonum, a vax floating point format. 239218822Sdim Out: a vax floating-point bit pattern. */ 24034351Sjb 241218822Sdimint 242218822Sdimflonum_gen2vax (int format_letter, /* One of 'd' 'f' 'g' 'h'. */ 243218822Sdim FLONUM_TYPE *f, 244218822Sdim LITTLENUM_TYPE *words) /* Deliver answer here. */ 24534351Sjb{ 24634351Sjb LITTLENUM_TYPE *lp; 24734351Sjb int precision; 24834351Sjb long exponent_bits; 24994536Sobrien int return_value; /* 0 == OK. */ 25034351Sjb 25134351Sjb return_value = what_kind_of_float (format_letter, &precision, &exponent_bits); 25234351Sjb 25334351Sjb if (return_value != 0) 254218822Sdim make_invalid_floating_point_number (words); 255218822Sdim 25634351Sjb else 25734351Sjb { 25834351Sjb if (f->low > f->leader) 259218822Sdim /* 0.0e0 seen. */ 260218822Sdim memset (words, '\0', sizeof (LITTLENUM_TYPE) * precision); 261218822Sdim 26234351Sjb else 26334351Sjb { 26434351Sjb long exponent_1; 26534351Sjb long exponent_2; 26634351Sjb long exponent_3; 26734351Sjb long exponent_4; 26834351Sjb int exponent_skippage; 26934351Sjb LITTLENUM_TYPE word1; 27034351Sjb 271218822Sdim /* JF: Deal with new Nan, +Inf and -Inf codes. */ 27234351Sjb if (f->sign != '-' && f->sign != '+') 27334351Sjb { 27434351Sjb make_invalid_floating_point_number (words); 27534351Sjb return return_value; 27634351Sjb } 27734351Sjb 278218822Sdim /* All vaxen floating_point formats (so far) have: 279218822Sdim Bit 15 is sign bit. 280218822Sdim Bits 14:n are excess-whatever exponent. 281218822Sdim Bits n-1:0 (if any) are most significant bits of fraction. 282218822Sdim Bits 15:0 of the next word are the next most significant bits. 283218822Sdim And so on for each other word. 28434351Sjb 285218822Sdim All this to be compatible with a KF11?? (Which is still faster 286218822Sdim than lots of vaxen I can think of, but it also has higher 287218822Sdim maintenance costs ... sigh). 288218822Sdim 289218822Sdim So we need: number of bits of exponent, number of bits of 290218822Sdim mantissa. */ 291218822Sdim 29234351Sjb bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS; 29334351Sjb littlenum_pointer = f->leader; 29434351Sjb littlenum_end = f->low; 295218822Sdim /* Seek (and forget) 1st significant bit. */ 29634351Sjb for (exponent_skippage = 0; 29734351Sjb !next_bits (1); 29834351Sjb exponent_skippage++);; 29934351Sjb 30034351Sjb exponent_1 = f->exponent + f->leader + 1 - f->low; 30194536Sobrien /* Radix LITTLENUM_RADIX, point just higher than f->leader. */ 30234351Sjb exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS; 30394536Sobrien /* Radix 2. */ 30434351Sjb exponent_3 = exponent_2 - exponent_skippage; 30594536Sobrien /* Forget leading zeros, forget 1st bit. */ 30634351Sjb exponent_4 = exponent_3 + (1 << (exponent_bits - 1)); 30794536Sobrien /* Offset exponent. */ 30834351Sjb 30934351Sjb if (exponent_4 & ~mask[exponent_bits]) 31034351Sjb { 311218822Sdim /* Exponent overflow. Lose immediately. */ 31234351Sjb make_invalid_floating_point_number (words); 31334351Sjb 314218822Sdim /* We leave return_value alone: admit we read the 315218822Sdim number, but return a floating exception 316218822Sdim because we can't encode the number. */ 31734351Sjb } 31834351Sjb else 31934351Sjb { 32034351Sjb lp = words; 32134351Sjb 322218822Sdim /* Word 1. Sign, exponent and perhaps high bits. 323218822Sdim Assume 2's complement integers. */ 32434351Sjb word1 = (((exponent_4 & mask[exponent_bits]) << (15 - exponent_bits)) 32534351Sjb | ((f->sign == '+') ? 0 : 0x8000) 32634351Sjb | next_bits (15 - exponent_bits)); 32734351Sjb *lp++ = word1; 32834351Sjb 32994536Sobrien /* The rest of the words are just mantissa bits. */ 33034351Sjb for (; lp < words + precision; lp++) 331218822Sdim *lp = next_bits (LITTLENUM_NUMBER_OF_BITS); 33234351Sjb 33334351Sjb if (next_bits (1)) 33434351Sjb { 335218822Sdim /* Since the NEXT bit is a 1, round UP the mantissa. 336218822Sdim The cunning design of these hidden-1 floats permits 337218822Sdim us to let the mantissa overflow into the exponent, and 338218822Sdim it 'does the right thing'. However, we lose if the 339218822Sdim highest-order bit of the lowest-order word flips. 340218822Sdim Is that clear? */ 34134351Sjb unsigned long carry; 34234351Sjb 34334351Sjb /* 344218822Sdim #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2) 345218822Sdim Please allow at least 1 more bit in carry than is in a LITTLENUM. 346218822Sdim We need that extra bit to hold a carry during a LITTLENUM carry 347218822Sdim propagation. Another extra bit (kept 0) will assure us that we 348218822Sdim don't get a sticky sign bit after shifting right, and that 349218822Sdim permits us to propagate the carry without any masking of bits. 350218822Sdim #endif */ 35134351Sjb for (carry = 1, lp--; 35234351Sjb carry && (lp >= words); 35334351Sjb lp--) 35434351Sjb { 35534351Sjb carry = *lp + carry; 35634351Sjb *lp = carry; 35734351Sjb carry >>= LITTLENUM_NUMBER_OF_BITS; 35834351Sjb } 35934351Sjb 36034351Sjb if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1))) 36134351Sjb { 36234351Sjb make_invalid_floating_point_number (words); 363218822Sdim /* We leave return_value alone: admit we read the 364218822Sdim number, but return a floating exception 365218822Sdim because we can't encode the number. */ 36634351Sjb } 367218822Sdim } 368218822Sdim } 369218822Sdim } 370218822Sdim } 371218822Sdim return return_value; 372218822Sdim} 37334351Sjb 374218822Sdim/* JF this used to be in vax.c but this looks like a better place for it. */ 37534351Sjb 376218822Sdim/* In: input_line_pointer->the 1st character of a floating-point 377218822Sdim number. 378218822Sdim 1 letter denoting the type of statement that wants a 379218822Sdim binary floating point number returned. 380218822Sdim Address of where to build floating point literal. 381218822Sdim Assumed to be 'big enough'. 382218822Sdim Address of where to return size of literal (in chars). 383218822Sdim 384218822Sdim Out: Input_line_pointer->of next char after floating number. 385218822Sdim Error message, or 0. 386218822Sdim Floating point literal. 387218822Sdim Number of chars we used for the literal. */ 38834351Sjb 389218822Sdim#define MAXIMUM_NUMBER_OF_LITTLENUMS 8 /* For .hfloats. */ 39034351Sjb 39134351Sjbchar * 392218822Sdimmd_atof (int what_statement_type, 393218822Sdim char *literalP, 394218822Sdim int *sizeP) 39534351Sjb{ 39634351Sjb LITTLENUM_TYPE words[MAXIMUM_NUMBER_OF_LITTLENUMS]; 397218822Sdim char kind_of_float; 398218822Sdim unsigned int number_of_chars; 399218822Sdim LITTLENUM_TYPE *littlenumP; 40034351Sjb 40134351Sjb switch (what_statement_type) 40234351Sjb { 403218822Sdim case 'F': 404218822Sdim case 'f': 40534351Sjb kind_of_float = 'f'; 40634351Sjb break; 40734351Sjb 408218822Sdim case 'D': 409218822Sdim case 'd': 41034351Sjb kind_of_float = 'd'; 41134351Sjb break; 41234351Sjb 413218822Sdim case 'g': 41434351Sjb kind_of_float = 'g'; 41534351Sjb break; 41634351Sjb 417218822Sdim case 'h': 41834351Sjb kind_of_float = 'h'; 41934351Sjb break; 42034351Sjb 42134351Sjb default: 42234351Sjb kind_of_float = 0; 42334351Sjb break; 42434351Sjb }; 42534351Sjb 42634351Sjb if (kind_of_float) 42734351Sjb { 428218822Sdim LITTLENUM_TYPE *limit; 42934351Sjb 43034351Sjb input_line_pointer = atof_vax (input_line_pointer, 43134351Sjb kind_of_float, 43234351Sjb words); 433218822Sdim /* The atof_vax() builds up 16-bit numbers. 434218822Sdim Since the assembler may not be running on 435218822Sdim a little-endian machine, be very careful about 436218822Sdim converting words to chars. */ 43734351Sjb number_of_chars = atof_vax_sizeof (kind_of_float); 43834351Sjb know (number_of_chars <= MAXIMUM_NUMBER_OF_LITTLENUMS * sizeof (LITTLENUM_TYPE)); 43934351Sjb limit = words + (number_of_chars / sizeof (LITTLENUM_TYPE)); 44034351Sjb for (littlenumP = words; littlenumP < limit; littlenumP++) 44134351Sjb { 44234351Sjb md_number_to_chars (literalP, *littlenumP, sizeof (LITTLENUM_TYPE)); 44334351Sjb literalP += sizeof (LITTLENUM_TYPE); 44434351Sjb }; 44534351Sjb } 44634351Sjb else 447218822Sdim number_of_chars = 0; 44834351Sjb 44934351Sjb *sizeP = number_of_chars; 45069180Sobrien return kind_of_float ? NULL : _("Bad call to md_atof()"); 45134351Sjb} 452