2003-02-27 Michael Snyder <msnyder@redhat.com>
[platform/upstream/binutils.git] / gdb / doublest.c
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
42 static 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.  */
48 static unsigned long
49 get_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
108 static void
109 convert_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.  Note the cast
177      to int; exp_bias is unsigned, so it's important to make sure the
178      operation is done in signed arithmetic.  */
179   if (!special_exponent)
180     exponent -= fmt->exp_bias;
181   else if (exponent == 0)
182     exponent = 1 - (int) fmt->exp_bias;
183
184   /* Build the result algebraically.  Might go infinite, underflow, etc;
185      who cares. */
186
187 /* If this format uses a hidden bit, explicitly add it in now.  Otherwise,
188    increment the exponent by one to account for the integer bit.  */
189
190   if (!special_exponent)
191     {
192       if (fmt->intbit == floatformat_intbit_no)
193         dto = ldexp (1.0, exponent);
194       else
195         exponent++;
196     }
197
198   while (mant_bits_left > 0)
199     {
200       mant_bits = min (mant_bits_left, 32);
201
202       mant = get_field (ufrom, fmt->byteorder, fmt->totalsize,
203                         mant_off, mant_bits);
204
205       dto += ldexp ((double) mant, exponent - mant_bits);
206       exponent -= mant_bits;
207       mant_off += mant_bits;
208       mant_bits_left -= mant_bits;
209     }
210
211   /* Negate it if negative.  */
212   if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
213     dto = -dto;
214   *to = dto;
215 }
216 \f
217 static void put_field (unsigned char *, enum floatformat_byteorders,
218                        unsigned int,
219                        unsigned int, unsigned int, unsigned long);
220
221 /* Set a field which starts at START and is LEN bytes long.  DATA and
222    TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER.  */
223 static void
224 put_field (unsigned char *data, enum floatformat_byteorders order,
225            unsigned int total_len, unsigned int start, unsigned int len,
226            unsigned long stuff_to_put)
227 {
228   unsigned int cur_byte;
229   int cur_bitshift;
230
231   /* Start at the least significant part of the field.  */
232   if (order == floatformat_little || order == floatformat_littlebyte_bigword)
233     {
234       int excess = FLOATFORMAT_CHAR_BIT - (total_len % FLOATFORMAT_CHAR_BIT);
235       cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) 
236                  - ((start + len + excess) / FLOATFORMAT_CHAR_BIT);
237       cur_bitshift = ((start + len + excess) % FLOATFORMAT_CHAR_BIT) 
238                      - FLOATFORMAT_CHAR_BIT;
239     }
240   else
241     {
242       cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
243       cur_bitshift =
244         ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
245     }
246   if (cur_bitshift > -FLOATFORMAT_CHAR_BIT)
247     {
248       *(data + cur_byte) &=
249         ~(((1 << ((start + len) % FLOATFORMAT_CHAR_BIT)) - 1)
250           << (-cur_bitshift));
251       *(data + cur_byte) |=
252         (stuff_to_put & ((1 << FLOATFORMAT_CHAR_BIT) - 1)) << (-cur_bitshift);
253     }
254   cur_bitshift += FLOATFORMAT_CHAR_BIT;
255   if (order == floatformat_little || order == floatformat_littlebyte_bigword)
256     ++cur_byte;
257   else
258     --cur_byte;
259
260   /* Move towards the most significant part of the field.  */
261   while (cur_bitshift < len)
262     {
263       if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT)
264         {
265           /* This is the last byte.  */
266           *(data + cur_byte) &=
267             ~((1 << (len - cur_bitshift)) - 1);
268           *(data + cur_byte) |= (stuff_to_put >> cur_bitshift);
269         }
270       else
271         *(data + cur_byte) = ((stuff_to_put >> cur_bitshift)
272                               & ((1 << FLOATFORMAT_CHAR_BIT) - 1));
273       cur_bitshift += FLOATFORMAT_CHAR_BIT;
274       if (order == floatformat_little || order == floatformat_littlebyte_bigword)
275         ++cur_byte;
276       else
277         --cur_byte;
278     }
279 }
280
281 #ifdef HAVE_LONG_DOUBLE
282 /* Return the fractional part of VALUE, and put the exponent of VALUE in *EPTR.
283    The range of the returned value is >= 0.5 and < 1.0.  This is equivalent to
284    frexp, but operates on the long double data type.  */
285
286 static long double ldfrexp (long double value, int *eptr);
287
288 static long double
289 ldfrexp (long double value, int *eptr)
290 {
291   long double tmp;
292   int exp;
293
294   /* Unfortunately, there are no portable functions for extracting the exponent
295      of a long double, so we have to do it iteratively by multiplying or dividing
296      by two until the fraction is between 0.5 and 1.0.  */
297
298   if (value < 0.0l)
299     value = -value;
300
301   tmp = 1.0l;
302   exp = 0;
303
304   if (value >= tmp)             /* Value >= 1.0 */
305     while (value >= tmp)
306       {
307         tmp *= 2.0l;
308         exp++;
309       }
310   else if (value != 0.0l)       /* Value < 1.0  and > 0.0 */
311     {
312       while (value < tmp)
313         {
314           tmp /= 2.0l;
315           exp--;
316         }
317       tmp *= 2.0l;
318       exp++;
319     }
320
321   *eptr = exp;
322   return value / tmp;
323 }
324 #endif /* HAVE_LONG_DOUBLE */
325
326
327 /* The converse: convert the DOUBLEST *FROM to an extended float
328    and store where TO points.  Neither FROM nor TO have any alignment
329    restrictions.  */
330
331 static void
332 convert_doublest_to_floatformat (CONST struct floatformat *fmt,
333                                  const DOUBLEST *from,
334                                  void *to)
335 {
336   DOUBLEST dfrom;
337   int exponent;
338   DOUBLEST mant;
339   unsigned int mant_bits, mant_off;
340   int mant_bits_left;
341   unsigned char *uto = (unsigned char *) to;
342
343   memcpy (&dfrom, from, sizeof (dfrom));
344   memset (uto, 0, (fmt->totalsize + FLOATFORMAT_CHAR_BIT - 1) 
345                     / FLOATFORMAT_CHAR_BIT);
346   if (dfrom == 0)
347     return;                     /* Result is zero */
348   if (dfrom != dfrom)           /* Result is NaN */
349     {
350       /* From is NaN */
351       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
352                  fmt->exp_len, fmt->exp_nan);
353       /* Be sure it's not infinity, but NaN value is irrel */
354       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
355                  32, 1);
356       return;
357     }
358
359   /* If negative, set the sign bit.  */
360   if (dfrom < 0)
361     {
362       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1);
363       dfrom = -dfrom;
364     }
365
366   if (dfrom + dfrom == dfrom && dfrom != 0.0)   /* Result is Infinity */
367     {
368       /* Infinity exponent is same as NaN's.  */
369       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
370                  fmt->exp_len, fmt->exp_nan);
371       /* Infinity mantissa is all zeroes.  */
372       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
373                  fmt->man_len, 0);
374       return;
375     }
376
377 #ifdef HAVE_LONG_DOUBLE
378   mant = ldfrexp (dfrom, &exponent);
379 #else
380   mant = frexp (dfrom, &exponent);
381 #endif
382
383   put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, fmt->exp_len,
384              exponent + fmt->exp_bias - 1);
385
386   mant_bits_left = fmt->man_len;
387   mant_off = fmt->man_start;
388   while (mant_bits_left > 0)
389     {
390       unsigned long mant_long;
391       mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;
392
393       mant *= 4294967296.0;
394       mant_long = ((unsigned long) mant) & 0xffffffffL;
395       mant -= mant_long;
396
397       /* If the integer bit is implicit, then we need to discard it.
398          If we are discarding a zero, we should be (but are not) creating
399          a denormalized number which means adjusting the exponent
400          (I think).  */
401       if (mant_bits_left == fmt->man_len
402           && fmt->intbit == floatformat_intbit_no)
403         {
404           mant_long <<= 1;
405           mant_long &= 0xffffffffL;
406           mant_bits -= 1;
407         }
408
409       if (mant_bits < 32)
410         {
411           /* The bits we want are in the most significant MANT_BITS bits of
412              mant_long.  Move them to the least significant.  */
413           mant_long >>= 32 - mant_bits;
414         }
415
416       put_field (uto, fmt->byteorder, fmt->totalsize,
417                  mant_off, mant_bits, mant_long);
418       mant_off += mant_bits;
419       mant_bits_left -= mant_bits;
420     }
421   if (fmt->byteorder == floatformat_littlebyte_bigword)
422     {
423       int count;
424       unsigned char *swaplow = uto;
425       unsigned char *swaphigh = uto + 4;
426       unsigned char tmp;
427
428       for (count = 0; count < 4; count++)
429         {
430           tmp = *swaplow;
431           *swaplow++ = *swaphigh;
432           *swaphigh++ = tmp;
433         }
434     }
435 }
436
437 /* Check if VAL (which is assumed to be a floating point number whose
438    format is described by FMT) is negative.  */
439
440 int
441 floatformat_is_negative (const struct floatformat *fmt, char *val)
442 {
443   unsigned char *uval = (unsigned char *) val;
444   gdb_assert (fmt != NULL);
445   return get_field (uval, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1);
446 }
447
448 /* Check if VAL is "not a number" (NaN) for FMT.  */
449
450 int
451 floatformat_is_nan (const struct floatformat *fmt, char *val)
452 {
453   unsigned char *uval = (unsigned char *) val;
454   long exponent;
455   unsigned long mant;
456   unsigned int mant_bits, mant_off;
457   int mant_bits_left;
458
459   gdb_assert (fmt != NULL);
460
461   if (! fmt->exp_nan)
462     return 0;
463
464   exponent = get_field (uval, fmt->byteorder, fmt->totalsize,
465                         fmt->exp_start, fmt->exp_len);
466
467   if (exponent != fmt->exp_nan)
468     return 0;
469
470   mant_bits_left = fmt->man_len;
471   mant_off = fmt->man_start;
472
473   while (mant_bits_left > 0)
474     {
475       mant_bits = min (mant_bits_left, 32);
476
477       mant = get_field (uval, fmt->byteorder, fmt->totalsize,
478                         mant_off, mant_bits);
479
480       /* If there is an explicit integer bit, mask it off.  */
481       if (mant_off == fmt->man_start
482           && fmt->intbit == floatformat_intbit_yes)
483         mant &= ~(1 << (mant_bits - 1));
484
485       if (mant)
486         return 1;
487
488       mant_off += mant_bits;
489       mant_bits_left -= mant_bits;
490     }
491
492   return 0;
493 }
494
495 /* Convert the mantissa of VAL (which is assumed to be a floating
496    point number whose format is described by FMT) into a hexadecimal
497    and store it in a static string.  Return a pointer to that string.  */
498
499 char *
500 floatformat_mantissa (const struct floatformat *fmt, char *val)
501 {
502   unsigned char *uval = (unsigned char *) val;
503   unsigned long mant;
504   unsigned int mant_bits, mant_off;
505   int mant_bits_left;
506   static char res[50];
507   char buf[9];
508
509   /* Make sure we have enough room to store the mantissa.  */
510   gdb_assert (fmt != NULL);
511   gdb_assert (sizeof res > ((fmt->man_len + 7) / 8) * 2);
512
513   mant_off = fmt->man_start;
514   mant_bits_left = fmt->man_len;
515   mant_bits = (mant_bits_left % 32) > 0 ? mant_bits_left % 32 : 32;
516
517   mant = get_field (uval, fmt->byteorder, fmt->totalsize,
518                     mant_off, mant_bits);
519
520   sprintf (res, "%lx", mant);
521
522   mant_off += mant_bits;
523   mant_bits_left -= mant_bits;
524   
525   while (mant_bits_left > 0)
526     {
527       mant = get_field (uval, fmt->byteorder, fmt->totalsize,
528                         mant_off, 32);
529
530       sprintf (buf, "%08lx", mant);
531       strcat (res, buf);
532
533       mant_off += 32;
534       mant_bits_left -= 32;
535     }
536
537   return res;
538 }
539
540 \f
541 /* Convert TO/FROM target to the hosts DOUBLEST floating-point format.
542
543    If the host and target formats agree, we just copy the raw data
544    into the appropriate type of variable and return, letting the host
545    increase precision as necessary.  Otherwise, we call the conversion
546    routine and let it do the dirty work.  */
547
548 #ifndef HOST_FLOAT_FORMAT
549 #define HOST_FLOAT_FORMAT 0
550 #endif
551 #ifndef HOST_DOUBLE_FORMAT
552 #define HOST_DOUBLE_FORMAT 0
553 #endif
554 #ifndef HOST_LONG_DOUBLE_FORMAT
555 #define HOST_LONG_DOUBLE_FORMAT 0
556 #endif
557
558 static const struct floatformat *host_float_format = HOST_FLOAT_FORMAT;
559 static const struct floatformat *host_double_format = HOST_DOUBLE_FORMAT;
560 static const struct floatformat *host_long_double_format = HOST_LONG_DOUBLE_FORMAT;
561
562 void
563 floatformat_to_doublest (const struct floatformat *fmt,
564                          const void *in, DOUBLEST *out)
565 {
566   gdb_assert (fmt != NULL);
567   if (fmt == host_float_format)
568     {
569       float val;
570       memcpy (&val, in, sizeof (val));
571       *out = val;
572     }
573   else if (fmt == host_double_format)
574     {
575       double val;
576       memcpy (&val, in, sizeof (val));
577       *out = val;
578     }
579   else if (fmt == host_long_double_format)
580     {
581       long double val;
582       memcpy (&val, in, sizeof (val));
583       *out = val;
584     }
585   else
586     convert_floatformat_to_doublest (fmt, in, out);
587 }
588
589 void
590 floatformat_from_doublest (const struct floatformat *fmt,
591                            const DOUBLEST *in, void *out)
592 {
593   gdb_assert (fmt != NULL);
594   if (fmt == host_float_format)
595     {
596       float val = *in;
597       memcpy (out, &val, sizeof (val));
598     }
599   else if (fmt == host_double_format)
600     {
601       double val = *in;
602       memcpy (out, &val, sizeof (val));
603     }
604   else if (fmt == host_long_double_format)
605     {
606       long double val = *in;
607       memcpy (out, &val, sizeof (val));
608     }
609   else
610     convert_doublest_to_floatformat (fmt, in, out);
611 }
612
613 \f
614 /* Return a floating-point format for a floating-point variable of
615    length LEN.  Return NULL, if no suitable floating-point format
616    could be found.
617
618    We need this functionality since information about the
619    floating-point format of a type is not always available to GDB; the
620    debug information typically only tells us the size of a
621    floating-point type.
622
623    FIXME: kettenis/2001-10-28: In many places, particularly in
624    target-dependent code, the format of floating-point types is known,
625    but not passed on by GDB.  This should be fixed.  */
626
627 const struct floatformat *
628 floatformat_from_length (int len)
629 {
630   if (len * TARGET_CHAR_BIT == TARGET_FLOAT_BIT)
631     return TARGET_FLOAT_FORMAT;
632   else if (len * TARGET_CHAR_BIT == TARGET_DOUBLE_BIT)
633     return TARGET_DOUBLE_FORMAT;
634   else if (len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_BIT)
635     return TARGET_LONG_DOUBLE_FORMAT;
636
637   return NULL;
638 }
639
640 const struct floatformat *
641 floatformat_from_type (const struct type *type)
642 {
643   gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
644   if (TYPE_FLOATFORMAT (type) != NULL)
645     return TYPE_FLOATFORMAT (type);
646   else
647     return floatformat_from_length (TYPE_LENGTH (type));
648 }
649
650 /* If the host doesn't define NAN, use zero instead.  */
651 #ifndef NAN
652 #define NAN 0.0
653 #endif
654
655 /* Extract a floating-point number of length LEN from a target-order
656    byte-stream at ADDR.  Returns the value as type DOUBLEST.  */
657
658 DOUBLEST
659 extract_floating (const void *addr, int len)
660 {
661   const struct floatformat *fmt = floatformat_from_length (len);
662   DOUBLEST val;
663
664   if (fmt == NULL)
665     {
666       warning ("Can't extract a floating-point number of %d bytes.", len);
667       return NAN;
668     }
669
670   floatformat_to_doublest (fmt, addr, &val);
671   return val;
672 }
673
674 /* Store VAL as a floating-point number of length LEN to a
675    target-order byte-stream at ADDR.  */
676
677 void
678 store_floating (void *addr, int len, DOUBLEST val)
679 {
680   const struct floatformat *fmt = floatformat_from_length (len);
681
682   if (fmt == NULL)
683     {
684       warning ("Can't store a floating-point number of %d bytes.", len);
685       memset (addr, 0, len);
686       return;
687     }
688
689   floatformat_from_doublest (fmt, &val, addr);
690 }
691
692 /* Extract a floating-point number of type TYPE from a target-order
693    byte-stream at ADDR.  Returns the value as type DOUBLEST.  */
694
695 DOUBLEST
696 extract_typed_floating (const void *addr, const struct type *type)
697 {
698   DOUBLEST retval;
699
700   gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
701
702   if (TYPE_FLOATFORMAT (type) == NULL)
703     return extract_floating (addr, TYPE_LENGTH (type));
704
705   floatformat_to_doublest (TYPE_FLOATFORMAT (type), addr, &retval);
706   return retval;
707 }
708
709 /* Store VAL as a floating-point number of type TYPE to a target-order
710    byte-stream at ADDR.  */
711
712 void
713 store_typed_floating (void *addr, const struct type *type, DOUBLEST val)
714 {
715   gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
716
717   /* FIXME: kettenis/2001-10-28: It is debatable whether we should
718      zero out any remaining bytes in the target buffer when TYPE is
719      longer than the actual underlying floating-point format.  Perhaps
720      we should store a fixed bitpattern in those remaining bytes,
721      instead of zero, or perhaps we shouldn't touch those remaining
722      bytes at all.
723
724      NOTE: cagney/2001-10-28: With the way things currently work, it
725      isn't a good idea to leave the end bits undefined.  This is
726      because GDB writes out the entire sizeof(<floating>) bits of the
727      floating-point type even though the value might only be stored
728      in, and the target processor may only refer to, the first N <
729      TYPE_LENGTH (type) bits.  If the end of the buffer wasn't
730      initialized, GDB would write undefined data to the target.  An
731      errant program, refering to that undefined data, would then
732      become non-deterministic.
733
734      See also the function convert_typed_floating below.  */
735   memset (addr, 0, TYPE_LENGTH (type));
736
737   if (TYPE_FLOATFORMAT (type) == NULL)
738     store_floating (addr, TYPE_LENGTH (type), val);
739   else
740     floatformat_from_doublest (TYPE_FLOATFORMAT (type), &val, addr);
741 }
742
743 /* Convert a floating-point number of type FROM_TYPE from a
744    target-order byte-stream at FROM to a floating-point number of type
745    TO_TYPE, and store it to a target-order byte-stream at TO.  */
746
747 void
748 convert_typed_floating (const void *from, const struct type *from_type,
749                         void *to, const struct type *to_type)
750 {
751   const struct floatformat *from_fmt = floatformat_from_type (from_type);
752   const struct floatformat *to_fmt = floatformat_from_type (to_type);
753
754   gdb_assert (TYPE_CODE (from_type) == TYPE_CODE_FLT);
755   gdb_assert (TYPE_CODE (to_type) == TYPE_CODE_FLT);
756
757   if (from_fmt == NULL || to_fmt == NULL)
758     {
759       /* If we don't know the floating-point format of FROM_TYPE or
760          TO_TYPE, there's not much we can do.  We might make the
761          assumption that if the length of FROM_TYPE and TO_TYPE match,
762          their floating-point format would match too, but that
763          assumption might be wrong on targets that support
764          floating-point types that only differ in endianness for
765          example.  So we warn instead, and zero out the target buffer.  */
766       warning ("Can't convert floating-point number to desired type.");
767       memset (to, 0, TYPE_LENGTH (to_type));
768     }
769   else if (from_fmt == to_fmt)
770     {
771       /* We're in business.  The floating-point format of FROM_TYPE
772          and TO_TYPE match.  However, even though the floating-point
773          format matches, the length of the type might still be
774          different.  Make sure we don't overrun any buffers.  See
775          comment in store_typed_floating for a discussion about
776          zeroing out remaining bytes in the target buffer.  */
777       memset (to, 0, TYPE_LENGTH (to_type));
778       memcpy (to, from, min (TYPE_LENGTH (from_type), TYPE_LENGTH (to_type)));
779     }
780   else
781     {
782       /* The floating-point types don't match.  The best we can do
783          (aport from simulating the target FPU) is converting to the
784          widest floating-point type supported by the host, and then
785          again to the desired type.  */
786       DOUBLEST d;
787
788       floatformat_to_doublest (from_fmt, from, &d);
789       floatformat_from_doublest (to_fmt, &d, to);
790     }
791 }