OSDN Git Service

* toplev.c (debug_args, f_options, W_options): Mark
[pf3gnuchains/gcc-fork.git] / gcc / floatlib.c
index bdcdf57..ed13903 100644 (file)
 Warning! Only single-precision is actually implemented.  This file
 won't really be much use until double-precision is supported.
 
-However, once that is done, this file might eventually become a
-replacement for libgcc1.c.  It might also make possible
+However, once that is done, this file might make possible
 cross-compilation for an IEEE target machine from a non-IEEE
 host such as a VAX.
 
 If you'd like to work on completing this, please talk to rms@gnu.ai.mit.edu.
 
+--> Double precision floating support added by James Carlson on 20 April 1998.
 
 **
 ** Pat Wood
@@ -54,7 +54,6 @@ If you'd like to work on completing this, please talk to rms@gnu.ai.mit.edu.
 */
 
 /* the following deal with IEEE single-precision numbers */
-#define D_PHANTOM_BIT   0x00100000
 #define EXCESS         126
 #define SIGNBIT                0x80000000
 #define HIDDEN         (1 << 23)
@@ -70,10 +69,12 @@ If you'd like to work on completing this, please talk to rms@gnu.ai.mit.edu.
 #define SIGND(fp)      ((fp.l.upper) & SIGNBIT)
 #define MANTD(fp)      (((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \
                                (fp.l.lower >> 22))
+#define HIDDEND_LL     ((long long)1 << 52)
+#define MANTD_LL(fp)   ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
+#define PACKD_LL(s,e,m)        (((long long)((s)+((e)<<20))<<32)|(m))
 
 /* define SWAP for 386/960 reverse-byte-order brain-damaged CPUs */
-union double_long
-  {
+union double_long {
     double d;
 #ifdef SWAP
     struct {
@@ -86,7 +87,8 @@ union double_long
       unsigned long lower;
     } l;
 #endif
-  };
+    long long ll;
+};
 
 union float_long
   {
@@ -94,38 +96,7 @@ union float_long
     long l;
   };
 
-   struct _ieee {
-#ifdef SWAP
-      unsigned mantissa2 : 32;
-      unsigned mantissa1 : 20;
-      unsigned exponent  : 11;
-      unsigned sign      : 1;
-#else
-      unsigned exponent  : 11;
-      unsigned sign      : 1;
-      unsigned mantissa2 : 32;
-      unsigned mantissa1 : 20;
-#endif
-   };
-
-   union _doubleu {
-      double d;
-      struct _ieee ieee;
-#ifdef SWAP
-      struct {
-         unsigned long lower;
-         long upper;
-      } l;
-#else
-      struct {
-         long upper;
-         unsigned long lower;
-      } l;
-#endif
-   };
-
 /* add two floats */
-
 float
 __addsf3 (float a1, float a2)
 {
@@ -138,18 +109,22 @@ __addsf3 (float a1, float a2)
   fl2.f = a2;
 
   /* check for zero args */
-  if (!fl1.l)
-    return (fl2.f);
+  if (!fl1.l) {
+      fl1.f = fl2.f;
+      goto test_done;
+  }
   if (!fl2.l)
-    return (fl1.f);
+      goto test_done;
 
   exp1 = EXP (fl1.l);
   exp2 = EXP (fl2.l);
 
   if (exp1 > exp2 + 25)
-    return (fl1.l);
-  if (exp2 > exp1 + 25)
-    return (fl2.l);
+      goto test_done;
+  if (exp2 > exp1 + 25) {
+      fl1.f = fl2.f;
+      goto test_done;
+  }
 
   /* do everything in excess precision so's we can round later */
   mant1 = MANT (fl1.l) << 6;
@@ -176,8 +151,10 @@ __addsf3 (float a1, float a2)
       mant1 = -mant1;
       sign = SIGNBIT;
     }
-  else if (!mant1)
-    return (0);
+  else if (!mant1) {
+      fl1.f = 0;
+      goto test_done;
+  }
 
   /* normalize up */
   while (!(mant1 & 0xE0000000))
@@ -211,11 +188,11 @@ __addsf3 (float a1, float a2)
 
   /* pack up and go home */
   fl1.l = PACK (sign, exp1, mant1);
+test_done:
   return (fl1.f);
 }
 
 /* subtract two floats */
