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

Subversion Repositories ion

[/] [ion/] [trunk/] [src/] [common/] [libsoc/] [src/] [fp-bit.c] - Blame information for rev 229

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 178 ja_rd
/* This is a software floating point library which can be used instead of
2
   the floating point routines in libgcc1.c for targets without hardware
3
   floating point.
4
 Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
5
 
6
This file is free software; you can redistribute it and/or modify it
7
under the terms of the GNU General Public License as published by the
8
Free Software Foundation; either version 2, or (at your option) any
9
later version.
10
 
11
In addition to the permissions in the GNU General Public License, the
12
Free Software Foundation gives you unlimited permission to link the
13
compiled version of this file with other programs, and to distribute
14
those programs without any restriction coming from the use of this
15
file.  (The General Public License restrictions do apply in other
16
respects; for example, they cover modification of the file, and
17
distribution when not linked into another program.)
18
 
19
This file is distributed in the hope that it will be useful, but
20
WITHOUT ANY WARRANTY; without even the implied warranty of
21
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22
General Public License for more details.
23
 
24
You should have received a copy of the GNU General Public License
25
along with this program; see the file COPYING.  If not, write to
26
the Free Software Foundation, 59 Temple Place - Suite 330,
27
Boston, MA 02111-1307, USA.  */
28
 
29
/* As a special exception, if you link this library with other files,
30
   some of which are compiled with GCC, to produce an executable,
31
   this library does not by itself cause the resulting executable
32
   to be covered by the GNU General Public License.
33
   This exception does not however invalidate any other reasons why
34
   the executable file might be covered by the GNU General Public License.  */
35
 
36
/* This implements IEEE 754 format arithmetic, but does not provide a
37
   mechanism for setting the rounding mode, or for generating or handling
38
   exceptions.
39
 
40
   The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
41
   Wilson, all of Cygnus Support.  */
42
 
43
/* The intended way to use this file is to make two copies, add `#define FLOAT'
44
   to one copy, then compile both copies and add them to libgcc.a.  */
45
/* #define FLOAT */
46
#include <stdint.h>
47
/* The following macros can be defined to change the behaviour of this file:
48
   FLOAT: Implement a `float', aka SFmode, fp library.  If this is not
49
     defined, then this file implements a `double', aka DFmode, fp library.
50
   FLOAT_ONLY: Used with FLOAT, to implement a `float' only library, i.e.
51
     don't include float->double conversion which requires the double library.
52
     This is useful only for machines which can't support doubles, e.g. some
53
     8-bit processors.
54
   CMPtype: Specify the type that floating point compares should return.
55
     This defaults to SItype, aka int.
56
   US_SOFTWARE_GOFAST: This makes all entry points use the same names as the
57
     US Software goFast library.  If this is not defined, the entry points use
58
     the same names as libgcc1.c.
59
   _DEBUG_BITFLOAT: This makes debugging the code a little easier, by adding
60
     two integers to the FLO_union_type.
61
   NO_NANS: Disable nan and infinity handling
62
   SMALL_MACHINE: Useful when operations on QIs and HIs are faster
63
     than on an SI */
64
 
65
/* We don't currently support extended floats (long doubles) on machines
66
   without hardware to deal with them.
67
 
68
   These stubs are just to keep the linker from complaining about unresolved
69
   references which can be pulled in from libio & libstdc++, even if the
70
   user isn't using long doubles.  However, they may generate an unresolved
71
   external to abort if abort is not used by the function, and the stubs
72
   are referenced from within libc, since libgcc goes before and after the
73
   system library.  */
74
 
75
#ifdef EXTENDED_FLOAT_STUBS
76
__truncxfsf2 (){ abort(); }
77
__extendsfxf2 (){ abort(); }
78
__addxf3 (){ abort(); }
79
__divxf3 (){ abort(); }
80
__eqxf2 (){ abort(); }
81
__extenddfxf2 (){ abort(); }
82
__gtxf2 (){ abort(); }
83
__lexf2 (){ abort(); }
84
__ltxf2 (){ abort(); }
85
__mulxf3 (){ abort(); }
86
__negxf2 (){ abort(); }
87
__nexf2 (){ abort(); }
88
__subxf3 (){ abort(); }
89
__truncxfdf2 (){ abort(); }
90
 
91
__trunctfsf2 (){ abort(); }
92
__extendsftf2 (){ abort(); }
93
__addtf3 (){ abort(); }
94
__divtf3 (){ abort(); }
95
__eqtf2 (){ abort(); }
96
__extenddftf2 (){ abort(); }
97
__gttf2 (){ abort(); }
98
__letf2 (){ abort(); }
99
__lttf2 (){ abort(); }
100
__multf3 (){ abort(); }
101
__negtf2 (){ abort(); }
102
__netf2 (){ abort(); }
103
__subtf3 (){ abort(); }
104
__trunctfdf2 (){ abort(); }
105
#else   /* !EXTENDED_FLOAT_STUBS, rest of file */
106
 
107
/*
108
typedef SFtype __attribute__ ((mode (SF)));
109
typedef DFtype __attribute__ ((mode (DF)));
110
 
111
typedef int HItype __attribute__ ((mode (HI)));
112
typedef int SItype __attribute__ ((mode (SI)));
113
typedef int DItype __attribute__ ((mode (DI)));
114
*/
115
 
116
typedef int32_t SFtype;
117
typedef int64_t DFtype;
118
 
119
typedef int16_t HItype;
120
typedef int32_t SItype;
121
typedef int64_t DItype;
122
 
123
 
124
 
125
/* The type of the result of a fp compare */
126
#ifndef CMPtype
127
#define CMPtype SItype
128
#endif
129
 
130
typedef unsigned int UHItype __attribute__ ((mode (HI)));
131
typedef unsigned int USItype __attribute__ ((mode (SI)));
132
typedef unsigned int UDItype __attribute__ ((mode (DI)));
133
 
