1 /* atof_tahoe.c - turn a string into a Tahoe floating point number 2 Copyright 1987, 1993, 2000 Free Software Foundation, Inc. 3 4 /* This is really a simplified version of atof_vax.c. I glommed it wholesale 5 and then shaved it down. I don't even know how it works. (Don't you find 6 my honesty refreshing? Devon E Bowen <bowen@cs.buffalo.edu> 7 8 I don't allow uppercase letters in the precision descriptors. 9 i.e. 'f' and 'd' are allowed but 'F' and 'D' aren't. */ 10 11 #include "as.h" 12 13 /* Precision in LittleNums. */ 14 #define MAX_PRECISION (4) 15 #define D_PRECISION (4) 16 #define F_PRECISION (2) 17 18 /* Precision in chars. */ 19 #define D_PRECISION_CHARS (8) 20 #define F_PRECISION_CHARS (4) 21 22 /* Length in LittleNums of guard bits. */ 23 #define GUARD (2) 24 25 static const long int mask[] = 26 { 27 0x00000000, 28 0x00000001, 29 0x00000003, 30 0x00000007, 31 0x0000000f, 32 0x0000001f, 33 0x0000003f, 34 0x0000007f, 35 0x000000ff, 36 0x000001ff, 37 0x000003ff, 38 0x000007ff, 39 0x00000fff, 40 0x00001fff, 41 0x00003fff, 42 0x00007fff, 43 0x0000ffff, 44 0x0001ffff, 45 0x0003ffff, 46 0x0007ffff, 47 0x000fffff, 48 0x001fffff, 49 0x003fffff, 50 0x007fffff, 51 0x00ffffff, 52 0x01ffffff, 53 0x03ffffff, 54 0x07ffffff, 55 0x0fffffff, 56 0x1fffffff, 57 0x3fffffff, 58 0x7fffffff, 59 0xffffffff 60 }; 61 62 /* Shared between flonum_gen2tahoe and next_bits. */ 63 static int bits_left_in_littlenum; 64 static LITTLENUM_TYPE *littlenum_pointer; 65 static LITTLENUM_TYPE *littlenum_end; 66 67 #if __STDC__ == 1 68 69 int flonum_gen2tahoe (int format_letter, FLONUM_TYPE * f, 70 LITTLENUM_TYPE * words); 71 72 #else /* not __STDC__ */ 73 74 int flonum_gen2tahoe (); 75 76 #endif /* not __STDC__ */ 77 78 static int 79 next_bits (number_of_bits) 80 int number_of_bits; 81 { 82 int return_value; 83 84 if (littlenum_pointer < littlenum_end) 85 return 0; 86 if (number_of_bits >= bits_left_in_littlenum) 87 { 88 return_value = mask[bits_left_in_littlenum] & *littlenum_pointer; 89 number_of_bits -= bits_left_in_littlenum; 90 return_value <<= number_of_bits; 91 bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits; 92 littlenum_pointer--; 93 if (littlenum_pointer >= littlenum_end) 94 return_value |= ((*littlenum_pointer) >> (bits_left_in_littlenum)) & 95 mask[number_of_bits]; 96 } 97 else 98 { 99 bits_left_in_littlenum -= number_of_bits; 100 return_value = mask[number_of_bits] & 101 ((*littlenum_pointer) >> bits_left_in_littlenum); 102 } 103 return return_value; 104 } 105 106 static void 107 make_invalid_floating_point_number (words) 108 LITTLENUM_TYPE *words; 109 { 110 /* Floating Reserved Operand Code. */ 111 *words = 0x8000; 112 } 113 114 static int /* 0 means letter is OK. */ 115 what_kind_of_float (letter, precisionP, exponent_bitsP) 116 /* In: lowercase please. What kind of float? */ 117 char letter; 118 119 /* Number of 16-bit words in the float. */ 120 int *precisionP; 121 122 /* Number of exponent bits. */ 123 long int *exponent_bitsP; 124 { 125 int retval; /* 0: OK. */ 126 127 retval = 0; 128 switch (letter) 129 { 130 case 'f': 131 *precisionP = F_PRECISION; 132 *exponent_bitsP = 8; 133 break; 134 135 case 'd': 136 *precisionP = D_PRECISION; 137 *exponent_bitsP = 8; 138 break; 139 140 default: 141 retval = 69; 142 break; 143 } 144 return (retval); 145 } 146 147 /* Warning: This returns 16-bit LITTLENUMs, because that is what the 148 VAX thinks in. It is up to the caller to figure out any alignment 149 problems and to conspire for the bytes/word to be emitted in the 150 right order. Bigendians beware! */ 151 152 char * /* Return pointer past text consumed. */ 153 atof_tahoe (str, what_kind, words) 154 char *str; /* Text to convert to binary. */ 155 char what_kind; /* 'd', 'f', 'g', 'h' */ 156 LITTLENUM_TYPE *words; /* Build the binary here. */ 157 { 158 FLONUM_TYPE f; 159 LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD]; 160 /* Extra bits for zeroed low-order bits. */ 161 /* The 1st MAX_PRECISION are zeroed, the last contain flonum bits. */ 162 char *return_value; 163 int precision; /* Number of 16-bit words in the format. */ 164 long int exponent_bits; 165 166 return_value = str; 167 f.low = bits + MAX_PRECISION; 168 f.high = NULL; 169 f.leader = NULL; 170 f.exponent = NULL; 171 f.sign = '\0'; 172 173 if (what_kind_of_float (what_kind, &precision, &exponent_bits)) 174 { 175 /* We lost. */ 176 return_value = NULL; 177 make_invalid_floating_point_number (words); 178 } 179 if (return_value) 180 { 181 memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION); 182 183 /* Use more LittleNums than seems necessary: 184 the highest flonum may have 15 leading 0 bits, so could be 185 useless. */ 186 f.high = f.low + precision - 1 + GUARD; 187 188 if (atof_generic (&return_value, ".", "eE", &f)) 189 { 190 make_invalid_floating_point_number (words); 191 /* We lost. */ 192 return_value = NULL; 193 } 194 else 195 { 196 if (flonum_gen2tahoe (what_kind, &f, words)) 197 return_value = NULL; 198 } 199 } 200 return return_value; 201 } 202 203 /* In: a flonum, a Tahoe floating point format. 204 Out: a Tahoe floating-point bit pattern. */ 205 206 int /* 0: OK. */ 207 flonum_gen2tahoe (format_letter, f, words) 208 char format_letter; /* One of 'd' 'f'. */ 209 FLONUM_TYPE *f; 210 LITTLENUM_TYPE *words; /* Deliver answer here. */ 211 { 212 LITTLENUM_TYPE *lp; 213 int precision; 214 long int exponent_bits; 215 int return_value; /* 0 == OK. */ 216 217 return_value = 218 what_kind_of_float (format_letter, &precision, &exponent_bits); 219 if (return_value != 0) 220 { 221 make_invalid_floating_point_number (words); 222 } 223 else 224 { 225 if (f->low > f->leader) 226 { 227 /* 0.0e0 seen. */ 228 memset (words, '\0', sizeof (LITTLENUM_TYPE) * precision); 229 } 230 else 231 { 232 long int exponent_1; 233 long int exponent_2; 234 long int exponent_3; 235 long int exponent_4; 236 int exponent_skippage; 237 LITTLENUM_TYPE word1; 238 239 /* JF: Deal with new Nan, +Inf and -Inf codes. */ 240 if (f->sign != '-' && f->sign != '+') 241 { 242 make_invalid_floating_point_number (words); 243 return return_value; 244 } 245 /* All tahoe floating_point formats have: 246 Bit 15 is sign bit. 247 Bits 14:n are excess-whatever exponent. 248 Bits n-1:0 (if any) are most significant bits of fraction. 249 Bits 15:0 of the next word are the next most significant bits. 250 And so on for each other word. 251 252 So we need: number of bits of exponent, number of bits of 253 mantissa. */ 254 255 bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS; 256 littlenum_pointer = f->leader; 257 littlenum_end = f->low; 258 259 /* Seek (and forget) 1st significant bit. */ 260 for (exponent_skippage = 0; 261 !next_bits (1); 262 exponent_skippage++) 263 ; 264 265 exponent_1 = f->exponent + f->leader + 1 - f->low; 266 267 /* Radix LITTLENUM_RADIX, point just higher than f -> leader. */ 268 exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS; 269 270 /* Radix 2. */ 271 exponent_3 = exponent_2 - exponent_skippage; 272 273 /* Forget leading zeros, forget 1st bit. */ 274 exponent_4 = exponent_3 + (1 << (exponent_bits - 1)); 275 276 /* Offset exponent. */ 277 278 if (exponent_4 & ~mask[exponent_bits]) 279 { 280 /* Exponent overflow. Lose immediately. */ 281 282 make_invalid_floating_point_number (words); 283 284 /* We leave return_value alone: admit we read the 285 number, but return a floating exception because we 286 can't encode the number. */ 287 } 288 else 289 { 290 lp = words; 291 292 /* Word 1. Sign, exponent and perhaps high bits. */ 293 /* Assume 2's complement integers. */ 294 word1 = ((exponent_4 & mask[exponent_bits]) 295 << (15 - exponent_bits)) 296 | ((f->sign == '+') ? 0 : 0x8000) 297 | next_bits (15 - exponent_bits); 298 *lp++ = word1; 299 300 /* The rest of the words are just mantissa bits. */ 301 for (; lp < words + precision; lp++) 302 *lp = next_bits (LITTLENUM_NUMBER_OF_BITS); 303 304 if (next_bits (1)) 305 { 306 /* Since the NEXT bit is a 1, round UP the mantissa. 307 The cunning design of these hidden-1 floats permits 308 us to let the mantissa overflow into the exponent, and 309 it 'does the right thing'. However, we lose if the 310 highest-order bit of the lowest-order word flips. 311 Is that clear? */ 312 313 unsigned long int carry; 314 315 /* #if (sizeof(carry)) < ((sizeof(bits[0]) * 316 BITS_PER_CHAR) + 2) Please allow at least 1 more 317 bit in carry than is in a LITTLENUM. We need 318 that extra bit to hold a carry during a LITTLENUM 319 carry propagation. Another extra bit (kept 0) 320 will assure us that we don't get a sticky sign 321 bit after shifting right, and that permits us to 322 propagate the carry without any masking of bits. 323 #endif */ 324 for (carry = 1, lp--; 325 carry && (lp >= words); 326 lp--) 327 { 328 carry = *lp + carry; 329 *lp = carry; 330 carry >>= LITTLENUM_NUMBER_OF_BITS; 331 } 332 333 if ((word1 ^ *words) 334 & (1 << (LITTLENUM_NUMBER_OF_BITS - 1))) 335 { 336 make_invalid_floating_point_number (words); 337 /* We leave return_value alone: admit we read 338 the number, but return a floating exception 339 because we can't encode the number. */ 340 } 341 } /* if (we needed to round up) */ 342 } /* if (exponent overflow) */ 343 } /* if (0.0e0) */ 344 } /* if (float_type was OK) */ 345 return return_value; 346 } 347 348 /* In: input_line_pointer -> the 1st character of a floating-point 349 * number. 350 * 1 letter denoting the type of statement that wants a 351 * binary floating point number returned. 352 * Address of where to build floating point literal. 353 * Assumed to be 'big enough'. 354 * Address of where to return size of literal (in chars). 355 * 356 * Out: Input_line_pointer -> of next char after floating number. 357 * Error message, or 0. 358 * Floating point literal. 359 * Number of chars we used for the literal. */ 360 361 char * 362 md_atof (what_statement_type, literalP, sizeP) 363 char what_statement_type; 364 char *literalP; 365 int *sizeP; 366 { 367 LITTLENUM_TYPE words[MAX_PRECISION]; 368 register char kind_of_float; 369 register int number_of_chars; 370 register LITTLENUM_TYPE *littlenum_pointer; 371 372 switch (what_statement_type) 373 { 374 case 'f': /* .ffloat */ 375 case 'd': /* .dfloat */ 376 kind_of_float = what_statement_type; 377 break; 378 379 default: 380 kind_of_float = 0; 381 break; 382 } 383 384 if (kind_of_float) 385 { 386 register LITTLENUM_TYPE *limit; 387 388 input_line_pointer = atof_tahoe (input_line_pointer, 389 kind_of_float, 390 words); 391 /* The atof_tahoe() builds up 16-bit numbers. 392 Since the assembler may not be running on 393 a different-endian machine, be very careful about 394 converting words to chars. */ 395 number_of_chars = (kind_of_float == 'f' ? F_PRECISION_CHARS : 396 (kind_of_float == 'd' ? D_PRECISION_CHARS : 0)); 397 know (number_of_chars <= MAX_PRECISION * sizeof (LITTLENUM_TYPE)); 398 limit = words + (number_of_chars / sizeof (LITTLENUM_TYPE)); 399 for (littlenum_pointer = words; 400 littlenum_pointer < limit; 401 littlenum_pointer++) 402 { 403 md_number_to_chars (literalP, *littlenum_pointer, 404 sizeof (LITTLENUM_TYPE)); 405 literalP += sizeof (LITTLENUM_TYPE); 406 } 407 } 408 else 409 { 410 number_of_chars = 0; 411 } 412 413 *sizeP = number_of_chars; 414 return kind_of_float ? 0 : _("Bad call to md_atof()"); 415 } 416