1/*
2** libgcc support for software floating point.
3** Copyright (C) 1991 by Pipeline Associates, Inc.  All rights reserved.
4** Permission is granted to do *anything* you want with this file,
5** commercial or otherwise, provided this message remains intact.  So there!
6** I would appreciate receiving any updates/patches/changes that anyone
7** makes, and am willing to be the repository for said changes (am I
8** making a big mistake?).
9
10Warning! Only single-precision is actually implemented.  This file
11won't really be much use until double-precision is supported.
12
13However, once that is done, this file might eventually become a
14replacement for libgcc1.c.  It might also make possible
15cross-compilation for an IEEE target machine from a non-IEEE
16host such as a VAX.
17
18If you'd like to work on completing this, please talk to rms@gnu.ai.mit.edu.
19
20--> Double precision floating support added by James Carlson on 20 April 1998.
21
22**
23** Pat Wood
24** Pipeline Associates, Inc.
25** pipeline!phw@motown.com or
26** sun!pipeline!phw or
27** uunet!motown!pipeline!phw
28**
29** 05/01/91 -- V1.0 -- first release to gcc mailing lists
30** 05/04/91 -- V1.1 -- added float and double prototypes and return values
31**                  -- fixed problems with adding and subtracting zero
32**                  -- fixed rounding in truncdfsf2
33**                  -- fixed SWAP define and tested on 386
34*/
35
36/*
37** The following are routines that replace the libgcc soft floating point
38** routines that are called automatically when -msoft-float is selected.
39** The support single and double precision IEEE format, with provisions
40** for byte-swapped machines (tested on 386).  Some of the double-precision
41** routines work at full precision, but most of the hard ones simply punt
42** and call the single precision routines, producing a loss of accuracy.
43** long long support is not assumed or included.
44** Overall accuracy is close to IEEE (actually 68882) for single-precision
45** arithmetic.  I think there may still be a 1 in 1000 chance of a bit
46** being rounded the wrong way during a multiply.  I'm not fussy enough to
47** bother with it, but if anyone is, knock yourself out.
48**
49** Efficiency has only been addressed where it was obvious that something
50** would make a big difference.  Anyone who wants to do this right for
51** best speed should go in and rewrite in assembler.
52**
53** I have tested this only on a 68030 workstation and 386/ix integrated
54** in with -msoft-float.
55*/
56
57/* the following deal with IEEE single-precision numbers */
58#define EXCESS		126
59#define SIGNBIT		0x80000000
60#define HIDDEN		(1 << 23)
61#define SIGN(fp)	((fp) & SIGNBIT)
62#define EXP(fp)		(((fp) >> 23) & 0xFF)
63#define MANT(fp)	(((fp) & 0x7FFFFF) | HIDDEN)
64#define PACK(s,e,m)	((s) | ((e) << 23) | (m))
65
66/* the following deal with IEEE double-precision numbers */
67#define EXCESSD		1022
68#define HIDDEND		(1 << 20)
69#define EXPD(fp)	(((fp.l.upper) >> 20) & 0x7FF)
70#define SIGND(fp)	((fp.l.upper) & SIGNBIT)
71#define MANTD(fp)	(((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \
72				(fp.l.lower >> 22))
73#define HIDDEND_LL	((long long)1 << 52)
74#define MANTD_LL(fp)	((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
75#define PACKD_LL(s,e,m)	(((long long)((s)+((e)<<20))<<32)|(m))
76
77/* define SWAP for 386/960 reverse-byte-order brain-damaged CPUs */
78union double_long {
79    double d;
80#ifdef SWAP
81    struct {
82      unsigned long lower;
83      long upper;
84    } l;
85#else
86    struct {
87      long upper;
88      unsigned long lower;
89    } l;
90#endif
91    long long ll;
92};
93
94union float_long
95  {
96    float f;
97    long l;
98  };
99
100/* add two floats */
101float
102__addsf3 (float a1, float a2)
103{
104  register long mant1, mant2;
105  register union float_long fl1, fl2;
106  register int exp1, exp2;
107  int sign = 0;
108
109  fl1.f = a1;
110  fl2.f = a2;
111
112  /* check for zero args */
113  if (!fl1.l) {
114      fl1.f = fl2.f;
115      goto test_done;
116  }
117  if (!fl2.l)
118      goto test_done;
119
120  exp1 = EXP (fl1.l);
121  exp2 = EXP (fl2.l);
122
123  if (exp1 > exp2 + 25)
124      goto test_done;
125  if (exp2 > exp1 + 25) {
126      fl1.f = fl2.f;
127      goto test_done;
128  }
129
130  /* do everything in excess precision so's we can round later */
131  mant1 = MANT (fl1.l) << 6;
132  mant2 = MANT (fl2.l) << 6;
133
134  if (SIGN (fl1.l))
135    mant1 = -mant1;
136  if (SIGN (fl2.l))
137    mant2 = -mant2;
138
139  if (exp1 > exp2)
140    {
141      mant2 >>= exp1 - exp2;
142    }
143  else
144    {
145      mant1 >>= exp2 - exp1;
146      exp1 = exp2;
147    }
148  mant1 += mant2;
149
150  if (mant1 < 0)
151    {
152      mant1 = -mant1;
153      sign = SIGNBIT;
154    }
155  else if (!mant1) {
156      fl1.f = 0;
157      goto test_done;
158  }
159
160  /* normalize up */
161  while (!(mant1 & 0xE0000000))
162    {
163      mant1 <<= 1;
164      exp1--;
165    }
166
167  /* normalize down? */
168  if (mant1 & (1 << 30))
169    {
170      mant1 >>= 1;
171      exp1++;
172    }
173
174  /* round to even */
175  mant1 += (mant1 & 0x40) ? 0x20 : 0x1F;
176
177  /* normalize down? */
178  if (mant1 & (1 << 30))
179    {
180      mant1 >>= 1;
181      exp1++;
182    }
183
184  /* lose extra precision */
185  mant1 >>= 6;
186
187  /* turn off hidden bit */
188  mant1 &= ~HIDDEN;
189
190  /* pack up and go home */
191  fl1.l = PACK (sign, exp1, mant1);
192test_done:
193  return (fl1.f);
194}
195
196/* subtract two floats */
197float
198__subsf3 (float a1, float a2)
199{
200  register union float_long fl1, fl2;
201
202  fl1.f = a1;
203  fl2.f = a2;
204
205  /* check for zero args */
206  if (!fl2.l)
207    return (fl1.f);
208  if (!fl1.l)
209    return (-fl2.f);
210
211  /* twiddle sign bit and add */
212  fl2.l ^= SIGNBIT;
213  return __addsf3 (a1, fl2.f);
214}
215
216/* compare two floats */
217long
218__cmpsf2 (float a1, float a2)
219{
220  register union float_long fl1, fl2;
221
222  fl1.f = a1;
223  fl2.f = a2;
224
225  if (SIGN (fl1.l) && SIGN (fl2.l))
226    {
227      fl1.l ^= SIGNBIT;
228      fl2.l ^= SIGNBIT;
229    }
230  if (fl1.l < fl2.l)
231    return (-1);
232  if (fl1.l > fl2.l)
233    return (1);
234  return (0);
235}
236
237/* multiply two floats */
238float
239__mulsf3 (float a1, float a2)
240{
241  register union float_long fl1, fl2;
242  register unsigned long result;
243  register int exp;
244  int sign;
245
246  fl1.f = a1;
247  fl2.f = a2;
248
249  if (!fl1.l || !fl2.l) {
250      fl1.f = 0;
251      goto test_done;
252  }
253
254  /* compute sign and exponent */
255  sign = SIGN (fl1.l) ^ SIGN (fl2.l);
256  exp = EXP (fl1.l) - EXCESS;
257  exp += EXP (fl2.l);
258
259  fl1.l = MANT (fl1.l);
260  fl2.l = MANT (fl2.l);
261
262  /* the multiply is done as one 16x16 multiply and two 16x8 multiples */
263  result = (fl1.l >> 8) * (fl2.l >> 8);
264  result += ((fl1.l & 0xFF) * (fl2.l >> 8)) >> 8;
265  result += ((fl2.l & 0xFF) * (fl1.l >> 8)) >> 8;
266
267  result >>= 2;
268  if (result & 0x20000000)
269    {
270      /* round */
271      result += 0x20;
272      result >>= 6;
273    }
274  else
275    {
276      /* round */
277      result += 0x10;
278      result >>= 5;
279      exp--;
280    }
281  if (result & (HIDDEN<<1)) {
282    result >>= 1;
283    exp++;
284  }
285
286  result &= ~HIDDEN;
287
288  /* pack up and go home */
289  fl1.l = PACK (sign, exp, result);
290test_done:
291  return (fl1.f);
292}
293
294/* divide two floats */
295float
296__divsf3 (float a1, float a2)
297{
298  register union float_long fl1, fl2;
299  register int result;
300  register int mask;
301  register int exp, sign;
302
303  fl1.f = a1;
304  fl2.f = a2;
305
306  /* subtract exponents */
307  exp = EXP (fl1.l) - EXP (fl2.l) + EXCESS;
308
309  /* compute sign */
310  sign = SIGN (fl1.l) ^ SIGN (fl2.l);
311
312  /* divide by zero??? */
313  if (!fl2.l)
314    /* return NaN or -NaN */
315    return (sign ? 0xFFFFFFFF : 0x7FFFFFFF);
316
317  /* numerator zero??? */
318  if (!fl1.l)
319    return (0);
320
321  /* now get mantissas */
322  fl1.l = MANT (fl1.l);
323  fl2.l = MANT (fl2.l);
324
325  /* this assures we have 25 bits of precision in the end */
326  if (fl1.l < fl2.l)
327    {
328      fl1.l <<= 1;
329      exp--;
330    }
331
332  /* now we perform repeated subtraction of fl2.l from fl1.l */
333  mask = 0x1000000;
334  result = 0;
335  while (mask)
336    {
337      if (fl1.l >= fl2.l)
338	{
339	  result |= mask;
340	  fl1.l -= fl2.l;
341	}
342      fl1.l <<= 1;
343      mask >>= 1;
344    }
345
346  /* round */
347  result += 1;
348
349  /* normalize down */
350  exp++;
351  result >>= 1;
352
353  result &= ~HIDDEN;
354
355  /* pack up and go home */
356  fl1.l = PACK (sign, exp, result);
357  return (fl1.f);
358}
359
360/* convert int to double */
361double
362__floatsidf (register long a1)
363{
364  register int sign = 0, exp = 31 + EXCESSD;
365  union double_long dl;
366
367  if (!a1)
368    {
369      dl.l.upper = dl.l.lower = 0;
370      return (dl.d);
371    }
372
373  if (a1 < 0)
374    {
375      sign = SIGNBIT;
376      a1 = -a1;
377    }
378
379  while (a1 < 0x1000000)
380    {
381      a1 <<= 4;
382      exp -= 4;
383    }
384
385  while (a1 < 0x40000000)
386    {
387      a1 <<= 1;
388      exp--;
389    }
390
391  /* pack up and go home */
392  dl.l.upper = sign;
393  dl.l.upper |= exp << 20;
394  dl.l.upper |= (a1 >> 10) & ~HIDDEND;
395  dl.l.lower = a1 << 22;
396
397  return (dl.d);
398}
399
400double
401__floatdidf (register long long a1)
402{
403    register int exp = 63 + EXCESSD;
404    union double_long dl;
405
406    dl.l.upper = dl.l.lower = 0;
407    if (a1 == 0)
408	return (dl.d);
409
410    if (a1 < 0) {
411	dl.l.upper = SIGNBIT;
412	a1 = -a1;
413    }
414
415    while (a1 < (long long)1<<54) {
416	a1 <<= 8;
417	exp -= 8;
418    }
419    while (a1 < (long long)1<<62) {
420	a1 <<= 1;
421	exp -= 1;
422    }
423
424  /* pack up and go home */
425    dl.ll |= (a1 >> 10) & ~HIDDEND_LL;
426    dl.l.upper |= exp << 20;
427
428    return (dl.d);
429}
430
431float
432__floatsisf (register long a1)
433{
434    (float)__floatsidf(a1);
435}
436
437float
438__floatdisf (register long long a1)
439{
440    (float)__floatdidf(a1);
441}
442
443/* negate a float */
444float
445__negsf2 (float a1)
446{
447  register union float_long fl1;
448
449  fl1.f = a1;
450  if (!fl1.l)
451    return (0);
452
453  fl1.l ^= SIGNBIT;
454  return (fl1.f);
455}
456
457/* negate a double */
458double
459__negdf2 (double a1)
460{
461  register union double_long dl1;
462
463  dl1.d = a1;
464
465  if (!dl1.l.upper && !dl1.l.lower)
466      return (dl1.d);
467
468  dl1.l.upper ^= SIGNBIT;
469  return (dl1.d);
470}
471
472/* convert float to double */
473double
474__extendsfdf2 (float a1)
475{
476  register union float_long fl1;
477  register union double_long dl;
478  register int exp;
479
480  fl1.f = a1;
481
482  if (!fl1.l)
483    {
484      dl.l.upper = dl.l.lower = 0;
485      return (dl.d);
486    }
487
488  dl.l.upper = SIGN (fl1.l);
489  exp = EXP (fl1.l) - EXCESS + EXCESSD;
490  dl.l.upper |= exp << 20;
491  dl.l.upper |= (MANT (fl1.l) & ~HIDDEN) >> 3;
492  dl.l.lower = MANT (fl1.l) << 29;
493
494  return (dl.d);
495}
496
497/* convert double to float */
498float
499__truncdfsf2 (double a1)
500{
501  register int exp;
502  register long mant;
503  register union float_long fl;
504  register union double_long dl1;
505
506  dl1.d = a1;
507
508  if (!dl1.l.upper && !dl1.l.lower)
509    return (float)(0);
510
511  exp = EXPD (dl1) - EXCESSD + EXCESS;
512
513  /* shift double mantissa 6 bits so we can round */
514  mant = MANTD (dl1) >> 6;
515
516  /* now round and shift down */
517  mant += 1;
518  mant >>= 1;
519
520  /* did the round overflow? */
521  if (mant & 0xFE000000)
522    {
523      mant >>= 1;
524      exp++;
525    }
526
527  mant &= ~HIDDEN;
528
529  /* pack up and go home */
530  fl.l = PACK (SIGND (dl1), exp, mant);
531  return (fl.f);
532}
533
534/* compare two doubles */
535long
536__cmpdf2 (double a1, double a2)
537{
538  register union double_long dl1, dl2;
539
540  dl1.d = a1;
541  dl2.d = a2;
542
543  if (SIGND (dl1) && SIGND (dl2))
544    {
545      dl1.l.upper ^= SIGNBIT;
546      dl2.l.upper ^= SIGNBIT;
547    }
548  if (dl1.l.upper < dl2.l.upper)
549    return (-1);
550  if (dl1.l.upper > dl2.l.upper)
551    return (1);
552  if (dl1.l.lower < dl2.l.lower)
553    return (-1);
554  if (dl1.l.lower > dl2.l.lower)
555    return (1);
556  return (0);
557}
558
559/* convert double to int */
560long
561__fixdfsi (double a1)
562{
563  register union double_long dl1;
564  register int exp;
565  register long l;
566
567  dl1.d = a1;
568
569  if (!dl1.l.upper && !dl1.l.lower)
570    return (0);
571
572  exp = EXPD (dl1) - EXCESSD - 31;
573  l = MANTD (dl1);
574
575  if (exp > 0)
576      return SIGND(dl1) ? (1<<31) : ((1ul<<31)-1);
577
578  /* shift down until exp = 0 or l = 0 */
579  if (exp < 0 && exp > -32 && l)
580    l >>= -exp;
581  else
582    return (0);
583
584  return (SIGND (dl1) ? -l : l);
585}
586
587/* convert double to int */
588long long
589__fixdfdi (double a1)
590{
591    register union double_long dl1;
592    register int exp;
593    register long long l;
594
595    dl1.d = a1;
596
597    if (!dl1.l.upper && !dl1.l.lower)
598	return (0);
599
600    exp = EXPD (dl1) - EXCESSD - 64;
601    l = MANTD_LL(dl1);
602
603    if (exp > 0) {
604	l = (long long)1<<63;
605	if (!SIGND(dl1))
606	    l--;
607	return l;
608    }
609
610    /* shift down until exp = 0 or l = 0 */
611    if (exp < 0 && exp > -64 && l)
612	l >>= -exp;
613    else
614	return (0);
615
616    return (SIGND (dl1) ? -l : l);
617}
618
619/* convert double to unsigned int */
620unsigned long
621__fixunsdfsi (double a1)
622{
623  register union double_long dl1;
624  register int exp;
625  register unsigned long l;
626
627  dl1.d = a1;
628
629  if (!dl1.l.upper && !dl1.l.lower)
630    return (0);
631
632  exp = EXPD (dl1) - EXCESSD - 32;
633  l = (((((dl1.l.upper) & 0xFFFFF) | HIDDEND) << 11) | (dl1.l.lower >> 21));
634
635  if (exp > 0)
636    return (0xFFFFFFFFul);	/* largest integer */
637
638  /* shift down until exp = 0 or l = 0 */
639  if (exp < 0 && exp > -32 && l)
640    l >>= -exp;
641  else
642    return (0);
643
644  return (l);
645}
646
647/* convert double to unsigned int */
648unsigned long long
649__fixunsdfdi (double a1)
650{
651    register union double_long dl1;
652    register int exp;
653    register unsigned long long l;
654
655    dl1.d = a1;
656
657    if (dl1.ll == 0)
658	return (0);
659
660    exp = EXPD (dl1) - EXCESSD - 64;
661
662    l = dl1.ll;
663
664    if (exp > 0)
665	return (unsigned long long)-1;
666
667    /* shift down until exp = 0 or l = 0 */
668    if (exp < 0 && exp > -64 && l)
669	l >>= -exp;
670    else
671	return (0);
672
673    return (l);
674}
675
676/* addtwo doubles */
677double
678__adddf3 (double a1, double a2)
679{
680    register long long mant1, mant2;
681    register union double_long fl1, fl2;
682    register int exp1, exp2;
683    int sign = 0;
684
685    fl1.d = a1;
686    fl2.d = a2;
687
688    /* check for zero args */
689    if (!fl2.ll)
690	goto test_done;
691    if (!fl1.ll) {
692	fl1.d = fl2.d;
693	goto test_done;
694    }
695
696    exp1 = EXPD(fl1);
697    exp2 = EXPD(fl2);
698
699    if (exp1 > exp2 + 54)
700	goto test_done;
701    if (exp2 > exp1 + 54) {
702	fl1.d = fl2.d;
703	goto test_done;
704    }
705
706    /* do everything in excess precision so's we can round later */
707    mant1 = MANTD_LL(fl1) << 9;
708    mant2 = MANTD_LL(fl2) << 9;
709
710    if (SIGND(fl1))
711	mant1 = -mant1;
712    if (SIGND(fl2))
713	mant2 = -mant2;
714
715    if (exp1 > exp2)
716	mant2 >>= exp1 - exp2;
717    else {
718	mant1 >>= exp2 - exp1;
719	exp1 = exp2;
720    }
721    mant1 += mant2;
722
723    if (mant1 < 0) {
724	mant1 = -mant1;
725	sign = SIGNBIT;
726    } else if (!mant1) {
727	fl1.d = 0;
728	goto test_done;
729    }
730
731    /* normalize up */
732    while (!(mant1 & ((long long)7<<61))) {
733	mant1 <<= 1;
734	exp1--;
735    }
736
737    /* normalize down? */
738    if (mant1 & ((long long)3<<62)) {
739	mant1 >>= 1;
740	exp1++;
741    }
742
743    /* round to even */
744    mant1 += (mant1 & (1<<9)) ? (1<<8) : ((1<<8)-1);
745
746    /* normalize down? */
747    if (mant1 & ((long long)3<<62)) {
748	mant1 >>= 1;
749	exp1++;
750    }
751
752    /* lose extra precision */
753    mant1 >>= 9;
754
755    /* turn off hidden bit */
756    mant1 &= ~HIDDEND_LL;
757
758    /* pack up and go home */
759    fl1.ll = PACKD_LL(sign,exp1,mant1);
760
761test_done:
762    return (fl1.d);
763}
764
765/* subtract two doubles */
766double
767__subdf3 (double a1, double a2)
768{
769    register union double_long fl1, fl2;
770
771    fl1.d = a1;
772    fl2.d = a2;
773
774    /* check for zero args */
775    if (!fl2.ll)
776	return (fl1.d);
777    /* twiddle sign bit and add */
778    fl2.l.upper ^= SIGNBIT;
779    if (!fl1.ll)
780	return (fl2.d);
781    return __adddf3 (a1, fl2.d);
782}
783
784/* multiply two doubles */
785double
786__muldf3 (double a1, double a2)
787{
788    register union double_long fl1, fl2;
789    register unsigned long long result;
790    register int exp;
791    int sign;
792
793    fl1.d = a1;
794    fl2.d = a2;
795
796    if (!fl1.ll || !fl2.ll) {
797	fl1.d = 0;
798	goto test_done;
799    }
800
801    /* compute sign and exponent */
802    sign = SIGND(fl1) ^ SIGND(fl2);
803    exp = EXPD(fl1) - EXCESSD;
804    exp += EXPD(fl2);
805
806    fl1.ll = MANTD_LL(fl1);
807    fl2.ll = MANTD_LL(fl2);
808
809  /* the multiply is done as one 31x31 multiply and two 31x21 multiples */
810    result = (fl1.ll >> 21) * (fl2.ll >> 21);
811    result += ((fl1.ll & 0x1FFFFF) * (fl2.ll >> 21)) >> 21;
812    result += ((fl2.ll & 0x1FFFFF) * (fl1.ll >> 21)) >> 21;
813
814    result >>= 2;
815    if (result & ((long long)1<<61)) {
816	/* round */
817	result += 1<<8;
818	result >>= 9;
819    } else {
820	/* round */
821	result += 1<<7;
822	result >>= 8;
823	exp--;
824    }
825    if (result & (HIDDEND_LL<<1)) {
826	result >>= 1;
827	exp++;
828    }
829
830    result &= ~HIDDEND_LL;
831
832    /* pack up and go home */
833    fl1.ll = PACKD_LL(sign,exp,result);
834test_done:
835    return (fl1.d);
836}
837
838/* divide two doubles */
839double
840__divdf3 (double a1, double a2)
841{
842    register union double_long fl1, fl2;
843    register long long mask,result;
844    register int exp, sign;
845
846    fl1.d = a1;
847    fl2.d = a2;
848
849    /* subtract exponents */
850    exp = EXPD(fl1) - EXPD(fl2) + EXCESSD;
851
852    /* compute sign */
853    sign = SIGND(fl1) ^ SIGND(fl2);
854
855    /* numerator zero??? */
856    if (fl1.ll == 0) {
857	/* divide by zero??? */
858	if (fl2.ll == 0)
859	    fl1.ll = ((unsigned long long)1<<63)-1;	/* NaN */
860	else
861	    fl1.ll = 0;
862	goto test_done;
863    }
864
865    /* return +Inf or -Inf */
866    if (fl2.ll == 0) {
867	fl1.ll = PACKD_LL(SIGND(fl1),2047,0);
868	goto test_done;
869    }
870
871
872    /* now get mantissas */
873    fl1.ll = MANTD_LL(fl1);
874    fl2.ll = MANTD_LL(fl2);
875
876    /* this assures we have 54 bits of precision in the end */
877    if (fl1.ll < fl2.ll) {
878	fl1.ll <<= 1;
879	exp--;
880    }
881
882    /* now we perform repeated subtraction of fl2.ll from fl1.ll */
883    mask = (long long)1<<53;
884    result = 0;
885    while (mask) {
886	if (fl1.ll >= fl2.ll)
887	{
888	    result |= mask;
889	    fl1.ll -= fl2.ll;
890	}
891	fl1.ll <<= 1;
892	mask >>= 1;
893    }
894
895    /* round */
896    result += 1;
897
898    /* normalize down */
899    exp++;
900    result >>= 1;
901
902    result &= ~HIDDEND_LL;
903
904    /* pack up and go home */
905    fl1.ll = PACKD_LL(sign, exp, result);
906
907test_done:
908    return (fl1.d);
909}
910
911int
912__gtdf2 (double a1, double a2)
913{
914    return __cmpdf2 ((float) a1, (float) a2) > 0;
915}
916
917int
918__gedf2 (double a1, double a2)
919{
920    return (__cmpdf2 ((float) a1, (float) a2) >= 0) - 1;
921}
922
923int
924__ltdf2 (double a1, double a2)
925{
926    return - (__cmpdf2 ((float) a1, (float) a2) < 0);
927}
928
929int
930__ledf2 (double a1, double a2)
931{
932    return __cmpdf2 ((float) a1, (float) a2) > 0;
933}
934
935int
936__eqdf2 (double a1, double a2)
937{
938    return *(long long *) &a1 == *(long long *) &a2;
939}
940
941int
942__nedf2 (double a1, double a2)
943{
944    return *(long long *) &a1 != *(long long *) &a2;
945}
946