134
#define MAX_SI_INT   ((SItype) ((unsigned) (~0)>>1))
135
#define MAX_USI_INT  ((USItype) ~0)
136
 
137
 
138
#ifdef FLOAT_ONLY
139
#define NO_DI_MODE
140
#endif
141
 
142
#ifdef FLOAT
143
#       define NGARDS    7L
144
#       define GARDROUND 0x3f
145
#       define GARDMASK  0x7f
146
#       define GARDMSB   0x40
147
#       define EXPBITS 8
148
#       define EXPBIAS 127
149
#       define FRACBITS 23
150
#       define EXPMAX (0xff)
151
#       define QUIET_NAN 0x100000L
152
#       define FRAC_NBITS 32
153
#       define FRACHIGH  0x80000000L
154
#       define FRACHIGH2 0xc0000000L
155
#       define pack_d pack_f
156
#       define unpack_d unpack_f
157
        typedef USItype fractype;
158
        typedef UHItype halffractype;
159
        typedef SFtype FLO_type;
160
        typedef SItype intfrac;
161
 
162
#else
163
#       define PREFIXFPDP dp
164
#       define PREFIXSFDF df
165
#       define NGARDS 8L
166
#       define GARDROUND 0x7f
167
#       define GARDMASK  0xff
168
#       define GARDMSB   0x80
169
#       define EXPBITS 11
170
#       define EXPBIAS 1023
171
#       define FRACBITS 52
172
#       define EXPMAX (0x7ff)
173
#       define QUIET_NAN 0x8000000000000LL
174
#       define FRAC_NBITS 64
175
#       define FRACHIGH  0x8000000000000000LL
176
#       define FRACHIGH2 0xc000000000000000LL
177
        typedef UDItype fractype;
178
        typedef USItype halffractype;
179
        typedef DFtype FLO_type;
180
        typedef DItype intfrac;
181
#endif
182
 
183
#ifdef US_SOFTWARE_GOFAST
184
#       ifdef FLOAT
185
#               define add              fpadd
186
#               define sub              fpsub
187
#               define multiply         fpmul
188
#               define divide           fpdiv
189
#               define compare          fpcmp
190
#               define si_to_float      sitofp
191
#               define float_to_si      fptosi
192
#               define float_to_usi     fptoui
193
#               define negate           __negsf2
194
#               define sf_to_df         fptodp
195
#               define dptofp           dptofp
196
#else
197
#               define add              dpadd
198
#               define sub              dpsub
199
#               define multiply         dpmul
200
#               define divide           dpdiv
201
#               define compare          dpcmp
202
#               define si_to_float      litodp
203
#               define float_to_si      dptoli
204
#               define float_to_usi     dptoul
205
#               define negate           __negdf2
206
#               define df_to_sf         dptofp
207
#endif
208
#else
209
#       ifdef FLOAT
210
#               define add              __addsf3
211
#               define sub              __subsf3
212
#               define multiply         __mulsf3
213
#               define divide           __divsf3
214
#               define compare          __cmpsf2
215
#               define _eq_f2           __eqsf2
216
#               define _ne_f2           __nesf2
217
#               define _gt_f2           __gtsf2
218
#               define _ge_f2           __gesf2
219
#               define _lt_f2           __ltsf2
220
#               define _le_f2           __lesf2
221
#               define si_to_float      __floatsisf
222
#               define float_to_si      __fixsfsi
223
#               define float_to_usi     __fixunssfsi
224
#               define negate           __negsf2
225
#               define sf_to_df         __extendsfdf2
226
#else
227
#               define add              __adddf3
228
#               define sub              __subdf3
229
#               define multiply         __muldf3
230
#               define divide           __divdf3
231
#               define compare          __cmpdf2
232
#               define _eq_f2           __eqdf2
233
#               define _ne_f2           __nedf2
234
#               define _gt_f2           __gtdf2
235
#               define _ge_f2           __gedf2
236
#               define _lt_f2           __ltdf2
237
#               define _le_f2           __ledf2
238
#               define si_to_float      __floatsidf
239
#               define float_to_si      __fixdfsi
240
#               define float_to_usi     __fixunsdfsi
241
#               define negate           __negdf2
242
#               define df_to_sf         __truncdfsf2
243
#       endif
244
#endif
245
 
246
 
247
#define INLINE __inline__
248
 
249
/* Preserve the sticky-bit when shifting fractions to the right.  */
250
#define LSHIFT(a) { a = (a & 1) | (a >> 1); }
251
 
252
/* numeric parameters */
253
/* F_D_BITOFF is the number of bits offset between the MSB of the mantissa
254
   of a float and of a double. Assumes there are only two float types.
255
   (double::FRAC_BITS+double::NGARDS-(float::FRAC_BITS-float::NGARDS))
256
 */
257
#define F_D_BITOFF (52+8-(23+7))
258
 
259
 
260
#define NORMAL_EXPMIN (-(EXPBIAS)+1)
261
#define IMPLICIT_1 (1LL<<(FRACBITS+NGARDS))
262
#define IMPLICIT_2 (1LL<<(FRACBITS+1+NGARDS))
263
 
264
/* common types */
265
 
266
typedef enum
267
{
268
  CLASS_SNAN,
269
  CLASS_QNAN,
270
  CLASS_ZERO,
271
  CLASS_NUMBER,
272
  CLASS_INFINITY
273
} fp_class_type;
274
 
275
typedef struct
276
{
277
#ifdef SMALL_MACHINE
278
  char class;
279
  unsigned char sign;
280
  short normal_exp;
281
#else
282
  fp_class_type class;
283
  unsigned int sign;
284
  int normal_exp;
285
#endif
286
 
287
  union
288
    {
289
      fractype ll;
290
      halffractype l[2];
291
    } fraction;
292
} fp_number_type;
293
 
