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