15796c8dcSSimon Schubert /* Floating point routines for GDB, the GNU debugger. 25796c8dcSSimon Schubert 35796c8dcSSimon Schubert Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 4*c50c785cSJohn Marino 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 5*c50c785cSJohn Marino 2011 Free Software Foundation, Inc. 65796c8dcSSimon Schubert 75796c8dcSSimon Schubert This file is part of GDB. 85796c8dcSSimon Schubert 95796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify 105796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by 115796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or 125796c8dcSSimon Schubert (at your option) any later version. 135796c8dcSSimon Schubert 145796c8dcSSimon Schubert This program is distributed in the hope that it will be useful, 155796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of 165796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 175796c8dcSSimon Schubert GNU General Public License for more details. 185796c8dcSSimon Schubert 195796c8dcSSimon Schubert You should have received a copy of the GNU General Public License 205796c8dcSSimon Schubert along with this program. If not, see <http://www.gnu.org/licenses/>. */ 215796c8dcSSimon Schubert 225796c8dcSSimon Schubert /* Support for converting target fp numbers into host DOUBLEST format. */ 235796c8dcSSimon Schubert 245796c8dcSSimon Schubert /* XXX - This code should really be in libiberty/floatformat.c, 255796c8dcSSimon Schubert however configuration issues with libiberty made this very 265796c8dcSSimon Schubert difficult to do in the available time. */ 275796c8dcSSimon Schubert 285796c8dcSSimon Schubert #include "defs.h" 295796c8dcSSimon Schubert #include "doublest.h" 305796c8dcSSimon Schubert #include "floatformat.h" 315796c8dcSSimon Schubert #include "gdb_assert.h" 325796c8dcSSimon Schubert #include "gdb_string.h" 335796c8dcSSimon Schubert #include "gdbtypes.h" 345796c8dcSSimon Schubert #include <math.h> /* ldexp */ 355796c8dcSSimon Schubert 365796c8dcSSimon Schubert /* The odds that CHAR_BIT will be anything but 8 are low enough that I'm not 375796c8dcSSimon Schubert going to bother with trying to muck around with whether it is defined in 385796c8dcSSimon Schubert a system header, what we do if not, etc. */ 395796c8dcSSimon Schubert #define FLOATFORMAT_CHAR_BIT 8 405796c8dcSSimon Schubert 415796c8dcSSimon Schubert /* The number of bytes that the largest floating-point type that we 425796c8dcSSimon Schubert can convert to doublest will need. */ 435796c8dcSSimon Schubert #define FLOATFORMAT_LARGEST_BYTES 16 445796c8dcSSimon Schubert 455796c8dcSSimon Schubert /* Extract a field which starts at START and is LEN bytes long. DATA and 465796c8dcSSimon Schubert TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */ 475796c8dcSSimon Schubert static unsigned long 485796c8dcSSimon Schubert get_field (const bfd_byte *data, enum floatformat_byteorders order, 495796c8dcSSimon Schubert unsigned int total_len, unsigned int start, unsigned int len) 505796c8dcSSimon Schubert { 515796c8dcSSimon Schubert unsigned long result; 525796c8dcSSimon Schubert unsigned int cur_byte; 535796c8dcSSimon Schubert int cur_bitshift; 545796c8dcSSimon Schubert 555796c8dcSSimon Schubert /* Caller must byte-swap words before calling this routine. */ 565796c8dcSSimon Schubert gdb_assert (order == floatformat_little || order == floatformat_big); 575796c8dcSSimon Schubert 585796c8dcSSimon Schubert /* Start at the least significant part of the field. */ 595796c8dcSSimon Schubert if (order == floatformat_little) 605796c8dcSSimon Schubert { 615796c8dcSSimon Schubert /* We start counting from the other end (i.e, from the high bytes 625796c8dcSSimon Schubert rather than the low bytes). As such, we need to be concerned 635796c8dcSSimon Schubert with what happens if bit 0 doesn't start on a byte boundary. 645796c8dcSSimon Schubert I.e, we need to properly handle the case where total_len is 655796c8dcSSimon Schubert not evenly divisible by 8. So we compute ``excess'' which 665796c8dcSSimon Schubert represents the number of bits from the end of our starting 675796c8dcSSimon Schubert byte needed to get to bit 0. */ 685796c8dcSSimon Schubert int excess = FLOATFORMAT_CHAR_BIT - (total_len % FLOATFORMAT_CHAR_BIT); 69cf7f2e2dSJohn Marino 705796c8dcSSimon Schubert cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) 715796c8dcSSimon Schubert - ((start + len + excess) / FLOATFORMAT_CHAR_BIT); 725796c8dcSSimon Schubert cur_bitshift = ((start + len + excess) % FLOATFORMAT_CHAR_BIT) 735796c8dcSSimon Schubert - FLOATFORMAT_CHAR_BIT; 745796c8dcSSimon Schubert } 755796c8dcSSimon Schubert else 765796c8dcSSimon Schubert { 775796c8dcSSimon Schubert cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT; 785796c8dcSSimon Schubert cur_bitshift = 795796c8dcSSimon Schubert ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT; 805796c8dcSSimon Schubert } 815796c8dcSSimon Schubert if (cur_bitshift > -FLOATFORMAT_CHAR_BIT) 825796c8dcSSimon Schubert result = *(data + cur_byte) >> (-cur_bitshift); 835796c8dcSSimon Schubert else 845796c8dcSSimon Schubert result = 0; 855796c8dcSSimon Schubert cur_bitshift += FLOATFORMAT_CHAR_BIT; 865796c8dcSSimon Schubert if (order == floatformat_little) 875796c8dcSSimon Schubert ++cur_byte; 885796c8dcSSimon Schubert else 895796c8dcSSimon Schubert --cur_byte; 905796c8dcSSimon Schubert 915796c8dcSSimon Schubert /* Move towards the most significant part of the field. */ 925796c8dcSSimon Schubert while (cur_bitshift < len) 935796c8dcSSimon Schubert { 945796c8dcSSimon Schubert result |= (unsigned long)*(data + cur_byte) << cur_bitshift; 955796c8dcSSimon Schubert cur_bitshift += FLOATFORMAT_CHAR_BIT; 965796c8dcSSimon Schubert switch (order) 975796c8dcSSimon Schubert { 985796c8dcSSimon Schubert case floatformat_little: 995796c8dcSSimon Schubert ++cur_byte; 1005796c8dcSSimon Schubert break; 1015796c8dcSSimon Schubert case floatformat_big: 1025796c8dcSSimon Schubert --cur_byte; 1035796c8dcSSimon Schubert break; 1045796c8dcSSimon Schubert } 1055796c8dcSSimon Schubert } 1065796c8dcSSimon Schubert if (len < sizeof(result) * FLOATFORMAT_CHAR_BIT) 107*c50c785cSJohn Marino /* Mask out bits which are not part of the field. */ 1085796c8dcSSimon Schubert result &= ((1UL << len) - 1); 1095796c8dcSSimon Schubert return result; 1105796c8dcSSimon Schubert } 1115796c8dcSSimon Schubert 1125796c8dcSSimon Schubert /* Normalize the byte order of FROM into TO. If no normalization is 1135796c8dcSSimon Schubert needed then FMT->byteorder is returned and TO is not changed; 1145796c8dcSSimon Schubert otherwise the format of the normalized form in TO is returned. */ 1155796c8dcSSimon Schubert 1165796c8dcSSimon Schubert static enum floatformat_byteorders 1175796c8dcSSimon Schubert floatformat_normalize_byteorder (const struct floatformat *fmt, 1185796c8dcSSimon Schubert const void *from, void *to) 1195796c8dcSSimon Schubert { 1205796c8dcSSimon Schubert const unsigned char *swapin; 1215796c8dcSSimon Schubert unsigned char *swapout; 1225796c8dcSSimon Schubert int words; 1235796c8dcSSimon Schubert 1245796c8dcSSimon Schubert if (fmt->byteorder == floatformat_little 1255796c8dcSSimon Schubert || fmt->byteorder == floatformat_big) 1265796c8dcSSimon Schubert return fmt->byteorder; 1275796c8dcSSimon Schubert 1285796c8dcSSimon Schubert words = fmt->totalsize / FLOATFORMAT_CHAR_BIT; 1295796c8dcSSimon Schubert words >>= 2; 1305796c8dcSSimon Schubert 1315796c8dcSSimon Schubert swapout = (unsigned char *)to; 1325796c8dcSSimon Schubert swapin = (const unsigned char *)from; 1335796c8dcSSimon Schubert 1345796c8dcSSimon Schubert if (fmt->byteorder == floatformat_vax) 1355796c8dcSSimon Schubert { 1365796c8dcSSimon Schubert while (words-- > 0) 1375796c8dcSSimon Schubert { 1385796c8dcSSimon Schubert *swapout++ = swapin[1]; 1395796c8dcSSimon Schubert *swapout++ = swapin[0]; 1405796c8dcSSimon Schubert *swapout++ = swapin[3]; 1415796c8dcSSimon Schubert *swapout++ = swapin[2]; 1425796c8dcSSimon Schubert swapin += 4; 1435796c8dcSSimon Schubert } 1445796c8dcSSimon Schubert /* This may look weird, since VAX is little-endian, but it is 1455796c8dcSSimon Schubert easier to translate to big-endian than to little-endian. */ 1465796c8dcSSimon Schubert return floatformat_big; 1475796c8dcSSimon Schubert } 1485796c8dcSSimon Schubert else 1495796c8dcSSimon Schubert { 1505796c8dcSSimon Schubert gdb_assert (fmt->byteorder == floatformat_littlebyte_bigword); 1515796c8dcSSimon Schubert 1525796c8dcSSimon Schubert while (words-- > 0) 1535796c8dcSSimon Schubert { 1545796c8dcSSimon Schubert *swapout++ = swapin[3]; 1555796c8dcSSimon Schubert *swapout++ = swapin[2]; 1565796c8dcSSimon Schubert *swapout++ = swapin[1]; 1575796c8dcSSimon Schubert *swapout++ = swapin[0]; 1585796c8dcSSimon Schubert swapin += 4; 1595796c8dcSSimon Schubert } 1605796c8dcSSimon Schubert return floatformat_big; 1615796c8dcSSimon Schubert } 1625796c8dcSSimon Schubert } 1635796c8dcSSimon Schubert 1645796c8dcSSimon Schubert /* Convert from FMT to a DOUBLEST. 1655796c8dcSSimon Schubert FROM is the address of the extended float. 1665796c8dcSSimon Schubert Store the DOUBLEST in *TO. */ 1675796c8dcSSimon Schubert 1685796c8dcSSimon Schubert static void 1695796c8dcSSimon Schubert convert_floatformat_to_doublest (const struct floatformat *fmt, 1705796c8dcSSimon Schubert const void *from, 1715796c8dcSSimon Schubert DOUBLEST *to) 1725796c8dcSSimon Schubert { 1735796c8dcSSimon Schubert unsigned char *ufrom = (unsigned char *) from; 1745796c8dcSSimon Schubert DOUBLEST dto; 1755796c8dcSSimon Schubert long exponent; 1765796c8dcSSimon Schubert unsigned long mant; 1775796c8dcSSimon Schubert unsigned int mant_bits, mant_off; 1785796c8dcSSimon Schubert int mant_bits_left; 179*c50c785cSJohn Marino int special_exponent; /* It's a NaN, denorm or zero. */ 1805796c8dcSSimon Schubert enum floatformat_byteorders order; 1815796c8dcSSimon Schubert unsigned char newfrom[FLOATFORMAT_LARGEST_BYTES]; 1825796c8dcSSimon Schubert enum float_kind kind; 1835796c8dcSSimon Schubert 1845796c8dcSSimon Schubert gdb_assert (fmt->totalsize 1855796c8dcSSimon Schubert <= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT); 1865796c8dcSSimon Schubert 1875796c8dcSSimon Schubert /* For non-numbers, reuse libiberty's logic to find the correct 1885796c8dcSSimon Schubert format. We do not lose any precision in this case by passing 1895796c8dcSSimon Schubert through a double. */ 1905796c8dcSSimon Schubert kind = floatformat_classify (fmt, from); 1915796c8dcSSimon Schubert if (kind == float_infinite || kind == float_nan) 1925796c8dcSSimon Schubert { 1935796c8dcSSimon Schubert double dto; 194cf7f2e2dSJohn Marino 1955796c8dcSSimon Schubert floatformat_to_double (fmt, from, &dto); 1965796c8dcSSimon Schubert *to = (DOUBLEST) dto; 1975796c8dcSSimon Schubert return; 1985796c8dcSSimon Schubert } 1995796c8dcSSimon Schubert 2005796c8dcSSimon Schubert order = floatformat_normalize_byteorder (fmt, ufrom, newfrom); 2015796c8dcSSimon Schubert 2025796c8dcSSimon Schubert if (order != fmt->byteorder) 2035796c8dcSSimon Schubert ufrom = newfrom; 2045796c8dcSSimon Schubert 2055796c8dcSSimon Schubert if (fmt->split_half) 2065796c8dcSSimon Schubert { 2075796c8dcSSimon Schubert DOUBLEST dtop, dbot; 208cf7f2e2dSJohn Marino 2095796c8dcSSimon Schubert floatformat_to_doublest (fmt->split_half, ufrom, &dtop); 2105796c8dcSSimon Schubert /* Preserve the sign of 0, which is the sign of the top 2115796c8dcSSimon Schubert half. */ 2125796c8dcSSimon Schubert if (dtop == 0.0) 2135796c8dcSSimon Schubert { 2145796c8dcSSimon Schubert *to = dtop; 2155796c8dcSSimon Schubert return; 2165796c8dcSSimon Schubert } 2175796c8dcSSimon Schubert floatformat_to_doublest (fmt->split_half, 2185796c8dcSSimon Schubert ufrom + fmt->totalsize / FLOATFORMAT_CHAR_BIT / 2, 2195796c8dcSSimon Schubert &dbot); 2205796c8dcSSimon Schubert *to = dtop + dbot; 2215796c8dcSSimon Schubert return; 2225796c8dcSSimon Schubert } 2235796c8dcSSimon Schubert 2245796c8dcSSimon Schubert exponent = get_field (ufrom, order, fmt->totalsize, fmt->exp_start, 2255796c8dcSSimon Schubert fmt->exp_len); 2265796c8dcSSimon Schubert /* Note that if exponent indicates a NaN, we can't really do anything useful 2275796c8dcSSimon Schubert (not knowing if the host has NaN's, or how to build one). So it will 2285796c8dcSSimon Schubert end up as an infinity or something close; that is OK. */ 2295796c8dcSSimon Schubert 2305796c8dcSSimon Schubert mant_bits_left = fmt->man_len; 2315796c8dcSSimon Schubert mant_off = fmt->man_start; 2325796c8dcSSimon Schubert dto = 0.0; 2335796c8dcSSimon Schubert 2345796c8dcSSimon Schubert special_exponent = exponent == 0 || exponent == fmt->exp_nan; 2355796c8dcSSimon Schubert 236*c50c785cSJohn Marino /* Don't bias NaNs. Use minimum exponent for denorms. For 237*c50c785cSJohn Marino simplicity, we don't check for zero as the exponent doesn't matter. 238*c50c785cSJohn Marino Note the cast to int; exp_bias is unsigned, so it's important to 239*c50c785cSJohn Marino make sure the operation is done in signed arithmetic. */ 2405796c8dcSSimon Schubert if (!special_exponent) 2415796c8dcSSimon Schubert exponent -= fmt->exp_bias; 2425796c8dcSSimon Schubert else if (exponent == 0) 2435796c8dcSSimon Schubert exponent = 1 - fmt->exp_bias; 2445796c8dcSSimon Schubert 2455796c8dcSSimon Schubert /* Build the result algebraically. Might go infinite, underflow, etc; 2465796c8dcSSimon Schubert who cares. */ 2475796c8dcSSimon Schubert 2485796c8dcSSimon Schubert /* If this format uses a hidden bit, explicitly add it in now. Otherwise, 2495796c8dcSSimon Schubert increment the exponent by one to account for the integer bit. */ 2505796c8dcSSimon Schubert 2515796c8dcSSimon Schubert if (!special_exponent) 2525796c8dcSSimon Schubert { 2535796c8dcSSimon Schubert if (fmt->intbit == floatformat_intbit_no) 2545796c8dcSSimon Schubert dto = ldexp (1.0, exponent); 2555796c8dcSSimon Schubert else 2565796c8dcSSimon Schubert exponent++; 2575796c8dcSSimon Schubert } 2585796c8dcSSimon Schubert 2595796c8dcSSimon Schubert while (mant_bits_left > 0) 2605796c8dcSSimon Schubert { 2615796c8dcSSimon Schubert mant_bits = min (mant_bits_left, 32); 2625796c8dcSSimon Schubert 2635796c8dcSSimon Schubert mant = get_field (ufrom, order, fmt->totalsize, mant_off, mant_bits); 2645796c8dcSSimon Schubert 2655796c8dcSSimon Schubert dto += ldexp ((double) mant, exponent - mant_bits); 2665796c8dcSSimon Schubert exponent -= mant_bits; 2675796c8dcSSimon Schubert mant_off += mant_bits; 2685796c8dcSSimon Schubert mant_bits_left -= mant_bits; 2695796c8dcSSimon Schubert } 2705796c8dcSSimon Schubert 2715796c8dcSSimon Schubert /* Negate it if negative. */ 2725796c8dcSSimon Schubert if (get_field (ufrom, order, fmt->totalsize, fmt->sign_start, 1)) 2735796c8dcSSimon Schubert dto = -dto; 2745796c8dcSSimon Schubert *to = dto; 2755796c8dcSSimon Schubert } 2765796c8dcSSimon Schubert 2775796c8dcSSimon Schubert static void put_field (unsigned char *, enum floatformat_byteorders, 2785796c8dcSSimon Schubert unsigned int, 2795796c8dcSSimon Schubert unsigned int, unsigned int, unsigned long); 2805796c8dcSSimon Schubert 2815796c8dcSSimon Schubert /* Set a field which starts at START and is LEN bytes long. DATA and 2825796c8dcSSimon Schubert TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */ 2835796c8dcSSimon Schubert static void 2845796c8dcSSimon Schubert put_field (unsigned char *data, enum floatformat_byteorders order, 2855796c8dcSSimon Schubert unsigned int total_len, unsigned int start, unsigned int len, 2865796c8dcSSimon Schubert unsigned long stuff_to_put) 2875796c8dcSSimon Schubert { 2885796c8dcSSimon Schubert unsigned int cur_byte; 2895796c8dcSSimon Schubert int cur_bitshift; 2905796c8dcSSimon Schubert 2915796c8dcSSimon Schubert /* Caller must byte-swap words before calling this routine. */ 2925796c8dcSSimon Schubert gdb_assert (order == floatformat_little || order == floatformat_big); 2935796c8dcSSimon Schubert 2945796c8dcSSimon Schubert /* Start at the least significant part of the field. */ 2955796c8dcSSimon Schubert if (order == floatformat_little) 2965796c8dcSSimon Schubert { 2975796c8dcSSimon Schubert int excess = FLOATFORMAT_CHAR_BIT - (total_len % FLOATFORMAT_CHAR_BIT); 298cf7f2e2dSJohn Marino 2995796c8dcSSimon Schubert cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) 3005796c8dcSSimon Schubert - ((start + len + excess) / FLOATFORMAT_CHAR_BIT); 3015796c8dcSSimon Schubert cur_bitshift = ((start + len + excess) % FLOATFORMAT_CHAR_BIT) 3025796c8dcSSimon Schubert - FLOATFORMAT_CHAR_BIT; 3035796c8dcSSimon Schubert } 3045796c8dcSSimon Schubert else 3055796c8dcSSimon Schubert { 3065796c8dcSSimon Schubert cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT; 3075796c8dcSSimon Schubert cur_bitshift = 3085796c8dcSSimon Schubert ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT; 3095796c8dcSSimon Schubert } 3105796c8dcSSimon Schubert if (cur_bitshift > -FLOATFORMAT_CHAR_BIT) 3115796c8dcSSimon Schubert { 3125796c8dcSSimon Schubert *(data + cur_byte) &= 3135796c8dcSSimon Schubert ~(((1 << ((start + len) % FLOATFORMAT_CHAR_BIT)) - 1) 3145796c8dcSSimon Schubert << (-cur_bitshift)); 3155796c8dcSSimon Schubert *(data + cur_byte) |= 3165796c8dcSSimon Schubert (stuff_to_put & ((1 << FLOATFORMAT_CHAR_BIT) - 1)) << (-cur_bitshift); 3175796c8dcSSimon Schubert } 3185796c8dcSSimon Schubert cur_bitshift += FLOATFORMAT_CHAR_BIT; 3195796c8dcSSimon Schubert if (order == floatformat_little) 3205796c8dcSSimon Schubert ++cur_byte; 3215796c8dcSSimon Schubert else 3225796c8dcSSimon Schubert --cur_byte; 3235796c8dcSSimon Schubert 3245796c8dcSSimon Schubert /* Move towards the most significant part of the field. */ 3255796c8dcSSimon Schubert while (cur_bitshift < len) 3265796c8dcSSimon Schubert { 3275796c8dcSSimon Schubert if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT) 3285796c8dcSSimon Schubert { 3295796c8dcSSimon Schubert /* This is the last byte. */ 3305796c8dcSSimon Schubert *(data + cur_byte) &= 3315796c8dcSSimon Schubert ~((1 << (len - cur_bitshift)) - 1); 3325796c8dcSSimon Schubert *(data + cur_byte) |= (stuff_to_put >> cur_bitshift); 3335796c8dcSSimon Schubert } 3345796c8dcSSimon Schubert else 3355796c8dcSSimon Schubert *(data + cur_byte) = ((stuff_to_put >> cur_bitshift) 3365796c8dcSSimon Schubert & ((1 << FLOATFORMAT_CHAR_BIT) - 1)); 3375796c8dcSSimon Schubert cur_bitshift += FLOATFORMAT_CHAR_BIT; 3385796c8dcSSimon Schubert if (order == floatformat_little) 3395796c8dcSSimon Schubert ++cur_byte; 3405796c8dcSSimon Schubert else 3415796c8dcSSimon Schubert --cur_byte; 3425796c8dcSSimon Schubert } 3435796c8dcSSimon Schubert } 3445796c8dcSSimon Schubert 3455796c8dcSSimon Schubert #ifdef HAVE_LONG_DOUBLE 3465796c8dcSSimon Schubert /* Return the fractional part of VALUE, and put the exponent of VALUE in *EPTR. 3475796c8dcSSimon Schubert The range of the returned value is >= 0.5 and < 1.0. This is equivalent to 3485796c8dcSSimon Schubert frexp, but operates on the long double data type. */ 3495796c8dcSSimon Schubert 3505796c8dcSSimon Schubert static long double ldfrexp (long double value, int *eptr); 3515796c8dcSSimon Schubert 3525796c8dcSSimon Schubert static long double 3535796c8dcSSimon Schubert ldfrexp (long double value, int *eptr) 3545796c8dcSSimon Schubert { 3555796c8dcSSimon Schubert long double tmp; 3565796c8dcSSimon Schubert int exp; 3575796c8dcSSimon Schubert 358*c50c785cSJohn Marino /* Unfortunately, there are no portable functions for extracting the 359*c50c785cSJohn Marino exponent of a long double, so we have to do it iteratively by 360*c50c785cSJohn Marino multiplying or dividing by two until the fraction is between 0.5 361*c50c785cSJohn Marino and 1.0. */ 3625796c8dcSSimon Schubert 3635796c8dcSSimon Schubert if (value < 0.0l) 3645796c8dcSSimon Schubert value = -value; 3655796c8dcSSimon Schubert 3665796c8dcSSimon Schubert tmp = 1.0l; 3675796c8dcSSimon Schubert exp = 0; 3685796c8dcSSimon Schubert 3695796c8dcSSimon Schubert if (value >= tmp) /* Value >= 1.0 */ 3705796c8dcSSimon Schubert while (value >= tmp) 3715796c8dcSSimon Schubert { 3725796c8dcSSimon Schubert tmp *= 2.0l; 3735796c8dcSSimon Schubert exp++; 3745796c8dcSSimon Schubert } 3755796c8dcSSimon Schubert else if (value != 0.0l) /* Value < 1.0 and > 0.0 */ 3765796c8dcSSimon Schubert { 3775796c8dcSSimon Schubert while (value < tmp) 3785796c8dcSSimon Schubert { 3795796c8dcSSimon Schubert tmp /= 2.0l; 3805796c8dcSSimon Schubert exp--; 3815796c8dcSSimon Schubert } 3825796c8dcSSimon Schubert tmp *= 2.0l; 3835796c8dcSSimon Schubert exp++; 3845796c8dcSSimon Schubert } 3855796c8dcSSimon Schubert 3865796c8dcSSimon Schubert *eptr = exp; 3875796c8dcSSimon Schubert return value / tmp; 3885796c8dcSSimon Schubert } 3895796c8dcSSimon Schubert #endif /* HAVE_LONG_DOUBLE */ 3905796c8dcSSimon Schubert 3915796c8dcSSimon Schubert 3925796c8dcSSimon Schubert /* The converse: convert the DOUBLEST *FROM to an extended float and 3935796c8dcSSimon Schubert store where TO points. Neither FROM nor TO have any alignment 3945796c8dcSSimon Schubert restrictions. */ 3955796c8dcSSimon Schubert 3965796c8dcSSimon Schubert static void 3975796c8dcSSimon Schubert convert_doublest_to_floatformat (CONST struct floatformat *fmt, 3985796c8dcSSimon Schubert const DOUBLEST *from, void *to) 3995796c8dcSSimon Schubert { 4005796c8dcSSimon Schubert DOUBLEST dfrom; 4015796c8dcSSimon Schubert int exponent; 4025796c8dcSSimon Schubert DOUBLEST mant; 4035796c8dcSSimon Schubert unsigned int mant_bits, mant_off; 4045796c8dcSSimon Schubert int mant_bits_left; 4055796c8dcSSimon Schubert unsigned char *uto = (unsigned char *) to; 4065796c8dcSSimon Schubert enum floatformat_byteorders order = fmt->byteorder; 4075796c8dcSSimon Schubert unsigned char newto[FLOATFORMAT_LARGEST_BYTES]; 4085796c8dcSSimon Schubert 4095796c8dcSSimon Schubert if (order != floatformat_little) 4105796c8dcSSimon Schubert order = floatformat_big; 4115796c8dcSSimon Schubert 4125796c8dcSSimon Schubert if (order != fmt->byteorder) 4135796c8dcSSimon Schubert uto = newto; 4145796c8dcSSimon Schubert 4155796c8dcSSimon Schubert memcpy (&dfrom, from, sizeof (dfrom)); 4165796c8dcSSimon Schubert memset (uto, 0, (fmt->totalsize + FLOATFORMAT_CHAR_BIT - 1) 4175796c8dcSSimon Schubert / FLOATFORMAT_CHAR_BIT); 4185796c8dcSSimon Schubert 4195796c8dcSSimon Schubert if (fmt->split_half) 4205796c8dcSSimon Schubert { 4215796c8dcSSimon Schubert /* Use static volatile to ensure that any excess precision is 4225796c8dcSSimon Schubert removed via storing in memory, and so the top half really is 4235796c8dcSSimon Schubert the result of converting to double. */ 4245796c8dcSSimon Schubert static volatile double dtop, dbot; 4255796c8dcSSimon Schubert DOUBLEST dtopnv, dbotnv; 426cf7f2e2dSJohn Marino 4275796c8dcSSimon Schubert dtop = (double) dfrom; 4285796c8dcSSimon Schubert /* If the rounded top half is Inf, the bottom must be 0 not NaN 4295796c8dcSSimon Schubert or Inf. */ 4305796c8dcSSimon Schubert if (dtop + dtop == dtop && dtop != 0.0) 4315796c8dcSSimon Schubert dbot = 0.0; 4325796c8dcSSimon Schubert else 4335796c8dcSSimon Schubert dbot = (double) (dfrom - (DOUBLEST) dtop); 4345796c8dcSSimon Schubert dtopnv = dtop; 4355796c8dcSSimon Schubert dbotnv = dbot; 4365796c8dcSSimon Schubert floatformat_from_doublest (fmt->split_half, &dtopnv, uto); 4375796c8dcSSimon Schubert floatformat_from_doublest (fmt->split_half, &dbotnv, 4385796c8dcSSimon Schubert (uto 4395796c8dcSSimon Schubert + fmt->totalsize / FLOATFORMAT_CHAR_BIT / 2)); 4405796c8dcSSimon Schubert return; 4415796c8dcSSimon Schubert } 4425796c8dcSSimon Schubert 4435796c8dcSSimon Schubert if (dfrom == 0) 4445796c8dcSSimon Schubert return; /* Result is zero */ 4455796c8dcSSimon Schubert if (dfrom != dfrom) /* Result is NaN */ 4465796c8dcSSimon Schubert { 4475796c8dcSSimon Schubert /* From is NaN */ 4485796c8dcSSimon Schubert put_field (uto, order, fmt->totalsize, fmt->exp_start, 4495796c8dcSSimon Schubert fmt->exp_len, fmt->exp_nan); 450*c50c785cSJohn Marino /* Be sure it's not infinity, but NaN value is irrel. */ 4515796c8dcSSimon Schubert put_field (uto, order, fmt->totalsize, fmt->man_start, 4525796c8dcSSimon Schubert 32, 1); 4535796c8dcSSimon Schubert goto finalize_byteorder; 4545796c8dcSSimon Schubert } 4555796c8dcSSimon Schubert 4565796c8dcSSimon Schubert /* If negative, set the sign bit. */ 4575796c8dcSSimon Schubert if (dfrom < 0) 4585796c8dcSSimon Schubert { 4595796c8dcSSimon Schubert put_field (uto, order, fmt->totalsize, fmt->sign_start, 1, 1); 4605796c8dcSSimon Schubert dfrom = -dfrom; 4615796c8dcSSimon Schubert } 4625796c8dcSSimon Schubert 463*c50c785cSJohn Marino if (dfrom + dfrom == dfrom && dfrom != 0.0) /* Result is Infinity. */ 4645796c8dcSSimon Schubert { 4655796c8dcSSimon Schubert /* Infinity exponent is same as NaN's. */ 4665796c8dcSSimon Schubert put_field (uto, order, fmt->totalsize, fmt->exp_start, 4675796c8dcSSimon Schubert fmt->exp_len, fmt->exp_nan); 4685796c8dcSSimon Schubert /* Infinity mantissa is all zeroes. */ 4695796c8dcSSimon Schubert put_field (uto, order, fmt->totalsize, fmt->man_start, 4705796c8dcSSimon Schubert fmt->man_len, 0); 4715796c8dcSSimon Schubert goto finalize_byteorder; 4725796c8dcSSimon Schubert } 4735796c8dcSSimon Schubert 4745796c8dcSSimon Schubert #ifdef HAVE_LONG_DOUBLE 4755796c8dcSSimon Schubert mant = ldfrexp (dfrom, &exponent); 4765796c8dcSSimon Schubert #else 4775796c8dcSSimon Schubert mant = frexp (dfrom, &exponent); 4785796c8dcSSimon Schubert #endif 4795796c8dcSSimon Schubert 4805796c8dcSSimon Schubert put_field (uto, order, fmt->totalsize, fmt->exp_start, fmt->exp_len, 4815796c8dcSSimon Schubert exponent + fmt->exp_bias - 1); 4825796c8dcSSimon Schubert 4835796c8dcSSimon Schubert mant_bits_left = fmt->man_len; 4845796c8dcSSimon Schubert mant_off = fmt->man_start; 4855796c8dcSSimon Schubert while (mant_bits_left > 0) 4865796c8dcSSimon Schubert { 4875796c8dcSSimon Schubert unsigned long mant_long; 488cf7f2e2dSJohn Marino 4895796c8dcSSimon Schubert mant_bits = mant_bits_left < 32 ? mant_bits_left : 32; 4905796c8dcSSimon Schubert 4915796c8dcSSimon Schubert mant *= 4294967296.0; 4925796c8dcSSimon Schubert mant_long = ((unsigned long) mant) & 0xffffffffL; 4935796c8dcSSimon Schubert mant -= mant_long; 4945796c8dcSSimon Schubert 4955796c8dcSSimon Schubert /* If the integer bit is implicit, then we need to discard it. 4965796c8dcSSimon Schubert If we are discarding a zero, we should be (but are not) creating 4975796c8dcSSimon Schubert a denormalized number which means adjusting the exponent 4985796c8dcSSimon Schubert (I think). */ 4995796c8dcSSimon Schubert if (mant_bits_left == fmt->man_len 5005796c8dcSSimon Schubert && fmt->intbit == floatformat_intbit_no) 5015796c8dcSSimon Schubert { 5025796c8dcSSimon Schubert mant_long <<= 1; 5035796c8dcSSimon Schubert mant_long &= 0xffffffffL; 5045796c8dcSSimon Schubert /* If we are processing the top 32 mantissa bits of a doublest 5055796c8dcSSimon Schubert so as to convert to a float value with implied integer bit, 5065796c8dcSSimon Schubert we will only be putting 31 of those 32 bits into the 5075796c8dcSSimon Schubert final value due to the discarding of the top bit. In the 5085796c8dcSSimon Schubert case of a small float value where the number of mantissa 5095796c8dcSSimon Schubert bits is less than 32, discarding the top bit does not alter 5105796c8dcSSimon Schubert the number of bits we will be adding to the result. */ 5115796c8dcSSimon Schubert if (mant_bits == 32) 5125796c8dcSSimon Schubert mant_bits -= 1; 5135796c8dcSSimon Schubert } 5145796c8dcSSimon Schubert 5155796c8dcSSimon Schubert if (mant_bits < 32) 5165796c8dcSSimon Schubert { 5175796c8dcSSimon Schubert /* The bits we want are in the most significant MANT_BITS bits of 5185796c8dcSSimon Schubert mant_long. Move them to the least significant. */ 5195796c8dcSSimon Schubert mant_long >>= 32 - mant_bits; 5205796c8dcSSimon Schubert } 5215796c8dcSSimon Schubert 5225796c8dcSSimon Schubert put_field (uto, order, fmt->totalsize, 5235796c8dcSSimon Schubert mant_off, mant_bits, mant_long); 5245796c8dcSSimon Schubert mant_off += mant_bits; 5255796c8dcSSimon Schubert mant_bits_left -= mant_bits; 5265796c8dcSSimon Schubert } 5275796c8dcSSimon Schubert 5285796c8dcSSimon Schubert finalize_byteorder: 5295796c8dcSSimon Schubert /* Do we need to byte-swap the words in the result? */ 5305796c8dcSSimon Schubert if (order != fmt->byteorder) 5315796c8dcSSimon Schubert floatformat_normalize_byteorder (fmt, newto, to); 5325796c8dcSSimon Schubert } 5335796c8dcSSimon Schubert 5345796c8dcSSimon Schubert /* Check if VAL (which is assumed to be a floating point number whose 5355796c8dcSSimon Schubert format is described by FMT) is negative. */ 5365796c8dcSSimon Schubert 5375796c8dcSSimon Schubert int 5385796c8dcSSimon Schubert floatformat_is_negative (const struct floatformat *fmt, 5395796c8dcSSimon Schubert const bfd_byte *uval) 5405796c8dcSSimon Schubert { 5415796c8dcSSimon Schubert enum floatformat_byteorders order; 5425796c8dcSSimon Schubert unsigned char newfrom[FLOATFORMAT_LARGEST_BYTES]; 5435796c8dcSSimon Schubert 5445796c8dcSSimon Schubert gdb_assert (fmt != NULL); 5455796c8dcSSimon Schubert gdb_assert (fmt->totalsize 5465796c8dcSSimon Schubert <= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT); 5475796c8dcSSimon Schubert 5485796c8dcSSimon Schubert order = floatformat_normalize_byteorder (fmt, uval, newfrom); 5495796c8dcSSimon Schubert 5505796c8dcSSimon Schubert if (order != fmt->byteorder) 5515796c8dcSSimon Schubert uval = newfrom; 5525796c8dcSSimon Schubert 5535796c8dcSSimon Schubert return get_field (uval, order, fmt->totalsize, fmt->sign_start, 1); 5545796c8dcSSimon Schubert } 5555796c8dcSSimon Schubert 5565796c8dcSSimon Schubert /* Check if VAL is "not a number" (NaN) for FMT. */ 5575796c8dcSSimon Schubert 5585796c8dcSSimon Schubert enum float_kind 5595796c8dcSSimon Schubert floatformat_classify (const struct floatformat *fmt, 5605796c8dcSSimon Schubert const bfd_byte *uval) 5615796c8dcSSimon Schubert { 5625796c8dcSSimon Schubert long exponent; 5635796c8dcSSimon Schubert unsigned long mant; 5645796c8dcSSimon Schubert unsigned int mant_bits, mant_off; 5655796c8dcSSimon Schubert int mant_bits_left; 5665796c8dcSSimon Schubert enum floatformat_byteorders order; 5675796c8dcSSimon Schubert unsigned char newfrom[FLOATFORMAT_LARGEST_BYTES]; 5685796c8dcSSimon Schubert int mant_zero; 5695796c8dcSSimon Schubert 5705796c8dcSSimon Schubert gdb_assert (fmt != NULL); 5715796c8dcSSimon Schubert gdb_assert (fmt->totalsize 5725796c8dcSSimon Schubert <= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT); 5735796c8dcSSimon Schubert 5745796c8dcSSimon Schubert order = floatformat_normalize_byteorder (fmt, uval, newfrom); 5755796c8dcSSimon Schubert 5765796c8dcSSimon Schubert if (order != fmt->byteorder) 5775796c8dcSSimon Schubert uval = newfrom; 5785796c8dcSSimon Schubert 5795796c8dcSSimon Schubert exponent = get_field (uval, order, fmt->totalsize, fmt->exp_start, 5805796c8dcSSimon Schubert fmt->exp_len); 5815796c8dcSSimon Schubert 5825796c8dcSSimon Schubert mant_bits_left = fmt->man_len; 5835796c8dcSSimon Schubert mant_off = fmt->man_start; 5845796c8dcSSimon Schubert 5855796c8dcSSimon Schubert mant_zero = 1; 5865796c8dcSSimon Schubert while (mant_bits_left > 0) 5875796c8dcSSimon Schubert { 5885796c8dcSSimon Schubert mant_bits = min (mant_bits_left, 32); 5895796c8dcSSimon Schubert 5905796c8dcSSimon Schubert mant = get_field (uval, order, fmt->totalsize, mant_off, mant_bits); 5915796c8dcSSimon Schubert 5925796c8dcSSimon Schubert /* If there is an explicit integer bit, mask it off. */ 5935796c8dcSSimon Schubert if (mant_off == fmt->man_start 5945796c8dcSSimon Schubert && fmt->intbit == floatformat_intbit_yes) 5955796c8dcSSimon Schubert mant &= ~(1 << (mant_bits - 1)); 5965796c8dcSSimon Schubert 5975796c8dcSSimon Schubert if (mant) 5985796c8dcSSimon Schubert { 5995796c8dcSSimon Schubert mant_zero = 0; 6005796c8dcSSimon Schubert break; 6015796c8dcSSimon Schubert } 6025796c8dcSSimon Schubert 6035796c8dcSSimon Schubert mant_off += mant_bits; 6045796c8dcSSimon Schubert mant_bits_left -= mant_bits; 6055796c8dcSSimon Schubert } 6065796c8dcSSimon Schubert 6075796c8dcSSimon Schubert /* If exp_nan is not set, assume that inf, NaN, and subnormals are not 6085796c8dcSSimon Schubert supported. */ 6095796c8dcSSimon Schubert if (! fmt->exp_nan) 6105796c8dcSSimon Schubert { 6115796c8dcSSimon Schubert if (mant_zero) 6125796c8dcSSimon Schubert return float_zero; 6135796c8dcSSimon Schubert else 6145796c8dcSSimon Schubert return float_normal; 6155796c8dcSSimon Schubert } 6165796c8dcSSimon Schubert 6175796c8dcSSimon Schubert if (exponent == 0 && !mant_zero) 6185796c8dcSSimon Schubert return float_subnormal; 6195796c8dcSSimon Schubert 6205796c8dcSSimon Schubert if (exponent == fmt->exp_nan) 6215796c8dcSSimon Schubert { 6225796c8dcSSimon Schubert if (mant_zero) 6235796c8dcSSimon Schubert return float_infinite; 6245796c8dcSSimon Schubert else 6255796c8dcSSimon Schubert return float_nan; 6265796c8dcSSimon Schubert } 6275796c8dcSSimon Schubert 6285796c8dcSSimon Schubert if (mant_zero) 6295796c8dcSSimon Schubert return float_zero; 6305796c8dcSSimon Schubert 6315796c8dcSSimon Schubert return float_normal; 6325796c8dcSSimon Schubert } 6335796c8dcSSimon Schubert 6345796c8dcSSimon Schubert /* Convert the mantissa of VAL (which is assumed to be a floating 6355796c8dcSSimon Schubert point number whose format is described by FMT) into a hexadecimal 6365796c8dcSSimon Schubert and store it in a static string. Return a pointer to that string. */ 6375796c8dcSSimon Schubert 6385796c8dcSSimon Schubert const char * 6395796c8dcSSimon Schubert floatformat_mantissa (const struct floatformat *fmt, 6405796c8dcSSimon Schubert const bfd_byte *val) 6415796c8dcSSimon Schubert { 6425796c8dcSSimon Schubert unsigned char *uval = (unsigned char *) val; 6435796c8dcSSimon Schubert unsigned long mant; 6445796c8dcSSimon Schubert unsigned int mant_bits, mant_off; 6455796c8dcSSimon Schubert int mant_bits_left; 6465796c8dcSSimon Schubert static char res[50]; 6475796c8dcSSimon Schubert char buf[9]; 6485796c8dcSSimon Schubert int len; 6495796c8dcSSimon Schubert enum floatformat_byteorders order; 6505796c8dcSSimon Schubert unsigned char newfrom[FLOATFORMAT_LARGEST_BYTES]; 6515796c8dcSSimon Schubert 6525796c8dcSSimon Schubert gdb_assert (fmt != NULL); 6535796c8dcSSimon Schubert gdb_assert (fmt->totalsize 6545796c8dcSSimon Schubert <= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT); 6555796c8dcSSimon Schubert 6565796c8dcSSimon Schubert order = floatformat_normalize_byteorder (fmt, uval, newfrom); 6575796c8dcSSimon Schubert 6585796c8dcSSimon Schubert if (order != fmt->byteorder) 6595796c8dcSSimon Schubert uval = newfrom; 6605796c8dcSSimon Schubert 6615796c8dcSSimon Schubert if (! fmt->exp_nan) 6625796c8dcSSimon Schubert return 0; 6635796c8dcSSimon Schubert 6645796c8dcSSimon Schubert /* Make sure we have enough room to store the mantissa. */ 6655796c8dcSSimon Schubert gdb_assert (sizeof res > ((fmt->man_len + 7) / 8) * 2); 6665796c8dcSSimon Schubert 6675796c8dcSSimon Schubert mant_off = fmt->man_start; 6685796c8dcSSimon Schubert mant_bits_left = fmt->man_len; 6695796c8dcSSimon Schubert mant_bits = (mant_bits_left % 32) > 0 ? mant_bits_left % 32 : 32; 6705796c8dcSSimon Schubert 6715796c8dcSSimon Schubert mant = get_field (uval, order, fmt->totalsize, mant_off, mant_bits); 6725796c8dcSSimon Schubert 6735796c8dcSSimon Schubert len = xsnprintf (res, sizeof res, "%lx", mant); 6745796c8dcSSimon Schubert 6755796c8dcSSimon Schubert mant_off += mant_bits; 6765796c8dcSSimon Schubert mant_bits_left -= mant_bits; 6775796c8dcSSimon Schubert 6785796c8dcSSimon Schubert while (mant_bits_left > 0) 6795796c8dcSSimon Schubert { 6805796c8dcSSimon Schubert mant = get_field (uval, order, fmt->totalsize, mant_off, 32); 6815796c8dcSSimon Schubert 6825796c8dcSSimon Schubert xsnprintf (buf, sizeof buf, "%08lx", mant); 6835796c8dcSSimon Schubert gdb_assert (len + strlen (buf) <= sizeof res); 6845796c8dcSSimon Schubert strcat (res, buf); 6855796c8dcSSimon Schubert 6865796c8dcSSimon Schubert mant_off += 32; 6875796c8dcSSimon Schubert mant_bits_left -= 32; 6885796c8dcSSimon Schubert } 6895796c8dcSSimon Schubert 6905796c8dcSSimon Schubert return res; 6915796c8dcSSimon Schubert } 6925796c8dcSSimon Schubert 6935796c8dcSSimon Schubert 6945796c8dcSSimon Schubert /* Convert TO/FROM target to the hosts DOUBLEST floating-point format. 6955796c8dcSSimon Schubert 6965796c8dcSSimon Schubert If the host and target formats agree, we just copy the raw data 6975796c8dcSSimon Schubert into the appropriate type of variable and return, letting the host 6985796c8dcSSimon Schubert increase precision as necessary. Otherwise, we call the conversion 6995796c8dcSSimon Schubert routine and let it do the dirty work. */ 7005796c8dcSSimon Schubert 7015796c8dcSSimon Schubert static const struct floatformat *host_float_format = GDB_HOST_FLOAT_FORMAT; 7025796c8dcSSimon Schubert static const struct floatformat *host_double_format = GDB_HOST_DOUBLE_FORMAT; 703*c50c785cSJohn Marino static const struct floatformat *host_long_double_format 704*c50c785cSJohn Marino = GDB_HOST_LONG_DOUBLE_FORMAT; 7055796c8dcSSimon Schubert 7065796c8dcSSimon Schubert void 7075796c8dcSSimon Schubert floatformat_to_doublest (const struct floatformat *fmt, 7085796c8dcSSimon Schubert const void *in, DOUBLEST *out) 7095796c8dcSSimon Schubert { 7105796c8dcSSimon Schubert gdb_assert (fmt != NULL); 7115796c8dcSSimon Schubert if (fmt == host_float_format) 7125796c8dcSSimon Schubert { 7135796c8dcSSimon Schubert float val; 714cf7f2e2dSJohn Marino 7155796c8dcSSimon Schubert memcpy (&val, in, sizeof (val)); 7165796c8dcSSimon Schubert *out = val; 7175796c8dcSSimon Schubert } 7185796c8dcSSimon Schubert else if (fmt == host_double_format) 7195796c8dcSSimon Schubert { 7205796c8dcSSimon Schubert double val; 721cf7f2e2dSJohn Marino 7225796c8dcSSimon Schubert memcpy (&val, in, sizeof (val)); 7235796c8dcSSimon Schubert *out = val; 7245796c8dcSSimon Schubert } 7255796c8dcSSimon Schubert else if (fmt == host_long_double_format) 7265796c8dcSSimon Schubert { 7275796c8dcSSimon Schubert long double val; 728cf7f2e2dSJohn Marino 7295796c8dcSSimon Schubert memcpy (&val, in, sizeof (val)); 7305796c8dcSSimon Schubert *out = val; 7315796c8dcSSimon Schubert } 7325796c8dcSSimon Schubert else 7335796c8dcSSimon Schubert convert_floatformat_to_doublest (fmt, in, out); 7345796c8dcSSimon Schubert } 7355796c8dcSSimon Schubert 7365796c8dcSSimon Schubert void 7375796c8dcSSimon Schubert floatformat_from_doublest (const struct floatformat *fmt, 7385796c8dcSSimon Schubert const DOUBLEST *in, void *out) 7395796c8dcSSimon Schubert { 7405796c8dcSSimon Schubert gdb_assert (fmt != NULL); 7415796c8dcSSimon Schubert if (fmt == host_float_format) 7425796c8dcSSimon Schubert { 7435796c8dcSSimon Schubert float val = *in; 744cf7f2e2dSJohn Marino 7455796c8dcSSimon Schubert memcpy (out, &val, sizeof (val)); 7465796c8dcSSimon Schubert } 7475796c8dcSSimon Schubert else if (fmt == host_double_format) 7485796c8dcSSimon Schubert { 7495796c8dcSSimon Schubert double val = *in; 750cf7f2e2dSJohn Marino 7515796c8dcSSimon Schubert memcpy (out, &val, sizeof (val)); 7525796c8dcSSimon Schubert } 7535796c8dcSSimon Schubert else if (fmt == host_long_double_format) 7545796c8dcSSimon Schubert { 7555796c8dcSSimon Schubert long double val = *in; 756cf7f2e2dSJohn Marino 7575796c8dcSSimon Schubert memcpy (out, &val, sizeof (val)); 7585796c8dcSSimon Schubert } 7595796c8dcSSimon Schubert else 7605796c8dcSSimon Schubert convert_doublest_to_floatformat (fmt, in, out); 7615796c8dcSSimon Schubert } 7625796c8dcSSimon Schubert 7635796c8dcSSimon Schubert 7645796c8dcSSimon Schubert /* Return a floating-point format for a floating-point variable of 7655796c8dcSSimon Schubert length LEN. If no suitable floating-point format is found, an 7665796c8dcSSimon Schubert error is thrown. 7675796c8dcSSimon Schubert 7685796c8dcSSimon Schubert We need this functionality since information about the 7695796c8dcSSimon Schubert floating-point format of a type is not always available to GDB; the 7705796c8dcSSimon Schubert debug information typically only tells us the size of a 7715796c8dcSSimon Schubert floating-point type. 7725796c8dcSSimon Schubert 7735796c8dcSSimon Schubert FIXME: kettenis/2001-10-28: In many places, particularly in 7745796c8dcSSimon Schubert target-dependent code, the format of floating-point types is known, 7755796c8dcSSimon Schubert but not passed on by GDB. This should be fixed. */ 7765796c8dcSSimon Schubert 7775796c8dcSSimon Schubert static const struct floatformat * 7785796c8dcSSimon Schubert floatformat_from_length (struct gdbarch *gdbarch, int len) 7795796c8dcSSimon Schubert { 7805796c8dcSSimon Schubert const struct floatformat *format; 781cf7f2e2dSJohn Marino 782cf7f2e2dSJohn Marino if (len * TARGET_CHAR_BIT == gdbarch_half_bit (gdbarch)) 783cf7f2e2dSJohn Marino format = gdbarch_half_format (gdbarch) 784cf7f2e2dSJohn Marino [gdbarch_byte_order (gdbarch)]; 785cf7f2e2dSJohn Marino else if (len * TARGET_CHAR_BIT == gdbarch_float_bit (gdbarch)) 7865796c8dcSSimon Schubert format = gdbarch_float_format (gdbarch) 7875796c8dcSSimon Schubert [gdbarch_byte_order (gdbarch)]; 7885796c8dcSSimon Schubert else if (len * TARGET_CHAR_BIT == gdbarch_double_bit (gdbarch)) 7895796c8dcSSimon Schubert format = gdbarch_double_format (gdbarch) 7905796c8dcSSimon Schubert [gdbarch_byte_order (gdbarch)]; 7915796c8dcSSimon Schubert else if (len * TARGET_CHAR_BIT == gdbarch_long_double_bit (gdbarch)) 7925796c8dcSSimon Schubert format = gdbarch_long_double_format (gdbarch) 7935796c8dcSSimon Schubert [gdbarch_byte_order (gdbarch)]; 7945796c8dcSSimon Schubert /* On i386 the 'long double' type takes 96 bits, 7955796c8dcSSimon Schubert while the real number of used bits is only 80, 7965796c8dcSSimon Schubert both in processor and in memory. 7975796c8dcSSimon Schubert The code below accepts the real bit size. */ 7985796c8dcSSimon Schubert else if ((gdbarch_long_double_format (gdbarch) != NULL) 799cf7f2e2dSJohn Marino && (len * TARGET_CHAR_BIT 800cf7f2e2dSJohn Marino == gdbarch_long_double_format (gdbarch)[0]->totalsize)) 8015796c8dcSSimon Schubert format = gdbarch_long_double_format (gdbarch) 8025796c8dcSSimon Schubert [gdbarch_byte_order (gdbarch)]; 8035796c8dcSSimon Schubert else 8045796c8dcSSimon Schubert format = NULL; 8055796c8dcSSimon Schubert if (format == NULL) 8065796c8dcSSimon Schubert error (_("Unrecognized %d-bit floating-point type."), 8075796c8dcSSimon Schubert len * TARGET_CHAR_BIT); 8085796c8dcSSimon Schubert return format; 8095796c8dcSSimon Schubert } 8105796c8dcSSimon Schubert 8115796c8dcSSimon Schubert const struct floatformat * 8125796c8dcSSimon Schubert floatformat_from_type (const struct type *type) 8135796c8dcSSimon Schubert { 8145796c8dcSSimon Schubert struct gdbarch *gdbarch = get_type_arch (type); 815cf7f2e2dSJohn Marino 8165796c8dcSSimon Schubert gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT); 8175796c8dcSSimon Schubert if (TYPE_FLOATFORMAT (type) != NULL) 8185796c8dcSSimon Schubert return TYPE_FLOATFORMAT (type)[gdbarch_byte_order (gdbarch)]; 8195796c8dcSSimon Schubert else 8205796c8dcSSimon Schubert return floatformat_from_length (gdbarch, TYPE_LENGTH (type)); 8215796c8dcSSimon Schubert } 8225796c8dcSSimon Schubert 8235796c8dcSSimon Schubert /* Extract a floating-point number of type TYPE from a target-order 8245796c8dcSSimon Schubert byte-stream at ADDR. Returns the value as type DOUBLEST. */ 8255796c8dcSSimon Schubert 8265796c8dcSSimon Schubert DOUBLEST 8275796c8dcSSimon Schubert extract_typed_floating (const void *addr, const struct type *type) 8285796c8dcSSimon Schubert { 8295796c8dcSSimon Schubert const struct floatformat *fmt = floatformat_from_type (type); 8305796c8dcSSimon Schubert DOUBLEST retval; 8315796c8dcSSimon Schubert 8325796c8dcSSimon Schubert floatformat_to_doublest (fmt, addr, &retval); 8335796c8dcSSimon Schubert return retval; 8345796c8dcSSimon Schubert } 8355796c8dcSSimon Schubert 8365796c8dcSSimon Schubert /* Store VAL as a floating-point number of type TYPE to a target-order 8375796c8dcSSimon Schubert byte-stream at ADDR. */ 8385796c8dcSSimon Schubert 8395796c8dcSSimon Schubert void 8405796c8dcSSimon Schubert store_typed_floating (void *addr, const struct type *type, DOUBLEST val) 8415796c8dcSSimon Schubert { 8425796c8dcSSimon Schubert const struct floatformat *fmt = floatformat_from_type (type); 8435796c8dcSSimon Schubert 8445796c8dcSSimon Schubert /* FIXME: kettenis/2001-10-28: It is debatable whether we should 8455796c8dcSSimon Schubert zero out any remaining bytes in the target buffer when TYPE is 8465796c8dcSSimon Schubert longer than the actual underlying floating-point format. Perhaps 8475796c8dcSSimon Schubert we should store a fixed bitpattern in those remaining bytes, 8485796c8dcSSimon Schubert instead of zero, or perhaps we shouldn't touch those remaining 8495796c8dcSSimon Schubert bytes at all. 8505796c8dcSSimon Schubert 8515796c8dcSSimon Schubert NOTE: cagney/2001-10-28: With the way things currently work, it 8525796c8dcSSimon Schubert isn't a good idea to leave the end bits undefined. This is 8535796c8dcSSimon Schubert because GDB writes out the entire sizeof(<floating>) bits of the 8545796c8dcSSimon Schubert floating-point type even though the value might only be stored 8555796c8dcSSimon Schubert in, and the target processor may only refer to, the first N < 8565796c8dcSSimon Schubert TYPE_LENGTH (type) bits. If the end of the buffer wasn't 8575796c8dcSSimon Schubert initialized, GDB would write undefined data to the target. An 8585796c8dcSSimon Schubert errant program, refering to that undefined data, would then 8595796c8dcSSimon Schubert become non-deterministic. 8605796c8dcSSimon Schubert 8615796c8dcSSimon Schubert See also the function convert_typed_floating below. */ 8625796c8dcSSimon Schubert memset (addr, 0, TYPE_LENGTH (type)); 8635796c8dcSSimon Schubert 8645796c8dcSSimon Schubert floatformat_from_doublest (fmt, &val, addr); 8655796c8dcSSimon Schubert } 8665796c8dcSSimon Schubert 8675796c8dcSSimon Schubert /* Convert a floating-point number of type FROM_TYPE from a 8685796c8dcSSimon Schubert target-order byte-stream at FROM to a floating-point number of type 8695796c8dcSSimon Schubert TO_TYPE, and store it to a target-order byte-stream at TO. */ 8705796c8dcSSimon Schubert 8715796c8dcSSimon Schubert void 8725796c8dcSSimon Schubert convert_typed_floating (const void *from, const struct type *from_type, 8735796c8dcSSimon Schubert void *to, const struct type *to_type) 8745796c8dcSSimon Schubert { 8755796c8dcSSimon Schubert const struct floatformat *from_fmt = floatformat_from_type (from_type); 8765796c8dcSSimon Schubert const struct floatformat *to_fmt = floatformat_from_type (to_type); 8775796c8dcSSimon Schubert 8785796c8dcSSimon Schubert if (from_fmt == NULL || to_fmt == NULL) 8795796c8dcSSimon Schubert { 8805796c8dcSSimon Schubert /* If we don't know the floating-point format of FROM_TYPE or 8815796c8dcSSimon Schubert TO_TYPE, there's not much we can do. We might make the 8825796c8dcSSimon Schubert assumption that if the length of FROM_TYPE and TO_TYPE match, 8835796c8dcSSimon Schubert their floating-point format would match too, but that 8845796c8dcSSimon Schubert assumption might be wrong on targets that support 8855796c8dcSSimon Schubert floating-point types that only differ in endianness for 8865796c8dcSSimon Schubert example. So we warn instead, and zero out the target buffer. */ 8875796c8dcSSimon Schubert warning (_("Can't convert floating-point number to desired type.")); 8885796c8dcSSimon Schubert memset (to, 0, TYPE_LENGTH (to_type)); 8895796c8dcSSimon Schubert } 8905796c8dcSSimon Schubert else if (from_fmt == to_fmt) 8915796c8dcSSimon Schubert { 8925796c8dcSSimon Schubert /* We're in business. The floating-point format of FROM_TYPE 8935796c8dcSSimon Schubert and TO_TYPE match. However, even though the floating-point 8945796c8dcSSimon Schubert format matches, the length of the type might still be 8955796c8dcSSimon Schubert different. Make sure we don't overrun any buffers. See 8965796c8dcSSimon Schubert comment in store_typed_floating for a discussion about 8975796c8dcSSimon Schubert zeroing out remaining bytes in the target buffer. */ 8985796c8dcSSimon Schubert memset (to, 0, TYPE_LENGTH (to_type)); 8995796c8dcSSimon Schubert memcpy (to, from, min (TYPE_LENGTH (from_type), TYPE_LENGTH (to_type))); 9005796c8dcSSimon Schubert } 9015796c8dcSSimon Schubert else 9025796c8dcSSimon Schubert { 9035796c8dcSSimon Schubert /* The floating-point types don't match. The best we can do 9045796c8dcSSimon Schubert (apart from simulating the target FPU) is converting to the 9055796c8dcSSimon Schubert widest floating-point type supported by the host, and then 9065796c8dcSSimon Schubert again to the desired type. */ 9075796c8dcSSimon Schubert DOUBLEST d; 9085796c8dcSSimon Schubert 9095796c8dcSSimon Schubert floatformat_to_doublest (from_fmt, from, &d); 9105796c8dcSSimon Schubert floatformat_from_doublest (to_fmt, &d, to); 9115796c8dcSSimon Schubert } 9125796c8dcSSimon Schubert } 9135796c8dcSSimon Schubert 9145796c8dcSSimon Schubert const struct floatformat *floatformat_ieee_single[BFD_ENDIAN_UNKNOWN]; 9155796c8dcSSimon Schubert const struct floatformat *floatformat_ieee_double[BFD_ENDIAN_UNKNOWN]; 9165796c8dcSSimon Schubert const struct floatformat *floatformat_ieee_quad[BFD_ENDIAN_UNKNOWN]; 9175796c8dcSSimon Schubert const struct floatformat *floatformat_arm_ext[BFD_ENDIAN_UNKNOWN]; 9185796c8dcSSimon Schubert const struct floatformat *floatformat_ia64_spill[BFD_ENDIAN_UNKNOWN]; 9195796c8dcSSimon Schubert 9205796c8dcSSimon Schubert extern void _initialize_doublest (void); 9215796c8dcSSimon Schubert 9225796c8dcSSimon Schubert extern void 9235796c8dcSSimon Schubert _initialize_doublest (void) 9245796c8dcSSimon Schubert { 9255796c8dcSSimon Schubert floatformat_ieee_single[BFD_ENDIAN_LITTLE] = &floatformat_ieee_single_little; 9265796c8dcSSimon Schubert floatformat_ieee_single[BFD_ENDIAN_BIG] = &floatformat_ieee_single_big; 9275796c8dcSSimon Schubert floatformat_ieee_double[BFD_ENDIAN_LITTLE] = &floatformat_ieee_double_little; 9285796c8dcSSimon Schubert floatformat_ieee_double[BFD_ENDIAN_BIG] = &floatformat_ieee_double_big; 929*c50c785cSJohn Marino floatformat_arm_ext[BFD_ENDIAN_LITTLE] 930*c50c785cSJohn Marino = &floatformat_arm_ext_littlebyte_bigword; 9315796c8dcSSimon Schubert floatformat_arm_ext[BFD_ENDIAN_BIG] = &floatformat_arm_ext_big; 9325796c8dcSSimon Schubert floatformat_ia64_spill[BFD_ENDIAN_LITTLE] = &floatformat_ia64_spill_little; 9335796c8dcSSimon Schubert floatformat_ia64_spill[BFD_ENDIAN_BIG] = &floatformat_ia64_spill_big; 9345796c8dcSSimon Schubert floatformat_ieee_quad[BFD_ENDIAN_LITTLE] = &floatformat_ia64_quad_little; 9355796c8dcSSimon Schubert floatformat_ieee_quad[BFD_ENDIAN_BIG] = &floatformat_ia64_quad_big; 9365796c8dcSSimon Schubert } 937