doublest.c revision 98944
1/* Floating point routines for GDB, the GNU debugger.
2   Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
3   1997, 1998, 1999, 2000, 2001
4   Free Software Foundation, Inc.
5
6   This file is part of GDB.
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2 of the License, or
11   (at your option) any later version.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program; if not, write to the Free Software
20   Foundation, Inc., 59 Temple Place - Suite 330,
21   Boston, MA 02111-1307, USA.  */
22
23/* Support for converting target fp numbers into host DOUBLEST format.  */
24
25/* XXX - This code should really be in libiberty/floatformat.c,
26   however configuration issues with libiberty made this very
27   difficult to do in the available time.  */
28
29#include "defs.h"
30#include "doublest.h"
31#include "floatformat.h"
32#include "gdb_assert.h"
33#include "gdb_string.h"
34#include "gdbtypes.h"
35#include <math.h>		/* ldexp */
36
37/* The odds that CHAR_BIT will be anything but 8 are low enough that I'm not
38   going to bother with trying to muck around with whether it is defined in
39   a system header, what we do if not, etc.  */
40#define FLOATFORMAT_CHAR_BIT 8
41
42static unsigned long get_field (unsigned char *,
43				enum floatformat_byteorders,
44				unsigned int, unsigned int, unsigned int);
45
46/* Extract a field which starts at START and is LEN bytes long.  DATA and
47   TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER.  */
48static unsigned long
49get_field (unsigned char *data, enum floatformat_byteorders order,
50	   unsigned int total_len, unsigned int start, unsigned int len)
51{
52  unsigned long result;
53  unsigned int cur_byte;
54  int cur_bitshift;
55
56  /* Start at the least significant part of the field.  */
57  if (order == floatformat_little || order == floatformat_littlebyte_bigword)
58    {
59      /* We start counting from the other end (i.e, from the high bytes
60	 rather than the low bytes).  As such, we need to be concerned
61	 with what happens if bit 0 doesn't start on a byte boundary.
62	 I.e, we need to properly handle the case where total_len is
63	 not evenly divisible by 8.  So we compute ``excess'' which
64	 represents the number of bits from the end of our starting
65	 byte needed to get to bit 0. */
66      int excess = FLOATFORMAT_CHAR_BIT - (total_len % FLOATFORMAT_CHAR_BIT);
67      cur_byte = (total_len / FLOATFORMAT_CHAR_BIT)
68                 - ((start + len + excess) / FLOATFORMAT_CHAR_BIT);
69      cur_bitshift = ((start + len + excess) % FLOATFORMAT_CHAR_BIT)
70                     - FLOATFORMAT_CHAR_BIT;
71    }
72  else
73    {
74      cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
75      cur_bitshift =
76	((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
77    }
78  if (cur_bitshift > -FLOATFORMAT_CHAR_BIT)
79    result = *(data + cur_byte) >> (-cur_bitshift);
80  else
81    result = 0;
82  cur_bitshift += FLOATFORMAT_CHAR_BIT;
83  if (order == floatformat_little || order == floatformat_littlebyte_bigword)
84    ++cur_byte;
85  else
86    --cur_byte;
87
88  /* Move towards the most significant part of the field.  */
89  while (cur_bitshift < len)
90    {
91      result |= (unsigned long)*(data + cur_byte) << cur_bitshift;
92      cur_bitshift += FLOATFORMAT_CHAR_BIT;
93      if (order == floatformat_little || order == floatformat_littlebyte_bigword)
94	++cur_byte;
95      else
96	--cur_byte;
97    }
98  if (len < sizeof(result) * FLOATFORMAT_CHAR_BIT)
99    /* Mask out bits which are not part of the field */
100    result &= ((1UL << len) - 1);
101  return result;
102}
103
104/* Convert from FMT to a DOUBLEST.
105   FROM is the address of the extended float.
106   Store the DOUBLEST in *TO.  */
107
108static void
109convert_floatformat_to_doublest (const struct floatformat *fmt,
110				 const void *from,
111				 DOUBLEST *to)
112{
113  unsigned char *ufrom = (unsigned char *) from;
114  DOUBLEST dto;
115  long exponent;
116  unsigned long mant;
117  unsigned int mant_bits, mant_off;
118  int mant_bits_left;
119  int special_exponent;		/* It's a NaN, denorm or zero */
120
121  /* If the mantissa bits are not contiguous from one end of the
122     mantissa to the other, we need to make a private copy of the
123     source bytes that is in the right order since the unpacking
124     algorithm assumes that the bits are contiguous.
125
126     Swap the bytes individually rather than accessing them through
127     "long *" since we have no guarantee that they start on a long
128     alignment, and also sizeof(long) for the host could be different
129     than sizeof(long) for the target.  FIXME: Assumes sizeof(long)
130     for the target is 4. */
131
132  if (fmt->byteorder == floatformat_littlebyte_bigword)
133    {
134      static unsigned char *newfrom;
135      unsigned char *swapin, *swapout;
136      int longswaps;
137
138      longswaps = fmt->totalsize / FLOATFORMAT_CHAR_BIT;
139      longswaps >>= 3;
140
141      if (newfrom == NULL)
142	{
143	  newfrom = (unsigned char *) xmalloc (fmt->totalsize);
144	}
145      swapout = newfrom;
146      swapin = ufrom;
147      ufrom = newfrom;
148      while (longswaps-- > 0)
149	{
150	  /* This is ugly, but efficient */
151	  *swapout++ = swapin[4];
152	  *swapout++ = swapin[5];
153	  *swapout++ = swapin[6];
154	  *swapout++ = swapin[7];
155	  *swapout++ = swapin[0];
156	  *swapout++ = swapin[1];
157	  *swapout++ = swapin[2];
158	  *swapout++ = swapin[3];
159	  swapin += 8;
160	}
161    }
162
163  exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
164			fmt->exp_start, fmt->exp_len);
165  /* Note that if exponent indicates a NaN, we can't really do anything useful
166     (not knowing if the host has NaN's, or how to build one).  So it will
167     end up as an infinity or something close; that is OK.  */
168
169  mant_bits_left = fmt->man_len;
170  mant_off = fmt->man_start;
171  dto = 0.0;
172
173  special_exponent = exponent == 0 || exponent == fmt->exp_nan;
174
175/* Don't bias NaNs. Use minimum exponent for denorms. For simplicity,
176   we don't check for zero as the exponent doesn't matter. */
177  if (!special_exponent)
178    exponent -= fmt->exp_bias;
179  else if (exponent == 0)
180    exponent = 1 - fmt->exp_bias;
181
182  /* Build the result algebraically.  Might go infinite, underflow, etc;
183     who cares. */
184
185/* If this format uses a hidden bit, explicitly add it in now.  Otherwise,
186   increment the exponent by one to account for the integer bit.  */
187
188  if (!special_exponent)
189    {
190      if (fmt->intbit == floatformat_intbit_no)
191	dto = ldexp (1.0, exponent);
192      else
193	exponent++;
194    }
195
196  while (mant_bits_left > 0)
197    {
198      mant_bits = min (mant_bits_left, 32);
199
200      mant = get_field (ufrom, fmt->byteorder, fmt->totalsize,
201			mant_off, mant_bits);
202
203      dto += ldexp ((double) mant, exponent - mant_bits);
204      exponent -= mant_bits;
205      mant_off += mant_bits;
206      mant_bits_left -= mant_bits;
207    }
208
209  /* Negate it if negative.  */
210  if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
211    dto = -dto;
212  *to = dto;
213}
214
215static void put_field (unsigned char *, enum floatformat_byteorders,
216		       unsigned int,
217		       unsigned int, unsigned int, unsigned long);
218
219/* Set a field which starts at START and is LEN bytes long.  DATA and
220   TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER.  */
221static void
222put_field (unsigned char *data, enum floatformat_byteorders order,
223	   unsigned int total_len, unsigned int start, unsigned int len,
224	   unsigned long stuff_to_put)
225{
226  unsigned int cur_byte;
227  int cur_bitshift;
228
229  /* Start at the least significant part of the field.  */
230  if (order == floatformat_little || order == floatformat_littlebyte_bigword)
231    {
232      int excess = FLOATFORMAT_CHAR_BIT - (total_len % FLOATFORMAT_CHAR_BIT);
233      cur_byte = (total_len / FLOATFORMAT_CHAR_BIT)
234                 - ((start + len + excess) / FLOATFORMAT_CHAR_BIT);
235      cur_bitshift = ((start + len + excess) % FLOATFORMAT_CHAR_BIT)
236                     - FLOATFORMAT_CHAR_BIT;
237    }
238  else
239    {
240      cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
241      cur_bitshift =
242	((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
243    }
244  if (cur_bitshift > -FLOATFORMAT_CHAR_BIT)
245    {
246      *(data + cur_byte) &=
247	~(((1 << ((start + len) % FLOATFORMAT_CHAR_BIT)) - 1)
248	  << (-cur_bitshift));
249      *(data + cur_byte) |=
250	(stuff_to_put & ((1 << FLOATFORMAT_CHAR_BIT) - 1)) << (-cur_bitshift);
251    }
252  cur_bitshift += FLOATFORMAT_CHAR_BIT;
253  if (order == floatformat_little || order == floatformat_littlebyte_bigword)
254    ++cur_byte;
255  else
256    --cur_byte;
257
258  /* Move towards the most significant part of the field.  */
259  while (cur_bitshift < len)
260    {
261      if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT)
262	{
263	  /* This is the last byte.  */
264	  *(data + cur_byte) &=
265	    ~((1 << (len - cur_bitshift)) - 1);
266	  *(data + cur_byte) |= (stuff_to_put >> cur_bitshift);
267	}
268      else
269	*(data + cur_byte) = ((stuff_to_put >> cur_bitshift)
270			      & ((1 << FLOATFORMAT_CHAR_BIT) - 1));
271      cur_bitshift += FLOATFORMAT_CHAR_BIT;
272      if (order == floatformat_little || order == floatformat_littlebyte_bigword)
273	++cur_byte;
274      else
275	--cur_byte;
276    }
277}
278
279#ifdef HAVE_LONG_DOUBLE
280/* Return the fractional part of VALUE, and put the exponent of VALUE in *EPTR.
281   The range of the returned value is >= 0.5 and < 1.0.  This is equivalent to
282   frexp, but operates on the long double data type.  */
283
284static long double ldfrexp (long double value, int *eptr);
285
286static long double
287ldfrexp (long double value, int *eptr)
288{
289  long double tmp;
290  int exp;
291
292  /* Unfortunately, there are no portable functions for extracting the exponent
293     of a long double, so we have to do it iteratively by multiplying or dividing
294     by two until the fraction is between 0.5 and 1.0.  */
295
296  if (value < 0.0l)
297    value = -value;
298
299  tmp = 1.0l;
300  exp = 0;
301
302  if (value >= tmp)		/* Value >= 1.0 */
303    while (value >= tmp)
304      {
305	tmp *= 2.0l;
306	exp++;
307      }
308  else if (value != 0.0l)	/* Value < 1.0  and > 0.0 */
309    {
310      while (value < tmp)
311	{
312	  tmp /= 2.0l;
313	  exp--;
314	}
315      tmp *= 2.0l;
316      exp++;
317    }
318
319  *eptr = exp;
320  return value / tmp;
321}
322#endif /* HAVE_LONG_DOUBLE */
323
324
325/* The converse: convert the DOUBLEST *FROM to an extended float
326   and store where TO points.  Neither FROM nor TO have any alignment
327   restrictions.  */
328
329static void
330convert_doublest_to_floatformat (CONST struct floatformat *fmt,
331				 const DOUBLEST *from,
332				 void *to)
333{
334  DOUBLEST dfrom;
335  int exponent;
336  DOUBLEST mant;
337  unsigned int mant_bits, mant_off;
338  int mant_bits_left;
339  unsigned char *uto = (unsigned char *) to;
340
341  memcpy (&dfrom, from, sizeof (dfrom));
342  memset (uto, 0, (fmt->totalsize + FLOATFORMAT_CHAR_BIT - 1)
343                    / FLOATFORMAT_CHAR_BIT);
344  if (dfrom == 0)
345    return;			/* Result is zero */
346  if (dfrom != dfrom)		/* Result is NaN */
347    {
348      /* From is NaN */
349      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
350		 fmt->exp_len, fmt->exp_nan);
351      /* Be sure it's not infinity, but NaN value is irrel */
352      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
353		 32, 1);
354      return;
355    }
356
357  /* If negative, set the sign bit.  */
358  if (dfrom < 0)
359    {
360      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1);
361      dfrom = -dfrom;
362    }
363
364  if (dfrom + dfrom == dfrom && dfrom != 0.0)	/* Result is Infinity */
365    {
366      /* Infinity exponent is same as NaN's.  */
367      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
368		 fmt->exp_len, fmt->exp_nan);
369      /* Infinity mantissa is all zeroes.  */
370      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
371		 fmt->man_len, 0);
372      return;
373    }
374
375#ifdef HAVE_LONG_DOUBLE
376  mant = ldfrexp (dfrom, &exponent);
377#else
378  mant = frexp (dfrom, &exponent);
379#endif
380
381  put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, fmt->exp_len,
382	     exponent + fmt->exp_bias - 1);
383
384  mant_bits_left = fmt->man_len;
385  mant_off = fmt->man_start;
386  while (mant_bits_left > 0)
387    {
388      unsigned long mant_long;
389      mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;
390
391      mant *= 4294967296.0;
392      mant_long = ((unsigned long) mant) & 0xffffffffL;
393      mant -= mant_long;
394
395      /* If the integer bit is implicit, then we need to discard it.
396         If we are discarding a zero, we should be (but are not) creating
397         a denormalized number which means adjusting the exponent
398         (I think).  */
399      if (mant_bits_left == fmt->man_len
400	  && fmt->intbit == floatformat_intbit_no)
401	{
402	  mant_long <<= 1;
403	  mant_long &= 0xffffffffL;
404	  mant_bits -= 1;
405	}
406
407      if (mant_bits < 32)
408	{
409	  /* The bits we want are in the most significant MANT_BITS bits of
410	     mant_long.  Move them to the least significant.  */
411	  mant_long >>= 32 - mant_bits;
412	}
413
414      put_field (uto, fmt->byteorder, fmt->totalsize,
415		 mant_off, mant_bits, mant_long);
416      mant_off += mant_bits;
417      mant_bits_left -= mant_bits;
418    }
419  if (fmt->byteorder == floatformat_littlebyte_bigword)
420    {
421      int count;
422      unsigned char *swaplow = uto;
423      unsigned char *swaphigh = uto + 4;
424      unsigned char tmp;
425
426      for (count = 0; count < 4; count++)
427	{
428	  tmp = *swaplow;
429	  *swaplow++ = *swaphigh;
430	  *swaphigh++ = tmp;
431	}
432    }
433}
434
435/* Check if VAL (which is assumed to be a floating point number whose
436   format is described by FMT) is negative.  */
437
438int
439floatformat_is_negative (const struct floatformat *fmt, char *val)
440{
441  unsigned char *uval = (unsigned char *) val;
442  gdb_assert (fmt != NULL);
443  return get_field (uval, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1);
444}
445
446/* Check if VAL is "not a number" (NaN) for FMT.  */
447
448int
449floatformat_is_nan (const struct floatformat *fmt, char *val)
450{
451  unsigned char *uval = (unsigned char *) val;
452  long exponent;
453  unsigned long mant;
454  unsigned int mant_bits, mant_off;
455  int mant_bits_left;
456
457  gdb_assert (fmt != NULL);
458
459  if (! fmt->exp_nan)
460    return 0;
461
462  exponent = get_field (uval, fmt->byteorder, fmt->totalsize,
463			fmt->exp_start, fmt->exp_len);
464
465  if (exponent != fmt->exp_nan)
466    return 0;
467
468  mant_bits_left = fmt->man_len;
469  mant_off = fmt->man_start;
470
471  while (mant_bits_left > 0)
472    {
473      mant_bits = min (mant_bits_left, 32);
474
475      mant = get_field (uval, fmt->byteorder, fmt->totalsize,
476			mant_off, mant_bits);
477
478      /* If there is an explicit integer bit, mask it off.  */
479      if (mant_off == fmt->man_start
480	  && fmt->intbit == floatformat_intbit_yes)
481	mant &= ~(1 << (mant_bits - 1));
482
483      if (mant)
484	return 1;
485
486      mant_off += mant_bits;
487      mant_bits_left -= mant_bits;
488    }
489
490  return 0;
491}
492
493/* Convert the mantissa of VAL (which is assumed to be a floating
494   point number whose format is described by FMT) into a hexadecimal
495   and store it in a static string.  Return a pointer to that string.  */
496
497char *
498floatformat_mantissa (const struct floatformat *fmt, char *val)
499{
500  unsigned char *uval = (unsigned char *) val;
501  unsigned long mant;
502  unsigned int mant_bits, mant_off;
503  int mant_bits_left;
504  static char res[50];
505  char buf[9];
506
507  /* Make sure we have enough room to store the mantissa.  */
508  gdb_assert (fmt != NULL);
509  gdb_assert (sizeof res > ((fmt->man_len + 7) / 8) * 2);
510
511  mant_off = fmt->man_start;
512  mant_bits_left = fmt->man_len;
513  mant_bits = (mant_bits_left % 32) > 0 ? mant_bits_left % 32 : 32;
514
515  mant = get_field (uval, fmt->byteorder, fmt->totalsize,
516		    mant_off, mant_bits);
517
518  sprintf (res, "%lx", mant);
519
520  mant_off += mant_bits;
521  mant_bits_left -= mant_bits;
522
523  while (mant_bits_left > 0)
524    {
525      mant = get_field (uval, fmt->byteorder, fmt->totalsize,
526			mant_off, 32);
527
528      sprintf (buf, "%08lx", mant);
529      strcat (res, buf);
530
531      mant_off += 32;
532      mant_bits_left -= 32;
533    }
534
535  return res;
536}
537
538
539/* Convert TO/FROM target to the hosts DOUBLEST floating-point format.
540
541   If the host and target formats agree, we just copy the raw data
542   into the appropriate type of variable and return, letting the host
543   increase precision as necessary.  Otherwise, we call the conversion
544   routine and let it do the dirty work.  */
545
546#ifndef HOST_FLOAT_FORMAT
547#define HOST_FLOAT_FORMAT 0
548#endif
549#ifndef HOST_DOUBLE_FORMAT
550#define HOST_DOUBLE_FORMAT 0
551#endif
552#ifndef HOST_LONG_DOUBLE_FORMAT
553#define HOST_LONG_DOUBLE_FORMAT 0
554#endif
555
556static const struct floatformat *host_float_format = HOST_FLOAT_FORMAT;
557static const struct floatformat *host_double_format = HOST_DOUBLE_FORMAT;
558static const struct floatformat *host_long_double_format = HOST_LONG_DOUBLE_FORMAT;
559
560void
561floatformat_to_doublest (const struct floatformat *fmt,
562			 const void *in, DOUBLEST *out)
563{
564  gdb_assert (fmt != NULL);
565  if (fmt == host_float_format)
566    {
567      float val;
568      memcpy (&val, in, sizeof (val));
569      *out = val;
570    }
571  else if (fmt == host_double_format)
572    {
573      double val;
574      memcpy (&val, in, sizeof (val));
575      *out = val;
576    }
577  else if (fmt == host_long_double_format)
578    {
579      long double val;
580      memcpy (&val, in, sizeof (val));
581      *out = val;
582    }
583  else
584    convert_floatformat_to_doublest (fmt, in, out);
585}
586
587void
588floatformat_from_doublest (const struct floatformat *fmt,
589			   const DOUBLEST *in, void *out)
590{
591  gdb_assert (fmt != NULL);
592  if (fmt == host_float_format)
593    {
594      float val = *in;
595      memcpy (out, &val, sizeof (val));
596    }
597  else if (fmt == host_double_format)
598    {
599      double val = *in;
600      memcpy (out, &val, sizeof (val));
601    }
602  else if (fmt == host_long_double_format)
603    {
604      long double val = *in;
605      memcpy (out, &val, sizeof (val));
606    }
607  else
608    convert_doublest_to_floatformat (fmt, in, out);
609}
610
611
612/* Return a floating-point format for a floating-point variable of
613   length LEN.  Return NULL, if no suitable floating-point format
614   could be found.
615
616   We need this functionality since information about the
617   floating-point format of a type is not always available to GDB; the
618   debug information typically only tells us the size of a
619   floating-point type.
620
621   FIXME: kettenis/2001-10-28: In many places, particularly in
622   target-dependent code, the format of floating-point types is known,
623   but not passed on by GDB.  This should be fixed.  */
624
625const struct floatformat *
626floatformat_from_length (int len)
627{
628  if (len * TARGET_CHAR_BIT == TARGET_FLOAT_BIT)
629    return TARGET_FLOAT_FORMAT;
630  else if (len * TARGET_CHAR_BIT == TARGET_DOUBLE_BIT)
631    return TARGET_DOUBLE_FORMAT;
632  else if (len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_BIT)
633    return TARGET_LONG_DOUBLE_FORMAT;
634
635  return NULL;
636}
637
638const struct floatformat *
639floatformat_from_type (const struct type *type)
640{
641  gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
642  if (TYPE_FLOATFORMAT (type) != NULL)
643    return TYPE_FLOATFORMAT (type);
644  else
645    return floatformat_from_length (TYPE_LENGTH (type));
646}
647
648/* If the host doesn't define NAN, use zero instead.  */
649#ifndef NAN
650#define NAN 0.0
651#endif
652
653/* Extract a floating-point number of length LEN from a target-order
654   byte-stream at ADDR.  Returns the value as type DOUBLEST.  */
655
656DOUBLEST
657extract_floating (const void *addr, int len)
658{
659  const struct floatformat *fmt = floatformat_from_length (len);
660  DOUBLEST val;
661
662  if (fmt == NULL)
663    {
664      warning ("Can't store a floating-point number of %d bytes.", len);
665      return NAN;
666    }
667
668  floatformat_to_doublest (fmt, addr, &val);
669  return val;
670}
671
672/* Store VAL as a floating-point number of length LEN to a
673   target-order byte-stream at ADDR.  */
674
675void
676store_floating (void *addr, int len, DOUBLEST val)
677{
678  const struct floatformat *fmt = floatformat_from_length (len);
679
680  if (fmt == NULL)
681    {
682      warning ("Can't store a floating-point number of %d bytes.", len);
683      memset (addr, 0, len);
684    }
685
686  floatformat_from_doublest (fmt, &val, addr);
687}
688
689/* Extract a floating-point number of type TYPE from a target-order
690   byte-stream at ADDR.  Returns the value as type DOUBLEST.  */
691
692DOUBLEST
693extract_typed_floating (const void *addr, const struct type *type)
694{
695  DOUBLEST retval;
696
697  gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
698
699  if (TYPE_FLOATFORMAT (type) == NULL)
700    return extract_floating (addr, TYPE_LENGTH (type));
701
702  floatformat_to_doublest (TYPE_FLOATFORMAT (type), addr, &retval);
703  return retval;
704}
705
706/* Store VAL as a floating-point number of type TYPE to a target-order
707   byte-stream at ADDR.  */
708
709void
710store_typed_floating (void *addr, const struct type *type, DOUBLEST val)
711{
712  gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
713
714  /* FIXME: kettenis/2001-10-28: It is debatable whether we should
715     zero out any remaining bytes in the target buffer when TYPE is
716     longer than the actual underlying floating-point format.  Perhaps
717     we should store a fixed bitpattern in those remaining bytes,
718     instead of zero, or perhaps we shouldn't touch those remaining
719     bytes at all.
720
721     NOTE: cagney/2001-10-28: With the way things currently work, it
722     isn't a good idea to leave the end bits undefined.  This is
723     because GDB writes out the entire sizeof(<floating>) bits of the
724     floating-point type even though the value might only be stored
725     in, and the target processor may only refer to, the first N <
726     TYPE_LENGTH (type) bits.  If the end of the buffer wasn't
727     initialized, GDB would write undefined data to the target.  An
728     errant program, refering to that undefined data, would then
729     become non-deterministic.
730
731     See also the function convert_typed_floating below.  */
732  memset (addr, 0, TYPE_LENGTH (type));
733
734  if (TYPE_FLOATFORMAT (type) == NULL)
735    store_floating (addr, TYPE_LENGTH (type), val);
736  else
737    floatformat_from_doublest (TYPE_FLOATFORMAT (type), &val, addr);
738}
739
740/* Convert a floating-point number of type FROM_TYPE from a
741   target-order byte-stream at FROM to a floating-point number of type
742   TO_TYPE, and store it to a target-order byte-stream at TO.  */
743
744void
745convert_typed_floating (const void *from, const struct type *from_type,
746                        void *to, const struct type *to_type)
747{
748  const struct floatformat *from_fmt = floatformat_from_type (from_type);
749  const struct floatformat *to_fmt = floatformat_from_type (to_type);
750
751  gdb_assert (TYPE_CODE (from_type) == TYPE_CODE_FLT);
752  gdb_assert (TYPE_CODE (to_type) == TYPE_CODE_FLT);
753
754  if (from_fmt == NULL || to_fmt == NULL)
755    {
756      /* If we don't know the floating-point format of FROM_TYPE or
757         TO_TYPE, there's not much we can do.  We might make the
758         assumption that if the length of FROM_TYPE and TO_TYPE match,
759         their floating-point format would match too, but that
760         assumption might be wrong on targets that support
761         floating-point types that only differ in endianness for
762         example.  So we warn instead, and zero out the target buffer.  */
763      warning ("Can't convert floating-point number to desired type.");
764      memset (to, 0, TYPE_LENGTH (to_type));
765    }
766  else if (from_fmt == to_fmt)
767    {
768      /* We're in business.  The floating-point format of FROM_TYPE
769         and TO_TYPE match.  However, even though the floating-point
770         format matches, the length of the type might still be
771         different.  Make sure we don't overrun any buffers.  See
772         comment in store_typed_floating for a discussion about
773         zeroing out remaining bytes in the target buffer.  */
774      memset (to, 0, TYPE_LENGTH (to_type));
775      memcpy (to, from, min (TYPE_LENGTH (from_type), TYPE_LENGTH (to_type)));
776    }
777  else
778    {
779      /* The floating-point types don't match.  The best we can do
780         (aport from simulating the target FPU) is converting to the
781         widest floating-point type supported by the host, and then
782         again to the desired type.  */
783      DOUBLEST d;
784
785      floatformat_to_doublest (from_fmt, from, &d);
786      floatformat_from_doublest (to_fmt, &d, to);
787    }
788}
789