-
 float
 __subsf3 (float a1, float a2)
 {
@@ -236,7 +213,6 @@ __subsf3 (float a1, float a2)
 }
 
 /* compare two floats */
-
 long
 __cmpsf2 (float a1, float a2)
 {
@@ -258,7 +234,6 @@ __cmpsf2 (float a1, float a2)
 }
 
 /* multiply two floats */
-
 float
 __mulsf3 (float a1, float a2)
 {
@@ -270,8 +245,10 @@ __mulsf3 (float a1, float a2)
   fl1.f = a1;
   fl2.f = a2;
 
-  if (!fl1.l || !fl2.l)
-    return (0);
+  if (!fl1.l || !fl2.l) {
+      fl1.f = 0;
+      goto test_done;
+  }
 
   /* compute sign and exponent */
   sign = SIGN (fl1.l) ^ SIGN (fl2.l);
@@ -286,29 +263,34 @@ __mulsf3 (float a1, float a2)
   result += ((fl1.l & 0xFF) * (fl2.l >> 8)) >> 8;
   result += ((fl2.l & 0xFF) * (fl1.l >> 8)) >> 8;
 
-  if (result & 0x80000000)
+  result >>= 2;
+  if (result & 0x20000000)
     {
       /* round */
-      result += 0x80;
-      result >>= 8;
+      result += 0x20;
+      result >>= 6;
     }
   else
     {
       /* round */
-      result += 0x40;
-      result >>= 7;
+      result += 0x10;
+      result >>= 5;
       exp--;
     }
+  if (result & (HIDDEN<<1)) {
+    result >>= 1;
+    exp++;
+  }
 
   result &= ~HIDDEN;
 
   /* pack up and go home */
   fl1.l = PACK (sign, exp, result);
+test_done:
   return (fl1.f);
 }
 
 /* divide two floats */
-
 float
 __divsf3 (float a1, float a2)
 {
@@ -375,7 +357,6 @@ __divsf3 (float a1, float a2)
 }
 
 /* convert int to double */
-
 double
 __floatsidf (register long a1)
 {
@@ -415,9 +396,51 @@ __floatsidf (register long a1)
   return (dl.d);
 }
 
-/* negate a float */
+double
+__floatdidf (register long long a1)
+{
+    register int exp = 63 + EXCESSD;
+    union double_long dl;
+
+    dl.l.upper = dl.l.lower = 0;
+    if (a1 == 0)
+       return (dl.d);
+
+    if (a1 < 0) {
+       dl.l.upper = SIGNBIT;
+       a1 = -a1;
+    }
+
+    while (a1 < (long long)1<<54) {
+       a1 <<= 8;
+       exp -= 8;
+    }
+    while (a1 < (long long)1<<62) {
+       a1 <<= 1;
+       exp -= 1;
+    }
+
+  /* pack up and go home */
+    dl.ll |= (a1 >> 10) & ~HIDDEND_LL;
+    dl.l.upper |= exp << 20;
+
+    return (dl.d);
+}
 
 float
+__floatsisf (register long a1)
+{
+    (float)__floatsidf(a1);
+}
+
+float
+__floatdisf (register long long a1)
+{
+    (float)__floatdidf(a1);
+}
+
+/* negate a float */
+float
 __negsf2 (float a1)
 {
   register union float_long fl1;
@@ -431,7 +454,6 @@ __negsf2 (float a1)
 }
 
 /* negate a double */
-
 double
 __negdf2 (double a1)
 {
@@ -447,7 +469,6 @@ __negdf2 (double a1)
 }
 
 /* convert float to double */
-
 double
 __extendsfdf2 (float a1)
 {
@@ -473,7 +494,6 @@ __extendsfdf2 (float a1)
 }
 
 /* convert double to float */