294
typedef union
295
{
296
  FLO_type value;
297
  fractype value_raw;
298
 
299
#ifndef FLOAT
300
  halffractype words[2];
301
#endif
302
 
303
#ifdef FLOAT_BIT_ORDER_MISMATCH
304
  struct
305
    {
306
      fractype fraction:FRACBITS __attribute__ ((packed));
307
      unsigned int exp:EXPBITS __attribute__ ((packed));
308
      unsigned int sign:1 __attribute__ ((packed));
309
    }
310
  bits;
311
#endif
312
 
313
#ifdef _DEBUG_BITFLOAT
314
  struct
315
    {
316
      unsigned int sign:1 __attribute__ ((packed));
317
      unsigned int exp:EXPBITS __attribute__ ((packed));
318
      fractype fraction:FRACBITS __attribute__ ((packed));
319
    }
320
  bits_big_endian;
321
 
322
  struct
323
    {
324
      fractype fraction:FRACBITS __attribute__ ((packed));
325
      unsigned int exp:EXPBITS __attribute__ ((packed));
326
      unsigned int sign:1 __attribute__ ((packed));
327
    }
328
  bits_little_endian;
329
#endif
330
}
331
FLO_union_type;
332
 
333
 
334
/* end of header */
335
 
336
/* IEEE "special" number predicates */
337
 
338
#ifdef NO_NANS
339
 
340
#define nan() 0
341
#define isnan(x) 0
342
#define isinf(x) 0
343
#else
344
 
345
INLINE
346
static fp_number_type *
347
nan ()
348
{
349
  static fp_number_type thenan;
350
 
351
  return &thenan;
352
}
353
 
354
INLINE
355
static int
356
isnan ( fp_number_type *  x)
357
{
358
  return x->class == CLASS_SNAN || x->class == CLASS_QNAN;
359
}
360
 
361
INLINE
362
static int
363
isinf ( fp_number_type *  x)
364
{
365
  return x->class == CLASS_INFINITY;
366
}
367
 
368
#endif
369
 
370
INLINE
371
static int
372
iszero ( fp_number_type *  x)
373
{
374
  return x->class == CLASS_ZERO;
375
}
376
 
377
INLINE
378
static void
379
flip_sign ( fp_number_type *  x)
380
{
381
  x->sign = !x->sign;
382
}
383
 
384
static FLO_type
385
pack_d ( fp_number_type *  src)
386
{
387
  FLO_union_type dst;
388
  fractype fraction = src->fraction.ll; /* wasn't unsigned before? */
389
  int sign = src->sign;
390
  int exp = 0;
391
 
392
  if (isnan (src))
393
    {
394
      exp = EXPMAX;
395
      if (src->class == CLASS_QNAN || 1)
396
        {
397
          fraction |= QUIET_NAN;
398
        }
399
    }
400
  else if (isinf (src))
401
    {
402
      exp = EXPMAX;
403
      fraction = 0;
404
    }
405
  else if (iszero (src))
406
    {
407
      exp = 0;
408
      fraction = 0;
409
    }
410
  else if (fraction == 0)
411
    {
412
      exp = 0;
413
      sign = 0;
414
    }
415
  else
416
    {
417
      if (src->normal_exp < NORMAL_EXPMIN)
418
        {
419
          /* This number's exponent is too low to fit into the bits
420
             available in the number, so we'll store 0 in the exponent and
421
             shift the fraction to the right to make up for it.  */
422
 
423
          int shift = NORMAL_EXPMIN - src->normal_exp;
424
 
425
          exp = 0;
426
 
427
          if (shift > FRAC_NBITS - NGARDS)
428
            {
429
              /* No point shifting, since it's more that 64 out.  */
430
              fraction = 0;
431
            }
432
          else
433
            {
434
              /* Shift by the value */
435
              fraction >>= shift;
436
            }
437
          fraction >>= NGARDS;
438
        }
439
      else if (src->normal_exp > EXPBIAS)
440
        {
441
          exp = EXPMAX;
442
          fraction = 0;
443
        }
444
      else
445
        {
446
          exp = src->normal_exp + EXPBIAS;
447
          /* IF the gard bits are the all zero, but the first, then we're
448
             half way between two numbers, choose the one which makes the
449
             lsb of the answer 0.  */
450
          if ((fraction & GARDMASK) == GARDMSB)
451
            {
452
              if (fraction & (1 << NGARDS))
453
                fraction += GARDROUND + 1;
454
            }
455
          else
456
            {
457
              /* Add a one to the guards to round up */
458
              fraction += GARDROUND;
459
            }
460
          if (fraction >= IMPLICIT_2)
461
            {
462
              fraction >>= 1;
463
              exp += 1;
464
            }
465
          fraction >>= NGARDS;
466
        }
467
    }
468
 
469
  /* We previously used bitfields to store the number, but this doesn't
470
     handle little/big endian systems conveniently, so use shifts and
471
     masks */
472
#ifdef FLOAT_BIT_ORDER_MISMATCH
473
  dst.bits.fraction = fraction;
474
  dst.bits.exp = exp;
475
  dst.bits.sign = sign;
476
#else
477
  dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
478
  dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS;
479
  dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS);
480
#endif
481
 
482
#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
483
  {
484
    halffractype tmp = dst.words[0];
485
    dst.words[0] = dst.words[1];
486
    dst.words[1] = tmp;
487
  }
488
#endif
489
 
490
  return dst.value;
491
}
492
 
