28 #include "floatformat.h"
35 #define FLOATFORMAT_CHAR_BIT 8
39 #define FLOATFORMAT_LARGEST_BYTES 16
44 get_field (
const bfd_byte *data,
enum floatformat_byteorders order,
45 unsigned int total_len,
unsigned int start,
unsigned int len)
48 unsigned int cur_byte;
52 gdb_assert (order == floatformat_little || order == floatformat_big);
55 if (order == floatformat_little)
78 result = *(data + cur_byte) >> (-cur_bitshift);
82 if (order == floatformat_little)
88 while (cur_bitshift < len)
90 result |= (
unsigned long)*(data + cur_byte) << cur_bitshift;
94 case floatformat_little:
104 result &= ((1UL << len) - 1);
112 static enum floatformat_byteorders
114 const void *
from,
void *
to)
116 const unsigned char *swapin;
117 unsigned char *swapout;
120 if (fmt->byteorder == floatformat_little
121 || fmt->byteorder == floatformat_big)
122 return fmt->byteorder;
127 swapout = (
unsigned char *)to;
128 swapin = (
const unsigned char *)from;
130 if (fmt->byteorder == floatformat_vax)
134 *swapout++ = swapin[1];
135 *swapout++ = swapin[0];
136 *swapout++ = swapin[3];
137 *swapout++ = swapin[2];
142 return floatformat_big;
146 gdb_assert (fmt->byteorder == floatformat_littlebyte_bigword);
150 *swapout++ = swapin[3];
151 *swapout++ = swapin[2];
152 *swapout++ = swapin[1];
153 *swapout++ = swapin[0];
156 return floatformat_big;
169 unsigned char *ufrom = (
unsigned char *) from;
173 unsigned int mant_bits, mant_off;
175 int special_exponent;
176 enum floatformat_byteorders order;
191 floatformat_to_double (fmt->split_half ? fmt->split_half : fmt,
199 if (order != fmt->byteorder)
215 ufrom + fmt->totalsize / FLOATFORMAT_CHAR_BIT / 2,
221 exponent =
get_field (ufrom, order, fmt->totalsize, fmt->exp_start,
227 mant_bits_left = fmt->man_len;
228 mant_off = fmt->man_start;
231 special_exponent = exponent == 0 || exponent == fmt->exp_nan;
237 if (!special_exponent)
238 exponent -= fmt->exp_bias;
239 else if (exponent == 0)
240 exponent = 1 - fmt->exp_bias;
248 if (!special_exponent)
250 if (fmt->intbit == floatformat_intbit_no)
251 dto = ldexp (1.0, exponent);
256 while (mant_bits_left > 0)
258 mant_bits =
min (mant_bits_left, 32);
260 mant =
get_field (ufrom, order, fmt->totalsize, mant_off, mant_bits);
262 dto += ldexp ((
double) mant, exponent - mant_bits);
263 exponent -= mant_bits;
264 mant_off += mant_bits;
265 mant_bits_left -= mant_bits;
269 if (
get_field (ufrom, order, fmt->totalsize, fmt->sign_start, 1))
277 put_field (
unsigned char *data,
enum floatformat_byteorders order,
278 unsigned int total_len,
unsigned int start,
unsigned int len,
279 unsigned long stuff_to_put)
281 unsigned int cur_byte;
285 gdb_assert (order == floatformat_little || order == floatformat_big);
288 if (order == floatformat_little)
305 *(data + cur_byte) &=
308 *(data + cur_byte) |=
312 if (order == floatformat_little)
318 while (cur_bitshift < len)
323 *(data + cur_byte) &=
324 ~((1 << (len - cur_bitshift)) - 1);
325 *(data + cur_byte) |= (stuff_to_put >> cur_bitshift);
328 *(data + cur_byte) = ((stuff_to_put >> cur_bitshift)
331 if (order == floatformat_little)
349 unsigned int mant_bits, mant_off;
351 unsigned char *uto = (
unsigned char *) to;
352 enum floatformat_byteorders order = fmt->byteorder;
355 if (order != floatformat_little)
356 order = floatformat_big;
358 if (order != fmt->byteorder)
361 memcpy (&dfrom, from,
sizeof (dfrom));
370 static volatile double dtop, dbot;
373 dtop = (double) dfrom;
376 if (dtop + dtop == dtop && dtop != 0.0)
379 dbot = (double) (dfrom - (
DOUBLEST) dtop);
394 put_field (uto, order, fmt->totalsize, fmt->exp_start,
395 fmt->exp_len, fmt->exp_nan);
397 put_field (uto, order, fmt->totalsize, fmt->man_start,
399 goto finalize_byteorder;
405 put_field (uto, order, fmt->totalsize, fmt->sign_start, 1, 1);
409 if (dfrom + dfrom == dfrom && dfrom != 0.0)
412 put_field (uto, order, fmt->totalsize, fmt->exp_start,
413 fmt->exp_len, fmt->exp_nan);
415 put_field (uto, order, fmt->totalsize, fmt->man_start,
417 goto finalize_byteorder;
420 #ifdef HAVE_LONG_DOUBLE
421 mant = frexpl (dfrom, &exponent);
423 mant = frexp (dfrom, &exponent);
426 if (exponent + fmt->exp_bias <= 0)
430 put_field (uto, order, fmt->totalsize, fmt->exp_start,
432 put_field (uto, order, fmt->totalsize, fmt->man_start,
434 goto finalize_byteorder;
437 if (exponent + fmt->exp_bias >= (1 << fmt->exp_len))
441 put_field (uto, order, fmt->totalsize, fmt->exp_start,
442 fmt->exp_len, fmt->exp_nan);
443 put_field (uto, order, fmt->totalsize, fmt->man_start,
445 goto finalize_byteorder;
448 put_field (uto, order, fmt->totalsize, fmt->exp_start, fmt->exp_len,
449 exponent + fmt->exp_bias - 1);
451 mant_bits_left = fmt->man_len;
452 mant_off = fmt->man_start;
453 while (mant_bits_left > 0)
455 unsigned long mant_long;
457 mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;
459 mant *= 4294967296.0;
460 mant_long = ((
unsigned long) mant) & 0xffffffff
L;
467 if (mant_bits_left == fmt->man_len
468 && fmt->intbit == floatformat_intbit_no)
471 mant_long &= 0xffffffff
L;
487 mant_long >>= 32 - mant_bits;
491 mant_off, mant_bits, mant_long);
492 mant_off += mant_bits;
493 mant_bits_left -= mant_bits;
498 if (order != fmt->byteorder)
507 const bfd_byte *uval)
509 enum floatformat_byteorders order;
519 fmt = fmt->split_half;
523 if (order != fmt->byteorder)
526 return get_field (uval, order, fmt->totalsize, fmt->sign_start, 1);
533 const bfd_byte *uval)
537 unsigned int mant_bits, mant_off;
539 enum floatformat_byteorders order;
552 fmt = fmt->split_half;
556 if (order != fmt->byteorder)
559 exponent =
get_field (uval, order, fmt->totalsize, fmt->exp_start,
562 mant_bits_left = fmt->man_len;
563 mant_off = fmt->man_start;
566 while (mant_bits_left > 0)
568 mant_bits =
min (mant_bits_left, 32);
570 mant =
get_field (uval, order, fmt->totalsize, mant_off, mant_bits);
573 if (mant_off == fmt->man_start
574 && fmt->intbit == floatformat_intbit_yes)
575 mant &= ~(1 << (mant_bits - 1));
583 mant_off += mant_bits;
584 mant_bits_left -= mant_bits;
597 if (exponent == 0 && !mant_zero)
600 if (exponent == fmt->exp_nan)
622 unsigned char *uval = (
unsigned char *) val;
624 unsigned int mant_bits, mant_off;
629 enum floatformat_byteorders order;
644 fmt = fmt->split_half;
648 if (order != fmt->byteorder)
655 gdb_assert (
sizeof res > ((fmt->man_len + 7) / 8) * 2);
657 mant_off = fmt->man_start;
658 mant_bits_left = fmt->man_len;
659 mant_bits = (mant_bits_left % 32) > 0 ? mant_bits_left % 32 : 32;
661 mant =
get_field (uval, order, fmt->totalsize, mant_off, mant_bits);
663 len =
xsnprintf (res,
sizeof res,
"%lx", mant);
665 mant_off += mant_bits;
666 mant_bits_left -= mant_bits;
668 while (mant_bits_left > 0)
670 mant =
get_field (uval, order, fmt->totalsize, mant_off, 32);
672 xsnprintf (buf,
sizeof buf,
"%08lx", mant);
673 gdb_assert (len + strlen (buf) <=
sizeof res);
677 mant_bits_left -= 32;
705 memcpy (&val, in,
sizeof (val));
712 memcpy (&val, in,
sizeof (val));
719 memcpy (&val, in,
sizeof (val));
735 memcpy (out, &val,
sizeof (val));
741 memcpy (out, &val,
sizeof (val));
745 long double val = *in;
747 memcpy (out, &val,
sizeof (val));
767 static const struct floatformat *
770 const struct floatformat *format;
796 error (
_(
"Unrecognized %d-bit floating-point type."),
801 const struct floatformat *
863 void *
to,
const struct type *to_type)
868 if (from_fmt == NULL || to_fmt == NULL)
877 warning (
_(
"Can't convert floating-point number to desired type."));
880 else if (from_fmt == to_fmt)
const struct floatformat ** gdbarch_double_format(struct gdbarch *gdbarch)
void floatformat_from_doublest(const struct floatformat *fmt, const DOUBLEST *in, void *out)
int floatformat_is_negative(const struct floatformat *fmt, const bfd_byte *uval)
void warning(const char *fmt,...)
const struct floatformat ** gdbarch_long_double_format(struct gdbarch *gdbarch)
void convert_typed_floating(const void *from, const struct type *from_type, void *to, const struct type *to_type)
#define TYPE_FLOATFORMAT(thistype)
static unsigned long get_field(const bfd_byte *data, enum floatformat_byteorders order, unsigned int total_len, unsigned int start, unsigned int len)
#define GDB_HOST_DOUBLE_FORMAT
DOUBLEST extract_typed_floating(const void *addr, const struct type *type)
void floatformat_to_doublest(const struct floatformat *fmt, const void *in, DOUBLEST *out)
static const struct floatformat * host_long_double_format
#define FLOATFORMAT_CHAR_BIT
static void put_field(unsigned char *data, enum floatformat_byteorders order, unsigned int total_len, unsigned int start, unsigned int len, unsigned long stuff_to_put)
static const struct floatformat * host_double_format
const char * floatformat_mantissa(const struct floatformat *fmt, const bfd_byte *val)
#define FLOATFORMAT_LARGEST_BYTES
enum bfd_endian gdbarch_byte_order(struct gdbarch *gdbarch)
static enum floatformat_byteorders floatformat_normalize_byteorder(const struct floatformat *fmt, const void *from, void *to)
static void convert_doublest_to_floatformat(const struct floatformat *fmt, const DOUBLEST *from, void *to)
static const struct floatformat * floatformat_from_length(struct gdbarch *gdbarch, int len)
struct gdbarch * get_type_arch(const struct type *type)
int gdbarch_double_bit(struct gdbarch *gdbarch)
const struct floatformat ** gdbarch_half_format(struct gdbarch *gdbarch)
#define GDB_HOST_FLOAT_FORMAT
static const struct floatformat * host_float_format
int xsnprintf(char *str, size_t size, const char *format,...)
#define TYPE_CODE(thistype)
static void convert_floatformat_to_doublest(const struct floatformat *fmt, const void *from, DOUBLEST *to)
enum float_kind floatformat_classify(const struct floatformat *fmt, const bfd_byte *uval)
int gdbarch_float_bit(struct gdbarch *gdbarch)
#define GDB_HOST_LONG_DOUBLE_FORMAT
int gdbarch_half_bit(struct gdbarch *gdbarch)
const struct floatformat ** gdbarch_float_format(struct gdbarch *gdbarch)
#define TYPE_LENGTH(thistype)
int gdbarch_long_double_bit(struct gdbarch *gdbarch)
void error(const char *fmt,...)
void store_typed_floating(void *addr, const struct type *type, DOUBLEST val)
const ULONGEST const LONGEST len
const struct floatformat * floatformat_from_type(const struct type *type)