(root)/
glibc-2.38/
sysdeps/
ia64/
fpu/
libm_support.h
       1  /* file: libm_support.h */
       2  
       3  
       4  /*
       5  // Copyright (c) 2000 - 2004, Intel Corporation
       6  // All rights reserved.
       7  //
       8  //
       9  // Redistribution and use in source and binary forms, with or without
      10  // modification, are permitted provided that the following conditions are
      11  // met:
      12  //
      13  // * Redistributions of source code must retain the above copyright
      14  // notice, this list of conditions and the following disclaimer.
      15  //
      16  // * Redistributions in binary form must reproduce the above copyright
      17  // notice, this list of conditions and the following disclaimer in the
      18  // documentation and/or other materials provided with the distribution.
      19  //
      20  // * The name of Intel Corporation may not be used to endorse or promote
      21  // products derived from this software without specific prior written
      22  // permission.
      23  
      24  //
      25  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      26  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      27  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      28  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
      29  // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
      30  // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
      31  // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
      32  // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
      33  // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR TORT (INCLUDING
      34  // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
      35  // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      36  //
      37  // Intel Corporation is the author of this code, and requests that all
      38  // problem reports or change requests be submitted to it directly at
      39  // http://www.intel.com/software/products/opensource/libraries/num.htm.
      40  //
      41  
      42  // History: 02/02/2000 Initial version
      43  //          2/28/2000 added tags for logb and nextafter
      44  //          3/22/2000 Changes to support _LIB_VERSIONIMF variable
      45  //                    and filled some enum gaps. Added support for C99.
      46  //          5/31/2000 added prototypes for __libm_frexp_4l/8l
      47  //          8/10/2000 Changed declaration of _LIB_VERSIONIMF to work for library
      48  //                    builds and other application builds (precompiler directives).
      49  //          8/11/2000 Added pointers-to-matherr-functions declarations to allow
      50  //                    for user-defined matherr functions in the dll build.
      51  //         12/07/2000 Added scalbn error_types values.
      52  //          5/01/2001 Added error_types values for C99 nearest integer
      53  //                    functions.
      54  //          6/07/2001 Added error_types values for fdim.
      55  //          6/18/2001 Added include of complex_support.h.
      56  //          8/03/2001 Added error_types values for nexttoward, scalbln.
      57  //          8/23/2001 Corrected tag numbers from 186 and higher.
      58  //          8/27/2001 Added check for long int and long long int definitions.
      59  //         12/10/2001 Added error_types for erfc.
      60  //         12/27/2001 Added error_types for degree argument functions.
      61  //         01/02/2002 Added error_types for tand, cotd.
      62  //         01/04/2002 Delete include of complex_support.h
      63  //         01/23/2002 Deleted prototypes for __libm_frexp*.  Added check for
      64  //                    multiple int, long int, and long long int definitions.
      65  //         05/20/2002 Added error_types for cot.
      66  //         06/27/2002 Added error_types for sinhcosh.
      67  //         12/05/2002 Added error_types for annuity and compound
      68  //         04/10/2003 Added error_types for tgammal/tgamma/tgammaf
      69  //         05/16/2003 FP-treatment macros copied here from IA32 libm_support.h
      70  //         06/02/2003 Added pad into struct fp80 (12/16 bytes).
      71  //         08/01/2003 Added struct ker80 and macros for multiprecision addition,
      72  //                    subtraction, multiplication, division, square root.
      73  //         08/07/2003 History section updated.
      74  //         09/03/2003 ALIGN(n) macro added.
      75  //         10/01/2003 LDOUBLE_ALIGN and fp80 corrected on linux to 16 bytes.
      76  //         11/24/2004 Added ifdef around definitions of INT32/64
      77  //         12/15/2004 Added error_types for exp10, nextafter, nexttoward
      78  //                    underflow.  Moved error codes into libm_error_codes.h.
      79  //
      80  */
      81  
      82  #ifndef __LIBM_SUPPORT_H_INCLUDED__
      83  #define __LIBM_SUPPORT_H_INCLUDED__
      84  
      85  #include <math-svid-compat.h>
      86  
      87  #ifndef _LIBC
      88  #if !(defined(_WIN32) || defined(_WIN64))
      89  # pragma const_seg(".rodata") /* place constant data in text (code) section */
      90  #endif
      91  
      92  #if defined(__ICC) || defined(__ICL) || defined(__ECC) || defined(__ECL)
      93  # pragma warning( disable : 1682 )	/* #1682: ixplicit conversion of a 64-bit integral type to a smaller integral type (potential portability problem) */
      94  # pragma warning( disable : 1683 )	/* #1683: explicit conversion of a 64-bit integral type to a smaller integral type (potential portability problem) */
      95  #endif
      96  #endif
      97  
      98  /* macros to form a double value in hex representation (unsigned int type) */
      99  
     100  #define DOUBLE_HEX(hi,lo) 0x##lo,0x##hi /*LITTLE_ENDIAN*/
     101  
     102  #include "libm_cpu_defs.h"
     103  
     104  #if !(defined (IA64))
     105  #  include "libm_dll.h"
     106  #  include "libm_dispatch.h"
     107  #endif
     108  
     109  #include "libm_error_codes.h"
     110  
     111  struct exceptionf
     112  {
     113    int type;
     114    char *name;
     115    float arg1, arg2, retval;
     116  };
     117  
     118  # ifdef __cplusplus
     119  struct __exception
     120  {
     121    int type;
     122    char *name;
     123    double arg1, arg2, retval;
     124  };
     125  # else
     126  
     127  #  ifndef _LIBC
     128  struct exception
     129  {
     130    int type;
     131    char *name;
     132    double arg1, arg2, retval;
     133  };
     134  #  endif
     135  # endif
     136  
     137  struct exceptionl
     138  {
     139    int type;
     140    char *name;
     141    long double arg1, arg2, retval;
     142  };
     143  
     144  #if (defined (_MS_) && defined (IA64))
     145  #define   MATHERR_F   _matherrf
     146  #define   MATHERR_D   _matherr
     147  #else
     148  #define MATHERR_F   matherrf
     149  #define MATHERR_D   matherr
     150  #endif
     151  
     152  # ifdef __cplusplus
     153  #define EXC_DECL_D  __exception
     154  #else
     155  // exception is a reserved name in C++
     156  #define EXC_DECL_D  exception
     157  #endif
     158  
     159  extern int MATHERR_F(struct exceptionf*);
     160  extern int matherrl(struct exceptionl*);
     161  
     162  /* memory format definitions (LITTLE_ENDIAN only) */
     163  
     164  #if !(defined(SIZE_INT_32) || defined(SIZE_INT_64))
     165  # error "You need to define SIZE_INT_32 or SIZE_INT_64"
     166  #endif
     167  
     168  #if (defined(SIZE_INT_32) && defined(SIZE_INT_64))
     169  #error multiple integer size definitions; define SIZE_INT_32 or SIZE_INT_64
     170  #endif
     171  
     172  #if !(defined(SIZE_LONG_32) || defined(SIZE_LONG_64))
     173  # error "You need to define SIZE_LONG_32 or SIZE_LONG_64"
     174  #endif
     175  
     176  #if (defined(SIZE_LONG_32) && defined(SIZE_LONG_64))
     177  #error multiple integer size definitions; define SIZE_LONG_32 or SIZE_LONG_64
     178  #endif
     179  
     180  #if !defined(__USE_EXTERNAL_FPMEMTYP_H__)
     181  
     182  #define BIAS_32  0x007F
     183  #define BIAS_64  0x03FF
     184  #define BIAS_80  0x3FFF
     185  
     186  #define MAXEXP_32  0x00FE
     187  #define MAXEXP_64  0x07FE
     188  #define MAXEXP_80  0x7FFE
     189  
     190  #define EXPINF_32  0x00FF
     191  #define EXPINF_64  0x07FF
     192  #define EXPINF_80  0x7FFF
     193  
     194  struct fp32 { /*// sign:1 exponent:8 significand:23 (implied leading 1)*/
     195  #if defined(SIZE_INT_32)
     196      unsigned significand:23;
     197      unsigned exponent:8;
     198      unsigned sign:1;
     199  #elif defined(SIZE_INT_64)
     200      unsigned significand:23;
     201      unsigned exponent:8;
     202      unsigned sign:1;
     203  #endif
     204  };
     205  
     206  struct fp64 { /*/ sign:1 exponent:11 significand:52 (implied leading 1)*/
     207  #if defined(SIZE_INT_32)
     208      unsigned lo_significand:32;
     209      unsigned hi_significand:20;
     210      unsigned exponent:11;
     211      unsigned sign:1;
     212  #elif defined(SIZE_INT_64)
     213      unsigned significand:52;
     214      unsigned exponent:11;
     215      unsigned sign:1;
     216  #endif
     217  };
     218  
     219  struct fp80 { /*/ sign:1 exponent:15 significand:64 (NO implied bits) */
     220  #if defined(SIZE_INT_32)
     221      unsigned         lo_significand;
     222      unsigned         hi_significand;
     223      unsigned         exponent:15;
     224      unsigned         sign:1;
     225  #elif defined(SIZE_INT_64)
     226      unsigned         significand;
     227      unsigned         exponent:15;
     228      unsigned         sign:1;
     229  #endif
     230      unsigned         pad:16;
     231  #if !(defined(__unix__) && defined(__i386__))
     232      unsigned         padwin:32;
     233  #endif
     234  };
     235  
     236  #endif /*__USE_EXTERNAL_FPMEMTYP_H__*/
     237  
     238  #if !(defined(opensource))
     239  typedef          __int32  INT32;
     240  typedef   signed __int32 SINT32;
     241  typedef unsigned __int32 UINT32;
     242  
     243  typedef          __int64  INT64;
     244  typedef   signed __int64 SINT64;
     245  typedef unsigned __int64 UINT64;
     246  #else
     247  typedef          int  INT32;
     248  typedef   signed int SINT32;
     249  typedef unsigned int UINT32;
     250  
     251  typedef          long long  INT64;
     252  typedef   signed long long SINT64;
     253  typedef unsigned long long UINT64;
     254  #endif
     255  
     256  #if (defined(_WIN32) || defined(_WIN64))        /* Windows */
     257  # define I64CONST(bits) 0x##bits##i64
     258  # define U64CONST(bits) 0x##bits##ui64
     259  #elif (defined(__linux__) && defined(_M_IA64))  /* Linux,64 */
     260  # define I64CONST(bits) 0x##bits##L
     261  # define U64CONST(bits) 0x##bits##uL
     262  #else                                           /* Linux,32 */
     263  # define I64CONST(bits) 0x##bits##LL
     264  # define U64CONST(bits) 0x##bits##uLL
     265  #endif
     266  
     267  struct ker80 {
     268      union {
     269          long double ldhi;
     270          struct fp80 fphi;
     271      };
     272      union {
     273          long double ldlo;
     274          struct fp80 fplo;
     275      };
     276      int ex;
     277  };
     278  
     279  /* Addition: x+y                                            */
     280  /* The result is sum rhi+rlo                                */
     281  /* Temporary variables: t1                                  */
     282  /* All variables are in long double precision               */
     283  /* Correct if no overflow (algorithm by D.Knuth)           */
     284  #define __LIBM_ADDL1_K80( rhi,rlo,x,y, t1 )                 \
     285      rhi = x   + y;                                          \
     286      rlo = rhi - x;                                          \
     287      t1  = rhi - rlo;                                        \
     288      rlo = y   - rlo;                                        \
     289      t1  = x   - t1;                                         \
     290      rlo = rlo + t1;
     291  
     292  /* Addition: (xhi+xlo) + (yhi+ylo)                          */
     293  /* The result is sum rhi+rlo                                */
     294  /* Temporary variables: t1                                  */
     295  /* All variables are in long double precision               */
     296  /* Correct if no overflow (algorithm by T.J.Dekker)         */
     297  #define __LIBM_ADDL2_K80( rhi,rlo,xhi,xlo,yhi,ylo, t1 )     \
     298      rlo = xhi+yhi;                                          \
     299      if ( VALUE_GT_80(FP80(xhi),FP80(yhi)) ) {               \
     300          t1=xhi-rlo;t1=t1+yhi;t1=t1+ylo;t1=t1+xlo;           \
     301      } else {                                                \
     302          t1=yhi-rlo;t1=t1+xhi;t1=t1+xlo;t1=t1+ylo;           \
     303      }                                                       \
     304      rhi=rlo+t1;                                             \
     305      rlo=rlo-rhi;rlo=rlo+t1;
     306  
     307  /* Addition: r=x+y                                          */
     308  /* Variables r,x,y are pointers to struct ker80,            */
     309  /* all other variables are in long double precision         */
     310  /* Temporary variables: t1                                  */
     311  /* Correct if x and y belong to interval [2^-8000;2^8000],  */
     312  /* or when one or both of them are zero                     */
     313  #if   defined(SIZE_INT_32)
     314  #define __LIBM_ADDL_K80(r,x,y, t1)                          \
     315      if ( ((y)->ex+(y)->fphi.exponent-134 <                  \
     316            (x)->ex+(x)->fphi.exponent)       &&              \
     317           ((x)->ex+(x)->fphi.exponent <                      \
     318            (y)->ex+(y)->fphi.exponent+134)   &&              \
     319           !SIGNIFICAND_ZERO_80(&((x)->fphi)) &&              \
     320           !SIGNIFICAND_ZERO_80(&((y)->fphi)) )               \
     321      {                                                       \
     322          /* y/2^134 < x < y*2^134,               */          \
     323          /* and x,y are nonzero finite numbers   */          \
     324          if ( (x)->ex != (y)->ex ) {                         \
     325              /* adjust x->ex to y->ex */                     \
     326              /* t1 = 2^(x->ex - y->ex) */                    \
     327              FP80(t1)->sign = 0;                             \
     328              FP80(t1)->exponent = BIAS_80 + (x)->ex-(y)->ex; \
     329              /*  exponent is correct because             */  \
     330              /*  |x->ex - y->ex| =                       */  \
     331              /*  = |  (x->ex + x->fphi.exponent) -       */  \
     332              /*      -(y->ex + y->fphi.exponent) +       */  \
     333              /*              + y->fphi.exponent  -       */  \
     334              /*              - x->fphi.exponent     | <  */  \
     335              /*  < |  (x->ex+x->fphi.exponent) -         */  \
     336              /*      -(y->ex+y->fphi.exponent)      | +  */  \
     337              /*   +|  y->fphi.exponent -                 */  \
     338              /*      -x->fphi.exponent              | <  */  \
     339              /*  < 134 + 16000                           */  \
     340              FP80(t1)->hi_significand = 0x80000000;          \
     341              FP80(t1)->lo_significand = 0x00000000;          \
     342              (x)->ex = (y)->ex;                              \
     343              (x)->ldhi *= t1;                                \
     344              (x)->ldlo *= t1;                                \
     345          }                                                   \
     346          /* r==x+y */                                        \
     347          (r)->ex = (y)->ex;                                  \
     348          __LIBM_ADDL2_K80( (r)->ldhi,(r)->ldlo,              \
     349              (x)->ldhi,(x)->ldlo, (y)->ldhi,(y)->ldlo, t1 ); \
     350      } else if ( SIGNIFICAND_ZERO_80(&((x)->fphi)) ||        \
     351               ((y)->ex+(y)->fphi.exponent-BIAS_80 - 134 >=   \
     352                (x)->ex+(x)->fphi.exponent-BIAS_80) )         \
     353      {                                                       \
     354          /* |x|<<|y| */                                      \
     355          *(r) = *(y);                                        \
     356      } else {                                                \
     357          /* |y|<<|x| */                                      \
     358          *(r) = *(x);                                        \
     359      }
     360  #elif defined(SIZE_INT_64)
     361  #define __LIBM_ADDL_K80(r,x,y, t1)                          \
     362      if ( ((y)->ex+(y)->fphi.exponent-134 <                  \
     363            (x)->ex+(x)->fphi.exponent)       &&              \
     364           ((x)->ex+(x)->fphi.exponent <                      \
     365            (y)->ex+(y)->fphi.exponent+134)   &&              \
     366           !SIGNIFICAND_ZERO_80(&((x)->fphi)) &&              \
     367           !SIGNIFICAND_ZERO_80(&((y)->fphi)) )               \
     368      {                                                       \
     369          /* y/2^134 < x < y*2^134,               */          \
     370          /* and x,y are nonzero finite numbers   */          \
     371          if ( (x)->ex != (y)->ex ) {                         \
     372              /* adjust x->ex to y->ex */                     \
     373              /* t1 = 2^(x->ex - y->ex) */                    \
     374              FP80(t1)->sign = 0;                             \
     375              FP80(t1)->exponent = BIAS_80 + (x)->ex-(y)->ex; \
     376              /*  exponent is correct because             */  \
     377              /*  |x->ex - y->ex| =                       */  \
     378              /*  = |  (x->ex + x->fphi.exponent) -       */  \
     379              /*      -(y->ex + y->fphi.exponent) +       */  \
     380              /*              + y->fphi.exponent  -       */  \
     381              /*              - x->fphi.exponent     | <  */  \
     382              /*  < |  (x->ex+x->fphi.exponent) -         */  \
     383              /*      -(y->ex+y->fphi.exponent)      | +  */  \
     384              /*   +|  y->fphi.exponent -                 */  \
     385              /*      -x->fphi.exponent              | <  */  \
     386              /*  < 134 + 16000                           */  \
     387              FP80(t1)->significand = 0x8000000000000000;     \
     388              (x)->ex = (y)->ex;                              \
     389              (x)->ldhi *= t1;                                \
     390              (x)->ldlo *= t1;                                \
     391          }                                                   \
     392          /* r==x+y */                                        \
     393          (r)->ex = (y)->ex;                                  \
     394          __LIBM_ADDL2_K80( (r)->ldhi,(r)->ldlo,              \
     395              (x)->ldhi,(x)->ldlo, (y)->ldhi,(y)->ldlo, t1 ); \
     396      } else if ( SIGNIFICAND_ZERO_80(&((x)->fphi)) ||        \
     397               ((y)->ex+(y)->fphi.exponent-BIAS_80 - 134 >=   \
     398                (x)->ex+(x)->fphi.exponent-BIAS_80) )         \
     399      {                                                       \
     400          /* |x|<<|y| */                                      \
     401          *(r) = *(y);                                        \
     402      } else {                                                \
     403          /* |y|<<|x| */                                      \
     404          *(r) = *(x);                                        \
     405      }
     406  #endif
     407  
     408  /* Addition: r=x+y                                          */
     409  /* Variables r,x,y are pointers to struct ker80,            */
     410  /* all other variables are in long double precision         */
     411  /* Temporary variables: t1                                  */
     412  /* Correct for any finite x and y                           */
     413  #define __LIBM_ADDL_NORM_K80(r,x,y, t1)                     \
     414      if ( ((x)->fphi.exponent-BIAS_80<-8000) ||              \
     415           ((x)->fphi.exponent-BIAS_80>+8000) ||              \
     416           ((y)->fphi.exponent-BIAS_80<-8000) ||              \
     417           ((y)->fphi.exponent-BIAS_80>+8000) )               \
     418      {                                                       \
     419          __libm_normalizel_k80(x);                           \
     420          __libm_normalizel_k80(y);                           \
     421      }                                                       \
     422      __LIBM_ADDL_K80(r,x,y, t1)
     423  
     424  /* Subtraction: x-y                                         */
     425  /* The result is sum rhi+rlo                                */
     426  /* Temporary variables: t1                                  */
     427  /* All variables are in long double precision               */
     428  /* Correct if no overflow (algorithm by D.Knuth)           */
     429  #define __LIBM_SUBL1_K80( rhi, rlo, x, y, t1 )              \
     430      rhi = x   - y;                                          \
     431      rlo = rhi - x;                                          \
     432      t1  = rhi - rlo;                                        \
     433      rlo = y   + rlo;                                        \
     434      t1  = x   - t1;                                         \
     435      rlo = t1  - rlo;
     436  
     437  /* Subtraction: (xhi+xlo) - (yhi+ylo)                       */
     438  /* The result is sum rhi+rlo                                */
     439  /* Temporary variables: t1                                  */
     440  /* All variables are in long double precision               */
     441  /* Correct if no overflow (algorithm by T.J.Dekker)         */
     442  #define __LIBM_SUBL2_K80( rhi,rlo,xhi,xlo,yhi,ylo, t1 )     \
     443      rlo = xhi-yhi;                                          \
     444      if ( VALUE_GT_80(FP80(xhi),FP80(yhi)) ) {               \
     445          t1=xhi-rlo;t1=t1-yhi;t1=t1-ylo;t1=t1+xlo;           \
     446      } else {                                                \
     447          t1=yhi+rlo;t1=xhi-t1;t1=t1+xlo;t1=t1-ylo;           \
     448      }                                                       \
     449      rhi=rlo+t1;                                             \
     450      rlo=rlo-rhi;rlo=rlo+t1;
     451  
     452  /* Subtraction: r=x-y                                       */
     453  /* Variables r,x,y are pointers to struct ker80,            */
     454  /* all other variables are in long double precision         */
     455  /* Temporary variables: t1                                  */
     456  /* Correct if x and y belong to interval [2^-8000;2^8000],  */
     457  /* or when one or both of them are zero                     */
     458  #if   defined(SIZE_INT_32)
     459  #define __LIBM_SUBL_K80(r,x,y, t1)                          \
     460      if ( ((y)->ex+(y)->fphi.exponent-134 <                  \
     461            (x)->ex+(x)->fphi.exponent)       &&              \
     462           ((x)->ex+(x)->fphi.exponent <                      \
     463            (y)->ex+(y)->fphi.exponent+134)   &&              \
     464           !SIGNIFICAND_ZERO_80(&((x)->fphi)) &&              \
     465           !SIGNIFICAND_ZERO_80(&((y)->fphi)) )               \
     466      {                                                       \
     467          /* y/2^134 < x < y*2^134,               */          \
     468          /* and x,y are nonzero finite numbers   */          \
     469          if ( (x)->ex != (y)->ex ) {                         \
     470              /* adjust x->ex to y->ex */                     \
     471              /* t1 = 2^(x->ex - y->ex) */                    \
     472              FP80(t1)->sign = 0;                             \
     473              FP80(t1)->exponent = BIAS_80 + (x)->ex-(y)->ex; \
     474              /*  exponent is correct because             */  \
     475              /*  |x->ex - y->ex| =                       */  \
     476              /*  = |  (x->ex + x->fphi.exponent) -       */  \
     477              /*      -(y->ex + y->fphi.exponent) +       */  \
     478              /*              + y->fphi.exponent  -       */  \
     479              /*              - x->fphi.exponent     | <  */  \
     480              /*  < |  (x->ex+x->fphi.exponent) -         */  \
     481              /*      -(y->ex+y->fphi.exponent)      | +  */  \
     482              /*   +|  y->fphi.exponent -                 */  \
     483              /*      -x->fphi.exponent              | <  */  \
     484              /*  < 134 + 16000                           */  \
     485              FP80(t1)->hi_significand = 0x80000000;          \
     486              FP80(t1)->lo_significand = 0x00000000;          \
     487              (x)->ex = (y)->ex;                              \
     488              (x)->ldhi *= t1;                                \
     489              (x)->ldlo *= t1;                                \
     490          }                                                   \
     491          /* r==x+y */                                        \
     492          (r)->ex = (y)->ex;                                  \
     493          __LIBM_SUBL2_K80( (r)->ldhi,(r)->ldlo,              \
     494              (x)->ldhi,(x)->ldlo, (y)->ldhi,(y)->ldlo, t1 ); \
     495      } else if ( SIGNIFICAND_ZERO_80(&((x)->fphi)) ||        \
     496               ((y)->ex+(y)->fphi.exponent-BIAS_80 - 134 >=   \
     497                (x)->ex+(x)->fphi.exponent-BIAS_80) )         \
     498      {                                                       \
     499          /* |x|<<|y| */                                      \
     500          (r)->ex   =   (y)->ex;                              \
     501          (r)->ldhi = -((y)->ldhi);                           \
     502          (r)->ldlo = -((y)->ldlo);                           \
     503      } else {                                                \
     504          /* |y|<<|x| */                                      \
     505          *(r) = *(x);                                        \
     506      }
     507  #elif defined(SIZE_INT_64)
     508  #define __LIBM_SUBL_K80(r,x,y, t1)                          \
     509      if ( ((y)->ex+(y)->fphi.exponent-134 <                  \
     510            (x)->ex+(x)->fphi.exponent)       &&              \
     511           ((x)->ex+(x)->fphi.exponent <                      \
     512            (y)->ex+(y)->fphi.exponent+134)   &&              \
     513           !SIGNIFICAND_ZERO_80(&((x)->fphi)) &&              \
     514           !SIGNIFICAND_ZERO_80(&((y)->fphi)) )               \
     515      {                                                       \
     516          /* y/2^134 < x < y*2^134,               */          \
     517          /* and x,y are nonzero finite numbers   */          \
     518          if ( (x)->ex != (y)->ex ) {                         \
     519              /* adjust x->ex to y->ex */                     \
     520              /* t1 = 2^(x->ex - y->ex) */                    \
     521              FP80(t1)->sign = 0;                             \
     522              FP80(t1)->exponent = BIAS_80 + (x)->ex-(y)->ex; \
     523              /*  exponent is correct because             */  \
     524              /*  |x->ex - y->ex| =                       */  \
     525              /*  = |  (x->ex + x->fphi.exponent) -       */  \
     526              /*      -(y->ex + y->fphi.exponent) +       */  \
     527              /*              + y->fphi.exponent  -       */  \
     528              /*              - x->fphi.exponent     | <  */  \
     529              /*  < |  (x->ex+x->fphi.exponent) -         */  \
     530              /*      -(y->ex+y->fphi.exponent)      | +  */  \
     531              /*   +|  y->fphi.exponent -                 */  \
     532              /*      -x->fphi.exponent              | <  */  \
     533              /*  < 134 + 16000                           */  \
     534              FP80(t1)->significand = 0x8000000000000000;     \
     535              (x)->ex = (y)->ex;                              \
     536              (x)->ldhi *= t1;                                \
     537              (x)->ldlo *= t1;                                \
     538          }                                                   \
     539          /* r==x+y */                                        \
     540          (r)->ex = (y)->ex;                                  \
     541          __LIBM_SUBL2_K80( (r)->ldhi,(r)->ldlo,              \
     542              (x)->ldhi,(x)->ldlo, (y)->ldhi,(y)->ldlo, t1 ); \
     543      } else if ( SIGNIFICAND_ZERO_80(&((x)->fphi)) ||        \
     544               ((y)->ex+(y)->fphi.exponent-BIAS_80 - 134 >=   \
     545                (x)->ex+(x)->fphi.exponent-BIAS_80) )         \
     546      {                                                       \
     547          /* |x|<<|y| */                                      \
     548          (r)->ex   =   (y)->ex;                              \
     549          (r)->ldhi = -((y)->ldhi);                           \
     550          (r)->ldlo = -((y)->ldlo);                           \
     551      } else {                                                \
     552          /* |y|<<|x| */                                      \
     553          *(r) = *(x);                                        \
     554      }
     555  #endif
     556  
     557  /* Subtraction: r=x+y                                       */
     558  /* Variables r,x,y are pointers to struct ker80,            */
     559  /* all other variables are in long double precision         */
     560  /* Temporary variables: t1                                  */
     561  /* Correct for any finite x and y                           */
     562  #define __LIBM_SUBL_NORM_K80(r,x,y, t1)                     \
     563      if ( ((x)->fphi.exponent-BIAS_80<-8000) ||              \
     564           ((x)->fphi.exponent-BIAS_80>+8000) ||              \
     565           ((y)->fphi.exponent-BIAS_80<-8000) ||              \
     566           ((y)->fphi.exponent-BIAS_80>+8000) )               \
     567      {                                                       \
     568          __libm_normalizel_k80(x);                           \
     569          __libm_normalizel_k80(y);                           \
     570      }                                                       \
     571      __LIBM_SUBL_K80(r,x,y, t1)
     572  
     573  /* Multiplication: x*y                                      */
     574  /* The result is sum rhi+rlo                                */
     575  /* Here t32 is the constant 2^32+1                          */
     576  /* Temporary variables: t1,t2,t3,t4,t5,t6                   */
     577  /* All variables are in long double precision               */
     578  /* Correct if no over/underflow (algorithm by T.J.Dekker)   */
     579  #define __LIBM_MULL1_K80(rhi,rlo,x,y,                       \
     580                                       t32,t1,t2,t3,t4,t5,t6) \
     581      t1=(x)*(t32); t3=x-t1; t3=t3+t1; t4=x-t3;               \
     582      t1=(y)*(t32); t5=y-t1; t5=t5+t1; t6=y-t5;               \
     583      t1=(t3)*(t5);                                           \
     584      t2=(t3)*(t6)+(t4)*(t5);                                 \
     585      rhi=t1+t2;                                              \
     586      rlo=t1-rhi; rlo=rlo+t2; rlo=rlo+(t4*t6);
     587  
     588  /* Multiplication: (xhi+xlo)*(yhi+ylo)                      */
     589  /* The result is sum rhi+rlo                                */
     590  /* Here t32 is the constant 2^32+1                          */
     591  /* Temporary variables: t1,t2,t3,t4,t5,t6,t7,t8             */
     592  /* All variables are in long double precision               */
     593  /* Correct if no over/underflow (algorithm by T.J.Dekker)   */
     594  #define __LIBM_MULL2_K80(rhi,rlo,xhi,xlo,yhi,ylo,           \
     595                                 t32,t1,t2,t3,t4,t5,t6,t7,t8) \
     596      __LIBM_MULL1_K80(t7,t8,xhi,yhi, t32,t1,t2,t3,t4,t5,t6)  \
     597      t1=(xhi)*(ylo)+(xlo)*(yhi); t1=t1+t8;                   \
     598      rhi=t7+t1;                                              \
     599      rlo=t7-rhi; rlo=rlo+t1;
     600  
     601  /* Multiplication: r=x*y                                    */
     602  /* Variables r,x,y are pointers to struct ker80,            */
     603  /* all other variables are in long double precision         */
     604  /* Here t32 is the constant 2^32+1                          */
     605  /* Temporary variables: t1,t2,t3,t4,t5,t6,t7,t8             */
     606  /* Correct if x and y belong to interval [2^-8000;2^8000]   */
     607  #define __LIBM_MULL_K80(r,x,y, t32,t1,t2,t3,t4,t5,t6,t7,t8) \
     608      (r)->ex = (x)->ex + (y)->ex;                            \
     609      __LIBM_MULL2_K80((r)->ldhi,(r)->ldlo,                   \
     610          (x)->ldhi,(x)->ldlo,(y)->ldhi,(y)->ldlo,            \
     611          t32,t1,t2,t3,t4,t5,t6,t7,t8)
     612  
     613  /* Multiplication: r=x*y                                    */
     614  /* Variables r,x,y are pointers to struct ker80,            */
     615  /* all other variables are in long double precision         */
     616  /* Here t32 is the constant 2^32+1                          */
     617  /* Temporary variables: t1,t2,t3,t4,t5,t6,t7,t8             */
     618  /* Correct for any finite x and y                           */
     619  #define __LIBM_MULL_NORM_K80(r,x,y,                         \
     620                                 t32,t1,t2,t3,t4,t5,t6,t7,t8) \
     621      if ( ((x)->fphi.exponent-BIAS_80<-8000) ||              \
     622           ((x)->fphi.exponent-BIAS_80>+8000) ||              \
     623           ((y)->fphi.exponent-BIAS_80<-8000) ||              \
     624           ((y)->fphi.exponent-BIAS_80>+8000) )               \
     625      {                                                       \
     626          __libm_normalizel_k80(x);                           \
     627          __libm_normalizel_k80(y);                           \
     628      }                                                       \
     629      __LIBM_MULL_K80(r,x,y, t32,t1,t2,t3,t4,t5,t6,t7,t8)
     630  
     631  /* Division: (xhi+xlo)/(yhi+ylo)                            */
     632  /* The result is sum rhi+rlo                                */
     633  /* Here t32 is the constant 2^32+1                          */
     634  /* Temporary variables: t1,t2,t3,t4,t5,t6,t7,t8,t9          */
     635  /* All variables are in long double precision               */
     636  /* Correct if no over/underflow (algorithm by T.J.Dekker)   */
     637  #define __LIBM_DIVL2_K80(rhi,rlo,xhi,xlo,yhi,ylo,           \
     638                              t32,t1,t2,t3,t4,t5,t6,t7,t8,t9) \
     639      t7=(xhi)/(yhi);                                         \
     640      __LIBM_MULL1_K80(t8,t9,t7,yhi, t32,t1,t2,t3,t4,t5,t6)   \
     641      t1=xhi-t8; t1=t1-t9; t1=t1+xlo; t1=t1-(t7)*(ylo);       \
     642      t1=(t1)/(yhi);                                          \
     643      rhi=t7+t1;                                              \
     644      rlo=t7-rhi; rlo=rlo+t1;
     645  
     646  /* Division: r=x/y                                          */
     647  /* Variables r,x,y are pointers to struct ker80,            */
     648  /* all other variables are in long double precision         */
     649  /* Here t32 is the constant 2^32+1                          */
     650  /* Temporary variables: t1,t2,t3,t4,t5,t6,t7,t8,t9          */
     651  /* Correct if x and y belong to interval [2^-8000;2^8000]   */
     652  #define __LIBM_DIVL_K80(r,x,y,                              \
     653                              t32,t1,t2,t3,t4,t5,t6,t7,t8,t9) \
     654      (r)->ex = (x)->ex - (y)->ex;                            \
     655      __LIBM_DIVL2_K80( (r)->ldhi,(r)->ldlo,                  \
     656          (x)->ldhi,(x)->ldlo,(y)->ldhi,(y)->ldlo,            \
     657          t32,t1,t2,t3,t4,t5,t6,t7,t8,t9)
     658  
     659  /* Division: r=x/y                                          */
     660  /* Variables r,x,y are pointers to struct ker80,            */
     661  /* all other variables are in long double precision         */
     662  /* Here t32 is the constant 2^32+1                          */
     663  /* Temporary variables: t1,t2,t3,t4,t5,t6,t7,t8             */
     664  /* Correct for any finite x and y                           */
     665  #define __LIBM_DIVL_NORM_K80(r,x,y,                         \
     666                              t32,t1,t2,t3,t4,t5,t6,t7,t8,t9) \
     667      if ( ((x)->fphi.exponent-BIAS_80<-8000) ||              \
     668           ((x)->fphi.exponent-BIAS_80>+8000) ||              \
     669           ((y)->fphi.exponent-BIAS_80<-8000) ||              \
     670           ((y)->fphi.exponent-BIAS_80>+8000) )               \
     671      {                                                       \
     672          __libm_normalizel_k80(x);                           \
     673          __libm_normalizel_k80(y);                           \
     674      }                                                       \
     675      __LIBM_DIVL_K80(r,x,y, t32,t1,t2,t3,t4,t5,t6,t7,t8,t9)
     676  
     677  /* Square root: sqrt(xhi+xlo)                               */
     678  /* The result is sum rhi+rlo                                */
     679  /* Here t32 is the constant 2^32+1                          */
     680  /*      half is the constant 0.5                            */
     681  /* Temporary variables: t1,t2,t3,t4,t5,t6,t7,t8,t9          */
     682  /* All variables are in long double precision               */
     683  /* Correct for positive xhi+xlo (algorithm by T.J.Dekker)   */
     684  #define __LIBM_SQRTL2_NORM_K80(rhi,rlo,xhi,xlo,             \
     685                         t32,half,t1,t2,t3,t4,t5,t6,t7,t8,t9) \
     686      t7=sqrtl(xhi);                                          \
     687      __LIBM_MULL1_K80(t8,t9,t7,t7, t32,t1,t2,t3,t4,t5,t6)    \
     688      t1=xhi-t8; t1=t1-t9; t1=t1+xlo; t1=(t1)*(half);         \
     689      t1=(t1)/(t7);                                           \
     690      rhi=t7+t1;                                              \
     691      rlo=t7-rhi; rlo=rlo+t1;
     692  
     693  /* Square root: r=sqrt(x)                                   */
     694  /* Variables r,x,y are pointers to struct ker80,            */
     695  /* all other variables are in long double precision         */
     696  /* Here t32 is the constant 2^32+1                          */
     697  /*      half is the constant 0.5                            */
     698  /* Temporary variables: t1,t2,t3,t4,t5,t6,t7,t8,t9          */
     699  /* Correct if x belongs to interval [2^-16000;2^16000]      */
     700  #define __LIBM_SQRTL_K80(r,x,                               \
     701                         t32,half,t1,t2,t3,t4,t5,t6,t7,t8,t9) \
     702      if ( ((x)->ex & 1) == 1 ) {                             \
     703          (x)->ex    = (x)->ex + 1;                           \
     704          (x)->ldhi *= half;                                  \
     705          (x)->ldlo *= half;                                  \
     706      }                                                       \
     707      (r)->ex = (x)->ex >> 1;                                 \
     708      __LIBM_SQRTL2_NORM_K80( (r)->ldhi,(r)->ldlo,            \
     709          (x)->ldhi,(x)->ldlo,                                \
     710          t32,half,t1,t2,t3,t4,t5,t6,t7,t8,t9)
     711  
     712  /* Square root: r=sqrt(x)                                   */
     713  /* Variables r,x,y are pointers to struct ker80,            */
     714  /* all other variables are in long double precision         */
     715  /* Here t32 is the constant 2^32+1                          */
     716  /*      half is the constant 0.5                            */
     717  /* Temporary variables: t1,t2,t3,t4,t5,t6,t7,t8,t9          */
     718  /* Correct for any positive x                               */
     719  #define __LIBM_SQRTL_NORM_K80(r,x,                          \
     720                         t32,half,t1,t2,t3,t4,t5,t6,t7,t8,t9) \
     721      if ( ((x)->fphi.exponent-BIAS_80<-16000) ||             \
     722           ((x)->fphi.exponent-BIAS_80>+16000) )              \
     723      {                                                       \
     724          __libm_normalizel_k80(x);                           \
     725      }                                                       \
     726      __LIBM_SQRTL_K80(r,x, t32,half,t1,t2,t3,t4,t5,t6,t7,t8,t9)
     727  
     728  
     729  #ifdef __INTEL_COMPILER
     730  #define ALIGN(n) __declspec(align(n))
     731  #else /* __INTEL_COMPILER */
     732  #define ALIGN(n)
     733  #endif /* __INTEL_COMPILER */
     734  
     735  /* macros to form a long double value in hex representation (unsigned short type) */
     736  
     737  #if (defined(__unix__) && defined(__i386__))
     738  # define LDOUBLE_ALIGN 12	/* IA32 Linux: 12-byte alignment */
     739  #else	/*__linux__ & IA32*/
     740  # define LDOUBLE_ALIGN 16	/* EFI2/IA32 Win or IPF Win/Linux: 16-byte alignment */
     741  #endif	/*__linux__ & IA32*/
     742  
     743  #if (LDOUBLE_ALIGN == 16)
     744  #define _XPD_ ,0x0000,0x0000,0x0000
     745  #else /*12*/
     746  #define _XPD_ ,0x0000
     747  #endif
     748  
     749  #define LDOUBLE_HEX(w4,w3,w2,w1,w0) 0x##w0,0x##w1,0x##w2,0x##w3,0x##w4 _XPD_ /*LITTLE_ENDIAN*/
     750  
     751  /* macros to sign-expand low 'num' bits of 'val' to native integer */
     752  
     753  #if defined(SIZE_INT_32)
     754  # define SIGN_EXPAND(val,num)  ((int)(val) << (32-(num))) >> (32-(num)) /* sign expand of 'num' LSBs */
     755  #elif defined(SIZE_INT_64)
     756  # define SIGN_EXPAND(val,num)  ((int)(val) << (64-(num))) >> (64-(num)) /* sign expand of 'num' LSBs */
     757  #endif
     758  
     759  /* macros to form pointers to FP number on-the-fly */
     760  
     761  #define FP32(f)  ((struct fp32 *)&f)
     762  #define FP64(d)  ((struct fp64 *)&d)
     763  #define FP80(ld) ((struct fp80 *)&ld)
     764  
     765  /* macros to extract signed low and high doubleword of long double */
     766  
     767  #if defined(SIZE_INT_32)
     768  # define HI_DWORD_80(ld) ((((FP80(ld)->sign << 15) | FP80(ld)->exponent) << 16) | \
     769                            ((FP80(ld)->hi_significand >> 16) & 0xFFFF))
     770  # define LO_DWORD_80(ld) SIGN_EXPAND(FP80(ld)->lo_significand, 32)
     771  #elif defined(SIZE_INT_64)
     772  # define HI_DWORD_80(ld) ((((FP80(ld)->sign << 15) | FP80(ld)->exponent) << 16) | \
     773                            ((FP80(ld)->significand >> 48) & 0xFFFF))
     774  # define LO_DWORD_80(ld) SIGN_EXPAND(FP80(ld)->significand, 32)
     775  #endif
     776  
     777  /* macros to extract hi bits of significand.
     778   * note that explicit high bit do not count (returns as is)
     779   */
     780  
     781  #if defined(SIZE_INT_32)
     782  # define HI_SIGNIFICAND_80(X,NBITS) ((X)->hi_significand >> (31 - (NBITS)))
     783  #elif defined(SIZE_INT_64)
     784  # define HI_SIGNIFICAND_80(X,NBITS) ((X)->significand >> (63 - (NBITS)))
     785  #endif
     786  
     787  /* macros to check, whether a significand bits are all zero, or some of them are non-zero.
     788   * note that SIGNIFICAND_ZERO_80 tests high bit also, but SIGNIFICAND_NONZERO_80 does not
     789   */
     790  
     791  #define SIGNIFICAND_ZERO_32(X)     ((X)->significand == 0)
     792  #define SIGNIFICAND_NONZERO_32(X)  ((X)->significand != 0)
     793  
     794  #if defined(SIZE_INT_32)
     795  # define SIGNIFICAND_ZERO_64(X)    (((X)->hi_significand == 0) && ((X)->lo_significand == 0))
     796  # define SIGNIFICAND_NONZERO_64(X) (((X)->hi_significand != 0) || ((X)->lo_significand != 0))
     797  #elif defined(SIZE_INT_64)
     798  # define SIGNIFICAND_ZERO_64(X)    ((X)->significand == 0)
     799  # define SIGNIFICAND_NONZERO_64(X) ((X)->significand != 0)
     800  #endif
     801  
     802  #if defined(SIZE_INT_32)
     803  # define SIGNIFICAND_ZERO_80(X)    (((X)->hi_significand == 0x00000000) && ((X)->lo_significand == 0))
     804  # define SIGNIFICAND_NONZERO_80(X) (((X)->hi_significand != 0x80000000) || ((X)->lo_significand != 0))
     805  #elif defined(SIZE_INT_64)
     806  # define SIGNIFICAND_ZERO_80(X)    ((X)->significand == 0x0000000000000000)
     807  # define SIGNIFICAND_NONZERO_80(X) ((X)->significand != 0x8000000000000000)
     808  #endif
     809  
     810  /* macros to compare long double with constant value, represented as hex */
     811  
     812  #define SIGNIFICAND_EQ_HEX_32(X,BITS) ((X)->significand == 0x ## BITS)
     813  #define SIGNIFICAND_GT_HEX_32(X,BITS) ((X)->significand >  0x ## BITS)
     814  #define SIGNIFICAND_GE_HEX_32(X,BITS) ((X)->significand >= 0x ## BITS)
     815  #define SIGNIFICAND_LT_HEX_32(X,BITS) ((X)->significand <  0x ## BITS)
     816  #define SIGNIFICAND_LE_HEX_32(X,BITS) ((X)->significand <= 0x ## BITS)
     817  
     818  #if defined(SIZE_INT_32)
     819  # define SIGNIFICAND_EQ_HEX_64(X,HI,LO) \
     820      (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand == 0x ## LO))
     821  # define SIGNIFICAND_GT_HEX_64(X,HI,LO) (((X)->hi_significand > 0x ## HI) || \
     822      (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand >  0x ## LO)))
     823  # define SIGNIFICAND_GE_HEX_64(X,HI,LO) (((X)->hi_significand > 0x ## HI) || \
     824      (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand >= 0x ## LO)))
     825  # define SIGNIFICAND_LT_HEX_64(X,HI,LO) (((X)->hi_significand < 0x ## HI) || \
     826      (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand <  0x ## LO)))
     827  # define SIGNIFICAND_LE_HEX_64(X,HI,LO) (((X)->hi_significand < 0x ## HI) || \
     828      (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand <= 0x ## LO)))
     829  #elif defined(SIZE_INT_64)
     830  # define SIGNIFICAND_EQ_HEX_64(X,HI,LO) ((X)->significand == 0x ## HI ## LO)
     831  # define SIGNIFICAND_GT_HEX_64(X,HI,LO) ((X)->significand >  0x ## HI ## LO)
     832  # define SIGNIFICAND_GE_HEX_64(X,HI,LO) ((X)->significand >= 0x ## HI ## LO)
     833  # define SIGNIFICAND_LT_HEX_64(X,HI,LO) ((X)->significand <  0x ## HI ## LO)
     834  # define SIGNIFICAND_LE_HEX_64(X,HI,LO) ((X)->significand <= 0x ## HI ## LO)
     835  #endif
     836  
     837  #if defined(SIZE_INT_32)
     838  # define SIGNIFICAND_EQ_HEX_80(X,HI,LO) \
     839      (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand == 0x ## LO))
     840  # define SIGNIFICAND_GT_HEX_80(X,HI,LO) (((X)->hi_significand > 0x ## HI) || \
     841      (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand >  0x ## LO)))
     842  # define SIGNIFICAND_GE_HEX_80(X,HI,LO) (((X)->hi_significand > 0x ## HI) || \
     843      (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand >= 0x ## LO)))
     844  # define SIGNIFICAND_LT_HEX_80(X,HI,LO) (((X)->hi_significand < 0x ## HI) || \
     845      (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand <  0x ## LO)))
     846  # define SIGNIFICAND_LE_HEX_80(X,HI,LO) (((X)->hi_significand < 0x ## HI) || \
     847      (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand <= 0x ## LO)))
     848  #elif defined(SIZE_INT_64)
     849  # define SIGNIFICAND_EQ_HEX_80(X,HI,LO) ((X)->significand == 0x ## HI ## LO)
     850  # define SIGNIFICAND_GT_HEX_80(X,HI,LO) ((X)->significand >  0x ## HI ## LO)
     851  # define SIGNIFICAND_GE_HEX_80(X,HI,LO) ((X)->significand >= 0x ## HI ## LO)
     852  # define SIGNIFICAND_LT_HEX_80(X,HI,LO) ((X)->significand <  0x ## HI ## LO)
     853  # define SIGNIFICAND_LE_HEX_80(X,HI,LO) ((X)->significand <= 0x ## HI ## LO)
     854  #endif
     855  
     856  #define VALUE_EQ_HEX_32(X,EXP,BITS) \
     857     (((X)->exponent == (EXP)) && (SIGNIFICAND_EQ_HEX_32(X, BITS)))
     858  #define VALUE_GT_HEX_32(X,EXP,BITS) (((X)->exponent > (EXP)) || \
     859     (((X)->exponent == (EXP)) && (SIGNIFICAND_GT_HEX_32(X, BITS))))
     860  #define VALUE_GE_HEX_32(X,EXP,BITS) (((X)->exponent > (EXP)) || \
     861     (((X)->exponent == (EXP)) && (SIGNIFICAND_GE_HEX_32(X, BITS))))
     862  #define VALUE_LT_HEX_32(X,EXP,BITS) (((X)->exponent < (EXP)) || \
     863     (((X)->exponent == (EXP)) && (SIGNIFICAND_LT_HEX_32(X, BITS))))
     864  #define VALUE_LE_HEX_32(X,EXP,BITS) (((X)->exponent < (EXP)) || \
     865     (((X)->exponent == (EXP)) && (SIGNIFICAND_LE_HEX_32(X, BITS))))
     866  
     867  #define VALUE_EQ_HEX_64(X,EXP,HI,LO) \
     868     (((X)->exponent == (EXP)) && (SIGNIFICAND_EQ_HEX_64(X, HI, LO)))
     869  #define VALUE_GT_HEX_64(X,EXP,HI,LO) (((X)->exponent > (EXP)) || \
     870     (((X)->exponent == (EXP)) && (SIGNIFICAND_GT_HEX_64(X, HI, LO))))
     871  #define VALUE_GE_HEX_64(X,EXP,HI,LO) (((X)->exponent > (EXP)) || \
     872     (((X)->exponent == (EXP)) && (SIGNIFICAND_GE_HEX_64(X, HI, LO))))
     873  #define VALUE_LT_HEX_64(X,EXP,HI,LO) (((X)->exponent < (EXP)) || \
     874     (((X)->exponent == (EXP)) && (SIGNIFICAND_LT_HEX_64(X, HI, LO))))
     875  #define VALUE_LE_HEX_64(X,EXP,HI,LO) (((X)->exponent < (EXP)) || \
     876     (((X)->exponent == (EXP)) && (SIGNIFICAND_LE_HEX_64(X, HI, LO))))
     877  
     878  #define VALUE_EQ_HEX_80(X,EXP,HI,LO) \
     879     (((X)->exponent == (EXP)) && (SIGNIFICAND_EQ_HEX_80(X, HI, LO)))
     880  #define VALUE_GT_HEX_80(X,EXP,HI,LO) (((X)->exponent > (EXP)) || \
     881     (((X)->exponent == (EXP)) && (SIGNIFICAND_GT_HEX_80(X, HI, LO))))
     882  #define VALUE_GE_HEX_80(X,EXP,HI,LO) (((X)->exponent > (EXP)) || \
     883     (((X)->exponent == (EXP)) && (SIGNIFICAND_GE_HEX_80(X, HI, LO))))
     884  #define VALUE_LT_HEX_80(X,EXP,HI,LO) (((X)->exponent < (EXP)) || \
     885     (((X)->exponent == (EXP)) && (SIGNIFICAND_LT_HEX_80(X, HI, LO))))
     886  #define VALUE_LE_HEX_80(X,EXP,HI,LO) (((X)->exponent < (EXP)) || \
     887     (((X)->exponent == (EXP)) && (SIGNIFICAND_LE_HEX_80(X, HI, LO))))
     888  
     889  /* macros to compare two long doubles */
     890  
     891  #define SIGNIFICAND_EQ_32(X,Y) ((X)->significand == (Y)->significand)
     892  #define SIGNIFICAND_GT_32(X,Y) ((X)->significand > (Y)->significand)
     893  #define SIGNIFICAND_GE_32(X,Y) ((X)->significand >= (Y)->significand)
     894  #define SIGNIFICAND_LT_32(X,Y) ((X)->significand < (Y)->significand)
     895  #define SIGNIFICAND_LE_32(X,Y) ((X)->significand <= (Y)->significand)
     896  
     897  #if defined(SIZE_INT_32)
     898  # define SIGNIFICAND_EQ_64(X,Y) \
     899    (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand == (Y)->lo_significand))
     900  # define SIGNIFICAND_GT_64(X,Y) (((X)->hi_significand > (Y)->hi_significand) || \
     901    (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand >  (Y)->lo_significand)))
     902  # define SIGNIFICAND_GE_64(X,Y) (((X)->hi_significand > (Y)->hi_significand) || \
     903    (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand >= (Y)->lo_significand)))
     904  # define SIGNIFICAND_LT_64(X,Y) (((X)->hi_significand < (Y)->hi_significand) || \
     905    (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand <  (Y)->lo_significand)))
     906  # define SIGNIFICAND_LE_64(X,Y) (((X)->hi_significand < (Y)->hi_significand) || \
     907    (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand <= (Y)->lo_significand)))
     908  #elif defined(SIZE_INT_64)
     909  # define SIGNIFICAND_EQ_64(X,Y) ((X)->significand == (Y)->significand)
     910  # define SIGNIFICAND_GT_64(X,Y) ((X)->significand >  (Y)->significand)
     911  # define SIGNIFICAND_GE_64(X,Y) ((X)->significand >= (Y)->significand)
     912  # define SIGNIFICAND_LT_64(X,Y) ((X)->significand <  (Y)->significand)
     913  # define SIGNIFICAND_LE_64(X,Y) ((X)->significand <= (Y)->significand)
     914  #endif
     915  
     916  #if defined(SIZE_INT_32)
     917  # define SIGNIFICAND_EQ_80(X,Y) \
     918      (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand == (Y)->lo_significand))
     919  # define SIGNIFICAND_GT_80(X,Y) (((X)->hi_significand > (Y)->hi_significand) || \
     920      (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand >  (Y)->lo_significand)))
     921  # define SIGNIFICAND_GE_80(X,Y) (((X)->hi_significand > (Y)->hi_significand) || \
     922      (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand >= (Y)->lo_significand)))
     923  # define SIGNIFICAND_LT_80(X,Y) (((X)->hi_significand < (Y)->hi_significand) || \
     924      (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand <  (Y)->lo_significand)))
     925  # define SIGNIFICAND_LE_80(X,Y) (((X)->hi_significand < (Y)->hi_significand) || \
     926      (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand <= (Y)->lo_significand)))
     927  #elif defined(SIZE_INT_64)
     928  # define SIGNIFICAND_EQ_80(X,Y) ((X)->significand == (Y)->significand)
     929  # define SIGNIFICAND_GT_80(X,Y) ((X)->significand >  (Y)->significand)
     930  # define SIGNIFICAND_GE_80(X,Y) ((X)->significand >= (Y)->significand)
     931  # define SIGNIFICAND_LT_80(X,Y) ((X)->significand <  (Y)->significand)
     932  # define SIGNIFICAND_LE_80(X,Y) ((X)->significand <= (Y)->significand)
     933  #endif
     934  
     935  #define VALUE_EQ_32(X,Y) \
     936     (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_EQ_32(X, Y)))
     937  #define VALUE_GT_32(X,Y) (((X)->exponent > (Y)->exponent) || \
     938     (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_GT_32(X, Y))))
     939  #define VALUE_GE_32(X,Y) (((X)->exponent > (Y)->exponent) || \
     940     (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_GE_32(X, Y))))
     941  #define VALUE_LT_32(X,Y) (((X)->exponent < (Y)->exponent) || \
     942     (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_LT_32(X, Y))))
     943  #define VALUE_LE_32(X,Y) (((X)->exponent < (Y)->exponent) || \
     944     (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_LE_32(X, Y))))
     945  
     946  #define VALUE_EQ_64(X,Y) \
     947     (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_EQ_64(X, Y)))
     948  #define VALUE_GT_64(X,Y) (((X)->exponent > (Y)->exponent) || \
     949     (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_GT_64(X, Y))))
     950  #define VALUE_GE_64(X,Y) (((X)->exponent > (Y)->exponent) || \
     951     (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_GE_64(X, Y))))
     952  #define VALUE_LT_64(X,Y) (((X)->exponent < (Y)->exponent) || \
     953     (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_LT_64(X, Y))))
     954  #define VALUE_LE_64(X,Y) (((X)->exponent < (Y)->exponent) || \
     955     (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_LE_64(X, Y))))
     956  
     957  #define VALUE_EQ_80(X,Y) \
     958     (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_EQ_80(X, Y)))
     959  #define VALUE_GT_80(X,Y) (((X)->exponent > (Y)->exponent) || \
     960     (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_GT_80(X, Y))))
     961  #define VALUE_GE_80(X,Y) (((X)->exponent > (Y)->exponent) || \
     962     (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_GE_80(X, Y))))
     963  #define VALUE_LT_80(X,Y) (((X)->exponent < (Y)->exponent) || \
     964     (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_LT_80(X, Y))))
     965  #define VALUE_LE_80(X,Y) (((X)->exponent < (Y)->exponent) || \
     966     (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_LE_80(X, Y))))
     967  
     968  /* add/subtract 1 ulp macros */
     969  
     970  #if defined(SIZE_INT_32)
     971  # define ADD_ULP_80(X) \
     972      if ((++(X)->lo_significand == 0) && \
     973          (++(X)->hi_significand == (((X)->exponent == 0) ? 0x80000000 : 0))) \
     974      { \
     975          (X)->hi_significand |= 0x80000000; \
     976          ++(X)->exponent; \
     977      }
     978  # define SUB_ULP_80(X) \
     979      if (--(X)->lo_significand == 0xFFFFFFFF) { \
     980          --(X)->hi_significand; \
     981          if (((X)->exponent != 0) && \
     982              ((X)->hi_significand == 0x7FFFFFFF) && \
     983              (--(X)->exponent != 0)) \
     984          { \
     985              (X)->hi_significand |= 0x80000000; \
     986          } \
     987      }
     988  #elif defined(SIZE_INT_64)
     989  # define ADD_ULP_80(X) \
     990      if (++(X)->significand == (((X)->exponent == 0) ? 0x8000000000000000 : 0))) { \
     991          (X)->significand |= 0x8000000000000000; \
     992          ++(X)->exponent; \
     993      }
     994  # define SUB_ULP_80(X) \
     995      { \
     996          --(X)->significand; \
     997          if (((X)->exponent != 0) && \
     998              ((X)->significand == 0x7FFFFFFFFFFFFFFF) && \
     999              (--(X)->exponent != 0)) \
    1000          { \
    1001              (X)->significand |= 0x8000000000000000; \
    1002          } \
    1003      }
    1004  #endif
    1005  
    1006  
    1007  /* */
    1008  
    1009  #define VOLATILE_32 /*volatile*/
    1010  #define VOLATILE_64 /*volatile*/
    1011  #define VOLATILE_80 /*volatile*/
    1012  
    1013  #define QUAD_TYPE _Quad
    1014  
    1015  #endif    /*__LIBM_SUPPORT_H_INCLUDED__*/