atof-ieee.c revision 78828
197403Sobrien/* atof_ieee.c - turn a Flonum into an IEEE floating point number 297403Sobrien Copyright 1987, 1992, 1994, 1996, 1997, 1998, 1999, 2000, 2001 397403Sobrien Free Software Foundation, Inc. 497403Sobrien 597403Sobrien This file is part of GAS, the GNU Assembler. 697403Sobrien 797403Sobrien GAS is free software; you can redistribute it and/or modify 897403Sobrien it under the terms of the GNU General Public License as published by 997403Sobrien the Free Software Foundation; either version 2, or (at your option) 1097403Sobrien any later version. 1197403Sobrien 1297403Sobrien GAS is distributed in the hope that it will be useful, 1397403Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1497403Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1597403Sobrien GNU General Public License for more details. 1697403Sobrien 1797403Sobrien You should have received a copy of the GNU General Public License 18169691Skan along with GAS; see the file COPYING. If not, write to the Free 1997403Sobrien Software Foundation, 59 Temple Place - Suite 330, Boston, MA 2097403Sobrien 02111-1307, USA. */ 2197403Sobrien 2297403Sobrien/* Some float formats are based on the IEEE standard, but use the 2397403Sobrien largest exponent for normal numbers instead of NaNs and infinites. 2497403Sobrien The macro TC_LARGEST_EXPONENT_IS_NORMAL should evaluate to true 2597403Sobrien if the target machine uses such a format. The macro can depend on 2697403Sobrien command line flags if necessary. There is no need to define the 2797403Sobrien macro if it would always be 0. */ 2897403Sobrien 2997403Sobrien#include "as.h" 3097403Sobrien 3197403Sobrien/* Flonums returned here. */ 3297403Sobrienextern FLONUM_TYPE generic_floating_point_number; 3397403Sobrien 3497403Sobrienstatic int next_bits PARAMS ((int)); 3597403Sobrienstatic void unget_bits PARAMS ((int)); 3697403Sobrienstatic void make_invalid_floating_point_number PARAMS ((LITTLENUM_TYPE *)); 3797403Sobrien 3897403Sobrienextern const char EXP_CHARS[]; 3997403Sobrien/* Precision in LittleNums. */ 4097403Sobrien/* Don't count the gap in the m68k extended precision format. */ 4197403Sobrien#define MAX_PRECISION (5) 4297403Sobrien#define F_PRECISION (2) 4397403Sobrien#define D_PRECISION (4) 4497403Sobrien#define X_PRECISION (5) 4597403Sobrien#define P_PRECISION (5) 4697403Sobrien 4797403Sobrien/* Length in LittleNums of guard bits. */ 4897403Sobrien#define GUARD (2) 4997403Sobrien 5097403Sobrien#ifndef TC_LARGEST_EXPONENT_IS_NORMAL 5197403Sobrien#define TC_LARGEST_EXPONENT_IS_NORMAL 0 5297403Sobrien#endif 5397403Sobrien 5497403Sobrienstatic const unsigned long mask[] = 5597403Sobrien{ 56169691Skan 0x00000000, 57169691Skan 0x00000001, 5897403Sobrien 0x00000003, 5997403Sobrien 0x00000007, 60132720Skan 0x0000000f, 61132720Skan 0x0000001f, 6297403Sobrien 0x0000003f, 6397403Sobrien 0x0000007f, 6497403Sobrien 0x000000ff, 6597403Sobrien 0x000001ff, 6697403Sobrien 0x000003ff, 6797403Sobrien 0x000007ff, 6897403Sobrien 0x00000fff, 69132720Skan 0x00001fff, 70132720Skan 0x00003fff, 71132720Skan 0x00007fff, 7297403Sobrien 0x0000ffff, 73132720Skan 0x0001ffff, 74 0x0003ffff, 75 0x0007ffff, 76 0x000fffff, 77 0x001fffff, 78 0x003fffff, 79 0x007fffff, 80 0x00ffffff, 81 0x01ffffff, 82 0x03ffffff, 83 0x07ffffff, 84 0x0fffffff, 85 0x1fffffff, 86 0x3fffffff, 87 0x7fffffff, 88 0xffffffff, 89}; 90 91static int bits_left_in_littlenum; 92static int littlenums_left; 93static LITTLENUM_TYPE *littlenum_pointer; 94 95static int 96next_bits (number_of_bits) 97 int number_of_bits; 98{ 99 int return_value; 100 101 if (!littlenums_left) 102 return (0); 103 if (number_of_bits >= bits_left_in_littlenum) 104 { 105 return_value = mask[bits_left_in_littlenum] & *littlenum_pointer; 106 number_of_bits -= bits_left_in_littlenum; 107 return_value <<= number_of_bits; 108 109 if (--littlenums_left) 110 { 111 bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits; 112 --littlenum_pointer; 113 return_value |= 114 (*littlenum_pointer >> bits_left_in_littlenum) 115 & mask[number_of_bits]; 116 } 117 } 118 else 119 { 120 bits_left_in_littlenum -= number_of_bits; 121 return_value = 122 mask[number_of_bits] & (*littlenum_pointer >> bits_left_in_littlenum); 123 } 124 return return_value; 125} 126 127/* Num had better be less than LITTLENUM_NUMBER_OF_BITS. */ 128 129static void 130unget_bits (num) 131 int num; 132{ 133 if (!littlenums_left) 134 { 135 ++littlenum_pointer; 136 ++littlenums_left; 137 bits_left_in_littlenum = num; 138 } 139 else if (bits_left_in_littlenum + num > LITTLENUM_NUMBER_OF_BITS) 140 { 141 bits_left_in_littlenum = 142 num - (LITTLENUM_NUMBER_OF_BITS - bits_left_in_littlenum); 143 ++littlenum_pointer; 144 ++littlenums_left; 145 } 146 else 147 bits_left_in_littlenum += num; 148} 149 150static void 151make_invalid_floating_point_number (words) 152 LITTLENUM_TYPE *words; 153{ 154 as_bad (_("cannot create floating-point number")); 155 /* Zero the leftmost bit. */ 156 words[0] = (LITTLENUM_TYPE) ((unsigned) -1) >> 1; 157 words[1] = (LITTLENUM_TYPE) -1; 158 words[2] = (LITTLENUM_TYPE) -1; 159 words[3] = (LITTLENUM_TYPE) -1; 160 words[4] = (LITTLENUM_TYPE) -1; 161 words[5] = (LITTLENUM_TYPE) -1; 162} 163 164/* Warning: This returns 16-bit LITTLENUMs. It is up to the caller to 165 figure out any alignment problems and to conspire for the 166 bytes/word to be emitted in the right order. Bigendians beware! */ 167 168/* Note that atof-ieee always has X and P precisions enabled. it is up 169 to md_atof to filter them out if the target machine does not support 170 them. */ 171 172/* Returns pointer past text consumed. */ 173 174char * 175atof_ieee (str, what_kind, words) 176 char *str; /* Text to convert to binary. */ 177 int what_kind; /* 'd', 'f', 'g', 'h'. */ 178 LITTLENUM_TYPE *words; /* Build the binary here. */ 179{ 180 /* Extra bits for zeroed low-order bits. 181 The 1st MAX_PRECISION are zeroed, the last contain flonum bits. */ 182 static LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD]; 183 char *return_value; 184 /* Number of 16-bit words in the format. */ 185 int precision; 186 long exponent_bits; 187 FLONUM_TYPE save_gen_flonum; 188 189 /* We have to save the generic_floating_point_number because it 190 contains storage allocation about the array of LITTLENUMs where 191 the value is actually stored. We will allocate our own array of 192 littlenums below, but have to restore the global one on exit. */ 193 save_gen_flonum = generic_floating_point_number; 194 195 return_value = str; 196 generic_floating_point_number.low = bits + MAX_PRECISION; 197 generic_floating_point_number.high = NULL; 198 generic_floating_point_number.leader = NULL; 199 generic_floating_point_number.exponent = 0; 200 generic_floating_point_number.sign = '\0'; 201 202 /* Use more LittleNums than seems necessary: the highest flonum may 203 have 15 leading 0 bits, so could be useless. */ 204 205 memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION); 206 207 switch (what_kind) 208 { 209 case 'f': 210 case 'F': 211 case 's': 212 case 'S': 213 precision = F_PRECISION; 214 exponent_bits = 8; 215 break; 216 217 case 'd': 218 case 'D': 219 case 'r': 220 case 'R': 221 precision = D_PRECISION; 222 exponent_bits = 11; 223 break; 224 225 case 'x': 226 case 'X': 227 case 'e': 228 case 'E': 229 precision = X_PRECISION; 230 exponent_bits = 15; 231 break; 232 233 case 'p': 234 case 'P': 235 236 precision = P_PRECISION; 237 exponent_bits = -1; 238 break; 239 240 default: 241 make_invalid_floating_point_number (words); 242 return (NULL); 243 } 244 245 generic_floating_point_number.high 246 = generic_floating_point_number.low + precision - 1 + GUARD; 247 248 if (atof_generic (&return_value, ".", EXP_CHARS, 249 &generic_floating_point_number)) 250 { 251 make_invalid_floating_point_number (words); 252 return (NULL); 253 } 254 gen_to_words (words, precision, exponent_bits); 255 256 /* Restore the generic_floating_point_number's storage alloc (and 257 everything else). */ 258 generic_floating_point_number = save_gen_flonum; 259 260 return return_value; 261} 262 263/* Turn generic_floating_point_number into a real float/double/extended. */ 264 265int 266gen_to_words (words, precision, exponent_bits) 267 LITTLENUM_TYPE *words; 268 int precision; 269 long exponent_bits; 270{ 271 int return_value = 0; 272 273 long exponent_1; 274 long exponent_2; 275 long exponent_3; 276 long exponent_4; 277 int exponent_skippage; 278 LITTLENUM_TYPE word1; 279 LITTLENUM_TYPE *lp; 280 LITTLENUM_TYPE *words_end; 281 282 words_end = words + precision; 283#ifdef TC_M68K 284 if (precision == X_PRECISION) 285 /* On the m68k the extended precision format has a gap of 16 bits 286 between the exponent and the mantissa. */ 287 words_end++; 288#endif 289 290 if (generic_floating_point_number.low > generic_floating_point_number.leader) 291 { 292 /* 0.0e0 seen. */ 293 if (generic_floating_point_number.sign == '+') 294 words[0] = 0x0000; 295 else 296 words[0] = 0x8000; 297 memset (&words[1], '\0', 298 (words_end - words - 1) * sizeof (LITTLENUM_TYPE)); 299 return return_value; 300 } 301 302 /* NaN: Do the right thing. */ 303 if (generic_floating_point_number.sign == 0) 304 { 305 if (TC_LARGEST_EXPONENT_IS_NORMAL) 306 as_warn ("NaNs are not supported by this target\n"); 307 if (precision == F_PRECISION) 308 { 309 words[0] = 0x7fff; 310 words[1] = 0xffff; 311 } 312 else if (precision == X_PRECISION) 313 { 314#ifdef TC_M68K 315 words[0] = 0x7fff; 316 words[1] = 0; 317 words[2] = 0xffff; 318 words[3] = 0xffff; 319 words[4] = 0xffff; 320 words[5] = 0xffff; 321#else /* ! TC_M68K */ 322#ifdef TC_I386 323 words[0] = 0xffff; 324 words[1] = 0xc000; 325 words[2] = 0; 326 words[3] = 0; 327 words[4] = 0; 328#else /* ! TC_I386 */ 329 abort (); 330#endif /* ! TC_I386 */ 331#endif /* ! TC_M68K */ 332 } 333 else 334 { 335 words[0] = 0x7fff; 336 words[1] = 0xffff; 337 words[2] = 0xffff; 338 words[3] = 0xffff; 339 } 340 return return_value; 341 } 342 else if (generic_floating_point_number.sign == 'P') 343 { 344 if (TC_LARGEST_EXPONENT_IS_NORMAL) 345 as_warn ("Infinities are not supported by this target\n"); 346 347 /* +INF: Do the right thing. */ 348 if (precision == F_PRECISION) 349 { 350 words[0] = 0x7f80; 351 words[1] = 0; 352 } 353 else if (precision == X_PRECISION) 354 { 355#ifdef TC_M68K 356 words[0] = 0x7fff; 357 words[1] = 0; 358 words[2] = 0; 359 words[3] = 0; 360 words[4] = 0; 361 words[5] = 0; 362#else /* ! TC_M68K */ 363#ifdef TC_I386 364 words[0] = 0x7fff; 365 words[1] = 0x8000; 366 words[2] = 0; 367 words[3] = 0; 368 words[4] = 0; 369#else /* ! TC_I386 */ 370 abort (); 371#endif /* ! TC_I386 */ 372#endif /* ! TC_M68K */ 373 } 374 else 375 { 376 words[0] = 0x7ff0; 377 words[1] = 0; 378 words[2] = 0; 379 words[3] = 0; 380 } 381 return return_value; 382 } 383 else if (generic_floating_point_number.sign == 'N') 384 { 385 if (TC_LARGEST_EXPONENT_IS_NORMAL) 386 as_warn ("Infinities are not supported by this target\n"); 387 388 /* Negative INF. */ 389 if (precision == F_PRECISION) 390 { 391 words[0] = 0xff80; 392 words[1] = 0x0; 393 } 394 else if (precision == X_PRECISION) 395 { 396#ifdef TC_M68K 397 words[0] = 0xffff; 398 words[1] = 0; 399 words[2] = 0; 400 words[3] = 0; 401 words[4] = 0; 402 words[5] = 0; 403#else /* ! TC_M68K */ 404#ifdef TC_I386 405 words[0] = 0xffff; 406 words[1] = 0x8000; 407 words[2] = 0; 408 words[3] = 0; 409 words[4] = 0; 410#else /* ! TC_I386 */ 411 abort (); 412#endif /* ! TC_I386 */ 413#endif /* ! TC_M68K */ 414 } 415 else 416 { 417 words[0] = 0xfff0; 418 words[1] = 0x0; 419 words[2] = 0x0; 420 words[3] = 0x0; 421 } 422 return return_value; 423 } 424 425 /* The floating point formats we support have: 426 Bit 15 is sign bit. 427 Bits 14:n are excess-whatever exponent. 428 Bits n-1:0 (if any) are most significant bits of fraction. 429 Bits 15:0 of the next word(s) are the next most significant bits. 430 431 So we need: number of bits of exponent, number of bits of 432 mantissa. */ 433 bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS; 434 littlenum_pointer = generic_floating_point_number.leader; 435 littlenums_left = (1 436 + generic_floating_point_number.leader 437 - generic_floating_point_number.low); 438 439 /* Seek (and forget) 1st significant bit. */ 440 for (exponent_skippage = 0; !next_bits (1); ++exponent_skippage);; 441 exponent_1 = (generic_floating_point_number.exponent 442 + generic_floating_point_number.leader 443 + 1 444 - generic_floating_point_number.low); 445 446 /* Radix LITTLENUM_RADIX, point just higher than 447 generic_floating_point_number.leader. */ 448 exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS; 449 450 /* Radix 2. */ 451 exponent_3 = exponent_2 - exponent_skippage; 452 453 /* Forget leading zeros, forget 1st bit. */ 454 exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2); 455 456 /* Offset exponent. */ 457 lp = words; 458 459 /* Word 1. Sign, exponent and perhaps high bits. */ 460 word1 = ((generic_floating_point_number.sign == '+') 461 ? 0 462 : (1 << (LITTLENUM_NUMBER_OF_BITS - 1))); 463 464 /* Assume 2's complement integers. */ 465 if (exponent_4 <= 0) 466 { 467 int prec_bits; 468 int num_bits; 469 470 unget_bits (1); 471 num_bits = -exponent_4; 472 prec_bits = 473 LITTLENUM_NUMBER_OF_BITS * precision - (exponent_bits + 1 + num_bits); 474#ifdef TC_I386 475 if (precision == X_PRECISION && exponent_bits == 15) 476 { 477 /* On the i386 a denormalized extended precision float is 478 shifted down by one, effectively decreasing the exponent 479 bias by one. */ 480 prec_bits -= 1; 481 num_bits += 1; 482 } 483#endif 484 485 if (num_bits >= LITTLENUM_NUMBER_OF_BITS - exponent_bits) 486 { 487 /* Bigger than one littlenum. */ 488 num_bits -= (LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits; 489 *lp++ = word1; 490 if (num_bits + exponent_bits + 1 491 > precision * LITTLENUM_NUMBER_OF_BITS) 492 { 493 /* Exponent overflow. */ 494 make_invalid_floating_point_number (words); 495 return return_value; 496 } 497#ifdef TC_M68K 498 if (precision == X_PRECISION && exponent_bits == 15) 499 *lp++ = 0; 500#endif 501 while (num_bits >= LITTLENUM_NUMBER_OF_BITS) 502 { 503 num_bits -= LITTLENUM_NUMBER_OF_BITS; 504 *lp++ = 0; 505 } 506 if (num_bits) 507 *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - (num_bits)); 508 } 509 else 510 { 511 if (precision == X_PRECISION && exponent_bits == 15) 512 { 513 *lp++ = word1; 514#ifdef TC_M68K 515 *lp++ = 0; 516#endif 517 *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - num_bits); 518 } 519 else 520 { 521 word1 |= next_bits ((LITTLENUM_NUMBER_OF_BITS - 1) 522 - (exponent_bits + num_bits)); 523 *lp++ = word1; 524 } 525 } 526 while (lp < words_end) 527 *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS); 528 529 /* Round the mantissa up, but don't change the number. */ 530 if (next_bits (1)) 531 { 532 --lp; 533 if (prec_bits >= LITTLENUM_NUMBER_OF_BITS) 534 { 535 int n = 0; 536 int tmp_bits; 537 538 n = 0; 539 tmp_bits = prec_bits; 540 while (tmp_bits > LITTLENUM_NUMBER_OF_BITS) 541 { 542 if (lp[n] != (LITTLENUM_TYPE) - 1) 543 break; 544 --n; 545 tmp_bits -= LITTLENUM_NUMBER_OF_BITS; 546 } 547 if (tmp_bits > LITTLENUM_NUMBER_OF_BITS 548 || (lp[n] & mask[tmp_bits]) != mask[tmp_bits] 549 || (prec_bits != (precision * LITTLENUM_NUMBER_OF_BITS 550 - exponent_bits - 1) 551#ifdef TC_I386 552 /* An extended precision float with only the integer 553 bit set would be invalid. That must be converted 554 to the smallest normalized number. */ 555 && !(precision == X_PRECISION 556 && prec_bits == (precision * LITTLENUM_NUMBER_OF_BITS 557 - exponent_bits - 2)) 558#endif 559 )) 560 { 561 unsigned long carry; 562 563 for (carry = 1; carry && (lp >= words); lp--) 564 { 565 carry = *lp + carry; 566 *lp = carry; 567 carry >>= LITTLENUM_NUMBER_OF_BITS; 568 } 569 } 570 else 571 { 572 /* This is an overflow of the denormal numbers. We 573 need to forget what we have produced, and instead 574 generate the smallest normalized number. */ 575 lp = words; 576 word1 = ((generic_floating_point_number.sign == '+') 577 ? 0 578 : (1 << (LITTLENUM_NUMBER_OF_BITS - 1))); 579 word1 |= (1 580 << ((LITTLENUM_NUMBER_OF_BITS - 1) 581 - exponent_bits)); 582 *lp++ = word1; 583#ifdef TC_I386 584 /* Set the integer bit in the extended precision format. 585 This cannot happen on the m68k where the mantissa 586 just overflows into the integer bit above. */ 587 if (precision == X_PRECISION) 588 *lp++ = 1 << (LITTLENUM_NUMBER_OF_BITS - 1); 589#endif 590 while (lp < words_end) 591 *lp++ = 0; 592 } 593 } 594 else 595 *lp += 1; 596 } 597 598 return return_value; 599 } 600 else if ((unsigned long) exponent_4 > mask[exponent_bits] 601 || (! TC_LARGEST_EXPONENT_IS_NORMAL 602 && (unsigned long) exponent_4 == mask[exponent_bits])) 603 { 604 /* Exponent overflow. Lose immediately. */ 605 606 /* We leave return_value alone: admit we read the 607 number, but return a floating exception 608 because we can't encode the number. */ 609 make_invalid_floating_point_number (words); 610 return return_value; 611 } 612 else 613 { 614 word1 |= (exponent_4 << ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits)) 615 | next_bits ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits); 616 } 617 618 *lp++ = word1; 619 620 /* X_PRECISION is special: on the 68k, it has 16 bits of zero in the 621 middle. Either way, it is then followed by a 1 bit. */ 622 if (exponent_bits == 15 && precision == X_PRECISION) 623 { 624#ifdef TC_M68K 625 *lp++ = 0; 626#endif 627 *lp++ = (1 << (LITTLENUM_NUMBER_OF_BITS - 1) 628 | next_bits (LITTLENUM_NUMBER_OF_BITS - 1)); 629 } 630 631 /* The rest of the words are just mantissa bits. */ 632 while (lp < words_end) 633 *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS); 634 635 if (next_bits (1)) 636 { 637 unsigned long carry; 638 /* Since the NEXT bit is a 1, round UP the mantissa. 639 The cunning design of these hidden-1 floats permits 640 us to let the mantissa overflow into the exponent, and 641 it 'does the right thing'. However, we lose if the 642 highest-order bit of the lowest-order word flips. 643 Is that clear? */ 644 645 /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2) 646 Please allow at least 1 more bit in carry than is in a LITTLENUM. 647 We need that extra bit to hold a carry during a LITTLENUM carry 648 propagation. Another extra bit (kept 0) will assure us that we 649 don't get a sticky sign bit after shifting right, and that 650 permits us to propagate the carry without any masking of bits. 651 #endif */ 652 for (carry = 1, lp--; carry; lp--) 653 { 654 carry = *lp + carry; 655 *lp = carry; 656 carry >>= LITTLENUM_NUMBER_OF_BITS; 657 if (lp == words) 658 break; 659 } 660 if (precision == X_PRECISION && exponent_bits == 15) 661 { 662 /* Extended precision numbers have an explicit integer bit 663 that we may have to restore. */ 664 if (lp == words) 665 { 666#ifdef TC_M68K 667 /* On the m68k there is a gap of 16 bits. We must 668 explicitly propagate the carry into the exponent. */ 669 words[0] += words[1]; 670 words[1] = 0; 671 lp++; 672#endif 673 /* Put back the integer bit. */ 674 lp[1] |= 1 << (LITTLENUM_NUMBER_OF_BITS - 1); 675 } 676 } 677 if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1))) 678 { 679 /* We leave return_value alone: admit we read the number, 680 but return a floating exception because we can't encode 681 the number. */ 682 *words &= ~(1 << (LITTLENUM_NUMBER_OF_BITS - 1)); 683#if 0 684 make_invalid_floating_point_number (words); 685 return return_value; 686#endif 687 } 688 } 689 return return_value; 690} 691 692#if 0 693/* Unused. */ 694/* This routine is a real kludge. Someone really should do it better, 695 but I'm too lazy, and I don't understand this stuff all too well 696 anyway. (JF) */ 697 698static void 699int_to_gen (x) 700 long x; 701{ 702 char buf[20]; 703 char *bufp; 704 705 sprintf (buf, "%ld", x); 706 bufp = &buf[0]; 707 if (atof_generic (&bufp, ".", EXP_CHARS, &generic_floating_point_number)) 708 as_bad (_("Error converting number to floating point (Exponent overflow?)")); 709} 710#endif 711 712#ifdef TEST 713char * 714print_gen (gen) 715 FLONUM_TYPE *gen; 716{ 717 FLONUM_TYPE f; 718 LITTLENUM_TYPE arr[10]; 719 double dv; 720 float fv; 721 static char sbuf[40]; 722 723 if (gen) 724 { 725 f = generic_floating_point_number; 726 generic_floating_point_number = *gen; 727 } 728 gen_to_words (&arr[0], 4, 11); 729 memcpy (&dv, &arr[0], sizeof (double)); 730 sprintf (sbuf, "%x %x %x %x %.14G ", arr[0], arr[1], arr[2], arr[3], dv); 731 gen_to_words (&arr[0], 2, 8); 732 memcpy (&fv, &arr[0], sizeof (float)); 733 sprintf (sbuf + strlen (sbuf), "%x %x %.12g\n", arr[0], arr[1], fv); 734 735 if (gen) 736 generic_floating_point_number = f; 737 738 return (sbuf); 739} 740 741#endif 742