OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [gdb/] [doublest.c] - Blame information for rev 840

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.