493
static void
494
unpack_d (FLO_union_type * src, fp_number_type * dst)
495
{
496
  /* We previously used bitfields to store the number, but this doesn't
497
     handle little/big endian systems conveniently, so use shifts and
498
     masks */
499
  fractype fraction;
500
  int exp;
501
  int sign;
502
 
503
#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
504
  FLO_union_type swapped;
505
 
506
  swapped.words[0] = src->words[1];
507
  swapped.words[1] = src->words[0];
508
  src = &swapped;
509
#endif
510
 
511
#ifdef FLOAT_BIT_ORDER_MISMATCH
512
  fraction = src->bits.fraction;
513
  exp = src->bits.exp;
514
  sign = src->bits.sign;
515
#else
516
  fraction = src->value_raw & ((((fractype)1) << FRACBITS) - (fractype)1);
517
  exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1);
518
  sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1;
519
#endif
520
 
521
  dst->sign = sign;
522
  if (exp == 0)
523
    {
524
      /* Hmm.  Looks like 0 */
525
      if (fraction == 0)
526
        {
527
          /* tastes like zero */
528
          dst->class = CLASS_ZERO;
529
        }
530
      else
531
        {
532
          /* Zero exponent with non zero fraction - it's denormalized,
533
             so there isn't a leading implicit one - we'll shift it so
534
             it gets one.  */
535
          dst->normal_exp = exp - EXPBIAS + 1;
536
          fraction <<= NGARDS;
537
 
538
          dst->class = CLASS_NUMBER;
539
#if 1
540
          while (fraction < IMPLICIT_1)
541
            {
542
              fraction <<= 1;
543
              dst->normal_exp--;
544
            }
545
#endif
546
          dst->fraction.ll = fraction;
547
        }
548
    }
549
  else if (exp == EXPMAX)
550
    {
551
      /* Huge exponent*/
552
      if (fraction == 0)
553
        {
554
          /* Attached to a zero fraction - means infinity */
555
          dst->class = CLASS_INFINITY;
556
        }
557
      else
558
        {
559
          /* Non zero fraction, means nan */
560
          if (fraction & QUIET_NAN)
561
            {
562
              dst->class = CLASS_QNAN;
563
            }
564
          else
565
            {
566
              dst->class = CLASS_SNAN;
567
            }
568
          /* Keep the fraction part as the nan number */
569
          dst->fraction.ll = fraction;
570
        }
571
    }
572
  else
573
    {
574
      /* Nothing strange about this number */
575
      dst->normal_exp = exp - EXPBIAS;
576
      dst->class = CLASS_NUMBER;
577
      dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;
578
    }
579
}
580
 
581
static fp_number_type *
582
_fpadd_parts (fp_number_type * a,
583
              fp_number_type * b,
584
              fp_number_type * tmp)
585
{
586
  intfrac tfraction;
587
 
588
  /* Put commonly used fields in local variables.  */
589
  int a_normal_exp;
590
  int b_normal_exp;
591
  fractype a_fraction;
592
  fractype b_fraction;
593
 
594
  if (isnan (a))
595
    {
596
      return a;
597
    }
598
  if (isnan (b))
599
    {
600
      return b;
601
    }
602
  if (isinf (a))
603
    {
604
      /* Adding infinities with opposite signs yields a NaN.  */
605
      if (isinf (b) && a->sign != b->sign)
606
        return nan ();
607
      return a;
608
    }
609
  if (isinf (b))
610
    {
611
      return b;
612
    }
613
  if (iszero (b))
614
    {
615
      return a;
616
    }
617
  if (iszero (a))
618
    {
619
      return b;
620
    }
621
 
622
  /* Got two numbers. shift the smaller and increment the exponent till
623
     they're the same */
624
  {
625
    int diff;
626
 
627
    a_normal_exp = a->normal_exp;
628
    b_normal_exp = b->normal_exp;
629
    a_fraction = a->fraction.ll;
630
    b_fraction = b->fraction.ll;
631
 
632
    diff = a_normal_exp - b_normal_exp;
633
 
634
    if (diff < 0)
635
      diff = -diff;
636
    if (diff < FRAC_NBITS)
637
      {
638
        /* ??? This does shifts one bit at a time.  Optimize.  */
639
        while (a_normal_exp > b_normal_exp)
640
          {
641
            b_normal_exp++;
642
            LSHIFT (b_fraction);
643
          }
644
        while (b_normal_exp > a_normal_exp)
645
          {
646
            a_normal_exp++;
647
            LSHIFT (a_fraction);
648
          }
649
      }
650
    else
651
      {
652
        /* Somethings's up.. choose the biggest */
653
        if (a_normal_exp > b_normal_exp)
654
          {
655
            b_normal_exp = a_normal_exp;
656
            b_fraction = 0;
657
          }
658
        else
659
          {
660
            a_normal_exp = b_normal_exp;
661
            a_fraction = 0;
662
          }
663
      }
664
  }
665
 
666
  if (a->sign != b->sign)
667
    {
668
      if (a->sign)
669
        {
670
          tfraction = -a_fraction + b_fraction;
671
        }
672
      else
673
        {
674
          tfraction = a_fraction - b_fraction;
675
        }
676
      if (tfraction > 0)
677
        {
678
          tmp->sign = 0;
679
          tmp->normal_exp = a_normal_exp;
680
          tmp->fraction.ll = tfraction;
681
        }
682
      else
683
        {
684
          tmp->sign = 1;
685
          tmp->normal_exp = a_normal_exp;
686
          tmp->fraction.ll = -tfraction;
687
        }
688
      /* and renormalize it */
689
 
690
      while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll)
691
        {
692
          tmp->fraction.ll <<= 1;
693
          tmp->normal_exp--;
694
        }
695
    }
696
  else
697
    {
698
      tmp->sign = a->sign;
699
      tmp->normal_exp = a_normal_exp;
700
      tmp->fraction.ll = a_fraction + b_fraction;
701
    }
702
  tmp->class = CLASS_NUMBER;
