floatformat.c revision 218822
118334Speter/* IEEE floating point support routines, for GDB, the GNU Debugger. 2169689Skan Copyright 1991, 1994, 1999, 2000, 2003, 2005, 2006 3132718Skan Free Software Foundation, Inc. 418334Speter 590075SobrienThis file is part of GDB. 618334Speter 790075SobrienThis program is free software; you can redistribute it and/or modify 890075Sobrienit under the terms of the GNU General Public License as published by 990075Sobrienthe Free Software Foundation; either version 2 of the License, or 1090075Sobrien(at your option) any later version. 1118334Speter 1290075SobrienThis program is distributed in the hope that it will be useful, 1390075Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of 1490075SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1590075SobrienGNU General Public License for more details. 1618334Speter 1718334SpeterYou should have received a copy of the GNU General Public License 1890075Sobrienalong with this program; if not, write to the Free Software 19169689SkanFoundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 20169689Skan 2118334Speter/* This is needed to pick up the NAN macro on some systems. */ 2218334Speter#define _GNU_SOURCE 2318334Speter 2418334Speter#ifdef HAVE_CONFIG_H 2518334Speter#include "config.h" 2618334Speter#endif 2718334Speter 2818334Speter#include <math.h> 2990075Sobrien 30132718Skan#ifdef HAVE_STRING_H 31132718Skan#include <string.h> 3218334Speter#endif 3318334Speter 3418334Speter/* On some platforms, <float.h> provides DBL_QNAN. */ 35117395Skan#ifdef STDC_HEADERS 36169689Skan#include <float.h> 37169689Skan#endif 3850397Sobrien 39169689Skan#include "ansidecl.h" 4018334Speter#include "libiberty.h" 4118334Speter#include "floatformat.h" 4218334Speter 4318334Speter#ifndef INFINITY 4418334Speter#ifdef HUGE_VAL 4518334Speter#define INFINITY HUGE_VAL 4618334Speter#else 4718334Speter#define INFINITY (1.0 / 0.0) 4818334Speter#endif 4918334Speter#endif 5018334Speter 5118334Speter#ifndef NAN 52117395Skan#ifdef DBL_QNAN 53117395Skan#define NAN DBL_QNAN 5418334Speter#else 5518334Speter#define NAN (0.0 / 0.0) 5618334Speter#endif 5718334Speter#endif 5818334Speter 5918334Speterstatic unsigned long get_field (const unsigned char *, 6018334Speter enum floatformat_byteorders, 6118334Speter unsigned int, 6218334Speter unsigned int, 6318334Speter unsigned int); 6418334Speterstatic int floatformat_always_valid (const struct floatformat *fmt, 6518334Speter const void *from); 6618334Speter 6718334Speterstatic int 6818334Speterfloatformat_always_valid (const struct floatformat *fmt ATTRIBUTE_UNUSED, 69132718Skan const void *from ATTRIBUTE_UNUSED) 7018334Speter{ 7190075Sobrien return 1; 7290075Sobrien} 73169689Skan 7418334Speter/* The odds that CHAR_BIT will be anything but 8 are low enough that I'm not 75169689Skan going to bother with trying to muck around with whether it is defined in 76169689Skan a system header, what we do if not, etc. */ 77169689Skan#define FLOATFORMAT_CHAR_BIT 8 78169689Skan 79169689Skan/* floatformats for IEEE single and double, big and little endian. */ 80169689Skanconst struct floatformat floatformat_ieee_single_big = 81169689Skan{ 82169689Skan floatformat_big, 32, 0, 1, 8, 127, 255, 9, 23, 83260011Spfg floatformat_intbit_no, 84169689Skan "floatformat_ieee_single_big", 85169689Skan floatformat_always_valid 86169689Skan}; 87169689Skanconst struct floatformat floatformat_ieee_single_little = 8818334Speter{ 8990075Sobrien floatformat_little, 32, 0, 1, 8, 127, 255, 9, 23, 9018334Speter floatformat_intbit_no, 91169689Skan "floatformat_ieee_single_little", 9218334Speter floatformat_always_valid 9318334Speter}; 9418334Speterconst struct floatformat floatformat_ieee_double_big = 9518334Speter{ 9618334Speter floatformat_big, 64, 0, 1, 11, 1023, 2047, 12, 52, 9718334Speter floatformat_intbit_no, 9818334Speter "floatformat_ieee_double_big", 9918334Speter floatformat_always_valid 100169689Skan}; 10118334Speterconst struct floatformat floatformat_ieee_double_little = 10218334Speter{ 10390075Sobrien floatformat_little, 64, 0, 1, 11, 1023, 2047, 12, 52, 104169689Skan floatformat_intbit_no, 10590075Sobrien "floatformat_ieee_double_little", 10618334Speter floatformat_always_valid 10718334Speter}; 10818334Speter 10918334Speter/* floatformat for IEEE double, little endian byte order, with big endian word 11018334Speter ordering, as on the ARM. */ 11190075Sobrien 11290075Sobrienconst struct floatformat floatformat_ieee_double_littlebyte_bigword = 113169689Skan{ 114169689Skan floatformat_littlebyte_bigword, 64, 0, 1, 11, 1023, 2047, 12, 52, 115169689Skan floatformat_intbit_no, 11618334Speter "floatformat_ieee_double_littlebyte_bigword", 11718334Speter floatformat_always_valid 11818334Speter}; 11918334Speter 120/* floatformat for VAX. Not quite IEEE, but close enough. */ 121 122const struct floatformat floatformat_vax_f = 123{ 124 floatformat_vax, 32, 0, 1, 8, 129, 0, 9, 23, 125 floatformat_intbit_no, 126 "floatformat_vax_f", 127 floatformat_always_valid 128}; 129const struct floatformat floatformat_vax_d = 130{ 131 floatformat_vax, 64, 0, 1, 8, 129, 0, 9, 55, 132 floatformat_intbit_no, 133 "floatformat_vax_d", 134 floatformat_always_valid 135}; 136const struct floatformat floatformat_vax_g = 137{ 138 floatformat_vax, 64, 0, 1, 11, 1025, 0, 12, 52, 139 floatformat_intbit_no, 140 "floatformat_vax_g", 141 floatformat_always_valid 142}; 143 144static int floatformat_i387_ext_is_valid (const struct floatformat *fmt, 145 const void *from); 146 147static int 148floatformat_i387_ext_is_valid (const struct floatformat *fmt, const void *from) 149{ 150 /* In the i387 double-extended format, if the exponent is all ones, 151 then the integer bit must be set. If the exponent is neither 0 152 nor ~0, the intbit must also be set. Only if the exponent is 153 zero can it be zero, and then it must be zero. */ 154 unsigned long exponent, int_bit; 155 const unsigned char *ufrom = (const unsigned char *) from; 156 157 exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize, 158 fmt->exp_start, fmt->exp_len); 159 int_bit = get_field (ufrom, fmt->byteorder, fmt->totalsize, 160 fmt->man_start, 1); 161 162 if ((exponent == 0) != (int_bit == 0)) 163 return 0; 164 else 165 return 1; 166} 167 168const struct floatformat floatformat_i387_ext = 169{ 170 floatformat_little, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64, 171 floatformat_intbit_yes, 172 "floatformat_i387_ext", 173 floatformat_i387_ext_is_valid 174}; 175const struct floatformat floatformat_m68881_ext = 176{ 177 /* Note that the bits from 16 to 31 are unused. */ 178 floatformat_big, 96, 0, 1, 15, 0x3fff, 0x7fff, 32, 64, 179 floatformat_intbit_yes, 180 "floatformat_m68881_ext", 181 floatformat_always_valid 182}; 183const struct floatformat floatformat_i960_ext = 184{ 185 /* Note that the bits from 0 to 15 are unused. */ 186 floatformat_little, 96, 16, 17, 15, 0x3fff, 0x7fff, 32, 64, 187 floatformat_intbit_yes, 188 "floatformat_i960_ext", 189 floatformat_always_valid 190}; 191const struct floatformat floatformat_m88110_ext = 192{ 193 floatformat_big, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64, 194 floatformat_intbit_yes, 195 "floatformat_m88110_ext", 196 floatformat_always_valid 197}; 198const struct floatformat floatformat_m88110_harris_ext = 199{ 200 /* Harris uses raw format 128 bytes long, but the number is just an ieee 201 double, and the last 64 bits are wasted. */ 202 floatformat_big,128, 0, 1, 11, 0x3ff, 0x7ff, 12, 52, 203 floatformat_intbit_no, 204 "floatformat_m88110_ext_harris", 205 floatformat_always_valid 206}; 207const struct floatformat floatformat_arm_ext_big = 208{ 209 /* Bits 1 to 16 are unused. */ 210 floatformat_big, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64, 211 floatformat_intbit_yes, 212 "floatformat_arm_ext_big", 213 floatformat_always_valid 214}; 215const struct floatformat floatformat_arm_ext_littlebyte_bigword = 216{ 217 /* Bits 1 to 16 are unused. */ 218 floatformat_littlebyte_bigword, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64, 219 floatformat_intbit_yes, 220 "floatformat_arm_ext_littlebyte_bigword", 221 floatformat_always_valid 222}; 223const struct floatformat floatformat_ia64_spill_big = 224{ 225 floatformat_big, 128, 0, 1, 17, 65535, 0x1ffff, 18, 64, 226 floatformat_intbit_yes, 227 "floatformat_ia64_spill_big", 228 floatformat_always_valid 229}; 230const struct floatformat floatformat_ia64_spill_little = 231{ 232 floatformat_little, 128, 0, 1, 17, 65535, 0x1ffff, 18, 64, 233 floatformat_intbit_yes, 234 "floatformat_ia64_spill_little", 235 floatformat_always_valid 236}; 237const struct floatformat floatformat_ia64_quad_big = 238{ 239 floatformat_big, 128, 0, 1, 15, 16383, 0x7fff, 16, 112, 240 floatformat_intbit_no, 241 "floatformat_ia64_quad_big", 242 floatformat_always_valid 243}; 244const struct floatformat floatformat_ia64_quad_little = 245{ 246 floatformat_little, 128, 0, 1, 15, 16383, 0x7fff, 16, 112, 247 floatformat_intbit_no, 248 "floatformat_ia64_quad_little", 249 floatformat_always_valid 250}; 251 252 253#ifndef min 254#define min(a, b) ((a) < (b) ? (a) : (b)) 255#endif 256 257/* Extract a field which starts at START and is LEN bits long. DATA and 258 TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */ 259static unsigned long 260get_field (const unsigned char *data, enum floatformat_byteorders order, 261 unsigned int total_len, unsigned int start, unsigned int len) 262{ 263 unsigned long result = 0; 264 unsigned int cur_byte; 265 int lo_bit, hi_bit, cur_bitshift = 0; 266 int nextbyte = (order == floatformat_little) ? 1 : -1; 267 268 /* Start is in big-endian bit order! Fix that first. */ 269 start = total_len - (start + len); 270 271 /* Start at the least significant part of the field. */ 272 if (order == floatformat_little) 273 cur_byte = start / FLOATFORMAT_CHAR_BIT; 274 else 275 cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT; 276 277 lo_bit = start % FLOATFORMAT_CHAR_BIT; 278 hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT); 279 280 do 281 { 282 unsigned int shifted = *(data + cur_byte) >> lo_bit; 283 unsigned int bits = hi_bit - lo_bit; 284 unsigned int mask = (1 << bits) - 1; 285 result |= (shifted & mask) << cur_bitshift; 286 len -= bits; 287 cur_bitshift += bits; 288 cur_byte += nextbyte; 289 lo_bit = 0; 290 hi_bit = min (len, FLOATFORMAT_CHAR_BIT); 291 } 292 while (len != 0); 293 294 return result; 295} 296 297/* Convert from FMT to a double. 298 FROM is the address of the extended float. 299 Store the double in *TO. */ 300 301void 302floatformat_to_double (const struct floatformat *fmt, 303 const void *from, double *to) 304{ 305 const unsigned char *ufrom = (const unsigned char *) from; 306 double dto; 307 long exponent; 308 unsigned long mant; 309 unsigned int mant_bits, mant_off; 310 int mant_bits_left; 311 int special_exponent; /* It's a NaN, denorm or zero */ 312 313 exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize, 314 fmt->exp_start, fmt->exp_len); 315 316 /* If the exponent indicates a NaN, we don't have information to 317 decide what to do. So we handle it like IEEE, except that we 318 don't try to preserve the type of NaN. FIXME. */ 319 if ((unsigned long) exponent == fmt->exp_nan) 320 { 321 int nan; 322 323 mant_off = fmt->man_start; 324 mant_bits_left = fmt->man_len; 325 nan = 0; 326 while (mant_bits_left > 0) 327 { 328 mant_bits = min (mant_bits_left, 32); 329 330 if (get_field (ufrom, fmt->byteorder, fmt->totalsize, 331 mant_off, mant_bits) != 0) 332 { 333 /* This is a NaN. */ 334 nan = 1; 335 break; 336 } 337 338 mant_off += mant_bits; 339 mant_bits_left -= mant_bits; 340 } 341 342 /* On certain systems (such as GNU/Linux), the use of the 343 INFINITY macro below may generate a warning that can not be 344 silenced due to a bug in GCC (PR preprocessor/11931). The 345 preprocessor fails to recognise the __extension__ keyword in 346 conjunction with the GNU/C99 extension for hexadecimal 347 floating point constants and will issue a warning when 348 compiling with -pedantic. */ 349 if (nan) 350 dto = NAN; 351 else 352 dto = INFINITY; 353 354 if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1)) 355 dto = -dto; 356 357 *to = dto; 358 359 return; 360 } 361 362 mant_bits_left = fmt->man_len; 363 mant_off = fmt->man_start; 364 dto = 0.0; 365 366 special_exponent = exponent == 0 || (unsigned long) exponent == fmt->exp_nan; 367 368 /* Don't bias zero's, denorms or NaNs. */ 369 if (!special_exponent) 370 exponent -= fmt->exp_bias; 371 372 /* Build the result algebraically. Might go infinite, underflow, etc; 373 who cares. */ 374 375 /* If this format uses a hidden bit, explicitly add it in now. Otherwise, 376 increment the exponent by one to account for the integer bit. */ 377 378 if (!special_exponent) 379 { 380 if (fmt->intbit == floatformat_intbit_no) 381 dto = ldexp (1.0, exponent); 382 else 383 exponent++; 384 } 385 386 while (mant_bits_left > 0) 387 { 388 mant_bits = min (mant_bits_left, 32); 389 390 mant = get_field (ufrom, fmt->byteorder, fmt->totalsize, 391 mant_off, mant_bits); 392 393 /* Handle denormalized numbers. FIXME: What should we do for 394 non-IEEE formats? */ 395 if (special_exponent && exponent == 0 && mant != 0) 396 dto += ldexp ((double)mant, 397 (- fmt->exp_bias 398 - mant_bits 399 - (mant_off - fmt->man_start) 400 + 1)); 401 else 402 dto += ldexp ((double)mant, exponent - mant_bits); 403 if (exponent != 0) 404 exponent -= mant_bits; 405 mant_off += mant_bits; 406 mant_bits_left -= mant_bits; 407 } 408 409 /* Negate it if negative. */ 410 if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1)) 411 dto = -dto; 412 *to = dto; 413} 414 415static void put_field (unsigned char *, enum floatformat_byteorders, 416 unsigned int, 417 unsigned int, 418 unsigned int, 419 unsigned long); 420 421/* Set a field which starts at START and is LEN bits long. DATA and 422 TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */ 423static void 424put_field (unsigned char *data, enum floatformat_byteorders order, 425 unsigned int total_len, unsigned int start, unsigned int len, 426 unsigned long stuff_to_put) 427{ 428 unsigned int cur_byte; 429 int lo_bit, hi_bit; 430 int nextbyte = (order == floatformat_little) ? 1 : -1; 431 432 /* Start is in big-endian bit order! Fix that first. */ 433 start = total_len - (start + len); 434 435 /* Start at the least significant part of the field. */ 436 if (order == floatformat_little) 437 cur_byte = start / FLOATFORMAT_CHAR_BIT; 438 else 439 cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT; 440 441 lo_bit = start % FLOATFORMAT_CHAR_BIT; 442 hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT); 443 444 do 445 { 446 unsigned char *byte_ptr = data + cur_byte; 447 unsigned int bits = hi_bit - lo_bit; 448 unsigned int mask = ((1 << bits) - 1) << lo_bit; 449 *byte_ptr = (*byte_ptr & ~mask) | ((stuff_to_put << lo_bit) & mask); 450 stuff_to_put >>= bits; 451 len -= bits; 452 cur_byte += nextbyte; 453 lo_bit = 0; 454 hi_bit = min (len, FLOATFORMAT_CHAR_BIT); 455 } 456 while (len != 0); 457} 458 459/* The converse: convert the double *FROM to an extended float 460 and store where TO points. Neither FROM nor TO have any alignment 461 restrictions. */ 462 463void 464floatformat_from_double (const struct floatformat *fmt, 465 const double *from, void *to) 466{ 467 double dfrom; 468 int exponent; 469 double mant; 470 unsigned int mant_bits, mant_off; 471 int mant_bits_left; 472 unsigned char *uto = (unsigned char *) to; 473 474 dfrom = *from; 475 memset (uto, 0, fmt->totalsize / FLOATFORMAT_CHAR_BIT); 476 477 /* If negative, set the sign bit. */ 478 if (dfrom < 0) 479 { 480 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1); 481 dfrom = -dfrom; 482 } 483 484 if (dfrom == 0) 485 { 486 /* 0.0. */ 487 return; 488 } 489 490 if (dfrom != dfrom) 491 { 492 /* NaN. */ 493 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, 494 fmt->exp_len, fmt->exp_nan); 495 /* Be sure it's not infinity, but NaN value is irrelevant. */ 496 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start, 497 32, 1); 498 return; 499 } 500 501 if (dfrom + dfrom == dfrom) 502 { 503 /* This can only happen for an infinite value (or zero, which we 504 already handled above). */ 505 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, 506 fmt->exp_len, fmt->exp_nan); 507 return; 508 } 509 510 mant = frexp (dfrom, &exponent); 511 if (exponent + fmt->exp_bias - 1 > 0) 512 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, 513 fmt->exp_len, exponent + fmt->exp_bias - 1); 514 else 515 { 516 /* Handle a denormalized number. FIXME: What should we do for 517 non-IEEE formats? */ 518 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, 519 fmt->exp_len, 0); 520 mant = ldexp (mant, exponent + fmt->exp_bias - 1); 521 } 522 523 mant_bits_left = fmt->man_len; 524 mant_off = fmt->man_start; 525 while (mant_bits_left > 0) 526 { 527 unsigned long mant_long; 528 mant_bits = mant_bits_left < 32 ? mant_bits_left : 32; 529 530 mant *= 4294967296.0; 531 mant_long = (unsigned long)mant; 532 mant -= mant_long; 533 534 /* If the integer bit is implicit, and we are not creating a 535 denormalized number, then we need to discard it. */ 536 if ((unsigned int) mant_bits_left == fmt->man_len 537 && fmt->intbit == floatformat_intbit_no 538 && exponent + fmt->exp_bias - 1 > 0) 539 { 540 mant_long &= 0x7fffffff; 541 mant_bits -= 1; 542 } 543 else if (mant_bits < 32) 544 { 545 /* The bits we want are in the most significant MANT_BITS bits of 546 mant_long. Move them to the least significant. */ 547 mant_long >>= 32 - mant_bits; 548 } 549 550 put_field (uto, fmt->byteorder, fmt->totalsize, 551 mant_off, mant_bits, mant_long); 552 mant_off += mant_bits; 553 mant_bits_left -= mant_bits; 554 } 555} 556 557/* Return non-zero iff the data at FROM is a valid number in format FMT. */ 558 559int 560floatformat_is_valid (const struct floatformat *fmt, const void *from) 561{ 562 return fmt->is_valid (fmt, from); 563} 564 565 566#ifdef IEEE_DEBUG 567 568#include <stdio.h> 569 570/* This is to be run on a host which uses IEEE floating point. */ 571 572void 573ieee_test (double n) 574{ 575 double result; 576 577 floatformat_to_double (&floatformat_ieee_double_little, &n, &result); 578 if ((n != result && (! isnan (n) || ! isnan (result))) 579 || (n < 0 && result >= 0) 580 || (n >= 0 && result < 0)) 581 printf ("Differ(to): %.20g -> %.20g\n", n, result); 582 583 floatformat_from_double (&floatformat_ieee_double_little, &n, &result); 584 if ((n != result && (! isnan (n) || ! isnan (result))) 585 || (n < 0 && result >= 0) 586 || (n >= 0 && result < 0)) 587 printf ("Differ(from): %.20g -> %.20g\n", n, result); 588 589#if 0 590 { 591 char exten[16]; 592 593 floatformat_from_double (&floatformat_m68881_ext, &n, exten); 594 floatformat_to_double (&floatformat_m68881_ext, exten, &result); 595 if (n != result) 596 printf ("Differ(to+from): %.20g -> %.20g\n", n, result); 597 } 598#endif 599 600#if IEEE_DEBUG > 1 601 /* This is to be run on a host which uses 68881 format. */ 602 { 603 long double ex = *(long double *)exten; 604 if (ex != n) 605 printf ("Differ(from vs. extended): %.20g\n", n); 606 } 607#endif 608} 609 610int 611main (void) 612{ 613 ieee_test (0.0); 614 ieee_test (0.5); 615 ieee_test (256.0); 616 ieee_test (0.12345); 617 ieee_test (234235.78907234); 618 ieee_test (-512.0); 619 ieee_test (-0.004321); 620 ieee_test (1.2E-70); 621 ieee_test (1.2E-316); 622 ieee_test (4.9406564584124654E-324); 623 ieee_test (- 4.9406564584124654E-324); 624 ieee_test (- 0.0); 625 ieee_test (- INFINITY); 626 ieee_test (- NAN); 627 ieee_test (INFINITY); 628 ieee_test (NAN); 629 return 0; 630} 631#endif 632