1/* atof_ieee.c - turn a Flonum into an IEEE floating point number 2 Copyright (C) 1987 Free Software Foundation, Inc. 3 4This file is part of GAS, the GNU Assembler. 5 6GAS is free software; you can redistribute it and/or modify 7it under the terms of the GNU General Public License as published by 8the Free Software Foundation; either version 1, or (at your option) 9any later version. 10 11GAS is distributed in the hope that it will be useful, 12but WITHOUT ANY WARRANTY; without even the implied warranty of 13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14GNU General Public License for more details. 15 16You should have received a copy of the GNU General Public License 17along with GAS; see the file COPYING. If not, write to 18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 19 20/* FROM line 22 */ 21#include "as.h" 22 23#include <stdio.h> 24#include <stdlib.h> 25#include <string.h> 26#include "expr.h" 27#include "md.h" 28#include "atof-ieee.h" 29#include "messages.h" 30 31/* Precision in LittleNums. */ 32#define MAX_PRECISION (6) 33#define F_PRECISION (2) 34#define D_PRECISION (4) 35#define X_PRECISION (6) 36#define P_PRECISION (6) 37 38/* Length in LittleNums of guard bits. */ 39#define GUARD (2) 40 41static uint32_t mask [] = { 42 0x00000000, 43 0x00000001, 44 0x00000003, 45 0x00000007, 46 0x0000000f, 47 0x0000001f, 48 0x0000003f, 49 0x0000007f, 50 0x000000ff, 51 0x000001ff, 52 0x000003ff, 53 0x000007ff, 54 0x00000fff, 55 0x00001fff, 56 0x00003fff, 57 0x00007fff, 58 0x0000ffff, 59 0x0001ffff, 60 0x0003ffff, 61 0x0007ffff, 62 0x000fffff, 63 0x001fffff, 64 0x003fffff, 65 0x007fffff, 66 0x00ffffff, 67 0x01ffffff, 68 0x03ffffff, 69 0x07ffffff, 70 0x0fffffff, 71 0x1fffffff, 72 0x3fffffff, 73 0x7fffffff, 74 0xffffffff 75 }; 76 77static int bits_left_in_littlenum; 78static int littlenums_left; 79static LITTLENUM_TYPE *littlenum_pointer; 80 81static 82int 83next_bits( 84int number_of_bits) 85{ 86 int return_value; 87 88 if(!littlenums_left) 89 return 0; 90 if (number_of_bits >= bits_left_in_littlenum) 91 { 92 return_value = mask [bits_left_in_littlenum] & *littlenum_pointer; 93 number_of_bits -= bits_left_in_littlenum; 94 return_value <<= number_of_bits; 95 if(--littlenums_left) { 96 bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits; 97 littlenum_pointer --; 98 return_value |= (*littlenum_pointer>>bits_left_in_littlenum) & mask[number_of_bits]; 99 } 100 } 101 else 102 { 103 bits_left_in_littlenum -= number_of_bits; 104 return_value = mask [number_of_bits] & (*littlenum_pointer>>bits_left_in_littlenum); 105 } 106 return (return_value); 107} 108 109/* Num had better be less than LITTLENUM_NUMBER_OF_BITS */ 110static 111void 112unget_bits( 113int num) 114{ 115 if(!littlenums_left) { 116 ++littlenum_pointer; 117 ++littlenums_left; 118 bits_left_in_littlenum=num; 119 } else if(bits_left_in_littlenum+num>LITTLENUM_NUMBER_OF_BITS) { 120 bits_left_in_littlenum= num-(LITTLENUM_NUMBER_OF_BITS-bits_left_in_littlenum); 121 ++littlenum_pointer; 122 ++littlenums_left; 123 } else 124 bits_left_in_littlenum+=num; 125} 126 127static 128void 129make_invalid_floating_point_number( 130LITTLENUM_TYPE *words) 131{ 132 as_warn("cannot create floating-point number"); 133 words[0]= (LITTLENUM_TYPE)(((unsigned)-1)>>1);/* Zero the leftmost bit*/ 134 words[1]= -1; 135 words[2]= -1; 136 words[3]= -1; 137 words[4]= -1; 138 words[5]= -1; 139} 140 141/***********************************************************************\ 142* Warning: this returns 16-bit LITTLENUMs. It is up to the caller * 143* to figure out any alignment problems and to conspire for the * 144* bytes/word to be emitted in the right order. Bigendians beware! * 145* * 146\***********************************************************************/ 147 148/* Note that atof-ieee always has X and P precisions enabled. it is up 149 to md_atof to filter them out if the target machine does not support 150 them. */ 151 152char * /* Return pointer past text consumed. */ 153atof_ieee( 154char *str, /* Text to convert to binary. */ 155char what_kind, /* 'd', 'f', 'g', 'h' */ 156LITTLENUM_TYPE *words) /* Build the binary here. */ 157{ 158 static LITTLENUM_TYPE bits [MAX_PRECISION + MAX_PRECISION + GUARD]; 159 /* Extra bits for zeroed low-order bits. */ 160 /* The 1st MAX_PRECISION are zeroed, */ 161 /* the last contain flonum bits. */ 162 char * return_value; 163 int precision; /* Number of 16-bit words in the format. */ 164 int32_t exponent_bits; 165 166 return_value = str; 167 generic_floating_point_number.low = bits + MAX_PRECISION; 168 generic_floating_point_number.high = NULL; 169 generic_floating_point_number.leader = NULL; 170 generic_floating_point_number.exponent = 0; 171 generic_floating_point_number.sign = '\0'; 172 173 /* Use more LittleNums than seems */ 174 /* necessary: the highest flonum may have */ 175 /* 15 leading 0 bits, so could be useless. */ 176 177 memset(bits, '\0', sizeof(LITTLENUM_TYPE) * MAX_PRECISION); 178 179 switch(what_kind) { 180 case 'f': 181 case 'F': 182 case 's': 183 case 'S': 184 precision = F_PRECISION; 185 exponent_bits = 8; 186 break; 187 188 case 'd': 189 case 'D': 190 case 'r': 191 case 'R': 192 precision = D_PRECISION; 193 exponent_bits = 11; 194 break; 195 196 case 'x': 197 case 'X': 198 case 'e': 199 case 'E': 200 precision = X_PRECISION; 201 exponent_bits = 15; 202 break; 203 204 case 'p': 205 case 'P': 206 207 precision = P_PRECISION; 208 exponent_bits= -1; 209 break; 210 211 default: 212 make_invalid_floating_point_number (words); 213 return NULL; 214 } 215 216 generic_floating_point_number.high = generic_floating_point_number.low + precision - 1 + GUARD; 217 218 if (atof_generic (& return_value, ".", md_EXP_CHARS, & generic_floating_point_number)) { 219 /* as_warn("Error converting floating point number (Exponent overflow?)"); */ 220#ifdef NeXT_MOD 221 if(precision==F_PRECISION) { 222 words[0]=0x7f80; 223 words[1]=0; 224 } else { 225 words[0]=0x7ff0; 226 words[1]=0; 227 words[2]=0; 228 words[3]=0; 229 } 230 if(generic_floating_point_number.sign=='-') 231 words[0] |= 0x8000; 232 return return_value; 233#else /* NeXT_MOD */ 234 make_invalid_floating_point_number (words); 235 return NULL; 236#endif /* NeXT_MOD */ 237 } 238 gen_to_words(words, precision, exponent_bits); 239 return return_value; 240} 241 242/* Turn generic_floating_point_number into a real float/double/extended */ 243int 244gen_to_words( 245LITTLENUM_TYPE *words, 246int precision, 247int exponent_bits) 248{ 249 int return_value=0; 250 251 int32_t exponent_1; 252 int32_t exponent_2; 253 int32_t exponent_3; 254 int32_t exponent_4; 255 int exponent_skippage; 256 LITTLENUM_TYPE word1; 257 LITTLENUM_TYPE * lp; 258 259 if (generic_floating_point_number.low > generic_floating_point_number.leader) { 260 /* 0.0e0 seen. */ 261 if(generic_floating_point_number.sign=='+') 262 words[0]=0x0000; 263 else 264 words[0]=0x8000; 265 memset(&words[1], '\0', sizeof(LITTLENUM_TYPE) * (precision-1)); 266 return return_value; 267 } 268 269 /* NaN: Do the right thing */ 270 if(generic_floating_point_number.sign==0) { 271 if(precision==F_PRECISION) { 272 words[0]=0x7fff; 273 words[1]=0xffff; 274 } else { 275 words[0]=0x7fff; 276 words[1]=0xffff; 277 words[2]=0xffff; 278 words[3]=0xffff; 279 } 280 return return_value; 281 } else if(generic_floating_point_number.sign=='P') { 282 /* +INF: Do the right thing */ 283 if(precision==F_PRECISION) { 284 words[0]=0x7f80; 285 words[1]=0; 286 } else { 287 words[0]=0x7ff0; 288 words[1]=0; 289 words[2]=0; 290 words[3]=0; 291 } 292 return return_value; 293 } else if(generic_floating_point_number.sign=='N') { 294 /* Negative INF */ 295 if(precision==F_PRECISION) { 296 words[0]=0xff80; 297 words[1]=0x0; 298 } else { 299 words[0]=0xfff0; 300 words[1]=0x0; 301 words[2]=0x0; 302 words[3]=0x0; 303 } 304 return return_value; 305 } 306 /* 307 * The floating point formats we support have: 308 * Bit 15 is sign bit. 309 * Bits 14:n are excess-whatever exponent. 310 * Bits n-1:0 (if any) are most significant bits of fraction. 311 * Bits 15:0 of the next word(s) are the next most significant bits. 312 * 313 * So we need: number of bits of exponent, number of bits of 314 * mantissa. 315 */ 316 bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS; 317 littlenum_pointer = generic_floating_point_number.leader; 318 littlenums_left = 1+generic_floating_point_number.leader - generic_floating_point_number.low; 319 /* Seek (and forget) 1st significant bit */ 320 for (exponent_skippage = 0;! next_bits(1); exponent_skippage ++) 321 ; 322 exponent_1 = generic_floating_point_number.exponent + generic_floating_point_number.leader + 1 - 323 generic_floating_point_number.low; 324 /* Radix LITTLENUM_RADIX, point just higher than generic_floating_point_number.leader. */ 325 exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS; 326 /* Radix 2. */ 327 exponent_3 = exponent_2 - exponent_skippage; 328 /* Forget leading zeros, forget 1st bit. */ 329 exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2); 330 /* Offset exponent. */ 331 332 lp = words; 333 334 /* Word 1. Sign, exponent and perhaps high bits. */ 335 word1 = (generic_floating_point_number.sign == '+') ? 0 : (1<<(LITTLENUM_NUMBER_OF_BITS-1)); 336 337 /* Assume 2's complement integers. */ 338 if(exponent_4<1 && exponent_4>=-62) { 339 int prec_bits; 340 int num_bits; 341 342 unget_bits(1); 343 num_bits= -exponent_4; 344 prec_bits=LITTLENUM_NUMBER_OF_BITS*precision-(exponent_bits+1+num_bits); 345 if(precision==X_PRECISION && exponent_bits==15) 346 prec_bits-=LITTLENUM_NUMBER_OF_BITS+1; 347 348 if(num_bits>=LITTLENUM_NUMBER_OF_BITS-exponent_bits) { 349 /* Bigger than one littlenum */ 350 num_bits-=(LITTLENUM_NUMBER_OF_BITS-1)-exponent_bits; 351 *lp++=word1; 352 if(num_bits+exponent_bits+1>=precision*LITTLENUM_NUMBER_OF_BITS) { 353 /* Exponent overflow */ 354#ifdef NeXT_MOD 355 if(precision==F_PRECISION) { 356 words[0]=0x7f80; 357 words[1]=0; 358 } else { 359 words[0]=0x7ff0; 360 words[1]=0; 361 words[2]=0; 362 words[3]=0; 363 } 364 if(generic_floating_point_number.sign=='-') 365 words[0] |= 0x8000; 366 return return_value; 367#else /* NeXT_MOD */ 368 make_invalid_floating_point_number(words); 369 return return_value; 370#endif /* NeXT_MOD */ 371 } 372 if(precision==X_PRECISION && exponent_bits==15) { 373 *lp++=0; 374 *lp++=0; 375 num_bits-=LITTLENUM_NUMBER_OF_BITS-1; 376 } 377 while(num_bits>=LITTLENUM_NUMBER_OF_BITS) { 378 num_bits-=LITTLENUM_NUMBER_OF_BITS; 379 *lp++=0; 380 } 381 if(num_bits) 382 *lp++=next_bits(LITTLENUM_NUMBER_OF_BITS-(num_bits)); 383 } else { 384 if(precision==X_PRECISION && exponent_bits==15) { 385 *lp++=word1; 386 *lp++=0; 387 if(num_bits==LITTLENUM_NUMBER_OF_BITS) { 388 *lp++=0; 389 *lp++=next_bits(LITTLENUM_NUMBER_OF_BITS-1); 390 } else if(num_bits==LITTLENUM_NUMBER_OF_BITS-1) 391 *lp++=0; 392 else 393 *lp++=next_bits(LITTLENUM_NUMBER_OF_BITS-1-num_bits); 394 num_bits=0; 395 } else { 396 word1|= next_bits ((LITTLENUM_NUMBER_OF_BITS-1) - (exponent_bits+num_bits)); 397 *lp++=word1; 398 } 399 } 400 while(lp<words+precision) 401 *lp++=next_bits(LITTLENUM_NUMBER_OF_BITS); 402 403#ifdef NeXT_MOD 404 /* 405 * Round the mantissa up, and let the rounding change the 406 * number if that happens. Noting that the largest denorm 407 * rounded up will produce the correct smallest normalilized 408 * number. This is not correct IEEE round to nearest as if 409 * the number is exactly half way between two numbers (the 410 * round bit is set and all lower bits are zero) the last bit 411 * is not set to zero. This would require that the input 412 * flonum be created from the decimal string with a correct 413 * sticky bit for the remaining digits so that could be used 414 * here. The reason the rounding is needed is so that the 415 * decimal version of the smallest denorm will not become 0. 416 */ 417#else /* !defined(NeXT_MOD) */ 418 /* Round the mantissa up, but don't change the number */ 419#endif /* NeXT_MOD */ 420 if(next_bits(1)) { 421 --lp; 422 if(prec_bits>LITTLENUM_NUMBER_OF_BITS) { 423 int n = 0; 424 int tmp_bits; 425 426 n=0; 427 tmp_bits=prec_bits; 428 while(tmp_bits>LITTLENUM_NUMBER_OF_BITS) { 429 if(lp[n]!=(LITTLENUM_TYPE)-1) 430 break; 431 --n; 432 tmp_bits-=LITTLENUM_NUMBER_OF_BITS; 433 } 434#ifndef NeXT_MOD 435 if(tmp_bits>LITTLENUM_NUMBER_OF_BITS || 436 (lp[n]&mask[tmp_bits])!=mask[tmp_bits]) 437#endif /* NeXT_MOD */ 438 { 439 uint32_t carry; 440 441 for (carry = 1; carry && (lp >= words); lp --) { 442 carry = * lp + carry; 443 * lp = carry; 444 carry >>= LITTLENUM_NUMBER_OF_BITS; 445 } 446 } 447 } 448 else 449#ifdef NeXT_MOD 450 *lp = *lp + 1; 451#else /* !defined(NeXT_MOD) */ 452 else if((*lp&mask[prec_bits])!=mask[prec_bits]) 453 *lp++; 454#endif /* NeXT_MOD */ 455 } 456 457 return return_value; 458 } else if (exponent_4 & ~ mask [exponent_bits]) { 459 /* 460 * Exponent overflow. Lose immediately. 461 */ 462 463 /* 464 * We leave return_value alone: admit we read the 465 * number, but return a floating exception 466 * because we can't encode the number. 467 */ 468#ifdef NeXT_MOD 469 if(precision==F_PRECISION) { 470 words[0]=0x7f80; 471 words[1]=0; 472 } else { 473 words[0]=0x7ff0; 474 words[1]=0; 475 words[2]=0; 476 words[3]=0; 477 } 478 if(generic_floating_point_number.sign=='-') 479 words[0] |= 0x8000; 480#else /* NeXT_MOD */ 481 make_invalid_floating_point_number (words); 482#endif /* NeXT_MOD */ 483 return return_value; 484 } else { 485 word1 |= (exponent_4 << ((LITTLENUM_NUMBER_OF_BITS-1) - exponent_bits)) 486 | next_bits ((LITTLENUM_NUMBER_OF_BITS-1) - exponent_bits); 487 } 488 489 * lp ++ = word1; 490 491 /* X_PRECISION is special: it has 16 bits of zero in the middle, 492 followed by a 1 bit. */ 493 if(exponent_bits==15 && precision==X_PRECISION) { 494 *lp++=0; 495 *lp++ = 1 << (LITTLENUM_NUMBER_OF_BITS - 1) | 496 next_bits(LITTLENUM_NUMBER_OF_BITS - 1); 497 } 498 499 /* The rest of the words are just mantissa bits. */ 500 while(lp < words + precision) 501 *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS); 502 503 if (next_bits (1)) { 504 uint32_t carry; 505 /* 506 * Since the NEXT bit is a 1, round UP the mantissa. 507 * The cunning design of these hidden-1 floats permits 508 * us to let the mantissa overflow into the exponent, and 509 * it 'does the right thing'. However, we lose if the 510 * highest-order bit of the lowest-order word flips. 511 * Is that clear? 512 */ 513 514 515/* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2) 516 Please allow at least 1 more bit in carry than is in a LITTLENUM. 517 We need that extra bit to hold a carry during a LITTLENUM carry 518 propagation. Another extra bit (kept 0) will assure us that we 519 don't get a sticky sign bit after shifting right, and that 520 permits us to propagate the carry without any masking of bits. 521#endif */ 522 for (carry = 1, lp --; carry && (lp >= words); lp --) { 523 carry = * lp + carry; 524 * lp = carry; 525 carry >>= LITTLENUM_NUMBER_OF_BITS; 526 } 527 if ( (word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)) ) { 528 /* We leave return_value alone: admit we read the 529 * number, but return a floating exception 530 * because we can't encode the number. 531 */ 532 *words&= ~ (1 << (LITTLENUM_NUMBER_OF_BITS - 1)); 533 /* make_invalid_floating_point_number (words); */ 534 /* return return_value; */ 535 } 536 } 537 return (return_value); 538} 539 540/* This routine is a real kludge. Someone really should do it better, but 541 I'm too lazy, and I don't understand this stuff all too well anyway 542 (JF) 543 */ 544void 545int_to_gen( 546int x) 547{ 548 char buf[20]; 549 char *bufp; 550 551 sprintf(buf,"%d",x); 552 bufp= &buf[0]; 553 if(atof_generic(&bufp,".", md_EXP_CHARS, &generic_floating_point_number)) 554 as_fatal("Error converting number to floating point (Exponent overflow?)"); 555} 556 557#ifdef TEST 558char * 559print_gen(gen) 560FLONUM_TYPE *gen; 561{ 562 FLONUM_TYPE f; 563 LITTLENUM_TYPE arr[10]; 564 double dv; 565 float fv; 566 static char sbuf[40]; 567 568 if(gen) { 569 f=generic_floating_point_number; 570 generic_floating_point_number= *gen; 571 } 572 gen_to_words(&arr[0],4,11); 573 memcpy(&dv, &arr[0], sizeof(double)); 574 sprintf(sbuf,"%x %x %x %x %.14G ",arr[0],arr[1],arr[2],arr[3],dv); 575 gen_to_words(&arr[0],2,8); 576 memcpy(&fv, &arr[0], sizeof(float)); 577 sprintf(sbuf+strlen(sbuf),"%x %x %.12g\n",arr[0],arr[1],fv); 578 if(gen) 579 generic_floating_point_number=f; 580 return sbuf; 581} 582#endif /* TEST */ 583