703
  /* Now the fraction is added, we have to shift down to renormalize the
704
     number */
705
 
706
  if (tmp->fraction.ll >= IMPLICIT_2)
707
    {
708
      LSHIFT (tmp->fraction.ll);
709
      tmp->normal_exp++;
710
    }
711
  return tmp;
712
 
713
}
714
 
715
FLO_type
716
add (FLO_type arg_a, FLO_type arg_b)
717
{
718
  fp_number_type a;
719
  fp_number_type b;
720
  fp_number_type tmp;
721
  fp_number_type *res;
722
 
723
  unpack_d ((FLO_union_type *) & arg_a, &a);
724
  unpack_d ((FLO_union_type *) & arg_b, &b);
725
 
726
  res = _fpadd_parts (&a, &b, &tmp);
727
 
728
  return pack_d (res);
729
}
730
 
731
FLO_type
732
sub (FLO_type arg_a, FLO_type arg_b)
733
{
734
  fp_number_type a;
735
  fp_number_type b;
736
  fp_number_type tmp;
737
  fp_number_type *res;
738
 
739
  unpack_d ((FLO_union_type *) & arg_a, &a);
740
  unpack_d ((FLO_union_type *) & arg_b, &b);
741
 
742
  b.sign ^= 1;
743
 
744
  res = _fpadd_parts (&a, &b, &tmp);
745
 
746
  return pack_d (res);
747
}
748
 
749
static fp_number_type *
750
_fpmul_parts ( fp_number_type *  a,
751
               fp_number_type *  b,
752
               fp_number_type * tmp)
753
{
754
  fractype low = 0;
755
  fractype high = 0;
756
 
757
  if (isnan (a))
758
    {
759
      a->sign = a->sign != b->sign;
760
      return a;
761
    }
762
  if (isnan (b))
763
    {
764
      b->sign = a->sign != b->sign;
765
      return b;
766
    }
767
  if (isinf (a))
768
    {
769
      if (iszero (b))
770
        return nan ();
771
      a->sign = a->sign != b->sign;
772
      return a;
773
    }
774
  if (isinf (b))
775
    {
776
      if (iszero (a))
777
        {
778
          return nan ();
779
        }
780
      b->sign = a->sign != b->sign;
781
      return b;
782
    }
783
  if (iszero (a))
784
    {
785
      a->sign = a->sign != b->sign;
786
      return a;
787
    }
788
  if (iszero (b))
789
    {
790
      b->sign = a->sign != b->sign;
791
      return b;
792
    }
793
 
794
  /* Calculate the mantissa by multiplying both 64bit numbers to get a
795
     128 bit number */
796
  {
797
    fractype x = a->fraction.ll;
798
    fractype ylow = b->fraction.ll;
799
    fractype yhigh = 0;
800
    int bit;
801
 
802
#if defined(NO_DI_MODE)
803
    {
804
      /* ??? This does multiplies one bit at a time.  Optimize.  */
805
      for (bit = 0; bit < FRAC_NBITS; bit++)
806
        {
807
          int carry;
808
 
809
          if (x & 1)
810
            {
811
              carry = (low += ylow) < ylow;
812
              high += yhigh + carry;
813
            }
814
          yhigh <<= 1;
815
          if (ylow & FRACHIGH)
816
            {
817
              yhigh |= 1;
818
            }
819
          ylow <<= 1;
820
          x >>= 1;
821
        }
822
    }
823
#elif defined(FLOAT) 
824
    {
825
      /* Multiplying two 32 bit numbers to get a 64 bit number  on
826
        a machine with DI, so we're safe */
827
 
828
      DItype answer = (DItype)(a->fraction.ll) * (DItype)(b->fraction.ll);
829
 
830
      high = answer >> 32;
831
      low = answer;
832
    }
833
#else
834
    /* Doing a 64*64 to 128 */
835
    {
836
      UDItype nl = a->fraction.ll & 0xffffffff;
837
      UDItype nh = a->fraction.ll >> 32;
838
      UDItype ml = b->fraction.ll & 0xffffffff;
839
      UDItype mh = b->fraction.ll >>32;
840
      UDItype pp_ll = ml * nl;
841
      UDItype pp_hl = mh * nl;
842
      UDItype pp_lh = ml * nh;
843
      UDItype pp_hh = mh * nh;
844
      UDItype res2 = 0;
845
      UDItype res0 = 0;
846
      UDItype ps_hh__ = pp_hl + pp_lh;
847
      if (ps_hh__ < pp_hl)
848
        res2 += 0x100000000LL;
849
      pp_hl = (ps_hh__ << 32) & 0xffffffff00000000LL;
850
      res0 = pp_ll + pp_hl;
851
      if (res0 < pp_ll)
852
        res2++;
853
      res2 += ((ps_hh__ >> 32) & 0xffffffffL) + pp_hh;
854
      high = res2;
855
      low = res0;
856
    }
857
#endif
858
  }
859
 
860
  tmp->normal_exp = a->normal_exp + b->normal_exp;
861
  tmp->sign = a->sign != b->sign;
862
#ifdef FLOAT
863
  tmp->normal_exp += 2;         /* ??????????????? */
864
#else
865
  tmp->normal_exp += 4;         /* ??????????????? */
866
#endif
867
  while (high >= IMPLICIT_2)
868
    {
869
      tmp->normal_exp++;
870
      if (high & 1)
871
        {
872
          low >>= 1;
873
          low |= FRACHIGH;
874
        }
875
      high >>= 1;
876
    }
877
  while (high < IMPLICIT_1)
878
    {
879
      tmp->normal_exp--;
880
 
881
      high <<= 1;
882
      if (low & FRACHIGH)
883
        high |= 1;
884
      low <<= 1;
885
    }
886
  /* rounding is tricky. if we only round if it won't make us round later. */
887
#if 0
888
  if (low & FRACHIGH2)
889
    {
890
      if (((high & GARDMASK) != GARDMSB)
891
          && (((high + 1) & GARDMASK) == GARDMSB))
892
        {
893
          /* don't round, it gets done again later. */
894
        }
895
      else
896
        {
897
          high++;
898
        }
899
    }
900
#endif
901
  if ((high & GARDMASK) == GARDMSB)
902
    {
903
      if (high & (1 << NGARDS))
904
        {
905
          /* half way, so round to even */
906
          high += GARDROUND + 1;
907
        }
908
      else if (low)
909
        {
910
          /* but we really weren't half way */
911
          high += GARDROUND + 1;
912
        }
913
    }
914
  tmp->fraction.ll = high;
915
  tmp->class = CLASS_NUMBER;
916
  return tmp;
917
}
918
 
