convert_numeric.c (18939B)
1 /* IEEE floating point support routines, for GDB, the GNU Debugger. 2 Copyright 1991, 1994, 1999, 2000, 2003, 2005, 2006 3 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 20 21 /* This is needed to pick up the NAN macro on some systems. */ 22 /* #define _GNU_SOURCE */ 23 24 #ifdef HAVE_CONFIG_H 25 #include "config.h" 26 #endif 27 28 #include <math.h> 29 30 #ifdef HAVE_STRING_H 31 #include <string.h> 32 #endif 33 34 /* On some platforms, <float.h> provides DBL_QNAN. */ 35 #ifdef STDC_HEADERS 36 #include <float.h> 37 #endif 38 39 /*#include "ansidecl.h"*/ 40 /*#include "libiberty.h"*/ 41 #include "convert_numeric.h" 42 43 #ifndef INFINITY 44 #ifdef HUGE_VAL 45 #define INFINITY HUGE_VAL 46 #else 47 #define INFINITY (1.0 / 0.0) 48 #endif 49 #endif 50 51 #ifndef NAN 52 #ifdef DBL_QNAN 53 #define NAN DBL_QNAN 54 #else 55 #define NAN (0.0 / 0.0) 56 #endif 57 #endif 58 59 static unsigned long get_field (const unsigned char *, 60 enum EXTRACTOR_floatformat_byteorders, 61 unsigned int, 62 unsigned int, 63 unsigned int); 64 65 static int floatformat_always_valid (const struct EXTRACTOR_floatformat *fmt, 66 const void *from); 67 68 static int 69 floatformat_always_valid (const struct 70 EXTRACTOR_floatformat *fmt /*ATTRIBUTE_UNUSED*/, 71 const void *from /*ATTRIBUTE_UNUSED*/) 72 { 73 return 1; 74 } 75 76 77 /* The odds that CHAR_BIT will be anything but 8 are low enough that I'm not 78 going to bother with trying to muck around with whether it is defined in 79 a system header, what we do if not, etc. */ 80 #define FLOATFORMAT_CHAR_BIT 8 81 82 /* floatformats for IEEE single and double, big and little endian. */ 83 const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ieee_single_big = { 84 floatformat_big, 32, 0, 1, 8, 127, 255, 9, 23, 85 floatformat_intbit_no, 86 "floatformat_ieee_single_big", 87 floatformat_always_valid 88 }; 89 const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ieee_single_little = { 90 floatformat_little, 32, 0, 1, 8, 127, 255, 9, 23, 91 floatformat_intbit_no, 92 "floatformat_ieee_single_little", 93 floatformat_always_valid 94 }; 95 const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ieee_double_big = { 96 floatformat_big, 64, 0, 1, 11, 1023, 2047, 12, 52, 97 floatformat_intbit_no, 98 "floatformat_ieee_double_big", 99 floatformat_always_valid 100 }; 101 const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ieee_double_little = { 102 floatformat_little, 64, 0, 1, 11, 1023, 2047, 12, 52, 103 floatformat_intbit_no, 104 "floatformat_ieee_double_little", 105 floatformat_always_valid 106 }; 107 108 /* floatformat for IEEE double, little endian byte order, with big endian word 109 ordering, as on the ARM. */ 110 111 const struct EXTRACTOR_floatformat 112 EXTRACTOR_floatformat_ieee_double_littlebyte_bigword = { 113 floatformat_littlebyte_bigword, 64, 0, 1, 11, 1023, 2047, 12, 52, 114 floatformat_intbit_no, 115 "floatformat_ieee_double_littlebyte_bigword", 116 floatformat_always_valid 117 }; 118 119 /* floatformat for VAX. Not quite IEEE, but close enough. */ 120 121 const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_vax_f = { 122 floatformat_vax, 32, 0, 1, 8, 129, 0, 9, 23, 123 floatformat_intbit_no, 124 "floatformat_vax_f", 125 floatformat_always_valid 126 }; 127 const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_vax_d = { 128 floatformat_vax, 64, 0, 1, 8, 129, 0, 9, 55, 129 floatformat_intbit_no, 130 "floatformat_vax_d", 131 floatformat_always_valid 132 }; 133 const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_vax_g = { 134 floatformat_vax, 64, 0, 1, 11, 1025, 0, 12, 52, 135 floatformat_intbit_no, 136 "floatformat_vax_g", 137 floatformat_always_valid 138 }; 139 140 static int floatformat_i387_ext_is_valid (const struct 141 EXTRACTOR_floatformat *fmt, 142 const void *from); 143 144 static int 145 floatformat_i387_ext_is_valid (const struct EXTRACTOR_floatformat *fmt, const 146 void *from) 147 { 148 /* In the i387 double-extended format, if the exponent is all ones, 149 then the integer bit must be set. If the exponent is neither 0 150 nor ~0, the intbit must also be set. Only if the exponent is 151 zero can it be zero, and then it must be zero. */ 152 unsigned long exponent, int_bit; 153 const unsigned char *ufrom = (const unsigned char *) from; 154 155 exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize, 156 fmt->exp_start, fmt->exp_len); 157 int_bit = get_field (ufrom, fmt->byteorder, fmt->totalsize, 158 fmt->man_start, 1); 159 160 if ((exponent == 0) != (int_bit == 0)) 161 return 0; 162 else 163 return 1; 164 } 165 166 167 const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_i387_ext = { 168 floatformat_little, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64, 169 floatformat_intbit_yes, 170 "floatformat_i387_ext", 171 floatformat_i387_ext_is_valid 172 }; 173 const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_m68881_ext = { 174 /* Note that the bits from 16 to 31 are unused. */ 175 floatformat_big, 96, 0, 1, 15, 0x3fff, 0x7fff, 32, 64, 176 floatformat_intbit_yes, 177 "floatformat_m68881_ext", 178 floatformat_always_valid 179 }; 180 const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_i960_ext = { 181 /* Note that the bits from 0 to 15 are unused. */ 182 floatformat_little, 96, 16, 17, 15, 0x3fff, 0x7fff, 32, 64, 183 floatformat_intbit_yes, 184 "floatformat_i960_ext", 185 floatformat_always_valid 186 }; 187 const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_m88110_ext = { 188 floatformat_big, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64, 189 floatformat_intbit_yes, 190 "floatformat_m88110_ext", 191 floatformat_always_valid 192 }; 193 const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_m88110_harris_ext = { 194 /* Harris uses raw format 128 bytes long, but the number is just an ieee 195 double, and the last 64 bits are wasted. */ 196 floatformat_big,128, 0, 1, 11, 0x3ff, 0x7ff, 12, 52, 197 floatformat_intbit_no, 198 "floatformat_m88110_ext_harris", 199 floatformat_always_valid 200 }; 201 const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_arm_ext_big = { 202 /* Bits 1 to 16 are unused. */ 203 floatformat_big, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64, 204 floatformat_intbit_yes, 205 "floatformat_arm_ext_big", 206 floatformat_always_valid 207 }; 208 const struct EXTRACTOR_floatformat 209 EXTRACTOR_floatformat_arm_ext_littlebyte_bigword = { 210 /* Bits 1 to 16 are unused. */ 211 floatformat_littlebyte_bigword, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64, 212 floatformat_intbit_yes, 213 "floatformat_arm_ext_littlebyte_bigword", 214 floatformat_always_valid 215 }; 216 const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ia64_spill_big = { 217 floatformat_big, 128, 0, 1, 17, 65535, 0x1ffff, 18, 64, 218 floatformat_intbit_yes, 219 "floatformat_ia64_spill_big", 220 floatformat_always_valid 221 }; 222 const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ia64_spill_little = { 223 floatformat_little, 128, 0, 1, 17, 65535, 0x1ffff, 18, 64, 224 floatformat_intbit_yes, 225 "floatformat_ia64_spill_little", 226 floatformat_always_valid 227 }; 228 const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ia64_quad_big = { 229 floatformat_big, 128, 0, 1, 15, 16383, 0x7fff, 16, 112, 230 floatformat_intbit_no, 231 "floatformat_ia64_quad_big", 232 floatformat_always_valid 233 }; 234 const struct EXTRACTOR_floatformat EXTRACTOR_floatformat_ia64_quad_little = { 235 floatformat_little, 128, 0, 1, 15, 16383, 0x7fff, 16, 112, 236 floatformat_intbit_no, 237 "floatformat_ia64_quad_little", 238 floatformat_always_valid 239 }; 240 241 242 #ifndef min 243 #define min(a, b) ((a) < (b) ? (a) : (b)) 244 #endif 245 246 /* Extract a field which starts at START and is LEN bits long. DATA and 247 TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */ 248 static unsigned long 249 get_field (const unsigned char *data, enum EXTRACTOR_floatformat_byteorders 250 order, 251 unsigned int total_len, unsigned int start, unsigned int len) 252 { 253 unsigned long result = 0; 254 unsigned int cur_byte; 255 int lo_bit, hi_bit, cur_bitshift = 0; 256 int nextbyte = (order == floatformat_little) ? 1 : -1; 257 258 /* Start is in big-endian bit order! Fix that first. */ 259 start = total_len - (start + len); 260 261 /* Start at the least significant part of the field. */ 262 if (order == floatformat_little) 263 cur_byte = start / FLOATFORMAT_CHAR_BIT; 264 else 265 cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT; 266 267 lo_bit = start % FLOATFORMAT_CHAR_BIT; 268 hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT); 269 270 do 271 { 272 unsigned int shifted = *(data + cur_byte) >> lo_bit; 273 unsigned int bits = hi_bit - lo_bit; 274 unsigned int mask = (1 << bits) - 1; 275 result |= (shifted & mask) << cur_bitshift; 276 len -= bits; 277 cur_bitshift += bits; 278 cur_byte += nextbyte; 279 lo_bit = 0; 280 hi_bit = min (len, FLOATFORMAT_CHAR_BIT); 281 } 282 while (len != 0); 283 284 return result; 285 } 286 287 288 /* Convert from FMT to a double. 289 FROM is the address of the extended float. 290 Store the double in *TO. */ 291 292 void 293 EXTRACTOR_common_floatformat_to_double (const struct EXTRACTOR_floatformat *fmt, 294 const void *from, double *to) 295 { 296 const unsigned char *ufrom = (const unsigned char *) from; 297 double dto; 298 long exponent; 299 unsigned long mant; 300 unsigned int mant_bits, mant_off; 301 int mant_bits_left; 302 int special_exponent; /* It's a NaN, denorm or zero */ 303 304 exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize, 305 fmt->exp_start, fmt->exp_len); 306 307 /* If the exponent indicates a NaN, we don't have information to 308 decide what to do. So we handle it like IEEE, except that we 309 don't try to preserve the type of NaN. FIXME. */ 310 if ((unsigned long) exponent == fmt->exp_nan) 311 { 312 int nan; 313 314 mant_off = fmt->man_start; 315 mant_bits_left = fmt->man_len; 316 nan = 0; 317 while (mant_bits_left > 0) 318 { 319 mant_bits = min (mant_bits_left, 32); 320 321 if (get_field (ufrom, fmt->byteorder, fmt->totalsize, 322 mant_off, mant_bits) != 0) 323 { 324 /* This is a NaN. */ 325 nan = 1; 326 break; 327 } 328 329 mant_off += mant_bits; 330 mant_bits_left -= mant_bits; 331 } 332 333 /* On certain systems (such as GNU/Linux), the use of the 334 INFINITY macro below may generate a warning that can not be 335 silenced due to a bug in GCC (PR preprocessor/11931). The 336 preprocessor fails to recognise the __extension__ keyword in 337 conjunction with the GNU/C99 extension for hexadecimal 338 floating point constants and will issue a warning when 339 compiling with -pedantic. */if (nan) 340 dto = NAN; 341 else 342 dto = INFINITY; 343 344 if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1)) 345 dto = -dto; 346 347 *to = dto; 348 349 return; 350 } 351 352 mant_bits_left = fmt->man_len; 353 mant_off = fmt->man_start; 354 dto = 0.0; 355 356 special_exponent = (exponent == 0) || ((unsigned long) exponent == 357 fmt->exp_nan); 358 359 /* Don't bias zero's, denorms or NaNs. */ 360 if (! special_exponent) 361 exponent -= fmt->exp_bias; 362 363 /* Build the result algebraically. Might go infinite, underflow, etc; 364 who cares. */ 365 366 /* If this format uses a hidden bit, explicitly add it in now. Otherwise, 367 increment the exponent by one to account for the integer bit. */ 368 369 if (! special_exponent) 370 { 371 if (fmt->intbit == floatformat_intbit_no) 372 dto = ldexp (1.0, exponent); 373 else 374 exponent++; 375 } 376 377 while (mant_bits_left > 0) 378 { 379 mant_bits = min (mant_bits_left, 32); 380 381 mant = get_field (ufrom, fmt->byteorder, fmt->totalsize, 382 mant_off, mant_bits); 383 384 /* Handle denormalized numbers. FIXME: What should we do for 385 non-IEEE formats? */ 386 if (special_exponent && (exponent == 0) && (mant != 0) ) 387 dto += ldexp ((double) mant, 388 (-fmt->exp_bias 389 - mant_bits 390 - (mant_off - fmt->man_start) 391 + 1)); 392 else 393 dto += ldexp ((double) mant, exponent - mant_bits); 394 if (exponent != 0) 395 exponent -= mant_bits; 396 mant_off += mant_bits; 397 mant_bits_left -= mant_bits; 398 } 399 400 /* Negate it if negative. */ 401 if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1)) 402 dto = -dto; 403 *to = dto; 404 } 405 406 407 static void put_field (unsigned char *, enum EXTRACTOR_floatformat_byteorders, 408 unsigned int, 409 unsigned int, 410 unsigned int, 411 unsigned long); 412 413 /* Set a field which starts at START and is LEN bits long. DATA and 414 TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */ 415 static void 416 put_field (unsigned char *data, enum EXTRACTOR_floatformat_byteorders order, 417 unsigned int total_len, unsigned int start, unsigned int len, 418 unsigned long stuff_to_put) 419 { 420 unsigned int cur_byte; 421 int lo_bit, hi_bit; 422 int nextbyte = (order == floatformat_little) ? 1 : -1; 423 424 /* Start is in big-endian bit order! Fix that first. */ 425 start = total_len - (start + len); 426 427 /* Start at the least significant part of the field. */ 428 if (order == floatformat_little) 429 cur_byte = start / FLOATFORMAT_CHAR_BIT; 430 else 431 cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT; 432 433 lo_bit = start % FLOATFORMAT_CHAR_BIT; 434 hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT); 435 436 do 437 { 438 unsigned char *byte_ptr = data + cur_byte; 439 unsigned int bits = hi_bit - lo_bit; 440 unsigned int mask = ((1 << bits) - 1) << lo_bit; 441 *byte_ptr = (*byte_ptr & ~mask) | ((stuff_to_put << lo_bit) & mask); 442 stuff_to_put >>= bits; 443 len -= bits; 444 cur_byte += nextbyte; 445 lo_bit = 0; 446 hi_bit = min (len, FLOATFORMAT_CHAR_BIT); 447 } 448 while (len != 0); 449 } 450 451 452 /* The converse: convert the double *FROM to an extended float 453 and store where TO points. Neither FROM nor TO have any alignment 454 restrictions. */ 455 456 void 457 EXTRACTOR_common_floatformat_from_double (const struct 458 EXTRACTOR_floatformat *fmt, 459 const double *from, void *to) 460 { 461 double dfrom; 462 int exponent; 463 double mant; 464 unsigned int mant_bits, mant_off; 465 int mant_bits_left; 466 unsigned char *uto = (unsigned char *) to; 467 468 dfrom = *from; 469 memset (uto, 0, fmt->totalsize / FLOATFORMAT_CHAR_BIT); 470 471 /* If negative, set the sign bit. */ 472 if (dfrom < 0) 473 { 474 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1); 475 dfrom = -dfrom; 476 } 477 478 if (dfrom == 0) 479 { 480 /* 0.0. */ 481 return; 482 } 483 484 if (dfrom != dfrom) 485 { 486 /* NaN. */ 487 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, 488 fmt->exp_len, fmt->exp_nan); 489 /* Be sure it's not infinity, but NaN value is irrelevant. */ 490 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start, 491 32, 1); 492 return; 493 } 494 495 if (dfrom + dfrom == dfrom) 496 { 497 /* This can only happen for an infinite value (or zero, which we 498 already handled above). */ 499 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, 500 fmt->exp_len, fmt->exp_nan); 501 return; 502 } 503 504 mant = frexp (dfrom, &exponent); 505 if (exponent + fmt->exp_bias - 1 > 0) 506 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, 507 fmt->exp_len, exponent + fmt->exp_bias - 1); 508 else 509 { 510 /* Handle a denormalized number. FIXME: What should we do for 511 non-IEEE formats? */ 512 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, 513 fmt->exp_len, 0); 514 mant = ldexp (mant, exponent + fmt->exp_bias - 1); 515 } 516 517 mant_bits_left = fmt->man_len; 518 mant_off = fmt->man_start; 519 while (mant_bits_left > 0) 520 { 521 unsigned long mant_long; 522 mant_bits = mant_bits_left < 32 ? mant_bits_left : 32; 523 524 mant *= 4294967296.0; 525 mant_long = (unsigned long) mant; 526 mant -= mant_long; 527 528 /* If the integer bit is implicit, and we are not creating a 529 denormalized number, then we need to discard it. */ 530 if (( (unsigned int) mant_bits_left == fmt->man_len) 531 && (fmt->intbit == floatformat_intbit_no) 532 && (exponent + fmt->exp_bias - 1 > 0) ) 533 { 534 mant_long &= 0x7fffffff; 535 mant_bits -= 1; 536 } 537 else if (mant_bits < 32) 538 { 539 /* The bits we want are in the most significant MANT_BITS bits of 540 mant_long. Move them to the least significant. */ 541 mant_long >>= 32 - mant_bits; 542 } 543 544 put_field (uto, fmt->byteorder, fmt->totalsize, 545 mant_off, mant_bits, mant_long); 546 mant_off += mant_bits; 547 mant_bits_left -= mant_bits; 548 } 549 } 550 551 552 /* Return non-zero iff the data at FROM is a valid number in format FMT. */ 553 554 int 555 EXTRACTOR_common_floatformat_is_valid (const struct EXTRACTOR_floatformat *fmt, 556 const void *from) 557 { 558 return fmt->is_valid (fmt, from); 559 } 560 561 562 #ifdef IEEE_DEBUG 563 564 #include <stdio.h> 565 566 /* This is to be run on a host which uses IEEE floating point. */ 567 568 void 569 ieee_test (double n) 570 { 571 double result; 572 573 floatformat_to_double (&floatformat_ieee_double_little, &n, &result); 574 if (((n != result) && (! isnan (n) || ! isnan (result))) 575 || ((n < 0) && (result >= 0)) 576 || ((n >= 0) && (result < 0))) 577 printf ("Differ(to): %.20g -> %.20g\n", n, result); 578 579 floatformat_from_double (&floatformat_ieee_double_little, &n, &result); 580 if (((n != result) && (! isnan (n) || ! isnan (result))) 581 || ((n < 0) && (result >= 0)) 582 || ((n >= 0) && (result < 0))) 583 printf ("Differ(from): %.20g -> %.20g\n", n, result); 584 585 #if 0 586 { 587 char exten[16]; 588 589 floatformat_from_double (&floatformat_m68881_ext, &n, exten); 590 floatformat_to_double (&floatformat_m68881_ext, exten, &result); 591 if (n != result) 592 printf ("Differ(to+from): %.20g -> %.20g\n", n, result); 593 } 594 #endif 595 596 #if IEEE_DEBUG > 1 597 /* This is to be run on a host which uses 68881 format. */ 598 { 599 long double ex = *(long double *) exten; 600 if (ex != n) 601 printf ("Differ(from vs. extended): %.20g\n", n); 602 } 603 #endif 604 } 605 606 607 int 608 main (void) 609 { 610 ieee_test (0.0); 611 ieee_test (0.5); 612 ieee_test (256.0); 613 ieee_test (0.12345); 614 ieee_test (234235.78907234); 615 ieee_test (-512.0); 616 ieee_test (-0.004321); 617 ieee_test (1.2E-70); 618 ieee_test (1.2E-316); 619 ieee_test (4.9406564584124654E-324); 620 ieee_test (-4.9406564584124654E-324); 621 ieee_test (-0.0); 622 ieee_test (-INFINITY); 623 ieee_test (-NAN); 624 ieee_test (INFINITY); 625 ieee_test (NAN); 626 return 0; 627 } 628 629 630 #endif