-
 float
 __truncdfsf2 (double a1)
 {
@@ -485,7 +505,7 @@ __truncdfsf2 (double a1)
   dl1.d = a1;
 
   if (!dl1.l.upper && !dl1.l.lower)
-    return (0);
+    return (float)(0);
 
   exp = EXPD (dl1) - EXCESSD + EXCESS;
 
@@ -497,7 +517,7 @@ __truncdfsf2 (double a1)
   mant >>= 1;
 
   /* did the round overflow? */
-  if (mant & 0xFF000000)
+  if (mant & 0xFE000000)
     {
       mant >>= 1;
       exp++;
@@ -511,7 +531,6 @@ __truncdfsf2 (double a1)
 }
 
 /* compare two doubles */
-
 long
 __cmpdf2 (double a1, double a2)
 {
@@ -537,7 +556,6 @@ __cmpdf2 (double a1, double a2)
 }
 
 /* convert double to int */
-
 long
 __fixdfsi (double a1)
 {
@@ -554,7 +572,7 @@ __fixdfsi (double a1)
   l = MANTD (dl1);
 
   if (exp > 0)
-    return (0x7FFFFFFF | SIGND (dl1)); /* largest integer */
+      return SIGND(dl1) ? (1<<31) : ((1ul<<31)-1);
 
   /* shift down until exp = 0 or l = 0 */
   if (exp < 0 && exp > -32 && l)
@@ -565,10 +583,41 @@ __fixdfsi (double a1)
   return (SIGND (dl1) ? -l : l);
 }
 
-/* convert double to unsigned int */
+/* convert double to int */
+long long
+__fixdfdi (double a1)
+{
+    register union double_long dl1;
+    register int exp;
+    register long long l;
+
+    dl1.d = a1;
+
+    if (!dl1.l.upper && !dl1.l.lower)
+       return (0);
+
+    exp = EXPD (dl1) - EXCESSD - 64;
+    l = MANTD_LL(dl1);
+
+    if (exp > 0) {
+       l = (long long)1<<63;
+       if (!SIGND(dl1))
+           l--;
+       return l;
+    }
+
+    /* shift down until exp = 0 or l = 0 */
+    if (exp < 0 && exp > -64 && l)
+       l >>= -exp;
+    else
+       return (0);
+
+    return (SIGND (dl1) ? -l : l);
+}
 
-unsigned
-long __fixunsdfsi (double a1)
+/* convert double to unsigned int */
+unsigned long
+__fixunsdfsi (double a1)
 {
   register union double_long dl1;
   register int exp;
@@ -583,7 +632,7 @@ long __fixunsdfsi (double a1)
   l = (((((dl1.l.upper) & 0xFFFFF) | HIDDEND) << 11) | (dl1.l.lower >> 21));
 
   if (exp > 0)
-    return (0xFFFFFFFF);       /* largest integer */
+    return (0xFFFFFFFFul);     /* largest integer */
 
   /* shift down until exp = 0 or l = 0 */
   if (exp < 0 && exp > -32 && l)
@@ -594,245 +643,302 @@ long __fixunsdfsi (double a1)
   return (l);
 }
 
-/* For now, the hard double-precision routines simply
-   punt and do it in single */
-/* addtwo doubles */
-
-double
-__adddf3 (double a1, double a2)
-{
-  return ((float) a1 + (float) a2);
-}
-
-/* subtract two doubles */
-
-double
-__subdf3 (double a1, double a2)
-{
-  return ((float) a1 - (float) a2);
-}
-
-/* multiply two doubles */
-
-double
-__muldf3 (double a1, double a2)
+/* convert double to unsigned int */
+unsigned long long
+__fixunsdfdi (double a1)
 {
-  return ((float) a1 * (float) a2);
-}
-
-/*
- *
- * Name:   Barrett Richardson
- * E-mail: barrett@iglou.com
- * When:   Thu Dec 15 10:31:11 EST 1994
- *
- *    callable function:
- *
- *       double __divdf3(double a1, double a2);
- *
- *       Does software divide of a1 / a2.
- *
- *       Based largely on __divsf3() in floatlib.c in the gcc
- *       distribution.
- *
- *    Purpose: To be used in conjunction with the -msoft-float
- *             option of gcc. You should be able to tack it to the
- *             end of floatlib.c included in the gcc distribution,
- *             and delete the __divdf3() already there which just 
- *             calls the single precision function (or may just
- *             use the floating point processor with some configurations).
- *
- *   You may use this code for whatever your heart desires.
- */
+    register union double_long dl1;
+    register int exp;
+    register unsigned long long l;
 
+    dl1.d = a1;
 
+    if (dl1.ll == 0)
+       return (0);
 
+    exp = EXPD (dl1) - EXCESSD - 64;
 
-/*
- * Compare the the mantissas of two doubles.
- * Each mantissa is in two longs.
- * 
- *   return      1   if x1's mantissa is greater than x2's
- *              -1   if x1's mantissa is less than x2's
- *               0   if the two mantissa's are equal.
- *
- *   The Mantissas won't fit into a 4 byte word, so they are
- *   broken up into two parts.
- *
- *   This function is used internally by __divdf3()
- */
-
-int
-__dcmp (long x1m1, long x1m2, long x2m1, long x2m2)
-{
-   if (x1m1 > x2m1)
-      return 1;
-
-   if (x1m1 < x2m1)
-      return -1;
+    l = dl1.ll;
 
- /*  If the first word in the two mantissas were equal check the second word */
+    if (exp > 0)
+       return (unsigned long long)-1;
 
-   if (x1m2 > x2m2)
-      return 1;
+    /* shift down until exp = 0 or l = 0 */
+    if (exp < 0 && exp > -64 && l)
+       l >>= -exp;
+    else
+       return (0);
 
-   if (x1m2 < x2m2)
-      return -1;
-
-   return 0;
+    return (l);
 }
 
-
-/* divide two doubles */
-
+/* addtwo doubles */
 double
-__divdf3 (double a1, double a2)
+__adddf3 (double a1, double a2)
 {
+    register long long mant1, mant2;
+    register union double_long fl1, fl2;
+    register int exp1, exp2;
+    int sign = 0;
+
+    fl1.d = a1;
+    fl2.d = a2;
+
+    /* check for zero args */
+    if (!fl2.ll)
+       goto test_done;
+    if (!fl1.ll) {
+       fl1.d = fl2.d;
+       goto test_done;
+    }
 
-   int  sign,
-        exponent,
-        bit_bucket;
-
-   register unsigned long mantissa1,
-                          mantissa2,
-                          x1m1,
-                          x1m2,
-                          x2m1,
-                          x2m2,
-                          mask;
-
-   union _doubleu x1,
-                  x2,
-                  result;
-
-
-   x1.d = a1;
-   x2.d = a2;
-
-   exponent = x1.ieee.exponent - x2.ieee.exponent + EXCESSD;
-
-   sign = x1.ieee.sign ^ x2.ieee.sign;
-
-   x2.ieee.sign = 0;  /* don't want the sign bit to affect any zero */
-                      /* comparisons when checking for zero divide  */
-
-   if (!x2.l.lower && !x2.l.upper) { /* check for zero divide */
-      result.l.lower = 0x0;
-      if (sign)
-         result.l.upper = 0xFFF00000;   /* negative infinity */
-      else
-         result.l.upper = 0x7FF00000;   /* positive infinity */
-      return result.d;
-   }
+    exp1 = EXPD(fl1);
+    exp2 = EXPD(fl2);
 
-   if (!x1.l.upper && !x1.l.lower)  /* check for 0.0 numerator */
-      return (0.0);
+    if (exp1 > exp2 + 54)
+       goto test_done;
+    if (exp2 > exp1 + 54) {
+       fl1.d = fl2.d;
+       goto test_done;
+    }
 
-   x1m1 = x1.ieee.mantissa1 | D_PHANTOM_BIT;  /* turn on phantom bit */
-   x1m2 = x1.ieee.mantissa2;
+    /* do everything in excess precision so's we can round later */
+    mant1 = MANTD_LL(fl1) << 9;
+    mant2 = MANTD_LL(fl2) << 9;
 
-   x2m1 = x2.ieee.mantissa1 | D_PHANTOM_BIT;  /* turn on phantom bit */
-   x2m2 = x2.ieee.mantissa2;
+    if (SIGND(fl1))
+       mant1 = -mant1;
+    if (SIGND(fl2))
+       mant2 = -mant2;
 
-   if (__dcmp(x1m1,x1m2,x2m1,x2m2) < 0) {
+    if (exp1 > exp2)
+       mant2 >>= exp1 - exp2;
+    else {
+       mant1 >>= exp2 - exp1;
+       exp1 = exp2;
+    }
+    mant1 += mant2;
+
+    if (mant1 < 0) {
+       mant1 = -mant1;
+       sign = SIGNBIT;
+    } else if (!mant1) {
+       fl1.d = 0;
+       goto test_done;
+    }
 
-   /* if x1's mantissa is less than x2's shift it left one and decrement */
-   /* the exponent to accomodate the change in the mantissa              */
+    /* normalize up */
+    while (!(mant1 & ((long long)7<<61))) {
+       mant1 <<= 1;
+       exp1--;
+    }
 
-      x1m1 <<= 1;               /*                          */
-      bit_bucket = x1m2 >> 31;  /*  Shift mantissa left one */
-      x1m1 |= bit_bucket;       /*                          */
-      x1m2 <<= 1;               /*                          */
+    /* normalize down? */
+    if (mant1 & ((long long)3<<62)) {
+       mant1 >>= 1;
+       exp1++;
+    }
 
-      exponent--;
-   }
+    /* round to even */
+    mant1 += (mant1 & (1<<9)) ? (1<<8) : ((1<<8)-1);
 
+    /* normalize down? */
+    if (mant1 & ((long long)3<<62)) {
+       mant1 >>= 1;
+       exp1++;
+    }
 
-   mantissa1 = 0;
-   mantissa2 = 0;
+    /* lose extra precision */
+    mant1 >>= 9;
 
+    /* turn off hidden bit */
+    mant1 &= ~HIDDEND_LL;
 
-  /* Get the first part of the results mantissa using successive */
-  /* subtraction.                                                */
+    /* pack up and go home */
+    fl1.ll = PACKD_LL(sign,exp1,mant1);
 
-   mask = 0x00200000;
-   while (mask) {
+test_done:
+    return (fl1.d);
+}
 
-      if (__dcmp(x1m1,x1m2,x2m1,x2m2) >= 0) {
+/* subtract two doubles */
+double
+__subdf3 (double a1, double a2)
+{
+    register union double_long fl1, fl2;
+
+    fl1.d = a1;
+    fl2.d = a2;
+
+    /* check for zero args */
+    if (!fl2.ll)
+       return (fl1.d);
+    /* twiddle sign bit and add */
+    fl2.l.upper ^= SIGNBIT;
+    if (!fl1.ll)
+       return (fl2.d);
+    return __adddf3 (a1, fl2.d);
+}
 
-     /* subtract x2's mantissa from x1's */
+/* multiply two doubles */
+double
+__muldf3 (double a1, double a2)
+{
+    register union double_long fl1, fl2;
+    register unsigned long long result;
+    register int exp;
+    int sign;
 
-         mantissa1 |= mask;   /* turn on a bit in the result */
+    fl1.d = a1;
+    fl2.d = a2;
 
-         if (x2m2 > x1m2)
-            x1m1--;
-         x1m2 -= x2m2; 
-         x1m1 -= x2m1;
-      }
+    if (!fl1.ll || !fl2.ll) {
+       fl1.d = 0;
+       goto test_done;
+    }
 
-      x1m1 <<= 1;               /*                          */
-      bit_bucket = x1m2 >> 31;  /*  Shift mantissa left one */
-      x1m1 |= bit_bucket;       /*                          */
-      x1m2 <<= 1;               /*                          */
+    /* compute sign and exponent */
+    sign = SIGND(fl1) ^ SIGND(fl2);
+    exp = EXPD(fl1) - EXCESSD;
+    exp += EXPD(fl2);
+
+    fl1.ll = MANTD_LL(fl1);
+    fl2.ll = MANTD_LL(fl2);
+
+  /* the multiply is done as one 31x31 multiply and two 31x21 multiples */
+    result = (fl1.ll >> 21) * (fl2.ll >> 21);
+    result += ((fl1.ll & 0x1FFFFF) * (fl2.ll >> 21)) >> 21;
+    result += ((fl2.ll & 0x1FFFFF) * (fl1.ll >> 21)) >> 21;
+
+    result >>= 2;
+    if (result & ((long long)1<<61)) {
+       /* round */
+       result += 1<<8;
+       result >>= 9;
+    } else {
+       /* round */
+       result += 1<<7;
+       result >>= 8;
+       exp--;
+    }
+    if (result & (HIDDEND_LL<<1)) {
+       result >>= 1;
+       exp++;
+    }
 
-      mask >>= 1;
-   }
+    result &= ~HIDDEND_LL;
 
-  /* Get the second part of the results mantissa using successive */
-  /* subtraction.                                                 */
+    /* pack up and go home */
+    fl1.ll = PACKD_LL(sign,exp,result);
+test_done:
+    return (fl1.d);
+}
 
-   mask = 0x80000000;
-   while (mask) {
+/* divide two doubles */
+double
+__divdf3 (double a1, double a2)
+{
+    register union double_long fl1, fl2;
+    register long long mask,result;
+    register int exp, sign;
+
+    fl1.d = a1;
+    fl2.d = a2;
+
+    /* subtract exponents */
+    exp = EXPD(fl1) - EXPD(fl2) + EXCESSD;
+
+    /* compute sign */
+    sign = SIGND(fl1) ^ SIGND(fl2);
+
+    /* numerator zero??? */
+    if (fl1.ll == 0) {
+       /* divide by zero??? */
+       if (fl2.ll == 0)
+           fl1.ll = ((unsigned long long)1<<63)-1;     /* NaN */
+       else
+           fl1.ll = 0;
+       goto test_done;
+    }
 
-      if (__dcmp(x1m1,x1m2,x2m1,x2m2) >= 0) {
+    /* return +Inf or -Inf */
+    if (fl2.ll == 0) {
+       fl1.ll = PACKD_LL(SIGND(fl1),2047,0);
+       goto test_done;
+    }
 
-     /* subtract x2's mantissa from x1's */
 
-         mantissa2 |= mask;   /* turn on a bit in the result */
+    /* now get mantissas */
+    fl1.ll = MANTD_LL(fl1);
+    fl2.ll = MANTD_LL(fl2);
 
-         if (x2m2 > x1m2)
-            x1m1--;
-         x1m2 -= x2m2; 
-         x1m1 -= x2m1;
-      }
-      x1m1 <<= 1;               /*                          */
-      bit_bucket = x1m2 >> 31;  /*  Shift mantissa left one */
-      x1m1 |= bit_bucket;       /*                          */
-      x1m2 <<= 1;               /*                          */
+    /* this assures we have 54 bits of precision in the end */
+    if (fl1.ll < fl2.ll) {
+       fl1.ll <<= 1;
+       exp--;
+    }
 
-      mask >>= 1;
-   }
+    /* now we perform repeated subtraction of fl2.ll from fl1.ll */
+    mask = (long long)1<<53;
+    result = 0;
+    while (mask) {
+       if (fl1.ll >= fl2.ll)
+       {
+           result |= mask;
+           fl1.ll -= fl2.ll;
+       }
+       fl1.ll <<= 1;
+       mask >>= 1;
+    }
 
-  /* round up by adding 1 to mantissa */
+    /* round */
+    result += 1;
 
-   if (mantissa2 == 0xFFFFFFFF) {  /* check for over flow */
+    /* normalize down */
+    exp++;
+    result >>= 1;
 
-   /* spill if overflow */
+    result &= ~HIDDEND_LL;
 
-      mantissa2 = 0;
-      mantissa1++;
-   }
-   else
-      mantissa2++;
+    /* pack up and go home */
+    fl1.ll = PACKD_LL(sign, exp, result);
 
-   exponent++;   /* increment exponent (mantissa must be shifted right */
-                 /* also)                                              */
+test_done:
+    return (fl1.d);
+}
 
- /* shift mantissa right one and assume a phantom bit (which really gives */
- /* 53 bits of precision in the mantissa)                                 */
+int
+__gtdf2 (double a1, double a2)
+{
+    return __cmpdf2 ((float) a1, (float) a2) > 0;
+}
 
-   mantissa2 >>= 1;
-   bit_bucket = mantissa1 & 1;
-   mantissa2 |= (bit_bucket << 31);
-   mantissa1 >>= 1;
+int
+__gedf2 (double a1, double a2)
+{
+    return (__cmpdf2 ((float) a1, (float) a2) >= 0) - 1;
+}
 
-  /* put all the info into the result */
+int
+__ltdf2 (double a1, double a2)
+{
+    return - (__cmpdf2 ((float) a1, (float) a2) < 0);
+}
 
-   result.ieee.exponent  = exponent;
-   result.ieee.sign      = sign;
-   result.ieee.mantissa1 = mantissa1;
-   result.ieee.mantissa2 = mantissa2;
+int
+__ledf2 (double a1, double a2)
+{
+    return __cmpdf2 ((float) a1, (float) a2) > 0;
+}
 
+int
+__eqdf2 (double a1, double a2)
+{
+    return *(long long *) &a1 == *(long long *) &a2;
+}
 
-   return result.d;
+int
+__nedf2 (double a1, double a2)
+{
+    return *(long long *) &a1 != *(long long *) &a2;
 }