919
FLO_type
920
multiply (FLO_type arg_a, FLO_type arg_b)
921
{
922
  fp_number_type a;
923
  fp_number_type b;
924
  fp_number_type tmp;
925
  fp_number_type *res;
926
 
927
  unpack_d ((FLO_union_type *) & arg_a, &a);
928
  unpack_d ((FLO_union_type *) & arg_b, &b);
929
 
930
  res = _fpmul_parts (&a, &b, &tmp);
931
 
932
  return pack_d (res);
933
}
934
 
935
static fp_number_type *
936
_fpdiv_parts (fp_number_type * a,
937
              fp_number_type * b,
938
              fp_number_type * tmp)
939
{
940
  fractype low = 0;
941
  fractype high = 0;
942
  fractype r0, r1, y0, y1, bit;
943
  fractype q;
944
  fractype numerator;
945
  fractype denominator;
946
  fractype quotient;
947
  fractype remainder;
948
 
949
  if (isnan (a))
950
    {
951
      return a;
952
    }
953
  if (isnan (b))
954
    {
955
      return b;
956
    }
957
 
958
  a->sign = a->sign ^ b->sign;
959
 
960
  if (isinf (a) || iszero (a))
961
    {
962
      if (a->class == b->class)
963
        return nan ();
964
      return a;
965
    }
966
 
967
  if (isinf (b))
968
    {
969
      a->fraction.ll = 0;
970
      a->normal_exp = 0;
971
      return a;
972
    }
973
  if (iszero (b))
974
    {
975
      a->class = CLASS_INFINITY;
976
      return b;
977
    }
978
 
979
  /* Calculate the mantissa by multiplying both 64bit numbers to get a
980
     128 bit number */
981
  {
982
    int carry;
983
    intfrac d0, d1;             /* weren't unsigned before ??? */
984
 
985
    /* quotient =
986
       ( numerator / denominator) * 2^(numerator exponent -  denominator exponent)
987
     */
988
 
989
    a->normal_exp = a->normal_exp - b->normal_exp;
990
    numerator = a->fraction.ll;
991
    denominator = b->fraction.ll;
992
 
993
    if (numerator < denominator)
994
      {
995
        /* Fraction will be less than 1.0 */
996
        numerator *= 2;
997
        a->normal_exp--;
998
      }
999
    bit = IMPLICIT_1;
1000
    quotient = 0;
1001
    /* ??? Does divide one bit at a time.  Optimize.  */
1002
    while (bit)
1003
      {
1004
        if (numerator >= denominator)
1005
          {
1006
            quotient |= bit;
1007
            numerator -= denominator;
1008
          }
1009
        bit >>= 1;
1010
        numerator *= 2;
1011
      }
1012
 
1013
    if ((quotient & GARDMASK) == GARDMSB)
1014
      {
1015
        if (quotient & (1 << NGARDS))
1016
          {
1017
            /* half way, so round to even */
1018
            quotient += GARDROUND + 1;
1019
          }
1020
        else if (numerator)
1021
          {
1022
            /* but we really weren't half way, more bits exist */
1023
            quotient += GARDROUND + 1;
1024
          }
1025
      }
1026
 
1027
    a->fraction.ll = quotient;
1028
    return (a);
1029
  }
1030
}
1031
 
1032
FLO_type
1033
divide (FLO_type arg_a, FLO_type arg_b)
1034
{
1035
  fp_number_type a;
1036
  fp_number_type b;
1037
  fp_number_type tmp;
1038
  fp_number_type *res;
1039
 
1040
  unpack_d ((FLO_union_type *) & arg_a, &a);
1041
  unpack_d ((FLO_union_type *) & arg_b, &b);
1042
 
1043
  res = _fpdiv_parts (&a, &b, &tmp);
1044
 
1045
  return pack_d (res);
1046
}
1047
 
1048
/* according to the demo, fpcmp returns a comparison with 0... thus
1049
   a<b -> -1
1050
   a==b -> 0
1051
   a>b -> +1
1052
 */
1053
 
