2003-03-11 Pierre Muller <muller@ics.u-strasbg.fr>
[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   /* On i386 the 'long double' type takes 96 bits,
637      while the real number of used bits is only 80,
638      both in processor and in memory.  
639      The code below accepts the real bit size.  */ 
640   else if ((TARGET_LONG_DOUBLE_FORMAT != NULL) 
641            && (len * TARGET_CHAR_BIT ==
642                TARGET_LONG_DOUBLE_FORMAT->totalsize))
643     return TARGET_LONG_DOUBLE_FORMAT;
644
645   return NULL;
646 }
647
648 const struct floatformat *
649 floatformat_from_type (const struct type *type)
650 {
651   gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
652   if (TYPE_FLOATFORMAT (type) != NULL)
653     return TYPE_FLOATFORMAT (type);
654   else
655     return floatformat_from_length (TYPE_LENGTH (type));
656 }
657
658 /* If the host doesn't define NAN, use zero instead.  */
659 #ifndef NAN
660 #define NAN 0.0
661 #endif
662
663 /* Extract a floating-point number of length LEN from a target-order
664    byte-stream at ADDR.  Returns the value as type DOUBLEST.  */
665
666 DOUBLEST
667 extract_floating (const void *addr, int len)
668 {
669   const struct floatformat *fmt = floatformat_from_length (len);
670   DOUBLEST val;
671
672   if (fmt == NULL)
673     {
674       warning ("Can't extract a floating-point number of %d bytes.", len);
675       return NAN;
676     }
677
678   floatformat_to_doublest (fmt, addr, &val);
679   return val;
680 }
681
682 /* Store VAL as a floating-point number of length LEN to a
683    target-order byte-stream at ADDR.  */
684
685 void
686 store_floating (void *addr, int len, DOUBLEST val)
687 {
688   const struct floatformat *fmt = floatformat_from_length (len);
689
690   if (fmt == NULL)
691     {
692       warning ("Can't store a floating-point number of %d bytes.", len);
693       memset (addr, 0, len);
694       return;
695     }
696
697   floatformat_from_doublest (fmt, &val, addr);
698 }
699
700 /* Extract a floating-point number of type TYPE from a target-order
701    byte-stream at ADDR.  Returns the value as type DOUBLEST.  */
702
703 DOUBLEST
704 extract_typed_floating (const void *addr, const struct type *type)
705 {
706   DOUBLEST retval;
707
708   gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
709
710   if (TYPE_FLOATFORMAT (type) == NULL)
711     return extract_floating (addr, TYPE_LENGTH (type));
712
713   floatformat_to_doublest (TYPE_FLOATFORMAT (type), addr, &retval);
714   return retval;
715 }
716
717 /* Store VAL as a floating-point number of type TYPE to a target-order
718    byte-stream at ADDR.  */
719
720 void
721 store_typed_floating (void *addr, const struct type *type, DOUBLEST val)
722 {
723   gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
724
725   /* FIXME: kettenis/2001-10-28: It is debatable whether we should
726      zero out any remaining bytes in the target buffer when TYPE is
727      longer than the actual underlying floating-point format.  Perhaps
728      we should store a fixed bitpattern in those remaining bytes,
729      instead of zero, or perhaps we shouldn't touch those remaining
730      bytes at all.
731
732      NOTE: cagney/2001-10-28: With the way things currently work, it
733      isn't a good idea to leave the end bits undefined.  This is
734      because GDB writes out the entire sizeof(<floating>) bits of the
735      floating-point type even though the value might only be stored
736      in, and the target processor may only refer to, the first N <
737      TYPE_LENGTH (type) bits.  If the end of the buffer wasn't
738      initialized, GDB would write undefined data to the target.  An
739      errant program, refering to that undefined data, would then
740      become non-deterministic.
741
742      See also the function convert_typed_floating below.  */
743   memset (addr, 0, TYPE_LENGTH (type));
744
745   if (TYPE_FLOATFORMAT (type) == NULL)
746     store_floating (addr, TYPE_LENGTH (type), val);
747   else
748     floatformat_from_doublest (TYPE_FLOATFORMAT (type), &val, addr);
749 }
750
751 /* Convert a floating-point number of type FROM_TYPE from a
752    target-order byte-stream at FROM to a floating-point number of type
753    TO_TYPE, and store it to a target-order byte-stream at TO.  */
754
755 void
756 convert_typed_floating (const void *from, const struct type *from_type,
757                         void *to, const struct type *to_type)
758 {
759   const struct floatformat *from_fmt = floatformat_from_type (from_type);
760   const struct floatformat *to_fmt = floatformat_from_type (to_type);
761
762   gdb_assert (TYPE_CODE (from_type) == TYPE_CODE_FLT);
763   gdb_assert (TYPE_CODE (to_type) == TYPE_CODE_FLT);
764
765   if (from_fmt == NULL || to_fmt == NULL)
766     {
767       /* If we don't know the floating-point format of FROM_TYPE or
768          TO_TYPE, there's not much we can do.  We might make the
769          assumption that if the length of FROM_TYPE and TO_TYPE match,
770          their floating-point format would match too, but that
771          assumption might be wrong on targets that support
772          floating-point types that only differ in endianness for
773          example.  So we warn instead, and zero out the target buffer.  */
774       warning ("Can't convert floating-point number to desired type.");
775       memset (to, 0, TYPE_LENGTH (to_type));
776     }
777   else if (from_fmt == to_fmt)
778     {
779       /* We're in business.  The floating-point format of FROM_TYPE
780          and TO_TYPE match.  However, even though the floating-point
781          format matches, the length of the type might still be
782          different.  Make sure we don't overrun any buffers.  See
783          comment in store_typed_floating for a discussion about
784          zeroing out remaining bytes in the target buffer.  */
785       memset (to, 0, TYPE_LENGTH (to_type));
786       memcpy (to, from, min (TYPE_LENGTH (from_type), TYPE_LENGTH (to_type)));
787     }
788   else
789     {
790       /* The floating-point types don't match.  The best we can do
791          (aport from simulating the target FPU) is converting to the
792          widest floating-point type supported by the host, and then
793          again to the desired type.  */
794       DOUBLEST d;
795
796       floatformat_to_doublest (from_fmt, from, &d);
797       floatformat_from_doublest (to_fmt, &d, to);
798     }
799 }