1054
static int
1055
_fpcmp_parts (fp_number_type * a, fp_number_type * b)
1056
{
1057
#if 0
1058
  /* either nan -> unordered. Must be checked outside of this routine. */
1059
  if (isnan (a) && isnan (b))
1060
    {
1061
      return 1;                 /* still unordered! */
1062
    }
1063
#endif
1064
 
1065
  if (isnan (a) || isnan (b))
1066
    {
1067
      return 1;                 /* how to indicate unordered compare? */
1068
    }
1069
  if (isinf (a) && isinf (b))
1070
    {
1071
      /* +inf > -inf, but +inf != +inf */
1072
      /* b    \a| +inf(0)| -inf(1)
1073
       ______\+--------+--------
1074
       +inf(0)| a==b(0)| a<b(-1)
1075
       -------+--------+--------
1076
       -inf(1)| a>b(1) | a==b(0)
1077
       -------+--------+--------
1078
       So since unordered must be non zero, just line up the columns...
1079
       */
1080
      return b->sign - a->sign;
1081
    }
1082
  /* but not both... */
1083
  if (isinf (a))
1084
    {
1085
      return a->sign ? -1 : 1;
1086
    }
1087
  if (isinf (b))
1088
    {
1089
      return b->sign ? 1 : -1;
1090
    }
1091
  if (iszero (a) && iszero (b))
1092
    {
1093
      return 0;
1094
    }
1095
  if (iszero (a))
1096
    {
1097
      return b->sign ? 1 : -1;
1098
    }
1099
  if (iszero (b))
1100
    {
1101
      return a->sign ? -1 : 1;
1102
    }
1103
  /* now both are "normal". */
1104
  if (a->sign != b->sign)
1105
    {
1106
      /* opposite signs */
1107
      return a->sign ? -1 : 1;
1108
    }
1109
  /* same sign; exponents? */
1110
  if (a->normal_exp > b->normal_exp)
1111
    {
1112
      return a->sign ? -1 : 1;
1113
    }
1114
  if (a->normal_exp < b->normal_exp)
1115
    {
1116
      return a->sign ? 1 : -1;
1117
    }
1118
  /* same exponents; check size. */
1119
  if (a->fraction.ll > b->fraction.ll)
1120
    {
1121
      return a->sign ? -1 : 1;
1122
    }
1123
  if (a->fraction.ll < b->fraction.ll)
1124
    {
1125
      return a->sign ? 1 : -1;
1126
    }
1127
  /* after all that, they're equal. */
1128
  return 0;
1129
}
1130
 
1131
CMPtype
1132
compare (FLO_type arg_a, FLO_type arg_b)
1133
{
1134
  fp_number_type a;
1135
  fp_number_type b;
1136
 
1137
  unpack_d ((FLO_union_type *) & arg_a, &a);
1138
  unpack_d ((FLO_union_type *) & arg_b, &b);
1139
 
1140
  return _fpcmp_parts (&a, &b);
1141
}
1142
 
1143
#ifndef US_SOFTWARE_GOFAST
1144
 
1145
/* These should be optimized for their specific tasks someday.  */
1146
 
1147
CMPtype
1148
_eq_f2 (FLO_type arg_a, FLO_type arg_b)
1149
{
1150
  fp_number_type a;
1151
  fp_number_type b;
1152
 
1153
  unpack_d ((FLO_union_type *) & arg_a, &a);
1154
  unpack_d ((FLO_union_type *) & arg_b, &b);
1155
 
1156
  if (isnan (&a) || isnan (&b))
1157
    return 1;                   /* false, truth == 0 */
1158
 
1159
  return _fpcmp_parts (&a, &b) ;
1160
}
1161
 
1162
CMPtype
1163
_ne_f2 (FLO_type arg_a, FLO_type arg_b)
1164
{
1165
  fp_number_type a;
1166
  fp_number_type b;
1167
 
1168
  unpack_d ((FLO_union_type *) & arg_a, &a);
1169
  unpack_d ((FLO_union_type *) & arg_b, &b);
1170
 
1171
  if (isnan (&a) || isnan (&b))
1172
    return 1;                   /* true, truth != 0 */
1173
 
1174
  return  _fpcmp_parts (&a, &b) ;
1175
}
1176
 
1177
CMPtype
1178
_gt_f2 (FLO_type arg_a, FLO_type arg_b)
1179
{
1180
  fp_number_type a;
1181
  fp_number_type b;
1182
 
1183
  unpack_d ((FLO_union_type *) & arg_a, &a);
1184
  unpack_d ((FLO_union_type *) & arg_b, &b);
1185
 
1186
  if (isnan (&a) || isnan (&b))
1187
    return -1;                  /* false, truth > 0 */
1188
 
1189
  return _fpcmp_parts (&a, &b);
1190
}
1191
 
1192
CMPtype
1193
_ge_f2 (FLO_type arg_a, FLO_type arg_b)
1194
{
1195
  fp_number_type a;
1196
  fp_number_type b;
1197
 
1198
  unpack_d ((FLO_union_type *) & arg_a, &a);
1199
  unpack_d ((FLO_union_type *) & arg_b, &b);
1200
 
1201
  if (isnan (&a) || isnan (&b))
1202
    return -1;                  /* false, truth >= 0 */
1203
  return _fpcmp_parts (&a, &b) ;
1204
}
1205
 
1206
CMPtype
1207
_lt_f2 (FLO_type arg_a, FLO_type arg_b)
1208
{
1209
  fp_number_type a;
1210
  fp_number_type b;
1211
 
1212
  unpack_d ((FLO_union_type *) & arg_a, &a);
1213
  unpack_d ((FLO_union_type *) & arg_b, &b);
1214
 
1215
  if (isnan (&a) || isnan (&b))
1216
    return 1;                   /* false, truth < 0 */
1217
 
1218
  return _fpcmp_parts (&a, &b);
1219
}
1220
 
1221
CMPtype
1222
_le_f2 (FLO_type arg_a, FLO_type arg_b)
1223
{
1224
  fp_number_type a;
1225
  fp_number_type b;
1226
 
1227
  unpack_d ((FLO_union_type *) & arg_a, &a);
1228
  unpack_d ((FLO_union_type *) & arg_b, &b);
1229
 
1230
  if (isnan (&a) || isnan (&b))
1231
    return 1;                   /* false, truth <= 0 */
1232
 
1233
  return _fpcmp_parts (&a, &b) ;
1234
}
1235
 
1236
#endif /* ! US_SOFTWARE_GOFAST */
1237
 
1238
FLO_type
1239
si_to_float (SItype arg_a)
1240
{
1241
  fp_number_type in;
1242
 
1243
  in.class = CLASS_NUMBER;
1244
  in.sign = arg_a < 0;
1245
  if (!arg_a)
1246
    {
1247
      in.class = CLASS_ZERO;
1248
    }
1249
  else
1250
    {
1251
      in.normal_exp = FRACBITS + NGARDS;
1252
      if (in.sign)
1253
        {
1254
          /* Special case for minint, since there is no +ve integer
1255
             representation for it */
1256
          if (arg_a == 0x80000000)
1257
            {
1258
              return -2147483648.0;
1259
            }
1260
          in.fraction.ll = (-arg_a);
1261
        }
1262
      else
1263
        in.fraction.ll = arg_a;
1264
 
1265
      while (in.fraction.ll < (1LL << (FRACBITS + NGARDS)))
1266
        {
1267
          in.fraction.ll <<= 1;
1268
          in.normal_exp -= 1;
1269
        }
1270
    }
1271
  return pack_d (&in);
1272
}
1273
 
1274
SItype
1275
float_to_si (FLO_type arg_a)
1276
{
1277
  fp_number_type a;
1278
  SItype tmp;
1279
 
1280
  unpack_d ((FLO_union_type *) & arg_a, &a);
1281
  if (iszero (&a))
1282
    return 0;
1283
  if (isnan (&a))
1284
    return 0;
1285
  /* get reasonable MAX_SI_INT... */
1286
  if (isinf (&a))
1287
    return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
1288
  /* it is a number, but a small one */
1289
  if (a.normal_exp < 0)
1290
    return 0;
1291
  if (a.normal_exp > 30)
1292
    return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
1293
  tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
1294
  return a.sign ? (-tmp) : (tmp);
1295
}
1296
 
1297
#ifdef US_SOFTWARE_GOFAST
1298
/* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines,
1299
   we also define them for GOFAST because the ones in libgcc2.c have the
1300
   wrong names and I'd rather define these here and keep GOFAST CYG-LOC's
1301
   out of libgcc2.c.  We can't define these here if not GOFAST because then
1302
   there'd be duplicate copies.  */
1303
 
1304
USItype
1305
float_to_usi (FLO_type arg_a)
1306
{
1307
  fp_number_type a;
1308
 
1309
  unpack_d ((FLO_union_type *) & arg_a, &a);
1310
  if (iszero (&a))
1311
    return 0;
1312
  if (isnan (&a))
1313
    return 0;
1314
  /* it is a negative number */
1315
  if (a.sign)
1316
    return 0;
1317
  /* get reasonable MAX_USI_INT... */
1318
  if (isinf (&a))
1319
    return MAX_USI_INT;
1320
  /* it is a number, but a small one */
1321
  if (a.normal_exp < 0)
1322
    return 0;
1323
  if (a.normal_exp > 31)
1324
    return MAX_USI_INT;
1325
  else if (a.normal_exp > (FRACBITS + NGARDS))
1326
    return a.fraction.ll << (a.normal_exp - (FRACBITS + NGARDS));
1327
  else
1328
    return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
1329
}
1330
#endif
1331
 
1332
FLO_type
1333
negate (FLO_type arg_a)
1334
{
1335
  fp_number_type a;
1336
 
1337
  unpack_d ((FLO_union_type *) & arg_a, &a);
1338
  flip_sign (&a);
1339
  return pack_d (&a);
1340
}
1341
 
1342
#ifdef FLOAT
1343
 
1344
SFtype
1345
__make_fp(fp_class_type class,
1346
             unsigned int sign,
1347
             int exp,
1348
             USItype frac)
1349
{
1350
  fp_number_type in;
1351
 
1352
  in.class = class;
1353
  in.sign = sign;
1354
  in.normal_exp = exp;
1355
  in.fraction.ll = frac;
1356
  return pack_d (&in);
1357
}
1358
 
1359
#ifndef FLOAT_ONLY
1360
 
1361
/* This enables one to build an fp library that supports float but not double.
1362
   Otherwise, we would get an undefined reference to __make_dp.
1363
   This is needed for some 8-bit ports that can't handle well values that
1364
   are 8-bytes in size, so we just don't support double for them at all.  */
1365
 
1366
extern DFtype __make_dp (fp_class_type, unsigned int, int, UDItype frac);
1367
 
1368
DFtype
1369
sf_to_df (SFtype arg_a)
1370
{
1371
  fp_number_type in;
1372
 
1373
  unpack_d ((FLO_union_type *) & arg_a, &in);
1374
  return __make_dp (in.class, in.sign, in.normal_exp,
1375
                    ((UDItype) in.fraction.ll) << F_D_BITOFF);
1376
}
1377
 
1378
#endif
1379
#endif
1380
 
1381
#ifndef FLOAT
1382
 
1383
extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
1384
 
1385
DFtype
1386
__make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac)
1387
{
1388
  fp_number_type in;
1389
 
1390
  in.class = class;
1391
  in.sign = sign;
1392
  in.normal_exp = exp;
1393
  in.fraction.ll = frac;
1394
  return pack_d (&in);
1395
}
1396
 
1397
SFtype
1398
df_to_sf (DFtype arg_a)
1399
{
1400
  fp_number_type in;
1401
  USItype sffrac;
1402
 
1403
  unpack_d ((FLO_union_type *) & arg_a, &in);
1404
 
1405
  sffrac = in.fraction.ll >> F_D_BITOFF;
1406
 
1407
  /* We set the lowest guard bit in SFFRAC if we discarded any non
1408
     zero bits.  */
1409
  if ((in.fraction.ll & (((USItype) 1 << F_D_BITOFF) - 1)) != 0)
1410
    sffrac |= 1;
1411
 
1412
  return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
1413
}
1414
 
1415
#endif
1416
#endif /* !EXTENDED_FLOAT_STUBS */

powered by: WebSVN 2.1.0

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