Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* Software floating-point emulation. Common operations.
  2.    Copyright (C) 1997-2014 Free Software Foundation, Inc.
  3.    This file is part of the GNU C Library.
  4.    Contributed by Richard Henderson (rth@cygnus.com),
  5.                   Jakub Jelinek (jj@ultra.linux.cz),
  6.                   David S. Miller (davem@redhat.com) and
  7.                   Peter Maydell (pmaydell@chiark.greenend.org.uk).
  8.  
  9.    The GNU C Library is free software; you can redistribute it and/or
  10.    modify it under the terms of the GNU Lesser General Public
  11.    License as published by the Free Software Foundation; either
  12.    version 2.1 of the License, or (at your option) any later version.
  13.  
  14.    In addition to the permissions in the GNU Lesser General Public
  15.    License, the Free Software Foundation gives you unlimited
  16.    permission to link the compiled version of this file into
  17.    combinations with other programs, and to distribute those
  18.    combinations without any restriction coming from the use of this
  19.    file.  (The Lesser General Public License restrictions do apply in
  20.    other respects; for example, they cover modification of the file,
  21.    and distribution when not linked into a combine executable.)
  22.  
  23.    The GNU C Library is distributed in the hope that it will be useful,
  24.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  25.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  26.    Lesser General Public License for more details.
  27.  
  28.    You should have received a copy of the GNU Lesser General Public
  29.    License along with the GNU C Library; if not, see
  30.    <http://www.gnu.org/licenses/>.  */
  31.  
  32. #define _FP_DECL(wc, X)                         \
  33.   _FP_I_TYPE X##_c __attribute__ ((unused));    \
  34.   _FP_I_TYPE X##_s __attribute__ ((unused));    \
  35.   _FP_I_TYPE X##_e __attribute__ ((unused));    \
  36.   _FP_FRAC_DECL_##wc (X)
  37.  
  38. /* Test whether the qNaN bit denotes a signaling NaN.  */
  39. #define _FP_FRAC_SNANP(fs, X)                           \
  40.   ((_FP_QNANNEGATEDP)                                   \
  41.    ? (_FP_FRAC_HIGH_RAW_##fs (X) & _FP_QNANBIT_##fs)    \
  42.    : !(_FP_FRAC_HIGH_RAW_##fs (X) & _FP_QNANBIT_##fs))
  43. #define _FP_FRAC_SNANP_SEMIRAW(fs, X)                   \
  44.   ((_FP_QNANNEGATEDP)                                   \
  45.    ? (_FP_FRAC_HIGH_##fs (X) & _FP_QNANBIT_SH_##fs)     \
  46.    : !(_FP_FRAC_HIGH_##fs (X) & _FP_QNANBIT_SH_##fs))
  47.  
  48. /* Finish truly unpacking a native fp value by classifying the kind
  49.    of fp value and normalizing both the exponent and the fraction.  */
  50.  
  51. #define _FP_UNPACK_CANONICAL(fs, wc, X)                         \
  52.   do                                                            \
  53.     {                                                           \
  54.       switch (X##_e)                                            \
  55.         {                                                       \
  56.         default:                                                \
  57.           _FP_FRAC_HIGH_RAW_##fs (X) |= _FP_IMPLBIT_##fs;       \
  58.           _FP_FRAC_SLL_##wc (X, _FP_WORKBITS);                  \
  59.           X##_e -= _FP_EXPBIAS_##fs;                            \
  60.           X##_c = FP_CLS_NORMAL;                                \
  61.           break;                                                \
  62.                                                                 \
  63.         case 0:                                                 \
  64.           if (_FP_FRAC_ZEROP_##wc (X))                          \
  65.             X##_c = FP_CLS_ZERO;                                \
  66.           else if (FP_DENORM_ZERO)                              \
  67.             {                                                   \
  68.               X##_c = FP_CLS_ZERO;                              \
  69.               _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc);         \
  70.               FP_SET_EXCEPTION (FP_EX_DENORM);                  \
  71.             }                                                   \
  72.           else                                                  \
  73.             {                                                   \
  74.               /* A denormalized number.  */                     \
  75.               _FP_I_TYPE _FP_UNPACK_CANONICAL_shift;            \
  76.               _FP_FRAC_CLZ_##wc (_FP_UNPACK_CANONICAL_shift,    \
  77.                                  X);                            \
  78.               _FP_UNPACK_CANONICAL_shift -= _FP_FRACXBITS_##fs; \
  79.               _FP_FRAC_SLL_##wc (X, (_FP_UNPACK_CANONICAL_shift \
  80.                                      + _FP_WORKBITS));          \
  81.               X##_e -= (_FP_EXPBIAS_##fs - 1                    \
  82.                         + _FP_UNPACK_CANONICAL_shift);          \
  83.               X##_c = FP_CLS_NORMAL;                            \
  84.               FP_SET_EXCEPTION (FP_EX_DENORM);                  \
  85.             }                                                   \
  86.           break;                                                \
  87.                                                                 \
  88.         case _FP_EXPMAX_##fs:                                   \
  89.           if (_FP_FRAC_ZEROP_##wc (X))                          \
  90.             X##_c = FP_CLS_INF;                                 \
  91.           else                                                  \
  92.             {                                                   \
  93.               X##_c = FP_CLS_NAN;                               \
  94.               /* Check for signaling NaN.  */                   \
  95.               if (_FP_FRAC_SNANP (fs, X))                       \
  96.                 FP_SET_EXCEPTION (FP_EX_INVALID                 \
  97.                                   | FP_EX_INVALID_SNAN);        \
  98.             }                                                   \
  99.           break;                                                \
  100.         }                                                       \
  101.     }                                                           \
  102.   while (0)
  103.  
  104. /* Finish unpacking an fp value in semi-raw mode: the mantissa is
  105.    shifted by _FP_WORKBITS but the implicit MSB is not inserted and
  106.    other classification is not done.  */
  107. #define _FP_UNPACK_SEMIRAW(fs, wc, X)   _FP_FRAC_SLL_##wc (X, _FP_WORKBITS)
  108.  
  109. /* Check whether a raw or semi-raw input value should be flushed to
  110.    zero, and flush it to zero if so.  */
  111. #define _FP_CHECK_FLUSH_ZERO(fs, wc, X)                 \
  112.   do                                                    \
  113.     {                                                   \
  114.       if (FP_DENORM_ZERO                                \
  115.           && X##_e == 0                                 \
  116.           && !_FP_FRAC_ZEROP_##wc (X))                  \
  117.         {                                               \
  118.           _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc);     \
  119.           FP_SET_EXCEPTION (FP_EX_DENORM);              \
  120.         }                                               \
  121.     }                                                   \
  122.   while (0)
  123.  
  124. /* A semi-raw value has overflowed to infinity.  Adjust the mantissa
  125.    and exponent appropriately.  */
  126. #define _FP_OVERFLOW_SEMIRAW(fs, wc, X)                 \
  127.   do                                                    \
  128.     {                                                   \
  129.       if (FP_ROUNDMODE == FP_RND_NEAREST                \
  130.           || (FP_ROUNDMODE == FP_RND_PINF && !X##_s)    \
  131.           || (FP_ROUNDMODE == FP_RND_MINF && X##_s))    \
  132.         {                                               \
  133.           X##_e = _FP_EXPMAX_##fs;                      \
  134.           _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc);     \
  135.         }                                               \
  136.       else                                              \
  137.         {                                               \
  138.           X##_e = _FP_EXPMAX_##fs - 1;                  \
  139.           _FP_FRAC_SET_##wc (X, _FP_MAXFRAC_##wc);      \
  140.         }                                               \
  141.       FP_SET_EXCEPTION (FP_EX_INEXACT);                 \
  142.       FP_SET_EXCEPTION (FP_EX_OVERFLOW);                \
  143.     }                                                   \
  144.   while (0)
  145.  
  146. /* Check for a semi-raw value being a signaling NaN and raise the
  147.    invalid exception if so.  */
  148. #define _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X)                     \
  149.   do                                                            \
  150.     {                                                           \
  151.       if (X##_e == _FP_EXPMAX_##fs                              \
  152.           && !_FP_FRAC_ZEROP_##wc (X)                           \
  153.           && _FP_FRAC_SNANP_SEMIRAW (fs, X))                    \
  154.         FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_SNAN);  \
  155.     }                                                           \
  156.   while (0)
  157.  
  158. /* Choose a NaN result from an operation on two semi-raw NaN
  159.    values.  */
  160. #define _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP)                      \
  161.   do                                                                    \
  162.     {                                                                   \
  163.       /* _FP_CHOOSENAN expects raw values, so shift as required.  */    \
  164.       _FP_FRAC_SRL_##wc (X, _FP_WORKBITS);                              \
  165.       _FP_FRAC_SRL_##wc (Y, _FP_WORKBITS);                              \
  166.       _FP_CHOOSENAN (fs, wc, R, X, Y, OP);                              \
  167.       _FP_FRAC_SLL_##wc (R, _FP_WORKBITS);                              \
  168.     }                                                                   \
  169.   while (0)
  170.  
  171. /* Make the fractional part a quiet NaN, preserving the payload
  172.    if possible, otherwise make it the canonical quiet NaN and set
  173.    the sign bit accordingly.  */
  174. #define _FP_SETQNAN(fs, wc, X)                                  \
  175.   do                                                            \
  176.     {                                                           \
  177.       if (_FP_QNANNEGATEDP)                                     \
  178.         {                                                       \
  179.           _FP_FRAC_HIGH_RAW_##fs (X) &= _FP_QNANBIT_##fs - 1;   \
  180.           if (_FP_FRAC_ZEROP_##wc (X))                          \
  181.             {                                                   \
  182.               X##_s = _FP_NANSIGN_##fs;                         \
  183.               _FP_FRAC_SET_##wc (X, _FP_NANFRAC_##fs);          \
  184.             }                                                   \
  185.         }                                                       \
  186.       else                                                      \
  187.         _FP_FRAC_HIGH_RAW_##fs (X) |= _FP_QNANBIT_##fs;         \
  188.     }                                                           \
  189.   while (0)
  190. #define _FP_SETQNAN_SEMIRAW(fs, wc, X)                          \
  191.   do                                                            \
  192.     {                                                           \
  193.       if (_FP_QNANNEGATEDP)                                     \
  194.         {                                                       \
  195.           _FP_FRAC_HIGH_##fs (X) &= _FP_QNANBIT_SH_##fs - 1;    \
  196.           if (_FP_FRAC_ZEROP_##wc (X))                          \
  197.             {                                                   \
  198.               X##_s = _FP_NANSIGN_##fs;                         \
  199.               _FP_FRAC_SET_##wc (X, _FP_NANFRAC_##fs);          \
  200.               _FP_FRAC_SLL_##wc (X, _FP_WORKBITS);              \
  201.             }                                                   \
  202.         }                                                       \
  203.       else                                                      \
  204.         _FP_FRAC_HIGH_##fs (X) |= _FP_QNANBIT_SH_##fs;          \
  205.     }                                                           \
  206.   while (0)
  207.  
  208. /* Test whether a biased exponent is normal (not zero or maximum).  */
  209. #define _FP_EXP_NORMAL(fs, wc, X)       (((X##_e + 1) & _FP_EXPMAX_##fs) > 1)
  210.  
  211. /* Prepare to pack an fp value in semi-raw mode: the mantissa is
  212.    rounded and shifted right, with the rounding possibly increasing
  213.    the exponent (including changing a finite value to infinity).  */
  214. #define _FP_PACK_SEMIRAW(fs, wc, X)                             \
  215.   do                                                            \
  216.     {                                                           \
  217.       int _FP_PACK_SEMIRAW_is_tiny                              \
  218.         = X##_e == 0 && !_FP_FRAC_ZEROP_##wc (X);               \
  219.       if (_FP_TININESS_AFTER_ROUNDING                           \
  220.           && _FP_PACK_SEMIRAW_is_tiny)                          \
  221.         {                                                       \
  222.           FP_DECL_##fs (_FP_PACK_SEMIRAW_T);                    \
  223.           _FP_FRAC_COPY_##wc (_FP_PACK_SEMIRAW_T, X);           \
  224.           _FP_PACK_SEMIRAW_T##_s = X##_s;                       \
  225.           _FP_PACK_SEMIRAW_T##_e = X##_e;                       \
  226.           _FP_FRAC_SLL_##wc (_FP_PACK_SEMIRAW_T, 1);            \
  227.           _FP_ROUND (wc, _FP_PACK_SEMIRAW_T);                   \
  228.           if (_FP_FRAC_OVERP_##wc (fs, _FP_PACK_SEMIRAW_T))     \
  229.             _FP_PACK_SEMIRAW_is_tiny = 0;                       \
  230.         }                                                       \
  231.       _FP_ROUND (wc, X);                                        \
  232.       if (_FP_PACK_SEMIRAW_is_tiny)                             \
  233.         {                                                       \
  234.           if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT)               \
  235.               || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW))    \
  236.             FP_SET_EXCEPTION (FP_EX_UNDERFLOW);                 \
  237.         }                                                       \
  238.       if (_FP_FRAC_HIGH_##fs (X)                                \
  239.           & (_FP_OVERFLOW_##fs >> 1))                           \
  240.         {                                                       \
  241.           _FP_FRAC_HIGH_##fs (X) &= ~(_FP_OVERFLOW_##fs >> 1);  \
  242.           X##_e++;                                              \
  243.           if (X##_e == _FP_EXPMAX_##fs)                         \
  244.             _FP_OVERFLOW_SEMIRAW (fs, wc, X);                   \
  245.         }                                                       \
  246.       _FP_FRAC_SRL_##wc (X, _FP_WORKBITS);                      \
  247.       if (X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X)) \
  248.         {                                                       \
  249.           if (!_FP_KEEPNANFRACP)                                \
  250.             {                                                   \
  251.               _FP_FRAC_SET_##wc (X, _FP_NANFRAC_##fs);          \
  252.               X##_s = _FP_NANSIGN_##fs;                         \
  253.             }                                                   \
  254.           else                                                  \
  255.             _FP_SETQNAN (fs, wc, X);                            \
  256.         }                                                       \
  257.     }                                                           \
  258.   while (0)
  259.  
  260. /* Before packing the bits back into the native fp result, take care
  261.    of such mundane things as rounding and overflow.  Also, for some
  262.    kinds of fp values, the original parts may not have been fully
  263.    extracted -- but that is ok, we can regenerate them now.  */
  264.  
  265. #define _FP_PACK_CANONICAL(fs, wc, X)                                   \
  266.   do                                                                    \
  267.     {                                                                   \
  268.       switch (X##_c)                                                    \
  269.         {                                                               \
  270.         case FP_CLS_NORMAL:                                             \
  271.           X##_e += _FP_EXPBIAS_##fs;                                    \
  272.           if (X##_e > 0)                                                \
  273.             {                                                           \
  274.               _FP_ROUND (wc, X);                                        \
  275.               if (_FP_FRAC_OVERP_##wc (fs, X))                          \
  276.                 {                                                       \
  277.                   _FP_FRAC_CLEAR_OVERP_##wc (fs, X);                    \
  278.                   X##_e++;                                              \
  279.                 }                                                       \
  280.               _FP_FRAC_SRL_##wc (X, _FP_WORKBITS);                      \
  281.               if (X##_e >= _FP_EXPMAX_##fs)                             \
  282.                 {                                                       \
  283.                   /* Overflow.  */                                      \
  284.                   switch (FP_ROUNDMODE)                                 \
  285.                     {                                                   \
  286.                     case FP_RND_NEAREST:                                \
  287.                       X##_c = FP_CLS_INF;                               \
  288.                       break;                                            \
  289.                     case FP_RND_PINF:                                   \
  290.                       if (!X##_s)                                       \
  291.                         X##_c = FP_CLS_INF;                             \
  292.                       break;                                            \
  293.                     case FP_RND_MINF:                                   \
  294.                       if (X##_s)                                        \
  295.                         X##_c = FP_CLS_INF;                             \
  296.                       break;                                            \
  297.                     }                                                   \
  298.                   if (X##_c == FP_CLS_INF)                              \
  299.                     {                                                   \
  300.                       /* Overflow to infinity.  */                      \
  301.                       X##_e = _FP_EXPMAX_##fs;                          \
  302.                       _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc);         \
  303.                     }                                                   \
  304.                   else                                                  \
  305.                     {                                                   \
  306.                       /* Overflow to maximum normal.  */                \
  307.                       X##_e = _FP_EXPMAX_##fs - 1;                      \
  308.                       _FP_FRAC_SET_##wc (X, _FP_MAXFRAC_##wc);          \
  309.                     }                                                   \
  310.                   FP_SET_EXCEPTION (FP_EX_OVERFLOW);                    \
  311.                   FP_SET_EXCEPTION (FP_EX_INEXACT);                     \
  312.                 }                                                       \
  313.             }                                                           \
  314.           else                                                          \
  315.             {                                                           \
  316.               /* We've got a denormalized number.  */                   \
  317.               int _FP_PACK_CANONICAL_is_tiny = 1;                       \
  318.               if (_FP_TININESS_AFTER_ROUNDING && X##_e == 0)            \
  319.                 {                                                       \
  320.                   FP_DECL_##fs (_FP_PACK_CANONICAL_T);                  \
  321.                   _FP_FRAC_COPY_##wc (_FP_PACK_CANONICAL_T, X);         \
  322.                   _FP_PACK_CANONICAL_T##_s = X##_s;                     \
  323.                   _FP_PACK_CANONICAL_T##_e = X##_e;                     \
  324.                   _FP_ROUND (wc, _FP_PACK_CANONICAL_T);                 \
  325.                   if (_FP_FRAC_OVERP_##wc (fs, _FP_PACK_CANONICAL_T))   \
  326.                     _FP_PACK_CANONICAL_is_tiny = 0;                     \
  327.                 }                                                       \
  328.               X##_e = -X##_e + 1;                                       \
  329.               if (X##_e <= _FP_WFRACBITS_##fs)                          \
  330.                 {                                                       \
  331.                   _FP_FRAC_SRS_##wc (X, X##_e, _FP_WFRACBITS_##fs);     \
  332.                   _FP_ROUND (wc, X);                                    \
  333.                   if (_FP_FRAC_HIGH_##fs (X)                            \
  334.                       & (_FP_OVERFLOW_##fs >> 1))                       \
  335.                     {                                                   \
  336.                       X##_e = 1;                                        \
  337.                       _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc);         \
  338.                       FP_SET_EXCEPTION (FP_EX_INEXACT);                 \
  339.                     }                                                   \
  340.                   else                                                  \
  341.                     {                                                   \
  342.                       X##_e = 0;                                        \
  343.                       _FP_FRAC_SRL_##wc (X, _FP_WORKBITS);              \
  344.                     }                                                   \
  345.                   if (_FP_PACK_CANONICAL_is_tiny                        \
  346.                       && ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT)           \
  347.                           || (FP_TRAPPING_EXCEPTIONS                    \
  348.                               & FP_EX_UNDERFLOW)))                      \
  349.                     FP_SET_EXCEPTION (FP_EX_UNDERFLOW);                 \
  350.                 }                                                       \
  351.               else                                                      \
  352.                 {                                                       \
  353.                   /* Underflow to zero.  */                             \
  354.                   X##_e = 0;                                            \
  355.                   if (!_FP_FRAC_ZEROP_##wc (X))                         \
  356.                     {                                                   \
  357.                       _FP_FRAC_SET_##wc (X, _FP_MINFRAC_##wc);          \
  358.                       _FP_ROUND (wc, X);                                \
  359.                       _FP_FRAC_LOW_##wc (X) >>= (_FP_WORKBITS);         \
  360.                     }                                                   \
  361.                   FP_SET_EXCEPTION (FP_EX_UNDERFLOW);                   \
  362.                 }                                                       \
  363.             }                                                           \
  364.           break;                                                        \
  365.                                                                         \
  366.         case FP_CLS_ZERO:                                               \
  367.           X##_e = 0;                                                    \
  368.           _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc);                     \
  369.           break;                                                        \
  370.                                                                         \
  371.         case FP_CLS_INF:                                                \
  372.           X##_e = _FP_EXPMAX_##fs;                                      \
  373.           _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc);                     \
  374.           break;                                                        \
  375.                                                                         \
  376.         case FP_CLS_NAN:                                                \
  377.           X##_e = _FP_EXPMAX_##fs;                                      \
  378.           if (!_FP_KEEPNANFRACP)                                        \
  379.             {                                                           \
  380.               _FP_FRAC_SET_##wc (X, _FP_NANFRAC_##fs);                  \
  381.               X##_s = _FP_NANSIGN_##fs;                                 \
  382.             }                                                           \
  383.           else                                                          \
  384.             _FP_SETQNAN (fs, wc, X);                                    \
  385.           break;                                                        \
  386.         }                                                               \
  387.     }                                                                   \
  388.   while (0)
  389.  
  390. /* This one accepts raw argument and not cooked,  returns
  391.    1 if X is a signaling NaN.  */
  392. #define _FP_ISSIGNAN(fs, wc, X)                 \
  393.   ({                                            \
  394.     int _FP_ISSIGNAN_ret = 0;                   \
  395.     if (X##_e == _FP_EXPMAX_##fs)               \
  396.       {                                         \
  397.         if (!_FP_FRAC_ZEROP_##wc (X)            \
  398.             && _FP_FRAC_SNANP (fs, X))          \
  399.           _FP_ISSIGNAN_ret = 1;                 \
  400.       }                                         \
  401.     _FP_ISSIGNAN_ret;                           \
  402.   })
  403.  
  404.  
  405.  
  406.  
  407.  
  408. /* Addition on semi-raw values.  */
  409. #define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP)                           \
  410.   do                                                                    \
  411.     {                                                                   \
  412.       _FP_CHECK_FLUSH_ZERO (fs, wc, X);                                 \
  413.       _FP_CHECK_FLUSH_ZERO (fs, wc, Y);                                 \
  414.       if (X##_s == Y##_s)                                               \
  415.         {                                                               \
  416.           /* Addition.  */                                              \
  417.           R##_s = X##_s;                                                \
  418.           int _FP_ADD_INTERNAL_ediff = X##_e - Y##_e;                   \
  419.           if (_FP_ADD_INTERNAL_ediff > 0)                               \
  420.             {                                                           \
  421.               R##_e = X##_e;                                            \
  422.               if (Y##_e == 0)                                           \
  423.                 {                                                       \
  424.                   /* Y is zero or denormalized.  */                     \
  425.                   if (_FP_FRAC_ZEROP_##wc (Y))                          \
  426.                     {                                                   \
  427.                       _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X);             \
  428.                       _FP_FRAC_COPY_##wc (R, X);                        \
  429.                       goto add_done;                                    \
  430.                     }                                                   \
  431.                   else                                                  \
  432.                     {                                                   \
  433.                       FP_SET_EXCEPTION (FP_EX_DENORM);                  \
  434.                       _FP_ADD_INTERNAL_ediff--;                         \
  435.                       if (_FP_ADD_INTERNAL_ediff == 0)                  \
  436.                         {                                               \
  437.                           _FP_FRAC_ADD_##wc (R, X, Y);                  \
  438.                           goto add3;                                    \
  439.                         }                                               \
  440.                       if (X##_e == _FP_EXPMAX_##fs)                     \
  441.                         {                                               \
  442.                           _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X);         \
  443.                           _FP_FRAC_COPY_##wc (R, X);                    \
  444.                           goto add_done;                                \
  445.                         }                                               \
  446.                       goto add1;                                        \
  447.                     }                                                   \
  448.                 }                                                       \
  449.               else if (X##_e == _FP_EXPMAX_##fs)                        \
  450.                 {                                                       \
  451.                   /* X is NaN or Inf, Y is normal.  */                  \
  452.                   _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X);                 \
  453.                   _FP_FRAC_COPY_##wc (R, X);                            \
  454.                   goto add_done;                                        \
  455.                 }                                                       \
  456.                                                                         \
  457.               /* Insert implicit MSB of Y.  */                          \
  458.               _FP_FRAC_HIGH_##fs (Y) |= _FP_IMPLBIT_SH_##fs;            \
  459.                                                                         \
  460.             add1:                                                       \
  461.               /* Shift the mantissa of Y to the right                   \
  462.                  _FP_ADD_INTERNAL_EDIFF steps; remember to account      \
  463.                  later for the implicit MSB of X.  */                   \
  464.               if (_FP_ADD_INTERNAL_ediff <= _FP_WFRACBITS_##fs)         \
  465.                 _FP_FRAC_SRS_##wc (Y, _FP_ADD_INTERNAL_ediff,           \
  466.                                    _FP_WFRACBITS_##fs);                 \
  467.               else if (!_FP_FRAC_ZEROP_##wc (Y))                        \
  468.                 _FP_FRAC_SET_##wc (Y, _FP_MINFRAC_##wc);                \
  469.               _FP_FRAC_ADD_##wc (R, X, Y);                              \
  470.             }                                                           \
  471.           else if (_FP_ADD_INTERNAL_ediff < 0)                          \
  472.             {                                                           \
  473.               _FP_ADD_INTERNAL_ediff = -_FP_ADD_INTERNAL_ediff;         \
  474.               R##_e = Y##_e;                                            \
  475.               if (X##_e == 0)                                           \
  476.                 {                                                       \
  477.                   /* X is zero or denormalized.  */                     \
  478.                   if (_FP_FRAC_ZEROP_##wc (X))                          \
  479.                     {                                                   \
  480.                       _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y);             \
  481.                       _FP_FRAC_COPY_##wc (R, Y);                        \
  482.                       goto add_done;                                    \
  483.                     }                                                   \
  484.                   else                                                  \
  485.                     {                                                   \
  486.                       FP_SET_EXCEPTION (FP_EX_DENORM);                  \
  487.                       _FP_ADD_INTERNAL_ediff--;                         \
  488.                       if (_FP_ADD_INTERNAL_ediff == 0)                  \
  489.                         {                                               \
  490.                           _FP_FRAC_ADD_##wc (R, Y, X);                  \
  491.                           goto add3;                                    \
  492.                         }                                               \
  493.                       if (Y##_e == _FP_EXPMAX_##fs)                     \
  494.                         {                                               \
  495.                           _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y);         \
  496.                           _FP_FRAC_COPY_##wc (R, Y);                    \
  497.                           goto add_done;                                \
  498.                         }                                               \
  499.                       goto add2;                                        \
  500.                     }                                                   \
  501.                 }                                                       \
  502.               else if (Y##_e == _FP_EXPMAX_##fs)                        \
  503.                 {                                                       \
  504.                   /* Y is NaN or Inf, X is normal.  */                  \
  505.                   _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y);                 \
  506.                   _FP_FRAC_COPY_##wc (R, Y);                            \
  507.                   goto add_done;                                        \
  508.                 }                                                       \
  509.                                                                         \
  510.               /* Insert implicit MSB of X.  */                          \
  511.               _FP_FRAC_HIGH_##fs (X) |= _FP_IMPLBIT_SH_##fs;            \
  512.                                                                         \
  513.             add2:                                                       \
  514.               /* Shift the mantissa of X to the right                   \
  515.                  _FP_ADD_INTERNAL_EDIFF steps; remember to account      \
  516.                  later for the implicit MSB of Y.  */                   \
  517.               if (_FP_ADD_INTERNAL_ediff <= _FP_WFRACBITS_##fs)         \
  518.                 _FP_FRAC_SRS_##wc (X, _FP_ADD_INTERNAL_ediff,           \
  519.                                    _FP_WFRACBITS_##fs);                 \
  520.               else if (!_FP_FRAC_ZEROP_##wc (X))                        \
  521.                 _FP_FRAC_SET_##wc (X, _FP_MINFRAC_##wc);                \
  522.               _FP_FRAC_ADD_##wc (R, Y, X);                              \
  523.             }                                                           \
  524.           else                                                          \
  525.             {                                                           \
  526.               /* _FP_ADD_INTERNAL_ediff == 0.  */                       \
  527.               if (!_FP_EXP_NORMAL (fs, wc, X))                          \
  528.                 {                                                       \
  529.                   if (X##_e == 0)                                       \
  530.                     {                                                   \
  531.                       /* X and Y are zero or denormalized.  */          \
  532.                       R##_e = 0;                                        \
  533.                       if (_FP_FRAC_ZEROP_##wc (X))                      \
  534.                         {                                               \
  535.                           if (!_FP_FRAC_ZEROP_##wc (Y))                 \
  536.                             FP_SET_EXCEPTION (FP_EX_DENORM);            \
  537.                           _FP_FRAC_COPY_##wc (R, Y);                    \
  538.                           goto add_done;                                \
  539.                         }                                               \
  540.                       else if (_FP_FRAC_ZEROP_##wc (Y))                 \
  541.                         {                                               \
  542.                           FP_SET_EXCEPTION (FP_EX_DENORM);              \
  543.                           _FP_FRAC_COPY_##wc (R, X);                    \
  544.                           goto add_done;                                \
  545.                         }                                               \
  546.                       else                                              \
  547.                         {                                               \
  548.                           FP_SET_EXCEPTION (FP_EX_DENORM);              \
  549.                           _FP_FRAC_ADD_##wc (R, X, Y);                  \
  550.                           if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs) \
  551.                             {                                           \
  552.                               /* Normalized result.  */                 \
  553.                               _FP_FRAC_HIGH_##fs (R)                    \
  554.                                 &= ~(_FP_W_TYPE) _FP_IMPLBIT_SH_##fs;   \
  555.                               R##_e = 1;                                \
  556.                             }                                           \
  557.                           goto add_done;                                \
  558.                         }                                               \
  559.                     }                                                   \
  560.                   else                                                  \
  561.                     {                                                   \
  562.                       /* X and Y are NaN or Inf.  */                    \
  563.                       _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X);             \
  564.                       _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y);             \
  565.                       R##_e = _FP_EXPMAX_##fs;                          \
  566.                       if (_FP_FRAC_ZEROP_##wc (X))                      \
  567.                         _FP_FRAC_COPY_##wc (R, Y);                      \
  568.                       else if (_FP_FRAC_ZEROP_##wc (Y))                 \
  569.                         _FP_FRAC_COPY_##wc (R, X);                      \
  570.                       else                                              \
  571.                         _FP_CHOOSENAN_SEMIRAW (fs, wc, R, X, Y, OP);    \
  572.                       goto add_done;                                    \
  573.                     }                                                   \
  574.                 }                                                       \
  575.               /* The exponents of X and Y, both normal, are equal.  The \
  576.                  implicit MSBs will always add to increase the          \
  577.                  exponent.  */                                          \
  578.               _FP_FRAC_ADD_##wc (R, X, Y);                              \
  579.               R##_e = X##_e + 1;                                        \
  580.               _FP_FRAC_SRS_##wc (R, 1, _FP_WFRACBITS_##fs);             \
  581.               if (R##_e == _FP_EXPMAX_##fs)                             \
  582.                 /* Overflow to infinity (depending on rounding mode).  */ \
  583.                 _FP_OVERFLOW_SEMIRAW (fs, wc, R);                       \
  584.               goto add_done;                                            \
  585.             }                                                           \
  586.         add3:                                                           \
  587.           if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs)             \
  588.             {                                                           \
  589.               /* Overflow.  */                                          \
  590.               _FP_FRAC_HIGH_##fs (R) &= ~(_FP_W_TYPE) _FP_IMPLBIT_SH_##fs; \
  591.               R##_e++;                                                  \
  592.               _FP_FRAC_SRS_##wc (R, 1, _FP_WFRACBITS_##fs);             \
  593.               if (R##_e == _FP_EXPMAX_##fs)                             \
  594.                 /* Overflow to infinity (depending on rounding mode).  */ \
  595.                 _FP_OVERFLOW_SEMIRAW (fs, wc, R);                       \
  596.             }                                                           \
  597.         add_done: ;                                                     \
  598.         }                                                               \
  599.       else                                                              \
  600.         {                                                               \
  601.           /* Subtraction.  */                                           \
  602.           int _FP_ADD_INTERNAL_ediff = X##_e - Y##_e;                   \
  603.           if (_FP_ADD_INTERNAL_ediff > 0)                               \
  604.             {                                                           \
  605.               R##_e = X##_e;                                            \
  606.               R##_s = X##_s;                                            \
  607.               if (Y##_e == 0)                                           \
  608.                 {                                                       \
  609.                   /* Y is zero or denormalized.  */                     \
  610.                   if (_FP_FRAC_ZEROP_##wc (Y))                          \
  611.                     {                                                   \
  612.                       _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X);             \
  613.                       _FP_FRAC_COPY_##wc (R, X);                        \
  614.                       goto sub_done;                                    \
  615.                     }                                                   \
  616.                   else                                                  \
  617.                     {                                                   \
  618.                       FP_SET_EXCEPTION (FP_EX_DENORM);                  \
  619.                       _FP_ADD_INTERNAL_ediff--;                         \
  620.                       if (_FP_ADD_INTERNAL_ediff == 0)                  \
  621.                         {                                               \
  622.                           _FP_FRAC_SUB_##wc (R, X, Y);                  \
  623.                           goto sub3;                                    \
  624.                         }                                               \
  625.                       if (X##_e == _FP_EXPMAX_##fs)                     \
  626.                         {                                               \
  627.                           _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X);         \
  628.                           _FP_FRAC_COPY_##wc (R, X);                    \
  629.                           goto sub_done;                                \
  630.                         }                                               \
  631.                       goto sub1;                                        \
  632.                     }                                                   \
  633.                 }                                                       \
  634.               else if (X##_e == _FP_EXPMAX_##fs)                        \
  635.                 {                                                       \
  636.                   /* X is NaN or Inf, Y is normal.  */                  \
  637.                   _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X);                 \
  638.                   _FP_FRAC_COPY_##wc (R, X);                            \
  639.                   goto sub_done;                                        \
  640.                 }                                                       \
  641.                                                                         \
  642.               /* Insert implicit MSB of Y.  */                          \
  643.               _FP_FRAC_HIGH_##fs (Y) |= _FP_IMPLBIT_SH_##fs;            \
  644.                                                                         \
  645.             sub1:                                                       \
  646.               /* Shift the mantissa of Y to the right                   \
  647.                  _FP_ADD_INTERNAL_EDIFF steps; remember to account      \
  648.                  later for the implicit MSB of X.  */                   \
  649.               if (_FP_ADD_INTERNAL_ediff <= _FP_WFRACBITS_##fs)         \
  650.                 _FP_FRAC_SRS_##wc (Y, _FP_ADD_INTERNAL_ediff,           \
  651.                                    _FP_WFRACBITS_##fs);                 \
  652.               else if (!_FP_FRAC_ZEROP_##wc (Y))                        \
  653.                 _FP_FRAC_SET_##wc (Y, _FP_MINFRAC_##wc);                \
  654.               _FP_FRAC_SUB_##wc (R, X, Y);                              \
  655.             }                                                           \
  656.           else if (_FP_ADD_INTERNAL_ediff < 0)                          \
  657.             {                                                           \
  658.               _FP_ADD_INTERNAL_ediff = -_FP_ADD_INTERNAL_ediff;         \
  659.               R##_e = Y##_e;                                            \
  660.               R##_s = Y##_s;                                            \
  661.               if (X##_e == 0)                                           \
  662.                 {                                                       \
  663.                   /* X is zero or denormalized.  */                     \
  664.                   if (_FP_FRAC_ZEROP_##wc (X))                          \
  665.                     {                                                   \
  666.                       _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y);             \
  667.                       _FP_FRAC_COPY_##wc (R, Y);                        \
  668.                       goto sub_done;                                    \
  669.                     }                                                   \
  670.                   else                                                  \
  671.                     {                                                   \
  672.                       FP_SET_EXCEPTION (FP_EX_DENORM);                  \
  673.                       _FP_ADD_INTERNAL_ediff--;                         \
  674.                       if (_FP_ADD_INTERNAL_ediff == 0)                  \
  675.                         {                                               \
  676.                           _FP_FRAC_SUB_##wc (R, Y, X);                  \
  677.                           goto sub3;                                    \
  678.                         }                                               \
  679.                       if (Y##_e == _FP_EXPMAX_##fs)                     \
  680.                         {                                               \
  681.                           _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y);         \
  682.                           _FP_FRAC_COPY_##wc (R, Y);                    \
  683.                           goto sub_done;                                \
  684.                         }                                               \
  685.                       goto sub2;                                        \
  686.                     }                                                   \
  687.                 }                                                       \
  688.               else if (Y##_e == _FP_EXPMAX_##fs)                        \
  689.                 {                                                       \
  690.                   /* Y is NaN or Inf, X is normal.  */                  \
  691.                   _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y);                 \
  692.                   _FP_FRAC_COPY_##wc (R, Y);                            \
  693.                   goto sub_done;                                        \
  694.                 }                                                       \
  695.                                                                         \
  696.               /* Insert implicit MSB of X.  */                          \
  697.               _FP_FRAC_HIGH_##fs (X) |= _FP_IMPLBIT_SH_##fs;            \
  698.                                                                         \
  699.             sub2:                                                       \
  700.               /* Shift the mantissa of X to the right                   \
  701.                  _FP_ADD_INTERNAL_EDIFF steps; remember to account      \
  702.                  later for the implicit MSB of Y.  */                   \
  703.               if (_FP_ADD_INTERNAL_ediff <= _FP_WFRACBITS_##fs)         \
  704.                 _FP_FRAC_SRS_##wc (X, _FP_ADD_INTERNAL_ediff,           \
  705.                                    _FP_WFRACBITS_##fs);                 \
  706.               else if (!_FP_FRAC_ZEROP_##wc (X))                        \
  707.                 _FP_FRAC_SET_##wc (X, _FP_MINFRAC_##wc);                \
  708.               _FP_FRAC_SUB_##wc (R, Y, X);                              \
  709.             }                                                           \
  710.           else                                                          \
  711.             {                                                           \
  712.               /* ediff == 0.  */                                        \
  713.               if (!_FP_EXP_NORMAL (fs, wc, X))                          \
  714.                 {                                                       \
  715.                   if (X##_e == 0)                                       \
  716.                     {                                                   \
  717.                       /* X and Y are zero or denormalized.  */          \
  718.                       R##_e = 0;                                        \
  719.                       if (_FP_FRAC_ZEROP_##wc (X))                      \
  720.                         {                                               \
  721.                           _FP_FRAC_COPY_##wc (R, Y);                    \
  722.                           if (_FP_FRAC_ZEROP_##wc (Y))                  \
  723.                             R##_s = (FP_ROUNDMODE == FP_RND_MINF);      \
  724.                           else                                          \
  725.                             {                                           \
  726.                               FP_SET_EXCEPTION (FP_EX_DENORM);          \
  727.                               R##_s = Y##_s;                            \
  728.                             }                                           \
  729.                           goto sub_done;                                \
  730.                         }                                               \
  731.                       else if (_FP_FRAC_ZEROP_##wc (Y))                 \
  732.                         {                                               \
  733.                           FP_SET_EXCEPTION (FP_EX_DENORM);              \
  734.                           _FP_FRAC_COPY_##wc (R, X);                    \
  735.                           R##_s = X##_s;                                \
  736.                           goto sub_done;                                \
  737.                         }                                               \
  738.                       else                                              \
  739.                         {                                               \
  740.                           FP_SET_EXCEPTION (FP_EX_DENORM);              \
  741.                           _FP_FRAC_SUB_##wc (R, X, Y);                  \
  742.                           R##_s = X##_s;                                \
  743.                           if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs) \
  744.                             {                                           \
  745.                               /* |X| < |Y|, negate result.  */          \
  746.                               _FP_FRAC_SUB_##wc (R, Y, X);              \
  747.                               R##_s = Y##_s;                            \
  748.                             }                                           \
  749.                           else if (_FP_FRAC_ZEROP_##wc (R))             \
  750.                             R##_s = (FP_ROUNDMODE == FP_RND_MINF);      \
  751.                           goto sub_done;                                \
  752.                         }                                               \
  753.                     }                                                   \
  754.                   else                                                  \
  755.                     {                                                   \
  756.                       /* X and Y are NaN or Inf, of opposite signs.  */ \
  757.                       _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X);             \
  758.                       _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y);             \
  759.                       R##_e = _FP_EXPMAX_##fs;                          \
  760.                       if (_FP_FRAC_ZEROP_##wc (X))                      \
  761.                         {                                               \
  762.                           if (_FP_FRAC_ZEROP_##wc (Y))                  \
  763.                             {                                           \
  764.                               /* Inf - Inf.  */                         \
  765.                               R##_s = _FP_NANSIGN_##fs;                 \
  766.                               _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs);  \
  767.                               _FP_FRAC_SLL_##wc (R, _FP_WORKBITS);      \
  768.                               FP_SET_EXCEPTION (FP_EX_INVALID           \
  769.                                                 | FP_EX_INVALID_ISI);   \
  770.                             }                                           \
  771.                           else                                          \
  772.                             {                                           \
  773.                               /* Inf - NaN.  */                         \
  774.                               R##_s = Y##_s;                            \
  775.                               _FP_FRAC_COPY_##wc (R, Y);                \
  776.                             }                                           \
  777.                         }                                               \
  778.                       else                                              \
  779.                         {                                               \
  780.                           if (_FP_FRAC_ZEROP_##wc (Y))                  \
  781.                             {                                           \
  782.                               /* NaN - Inf.  */                         \
  783.                               R##_s = X##_s;                            \
  784.                               _FP_FRAC_COPY_##wc (R, X);                \
  785.                             }                                           \
  786.                           else                                          \
  787.                             {                                           \
  788.                               /* NaN - NaN.  */                         \
  789.                               _FP_CHOOSENAN_SEMIRAW (fs, wc, R, X, Y, OP); \
  790.                             }                                           \
  791.                         }                                               \
  792.                       goto sub_done;                                    \
  793.                     }                                                   \
  794.                 }                                                       \
  795.               /* The exponents of X and Y, both normal, are equal.  The \
  796.                  implicit MSBs cancel.  */                              \
  797.               R##_e = X##_e;                                            \
  798.               _FP_FRAC_SUB_##wc (R, X, Y);                              \
  799.               R##_s = X##_s;                                            \
  800.               if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs)         \
  801.                 {                                                       \
  802.                   /* |X| < |Y|, negate result.  */                      \
  803.                   _FP_FRAC_SUB_##wc (R, Y, X);                          \
  804.                   R##_s = Y##_s;                                        \
  805.                 }                                                       \
  806.               else if (_FP_FRAC_ZEROP_##wc (R))                         \
  807.                 {                                                       \
  808.                   R##_e = 0;                                            \
  809.                   R##_s = (FP_ROUNDMODE == FP_RND_MINF);                \
  810.                   goto sub_done;                                        \
  811.                 }                                                       \
  812.               goto norm;                                                \
  813.             }                                                           \
  814.         sub3:                                                           \
  815.           if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs)             \
  816.             {                                                           \
  817.               int _FP_ADD_INTERNAL_diff;                                \
  818.               /* Carry into most significant bit of larger one of X and Y, \
  819.                  canceling it; renormalize.  */                         \
  820.               _FP_FRAC_HIGH_##fs (R) &= _FP_IMPLBIT_SH_##fs - 1;        \
  821.             norm:                                                       \
  822.               _FP_FRAC_CLZ_##wc (_FP_ADD_INTERNAL_diff, R);             \
  823.               _FP_ADD_INTERNAL_diff -= _FP_WFRACXBITS_##fs;             \
  824.               _FP_FRAC_SLL_##wc (R, _FP_ADD_INTERNAL_diff);             \
  825.               if (R##_e <= _FP_ADD_INTERNAL_diff)                       \
  826.                 {                                                       \
  827.                   /* R is denormalized.  */                             \
  828.                   _FP_ADD_INTERNAL_diff                                 \
  829.                     = _FP_ADD_INTERNAL_diff - R##_e + 1;                \
  830.                   _FP_FRAC_SRS_##wc (R, _FP_ADD_INTERNAL_diff,          \
  831.                                      _FP_WFRACBITS_##fs);               \
  832.                   R##_e = 0;                                            \
  833.                 }                                                       \
  834.               else                                                      \
  835.                 {                                                       \
  836.                   R##_e -= _FP_ADD_INTERNAL_diff;                       \
  837.                   _FP_FRAC_HIGH_##fs (R) &= ~(_FP_W_TYPE) _FP_IMPLBIT_SH_##fs; \
  838.                 }                                                       \
  839.             }                                                           \
  840.         sub_done: ;                                                     \
  841.         }                                                               \
  842.     }                                                                   \
  843.   while (0)
  844.  
  845. #define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL (fs, wc, R, X, Y, '+')
  846. #define _FP_SUB(fs, wc, R, X, Y)                                        \
  847.   do                                                                    \
  848.     {                                                                   \
  849.       if (!(Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y)))      \
  850.         Y##_s ^= 1;                                                     \
  851.       _FP_ADD_INTERNAL (fs, wc, R, X, Y, '-');                          \
  852.     }                                                                   \
  853.   while (0)
  854.  
  855.  
  856. /* Main negation routine.  The input value is raw.  */
  857.  
  858. #define _FP_NEG(fs, wc, R, X)                   \
  859.   do                                            \
  860.     {                                           \
  861.       _FP_FRAC_COPY_##wc (R, X);                \
  862.       R##_e = X##_e;                            \
  863.       R##_s = 1 ^ X##_s;                        \
  864.     }                                           \
  865.   while (0)
  866.  
  867.  
  868. /* Main multiplication routine.  The input values should be cooked.  */
  869.  
  870. #define _FP_MUL(fs, wc, R, X, Y)                                \
  871.   do                                                            \
  872.     {                                                           \
  873.       R##_s = X##_s ^ Y##_s;                                    \
  874.       R##_e = X##_e + Y##_e + 1;                                \
  875.       switch (_FP_CLS_COMBINE (X##_c, Y##_c))                   \
  876.         {                                                       \
  877.         case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NORMAL):    \
  878.           R##_c = FP_CLS_NORMAL;                                \
  879.                                                                 \
  880.           _FP_MUL_MEAT_##fs (R, X, Y);                          \
  881.                                                                 \
  882.           if (_FP_FRAC_OVERP_##wc (fs, R))                      \
  883.             _FP_FRAC_SRS_##wc (R, 1, _FP_WFRACBITS_##fs);       \
  884.           else                                                  \
  885.             R##_e--;                                            \
  886.           break;                                                \
  887.                                                                 \
  888.         case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NAN):          \
  889.           _FP_CHOOSENAN (fs, wc, R, X, Y, '*');                 \
  890.           break;                                                \
  891.                                                                 \
  892.         case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NORMAL):       \
  893.         case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF):          \
  894.         case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO):         \
  895.           R##_s = X##_s;                                        \
  896.                                                                 \
  897.         case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF):          \
  898.         case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL):       \
  899.         case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NORMAL):      \
  900.         case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_ZERO):        \
  901.           _FP_FRAC_COPY_##wc (R, X);                            \
  902.           R##_c = X##_c;                                        \
  903.           break;                                                \
  904.                                                                 \
  905.         case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NAN):       \
  906.         case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN):          \
  907.         case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN):         \
  908.           R##_s = Y##_s;                                        \
  909.                                                                 \
  910.         case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_INF):       \
  911.         case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_ZERO):      \
  912.           _FP_FRAC_COPY_##wc (R, Y);                            \
  913.           R##_c = Y##_c;                                        \
  914.           break;                                                \
  915.                                                                 \
  916.         case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO):         \
  917.         case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_INF):         \
  918.           R##_s = _FP_NANSIGN_##fs;                             \
  919.           R##_c = FP_CLS_NAN;                                   \
  920.           _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs);              \
  921.           FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_IMZ); \
  922.           break;                                                \
  923.                                                                 \
  924.         default:                                                \
  925.           abort ();                                             \
  926.         }                                                       \
  927.     }                                                           \
  928.   while (0)
  929.  
  930.  
  931. /* Fused multiply-add.  The input values should be cooked.  */
  932.  
  933. #define _FP_FMA(fs, wc, dwc, R, X, Y, Z)                                \
  934.   do                                                                    \
  935.     {                                                                   \
  936.       FP_DECL_##fs (_FP_FMA_T);                                         \
  937.       _FP_FMA_T##_s = X##_s ^ Y##_s;                                    \
  938.       _FP_FMA_T##_e = X##_e + Y##_e + 1;                                \
  939.       switch (_FP_CLS_COMBINE (X##_c, Y##_c))                           \
  940.         {                                                               \
  941.         case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NORMAL):            \
  942.           switch (Z##_c)                                                \
  943.             {                                                           \
  944.             case FP_CLS_INF:                                            \
  945.             case FP_CLS_NAN:                                            \
  946.               R##_s = Z##_s;                                            \
  947.               _FP_FRAC_COPY_##wc (R, Z);                                \
  948.               R##_c = Z##_c;                                            \
  949.               break;                                                    \
  950.                                                                         \
  951.             case FP_CLS_ZERO:                                           \
  952.               R##_c = FP_CLS_NORMAL;                                    \
  953.               R##_s = _FP_FMA_T##_s;                                    \
  954.               R##_e = _FP_FMA_T##_e;                                    \
  955.                                                                         \
  956.               _FP_MUL_MEAT_##fs (R, X, Y);                              \
  957.                                                                         \
  958.               if (_FP_FRAC_OVERP_##wc (fs, R))                          \
  959.                 _FP_FRAC_SRS_##wc (R, 1, _FP_WFRACBITS_##fs);           \
  960.               else                                                      \
  961.                 R##_e--;                                                \
  962.               break;                                                    \
  963.                                                                         \
  964.             case FP_CLS_NORMAL:;                                        \
  965.               _FP_FRAC_DECL_##dwc (_FP_FMA_TD);                         \
  966.               _FP_FRAC_DECL_##dwc (_FP_FMA_ZD);                         \
  967.               _FP_FRAC_DECL_##dwc (_FP_FMA_RD);                         \
  968.               _FP_MUL_MEAT_DW_##fs (_FP_FMA_TD, X, Y);                  \
  969.               R##_e = _FP_FMA_T##_e;                                    \
  970.               int _FP_FMA_tsh                                           \
  971.                 = _FP_FRAC_HIGHBIT_DW_##dwc (fs, _FP_FMA_TD) == 0;      \
  972.               _FP_FMA_T##_e -= _FP_FMA_tsh;                             \
  973.               int _FP_FMA_ediff = _FP_FMA_T##_e - Z##_e;                \
  974.               if (_FP_FMA_ediff >= 0)                                   \
  975.                 {                                                       \
  976.                   int _FP_FMA_shift                                     \
  977.                     = _FP_WFRACBITS_##fs - _FP_FMA_tsh - _FP_FMA_ediff; \
  978.                   if (_FP_FMA_shift <= -_FP_WFRACBITS_##fs)             \
  979.                     _FP_FRAC_SET_##dwc (_FP_FMA_ZD, _FP_MINFRAC_##dwc); \
  980.                   else                                                  \
  981.                     {                                                   \
  982.                       _FP_FRAC_COPY_##dwc##_##wc (_FP_FMA_ZD, Z);       \
  983.                       if (_FP_FMA_shift < 0)                            \
  984.                         _FP_FRAC_SRS_##dwc (_FP_FMA_ZD, -_FP_FMA_shift, \
  985.                                             _FP_WFRACBITS_DW_##fs);     \
  986.                       else if (_FP_FMA_shift > 0)                       \
  987.                         _FP_FRAC_SLL_##dwc (_FP_FMA_ZD, _FP_FMA_shift); \
  988.                     }                                                   \
  989.                   R##_s = _FP_FMA_T##_s;                                \
  990.                   if (_FP_FMA_T##_s == Z##_s)                           \
  991.                     _FP_FRAC_ADD_##dwc (_FP_FMA_RD, _FP_FMA_TD,         \
  992.                                         _FP_FMA_ZD);                    \
  993.                   else                                                  \
  994.                     {                                                   \
  995.                       _FP_FRAC_SUB_##dwc (_FP_FMA_RD, _FP_FMA_TD,       \
  996.                                           _FP_FMA_ZD);                  \
  997.                       if (_FP_FRAC_NEGP_##dwc (_FP_FMA_RD))             \
  998.                         {                                               \
  999.                           R##_s = Z##_s;                                \
  1000.                           _FP_FRAC_SUB_##dwc (_FP_FMA_RD, _FP_FMA_ZD,   \
  1001.                                               _FP_FMA_TD);              \
  1002.                         }                                               \
  1003.                     }                                                   \
  1004.                 }                                                       \
  1005.               else                                                      \
  1006.                 {                                                       \
  1007.                   R##_e = Z##_e;                                        \
  1008.                   R##_s = Z##_s;                                        \
  1009.                   _FP_FRAC_COPY_##dwc##_##wc (_FP_FMA_ZD, Z);           \
  1010.                   _FP_FRAC_SLL_##dwc (_FP_FMA_ZD, _FP_WFRACBITS_##fs);  \
  1011.                   int _FP_FMA_shift = -_FP_FMA_ediff - _FP_FMA_tsh;     \
  1012.                   if (_FP_FMA_shift >= _FP_WFRACBITS_DW_##fs)           \
  1013.                     _FP_FRAC_SET_##dwc (_FP_FMA_TD, _FP_MINFRAC_##dwc); \
  1014.                   else if (_FP_FMA_shift > 0)                           \
  1015.                     _FP_FRAC_SRS_##dwc (_FP_FMA_TD, _FP_FMA_shift,      \
  1016.                                         _FP_WFRACBITS_DW_##fs);         \
  1017.                   if (Z##_s == _FP_FMA_T##_s)                           \
  1018.                     _FP_FRAC_ADD_##dwc (_FP_FMA_RD, _FP_FMA_ZD,         \
  1019.                                         _FP_FMA_TD);                    \
  1020.                   else                                                  \
  1021.                     _FP_FRAC_SUB_##dwc (_FP_FMA_RD, _FP_FMA_ZD,         \
  1022.                                         _FP_FMA_TD);                    \
  1023.                 }                                                       \
  1024.               if (_FP_FRAC_ZEROP_##dwc (_FP_FMA_RD))                    \
  1025.                 {                                                       \
  1026.                   if (_FP_FMA_T##_s == Z##_s)                           \
  1027.                     R##_s = Z##_s;                                      \
  1028.                   else                                                  \
  1029.                     R##_s = (FP_ROUNDMODE == FP_RND_MINF);              \
  1030.                   _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc);             \
  1031.                   R##_c = FP_CLS_ZERO;                                  \
  1032.                 }                                                       \
  1033.               else                                                      \
  1034.                 {                                                       \
  1035.                   int _FP_FMA_rlz;                                      \
  1036.                   _FP_FRAC_CLZ_##dwc (_FP_FMA_rlz, _FP_FMA_RD);         \
  1037.                   _FP_FMA_rlz -= _FP_WFRACXBITS_DW_##fs;                \
  1038.                   R##_e -= _FP_FMA_rlz;                                 \
  1039.                   int _FP_FMA_shift = _FP_WFRACBITS_##fs - _FP_FMA_rlz; \
  1040.                   if (_FP_FMA_shift > 0)                                \
  1041.                     _FP_FRAC_SRS_##dwc (_FP_FMA_RD, _FP_FMA_shift,      \
  1042.                                         _FP_WFRACBITS_DW_##fs);         \
  1043.                   else if (_FP_FMA_shift < 0)                           \
  1044.                     _FP_FRAC_SLL_##dwc (_FP_FMA_RD, -_FP_FMA_shift);    \
  1045.                   _FP_FRAC_COPY_##wc##_##dwc (R, _FP_FMA_RD);           \
  1046.                   R##_c = FP_CLS_NORMAL;                                \
  1047.                 }                                                       \
  1048.               break;                                                    \
  1049.             }                                                           \
  1050.           goto done_fma;                                                \
  1051.                                                                         \
  1052.         case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NAN):                  \
  1053.           _FP_CHOOSENAN (fs, wc, _FP_FMA_T, X, Y, '*');                 \
  1054.           break;                                                        \
  1055.                                                                         \
  1056.         case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NORMAL):               \
  1057.         case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF):                  \
  1058.         case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO):                 \
  1059.           _FP_FMA_T##_s = X##_s;                                        \
  1060.                                                                         \
  1061.         case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF):                  \
  1062.         case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL):               \
  1063.         case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NORMAL):              \
  1064.         case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_ZERO):                \
  1065.           _FP_FRAC_COPY_##wc (_FP_FMA_T, X);                            \
  1066.           _FP_FMA_T##_c = X##_c;                                        \
  1067.           break;                                                        \
  1068.                                                                         \
  1069.         case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NAN):               \
  1070.         case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN):                  \
  1071.         case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN):                 \
  1072.           _FP_FMA_T##_s = Y##_s;                                        \
  1073.                                                                         \
  1074.         case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_INF):               \
  1075.         case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_ZERO):              \
  1076.           _FP_FRAC_COPY_##wc (_FP_FMA_T, Y);                            \
  1077.           _FP_FMA_T##_c = Y##_c;                                        \
  1078.           break;                                                        \
  1079.                                                                         \
  1080.         case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO):                 \
  1081.         case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_INF):                 \
  1082.           _FP_FMA_T##_s = _FP_NANSIGN_##fs;                             \
  1083.           _FP_FMA_T##_c = FP_CLS_NAN;                                   \
  1084.           _FP_FRAC_SET_##wc (_FP_FMA_T, _FP_NANFRAC_##fs);              \
  1085.           FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_IMZ_FMA);     \
  1086.           break;                                                        \
  1087.                                                                         \
  1088.         default:                                                        \
  1089.           abort ();                                                     \
  1090.         }                                                               \
  1091.                                                                         \
  1092.       /* T = X * Y is zero, infinity or NaN.  */                        \
  1093.       switch (_FP_CLS_COMBINE (_FP_FMA_T##_c, Z##_c))                   \
  1094.         {                                                               \
  1095.         case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NAN):                  \
  1096.           _FP_CHOOSENAN (fs, wc, R, _FP_FMA_T, Z, '+');                 \
  1097.           break;                                                        \
  1098.                                                                         \
  1099.         case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NORMAL):               \
  1100.         case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF):                  \
  1101.         case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO):                 \
  1102.         case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL):               \
  1103.         case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO):                 \
  1104.           R##_s = _FP_FMA_T##_s;                                        \
  1105.           _FP_FRAC_COPY_##wc (R, _FP_FMA_T);                            \
  1106.           R##_c = _FP_FMA_T##_c;                                        \
  1107.           break;                                                        \
  1108.                                                                         \
  1109.         case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN):                  \
  1110.         case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN):                 \
  1111.         case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NORMAL):              \
  1112.         case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_INF):                 \
  1113.           R##_s = Z##_s;                                                \
  1114.           _FP_FRAC_COPY_##wc (R, Z);                                    \
  1115.           R##_c = Z##_c;                                                \
  1116.           break;                                                        \
  1117.                                                                         \
  1118.         case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF):                  \
  1119.           if (_FP_FMA_T##_s == Z##_s)                                   \
  1120.             {                                                           \
  1121.               R##_s = Z##_s;                                            \
  1122.               _FP_FRAC_COPY_##wc (R, Z);                                \
  1123.               R##_c = Z##_c;                                            \
  1124.             }                                                           \
  1125.           else                                                          \
  1126.             {                                                           \
  1127.               R##_s = _FP_NANSIGN_##fs;                                 \
  1128.               R##_c = FP_CLS_NAN;                                       \
  1129.               _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs);                  \
  1130.               FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_ISI);     \
  1131.             }                                                           \
  1132.           break;                                                        \
  1133.                                                                         \
  1134.         case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_ZERO):                \
  1135.           if (_FP_FMA_T##_s == Z##_s)                                   \
  1136.             R##_s = Z##_s;                                              \
  1137.           else                                                          \
  1138.             R##_s = (FP_ROUNDMODE == FP_RND_MINF);                      \
  1139.           _FP_FRAC_COPY_##wc (R, Z);                                    \
  1140.           R##_c = Z##_c;                                                \
  1141.           break;                                                        \
  1142.                                                                         \
  1143.         default:                                                        \
  1144.           abort ();                                                     \
  1145.         }                                                               \
  1146.     done_fma: ;                                                         \
  1147.     }                                                                   \
  1148.   while (0)
  1149.  
  1150.  
  1151. /* Main division routine.  The input values should be cooked.  */
  1152.  
  1153. #define _FP_DIV(fs, wc, R, X, Y)                                \
  1154.   do                                                            \
  1155.     {                                                           \
  1156.       R##_s = X##_s ^ Y##_s;                                    \
  1157.       R##_e = X##_e - Y##_e;                                    \
  1158.       switch (_FP_CLS_COMBINE (X##_c, Y##_c))                   \
  1159.         {                                                       \
  1160.         case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NORMAL):    \
  1161.           R##_c = FP_CLS_NORMAL;                                \
  1162.                                                                 \
  1163.           _FP_DIV_MEAT_##fs (R, X, Y);                          \
  1164.           break;                                                \
  1165.                                                                 \
  1166.         case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NAN):          \
  1167.           _FP_CHOOSENAN (fs, wc, R, X, Y, '/');                 \
  1168.           break;                                                \
  1169.                                                                 \
  1170.         case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NORMAL):       \
  1171.         case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF):          \
  1172.         case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO):         \
  1173.           R##_s = X##_s;                                        \
  1174.           _FP_FRAC_COPY_##wc (R, X);                            \
  1175.           R##_c = X##_c;                                        \
  1176.           break;                                                \
  1177.                                                                 \
  1178.         case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NAN):       \
  1179.         case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN):          \
  1180.         case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN):         \
  1181.           R##_s = Y##_s;                                        \
  1182.           _FP_FRAC_COPY_##wc (R, Y);                            \
  1183.           R##_c = Y##_c;                                        \
  1184.           break;                                                \
  1185.                                                                 \
  1186.         case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_INF):       \
  1187.         case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_INF):         \
  1188.         case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NORMAL):      \
  1189.           R##_c = FP_CLS_ZERO;                                  \
  1190.           break;                                                \
  1191.                                                                 \
  1192.         case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_ZERO):      \
  1193.           FP_SET_EXCEPTION (FP_EX_DIVZERO);                     \
  1194.         case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO):         \
  1195.         case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL):       \
  1196.           R##_c = FP_CLS_INF;                                   \
  1197.           break;                                                \
  1198.                                                                 \
  1199.         case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF):          \
  1200.         case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_ZERO):        \
  1201.           R##_s = _FP_NANSIGN_##fs;                             \
  1202.           R##_c = FP_CLS_NAN;                                   \
  1203.           _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs);              \
  1204.           FP_SET_EXCEPTION (FP_EX_INVALID                       \
  1205.                             | (X##_c == FP_CLS_INF              \
  1206.                                ? FP_EX_INVALID_IDI              \
  1207.                                : FP_EX_INVALID_ZDZ));           \
  1208.           break;                                                \
  1209.                                                                 \
  1210.         default:                                                \
  1211.           abort ();                                             \
  1212.         }                                                       \
  1213.     }                                                           \
  1214.   while (0)
  1215.  
  1216.  
  1217. /* Helper for comparisons.  EX is 0 not to raise exceptions, 1 to
  1218.    raise exceptions for signaling NaN operands, 2 to raise exceptions
  1219.    for all NaN operands.  Conditionals are organized to allow the
  1220.    compiler to optimize away code based on the value of EX.  */
  1221.  
  1222. #define _FP_CMP_CHECK_NAN(fs, wc, X, Y, ex)                             \
  1223.   do                                                                    \
  1224.     {                                                                   \
  1225.       /* The arguments are unordered, which may or may not result in    \
  1226.          an exception.  */                                              \
  1227.       if (ex)                                                           \
  1228.         {                                                               \
  1229.           /* At least some cases of unordered arguments result in       \
  1230.              exceptions; check whether this is one.  */                 \
  1231.           if (FP_EX_INVALID_SNAN || FP_EX_INVALID_VC)                   \
  1232.             {                                                           \
  1233.               /* Check separately for each case of "invalid"            \
  1234.                  exceptions.  */                                        \
  1235.               if ((ex) == 2)                                            \
  1236.                 FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_VC);    \
  1237.               if (_FP_ISSIGNAN (fs, wc, X)                              \
  1238.                   || _FP_ISSIGNAN (fs, wc, Y))                          \
  1239.                 FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_SNAN);  \
  1240.             }                                                           \
  1241.           /* Otherwise, we only need to check whether to raise an       \
  1242.              exception, not which case or cases it is.  */              \
  1243.           else if ((ex) == 2                                            \
  1244.                    || _FP_ISSIGNAN (fs, wc, X)                          \
  1245.                    || _FP_ISSIGNAN (fs, wc, Y))                         \
  1246.             FP_SET_EXCEPTION (FP_EX_INVALID);                           \
  1247.         }                                                               \
  1248.     }                                                                   \
  1249.   while (0)
  1250.  
  1251. /* Main differential comparison routine.  The inputs should be raw not
  1252.    cooked.  The return is -1, 0, 1 for normal values, UN
  1253.    otherwise.  */
  1254.  
  1255. #define _FP_CMP(fs, wc, ret, X, Y, un, ex)                              \
  1256.   do                                                                    \
  1257.     {                                                                   \
  1258.       /* NANs are unordered.  */                                        \
  1259.       if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X))        \
  1260.           || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y)))    \
  1261.         {                                                               \
  1262.           (ret) = (un);                                                 \
  1263.           _FP_CMP_CHECK_NAN (fs, wc, X, Y, (ex));                       \
  1264.         }                                                               \
  1265.       else                                                              \
  1266.         {                                                               \
  1267.           int _FP_CMP_is_zero_x;                                        \
  1268.           int _FP_CMP_is_zero_y;                                        \
  1269.                                                                         \
  1270.           _FP_CHECK_FLUSH_ZERO (fs, wc, X);                             \
  1271.           _FP_CHECK_FLUSH_ZERO (fs, wc, Y);                             \
  1272.                                                                         \
  1273.           _FP_CMP_is_zero_x                                             \
  1274.             = (!X##_e && _FP_FRAC_ZEROP_##wc (X)) ? 1 : 0;              \
  1275.           _FP_CMP_is_zero_y                                             \
  1276.             = (!Y##_e && _FP_FRAC_ZEROP_##wc (Y)) ? 1 : 0;              \
  1277.                                                                         \
  1278.           if (_FP_CMP_is_zero_x && _FP_CMP_is_zero_y)                   \
  1279.             (ret) = 0;                                                  \
  1280.           else if (_FP_CMP_is_zero_x)                                   \
  1281.             (ret) = Y##_s ? 1 : -1;                                     \
  1282.           else if (_FP_CMP_is_zero_y)                                   \
  1283.             (ret) = X##_s ? -1 : 1;                                     \
  1284.           else if (X##_s != Y##_s)                                      \
  1285.             (ret) = X##_s ? -1 : 1;                                     \
  1286.           else if (X##_e > Y##_e)                                       \
  1287.             (ret) = X##_s ? -1 : 1;                                     \
  1288.           else if (X##_e < Y##_e)                                       \
  1289.             (ret) = X##_s ? 1 : -1;                                     \
  1290.           else if (_FP_FRAC_GT_##wc (X, Y))                             \
  1291.             (ret) = X##_s ? -1 : 1;                                     \
  1292.           else if (_FP_FRAC_GT_##wc (Y, X))                             \
  1293.             (ret) = X##_s ? 1 : -1;                                     \
  1294.           else                                                          \
  1295.             (ret) = 0;                                                  \
  1296.         }                                                               \
  1297.     }                                                                   \
  1298.   while (0)
  1299.  
  1300.  
  1301. /* Simplification for strict equality.  */
  1302.  
  1303. #define _FP_CMP_EQ(fs, wc, ret, X, Y, ex)                               \
  1304.   do                                                                    \
  1305.     {                                                                   \
  1306.       /* NANs are unordered.  */                                        \
  1307.       if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X))        \
  1308.           || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y)))    \
  1309.         {                                                               \
  1310.           (ret) = 1;                                                    \
  1311.           _FP_CMP_CHECK_NAN (fs, wc, X, Y, (ex));                       \
  1312.         }                                                               \
  1313.       else                                                              \
  1314.         {                                                               \
  1315.           _FP_CHECK_FLUSH_ZERO (fs, wc, X);                             \
  1316.           _FP_CHECK_FLUSH_ZERO (fs, wc, Y);                             \
  1317.                                                                         \
  1318.           (ret) = !(X##_e == Y##_e                                      \
  1319.                     && _FP_FRAC_EQ_##wc (X, Y)                          \
  1320.                     && (X##_s == Y##_s                                  \
  1321.                         || (!X##_e && _FP_FRAC_ZEROP_##wc (X))));       \
  1322.         }                                                               \
  1323.     }                                                                   \
  1324.   while (0)
  1325.  
  1326. /* Version to test unordered.  */
  1327.  
  1328. #define _FP_CMP_UNORD(fs, wc, ret, X, Y, ex)                            \
  1329.   do                                                                    \
  1330.     {                                                                   \
  1331.       (ret) = ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X))   \
  1332.                || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y))); \
  1333.       if (ret)                                                          \
  1334.         _FP_CMP_CHECK_NAN (fs, wc, X, Y, (ex));                         \
  1335.     }                                                                   \
  1336.   while (0)
  1337.  
  1338. /* Main square root routine.  The input value should be cooked.  */
  1339.  
  1340. #define _FP_SQRT(fs, wc, R, X)                                          \
  1341.   do                                                                    \
  1342.     {                                                                   \
  1343.       _FP_FRAC_DECL_##wc (_FP_SQRT_T);                                  \
  1344.       _FP_FRAC_DECL_##wc (_FP_SQRT_S);                                  \
  1345.       _FP_W_TYPE _FP_SQRT_q;                                            \
  1346.       switch (X##_c)                                                    \
  1347.         {                                                               \
  1348.         case FP_CLS_NAN:                                                \
  1349.           _FP_FRAC_COPY_##wc (R, X);                                    \
  1350.           R##_s = X##_s;                                                \
  1351.           R##_c = FP_CLS_NAN;                                           \
  1352.           break;                                                        \
  1353.         case FP_CLS_INF:                                                \
  1354.           if (X##_s)                                                    \
  1355.             {                                                           \
  1356.               R##_s = _FP_NANSIGN_##fs;                                 \
  1357.               R##_c = FP_CLS_NAN; /* NAN */                             \
  1358.               _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs);                  \
  1359.               FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_SQRT);    \
  1360.             }                                                           \
  1361.           else                                                          \
  1362.             {                                                           \
  1363.               R##_s = 0;                                                \
  1364.               R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */               \
  1365.             }                                                           \
  1366.           break;                                                        \
  1367.         case FP_CLS_ZERO:                                               \
  1368.           R##_s = X##_s;                                                \
  1369.           R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */                    \
  1370.           break;                                                        \
  1371.         case FP_CLS_NORMAL:                                             \
  1372.           R##_s = 0;                                                    \
  1373.           if (X##_s)                                                    \
  1374.             {                                                           \
  1375.               R##_c = FP_CLS_NAN; /* NAN */                             \
  1376.               R##_s = _FP_NANSIGN_##fs;                                 \
  1377.               _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs);                  \
  1378.               FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_SQRT);    \
  1379.               break;                                                    \
  1380.             }                                                           \
  1381.           R##_c = FP_CLS_NORMAL;                                        \
  1382.           if (X##_e & 1)                                                \
  1383.             _FP_FRAC_SLL_##wc (X, 1);                                   \
  1384.           R##_e = X##_e >> 1;                                           \
  1385.           _FP_FRAC_SET_##wc (_FP_SQRT_S, _FP_ZEROFRAC_##wc);            \
  1386.           _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc);                     \
  1387.           _FP_SQRT_q = _FP_OVERFLOW_##fs >> 1;                          \
  1388.           _FP_SQRT_MEAT_##wc (R, _FP_SQRT_S, _FP_SQRT_T, X,             \
  1389.                               _FP_SQRT_q);                              \
  1390.         }                                                               \
  1391.     }                                                                   \
  1392.   while (0)
  1393.  
  1394. /* Convert from FP to integer.  Input is raw.  */
  1395.  
  1396. /* RSIGNED can have following values:
  1397.    0:  the number is required to be 0..(2^rsize)-1, if not, NV is set plus
  1398.        the result is either 0 or (2^rsize)-1 depending on the sign in such
  1399.        case.
  1400.    1:  the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not,
  1401.        NV is set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
  1402.        depending on the sign in such case.
  1403.    2:  the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not,
  1404.        NV is set plus the result is reduced modulo 2^rsize.
  1405.    -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is
  1406.        set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
  1407.        depending on the sign in such case.  */
  1408. #define _FP_TO_INT(fs, wc, r, X, rsize, rsigned)                        \
  1409.   do                                                                    \
  1410.     {                                                                   \
  1411.       if (X##_e < _FP_EXPBIAS_##fs)                                     \
  1412.         {                                                               \
  1413.           (r) = 0;                                                      \
  1414.           if (X##_e == 0)                                               \
  1415.             {                                                           \
  1416.               if (!_FP_FRAC_ZEROP_##wc (X))                             \
  1417.                 {                                                       \
  1418.                   if (!FP_DENORM_ZERO)                                  \
  1419.                     FP_SET_EXCEPTION (FP_EX_INEXACT);                   \
  1420.                   FP_SET_EXCEPTION (FP_EX_DENORM);                      \
  1421.                 }                                                       \
  1422.             }                                                           \
  1423.           else                                                          \
  1424.             FP_SET_EXCEPTION (FP_EX_INEXACT);                           \
  1425.         }                                                               \
  1426.       else if ((rsigned) == 2                                           \
  1427.                && (X##_e                                                \
  1428.                    >= ((_FP_EXPMAX_##fs                                 \
  1429.                         < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs + (rsize) - 1) \
  1430.                        ? _FP_EXPMAX_##fs                                \
  1431.                        : _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs + (rsize) - 1))) \
  1432.         {                                                               \
  1433.           /* Overflow resulting in 0.  */                               \
  1434.           (r) = 0;                                                      \
  1435.           FP_SET_EXCEPTION (FP_EX_INVALID                               \
  1436.                             | FP_EX_INVALID_CVI                         \
  1437.                             | ((FP_EX_INVALID_SNAN                      \
  1438.                                 && _FP_ISSIGNAN (fs, wc, X))            \
  1439.                                ? FP_EX_INVALID_SNAN                     \
  1440.                                : 0));                                   \
  1441.         }                                                               \
  1442.       else if ((rsigned) != 2                                           \
  1443.                && (X##_e >= (_FP_EXPMAX_##fs < _FP_EXPBIAS_##fs + (rsize) \
  1444.                              ? _FP_EXPMAX_##fs                          \
  1445.                              : (_FP_EXPBIAS_##fs + (rsize)              \
  1446.                                 - ((rsigned) > 0 || X##_s)))            \
  1447.                    || (!(rsigned) && X##_s)))                           \
  1448.         {                                                               \
  1449.           /* Overflow or converting to the most negative integer.  */   \
  1450.           if (rsigned)                                                  \
  1451.             {                                                           \
  1452.               (r) = 1;                                                  \
  1453.               (r) <<= (rsize) - 1;                                      \
  1454.               (r) -= 1 - X##_s;                                         \
  1455.             }                                                           \
  1456.           else                                                          \
  1457.             {                                                           \
  1458.               (r) = 0;                                                  \
  1459.               if (!X##_s)                                               \
  1460.                 (r) = ~(r);                                             \
  1461.             }                                                           \
  1462.                                                                         \
  1463.           if (_FP_EXPBIAS_##fs + (rsize) - 1 < _FP_EXPMAX_##fs          \
  1464.               && (rsigned)                                              \
  1465.               && X##_s                                                  \
  1466.               && X##_e == _FP_EXPBIAS_##fs + (rsize) - 1)               \
  1467.             {                                                           \
  1468.               /* Possibly converting to most negative integer; check the \
  1469.                  mantissa.  */                                          \
  1470.               int _FP_TO_INT_inexact = 0;                               \
  1471.               (void) ((_FP_FRACBITS_##fs > (rsize))                     \
  1472.                       ? ({                                              \
  1473.                           _FP_FRAC_SRST_##wc (X, _FP_TO_INT_inexact,    \
  1474.                                               _FP_FRACBITS_##fs - (rsize), \
  1475.                                               _FP_FRACBITS_##fs);       \
  1476.                           0;                                            \
  1477.                         })                                              \
  1478.                       : 0);                                             \
  1479.               if (!_FP_FRAC_ZEROP_##wc (X))                             \
  1480.                 FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_CVI);   \
  1481.               else if (_FP_TO_INT_inexact)                              \
  1482.                 FP_SET_EXCEPTION (FP_EX_INEXACT);                       \
  1483.             }                                                           \
  1484.           else                                                          \
  1485.             FP_SET_EXCEPTION (FP_EX_INVALID                             \
  1486.                               | FP_EX_INVALID_CVI                       \
  1487.                               | ((FP_EX_INVALID_SNAN                    \
  1488.                                   && _FP_ISSIGNAN (fs, wc, X))          \
  1489.                                  ? FP_EX_INVALID_SNAN                   \
  1490.                                  : 0));                                 \
  1491.         }                                                               \
  1492.       else                                                              \
  1493.         {                                                               \
  1494.           int _FP_TO_INT_inexact = 0;                                   \
  1495.           _FP_FRAC_HIGH_RAW_##fs (X) |= _FP_IMPLBIT_##fs;               \
  1496.           if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1)        \
  1497.             {                                                           \
  1498.               _FP_FRAC_ASSEMBLE_##wc ((r), X, (rsize));                 \
  1499.               (r) <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \
  1500.             }                                                           \
  1501.           else                                                          \
  1502.             {                                                           \
  1503.               _FP_FRAC_SRST_##wc (X, _FP_TO_INT_inexact,                \
  1504.                                   (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs - 1 \
  1505.                                    - X##_e),                            \
  1506.                                   _FP_FRACBITS_##fs);                   \
  1507.               _FP_FRAC_ASSEMBLE_##wc ((r), X, (rsize));                 \
  1508.             }                                                           \
  1509.           if ((rsigned) && X##_s)                                       \
  1510.             (r) = -(r);                                                 \
  1511.           if ((rsigned) == 2 && X##_e >= _FP_EXPBIAS_##fs + (rsize) - 1) \
  1512.             {                                                           \
  1513.               /* Overflow or converting to the most negative integer.  */ \
  1514.               if (X##_e > _FP_EXPBIAS_##fs + (rsize) - 1                \
  1515.                   || !X##_s                                             \
  1516.                   || (r) != (((typeof (r)) 1) << ((rsize) - 1)))        \
  1517.                 {                                                       \
  1518.                   _FP_TO_INT_inexact = 0;                               \
  1519.                   FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_CVI); \
  1520.                 }                                                       \
  1521.             }                                                           \
  1522.           if (_FP_TO_INT_inexact)                                       \
  1523.             FP_SET_EXCEPTION (FP_EX_INEXACT);                           \
  1524.         }                                                               \
  1525.     }                                                                   \
  1526.   while (0)
  1527.  
  1528. /* Convert integer to fp.  Output is raw.  RTYPE is unsigned even if
  1529.    input is signed.  */
  1530. #define _FP_FROM_INT(fs, wc, X, r, rsize, rtype)                        \
  1531.   do                                                                    \
  1532.     {                                                                   \
  1533.       if (r)                                                            \
  1534.         {                                                               \
  1535.           rtype _FP_FROM_INT_ur;                                        \
  1536.                                                                         \
  1537.           if ((X##_s = ((r) < 0)))                                      \
  1538.             (r) = -(rtype) (r);                                         \
  1539.                                                                         \
  1540.           _FP_FROM_INT_ur = (rtype) (r);                                \
  1541.           (void) (((rsize) <= _FP_W_TYPE_SIZE)                          \
  1542.                   ? ({                                                  \
  1543.                       int _FP_FROM_INT_lz;                              \
  1544.                       __FP_CLZ (_FP_FROM_INT_lz,                        \
  1545.                                 (_FP_W_TYPE) _FP_FROM_INT_ur);          \
  1546.                       X##_e = (_FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1   \
  1547.                                - _FP_FROM_INT_lz);                      \
  1548.                     })                                                  \
  1549.                   : (((rsize) <= 2 * _FP_W_TYPE_SIZE)                   \
  1550.                      ? ({                                               \
  1551.                          int _FP_FROM_INT_lz;                           \
  1552.                          __FP_CLZ_2 (_FP_FROM_INT_lz,                   \
  1553.                                      (_FP_W_TYPE) (_FP_FROM_INT_ur      \
  1554.                                                    >> _FP_W_TYPE_SIZE), \
  1555.                                      (_FP_W_TYPE) _FP_FROM_INT_ur);     \
  1556.                          X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \
  1557.                                   - _FP_FROM_INT_lz);                   \
  1558.                        })                                               \
  1559.                      : (abort (), 0)));                                 \
  1560.                                                                         \
  1561.           if ((rsize) - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs         \
  1562.               && X##_e >= _FP_EXPMAX_##fs)                              \
  1563.             {                                                           \
  1564.               /* Exponent too big; overflow to infinity.  (May also     \
  1565.                  happen after rounding below.)  */                      \
  1566.               _FP_OVERFLOW_SEMIRAW (fs, wc, X);                         \
  1567.               goto pack_semiraw;                                        \
  1568.             }                                                           \
  1569.                                                                         \
  1570.           if ((rsize) <= _FP_FRACBITS_##fs                              \
  1571.               || X##_e < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs)          \
  1572.             {                                                           \
  1573.               /* Exactly representable; shift left.  */                 \
  1574.               _FP_FRAC_DISASSEMBLE_##wc (X, _FP_FROM_INT_ur, (rsize));  \
  1575.               if (_FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1 - X##_e > 0) \
  1576.                 _FP_FRAC_SLL_##wc (X, (_FP_EXPBIAS_##fs                 \
  1577.                                        + _FP_FRACBITS_##fs - 1 - X##_e)); \
  1578.             }                                                           \
  1579.           else                                                          \
  1580.             {                                                           \
  1581.               /* More bits in integer than in floating type; need to    \
  1582.                  round.  */                                             \
  1583.               if (_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 < X##_e)    \
  1584.                 _FP_FROM_INT_ur                                         \
  1585.                   = ((_FP_FROM_INT_ur >> (X##_e - _FP_EXPBIAS_##fs      \
  1586.                                           - _FP_WFRACBITS_##fs + 1))    \
  1587.                      | ((_FP_FROM_INT_ur                                \
  1588.                          << ((rsize) - (X##_e - _FP_EXPBIAS_##fs        \
  1589.                                         - _FP_WFRACBITS_##fs + 1)))     \
  1590.                         != 0));                                         \
  1591.               _FP_FRAC_DISASSEMBLE_##wc (X, _FP_FROM_INT_ur, (rsize));  \
  1592.               if ((_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 - X##_e) > 0) \
  1593.                 _FP_FRAC_SLL_##wc (X, (_FP_EXPBIAS_##fs                 \
  1594.                                        + _FP_WFRACBITS_##fs - 1 - X##_e)); \
  1595.               _FP_FRAC_HIGH_##fs (X) &= ~(_FP_W_TYPE) _FP_IMPLBIT_SH_##fs; \
  1596.             pack_semiraw:                                               \
  1597.               _FP_PACK_SEMIRAW (fs, wc, X);                             \
  1598.             }                                                           \
  1599.         }                                                               \
  1600.       else                                                              \
  1601.         {                                                               \
  1602.           X##_s = 0;                                                    \
  1603.           X##_e = 0;                                                    \
  1604.           _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc);                     \
  1605.         }                                                               \
  1606.     }                                                                   \
  1607.   while (0)
  1608.  
  1609.  
  1610. /* Extend from a narrower floating-point format to a wider one.  Input
  1611.    and output are raw.  */
  1612. #define FP_EXTEND(dfs, sfs, dwc, swc, D, S)                             \
  1613.   do                                                                    \
  1614.     {                                                                   \
  1615.       if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs                       \
  1616.           || (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs                      \
  1617.               < _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs)                   \
  1618.           || (_FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1 \
  1619.               && _FP_EXPBIAS_##dfs != _FP_EXPBIAS_##sfs))               \
  1620.         abort ();                                                       \
  1621.       D##_s = S##_s;                                                    \
  1622.       _FP_FRAC_COPY_##dwc##_##swc (D, S);                               \
  1623.       if (_FP_EXP_NORMAL (sfs, swc, S))                                 \
  1624.         {                                                               \
  1625.           D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs;        \
  1626.           _FP_FRAC_SLL_##dwc (D, (_FP_FRACBITS_##dfs - _FP_FRACBITS_##sfs)); \
  1627.         }                                                               \
  1628.       else                                                              \
  1629.         {                                                               \
  1630.           if (S##_e == 0)                                               \
  1631.             {                                                           \
  1632.               _FP_CHECK_FLUSH_ZERO (sfs, swc, S);                       \
  1633.               if (_FP_FRAC_ZEROP_##swc (S))                             \
  1634.                 D##_e = 0;                                              \
  1635.               else if (_FP_EXPBIAS_##dfs                                \
  1636.                        < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1)    \
  1637.                 {                                                       \
  1638.                   FP_SET_EXCEPTION (FP_EX_DENORM);                      \
  1639.                   _FP_FRAC_SLL_##dwc (D, (_FP_FRACBITS_##dfs            \
  1640.                                           - _FP_FRACBITS_##sfs));       \
  1641.                   D##_e = 0;                                            \
  1642.                   if (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)         \
  1643.                     FP_SET_EXCEPTION (FP_EX_UNDERFLOW);                 \
  1644.                 }                                                       \
  1645.               else                                                      \
  1646.                 {                                                       \
  1647.                   int FP_EXTEND_lz;                                     \
  1648.                   FP_SET_EXCEPTION (FP_EX_DENORM);                      \
  1649.                   _FP_FRAC_CLZ_##swc (FP_EXTEND_lz, S);                 \
  1650.                   _FP_FRAC_SLL_##dwc (D,                                \
  1651.                                       FP_EXTEND_lz + _FP_FRACBITS_##dfs \
  1652.                                       - _FP_FRACTBITS_##sfs);           \
  1653.                   D##_e = (_FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs + 1    \
  1654.                            + _FP_FRACXBITS_##sfs - FP_EXTEND_lz);       \
  1655.                 }                                                       \
  1656.             }                                                           \
  1657.           else                                                          \
  1658.             {                                                           \
  1659.               D##_e = _FP_EXPMAX_##dfs;                                 \
  1660.               if (!_FP_FRAC_ZEROP_##swc (S))                            \
  1661.                 {                                                       \
  1662.                   if (_FP_FRAC_SNANP (sfs, S))                          \
  1663.                     FP_SET_EXCEPTION (FP_EX_INVALID                     \
  1664.                                       | FP_EX_INVALID_SNAN);            \
  1665.                   _FP_FRAC_SLL_##dwc (D, (_FP_FRACBITS_##dfs            \
  1666.                                           - _FP_FRACBITS_##sfs));       \
  1667.                   _FP_SETQNAN (dfs, dwc, D);                            \
  1668.                 }                                                       \
  1669.             }                                                           \
  1670.         }                                                               \
  1671.     }                                                                   \
  1672.   while (0)
  1673.  
  1674. /* Truncate from a wider floating-point format to a narrower one.
  1675.    Input and output are semi-raw.  */
  1676. #define FP_TRUNC(dfs, sfs, dwc, swc, D, S)                              \
  1677.   do                                                                    \
  1678.     {                                                                   \
  1679.       if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs                       \
  1680.           || (_FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1 \
  1681.               && _FP_EXPBIAS_##sfs != _FP_EXPBIAS_##dfs))               \
  1682.         abort ();                                                       \
  1683.       D##_s = S##_s;                                                    \
  1684.       if (_FP_EXP_NORMAL (sfs, swc, S))                                 \
  1685.         {                                                               \
  1686.           D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs;        \
  1687.           if (D##_e >= _FP_EXPMAX_##dfs)                                \
  1688.             _FP_OVERFLOW_SEMIRAW (dfs, dwc, D);                         \
  1689.           else                                                          \
  1690.             {                                                           \
  1691.               if (D##_e <= 0)                                           \
  1692.                 {                                                       \
  1693.                   if (D##_e < 1 - _FP_FRACBITS_##dfs)                   \
  1694.                     {                                                   \
  1695.                       _FP_FRAC_SET_##swc (S, _FP_ZEROFRAC_##swc);       \
  1696.                       _FP_FRAC_LOW_##swc (S) |= 1;                      \
  1697.                     }                                                   \
  1698.                   else                                                  \
  1699.                     {                                                   \
  1700.                       _FP_FRAC_HIGH_##sfs (S) |= _FP_IMPLBIT_SH_##sfs;  \
  1701.                       _FP_FRAC_SRS_##swc (S, (_FP_WFRACBITS_##sfs       \
  1702.                                               - _FP_WFRACBITS_##dfs     \
  1703.                                               + 1 - D##_e),             \
  1704.                                           _FP_WFRACBITS_##sfs);         \
  1705.                     }                                                   \
  1706.                   D##_e = 0;                                            \
  1707.                 }                                                       \
  1708.               else                                                      \
  1709.                 _FP_FRAC_SRS_##swc (S, (_FP_WFRACBITS_##sfs             \
  1710.                                         - _FP_WFRACBITS_##dfs),         \
  1711.                                     _FP_WFRACBITS_##sfs);               \
  1712.               _FP_FRAC_COPY_##dwc##_##swc (D, S);                       \
  1713.             }                                                           \
  1714.         }                                                               \
  1715.       else                                                              \
  1716.         {                                                               \
  1717.           if (S##_e == 0)                                               \
  1718.             {                                                           \
  1719.               _FP_CHECK_FLUSH_ZERO (sfs, swc, S);                       \
  1720.               D##_e = 0;                                                \
  1721.               if (_FP_FRAC_ZEROP_##swc (S))                             \
  1722.                 _FP_FRAC_SET_##dwc (D, _FP_ZEROFRAC_##dwc);             \
  1723.               else                                                      \
  1724.                 {                                                       \
  1725.                   FP_SET_EXCEPTION (FP_EX_DENORM);                      \
  1726.                   if (_FP_EXPBIAS_##sfs                                 \
  1727.                       < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1)     \
  1728.                     {                                                   \
  1729.                       _FP_FRAC_SRS_##swc (S, (_FP_WFRACBITS_##sfs       \
  1730.                                               - _FP_WFRACBITS_##dfs),   \
  1731.                                           _FP_WFRACBITS_##sfs);         \
  1732.                       _FP_FRAC_COPY_##dwc##_##swc (D, S);               \
  1733.                     }                                                   \
  1734.                   else                                                  \
  1735.                     {                                                   \
  1736.                       _FP_FRAC_SET_##dwc (D, _FP_ZEROFRAC_##dwc);       \
  1737.                       _FP_FRAC_LOW_##dwc (D) |= 1;                      \
  1738.                     }                                                   \
  1739.                 }                                                       \
  1740.             }                                                           \
  1741.           else                                                          \
  1742.             {                                                           \
  1743.               D##_e = _FP_EXPMAX_##dfs;                                 \
  1744.               if (_FP_FRAC_ZEROP_##swc (S))                             \
  1745.                 _FP_FRAC_SET_##dwc (D, _FP_ZEROFRAC_##dwc);             \
  1746.               else                                                      \
  1747.                 {                                                       \
  1748.                   _FP_CHECK_SIGNAN_SEMIRAW (sfs, swc, S);               \
  1749.                   _FP_FRAC_SRL_##swc (S, (_FP_WFRACBITS_##sfs           \
  1750.                                           - _FP_WFRACBITS_##dfs));      \
  1751.                   _FP_FRAC_COPY_##dwc##_##swc (D, S);                   \
  1752.                   /* Semi-raw NaN must have all workbits cleared.  */   \
  1753.                   _FP_FRAC_LOW_##dwc (D)                                \
  1754.                     &= ~(_FP_W_TYPE) ((1 << _FP_WORKBITS) - 1);         \
  1755.                   _FP_SETQNAN_SEMIRAW (dfs, dwc, D);                    \
  1756.                 }                                                       \
  1757.             }                                                           \
  1758.         }                                                               \
  1759.     }                                                                   \
  1760.   while (0)
  1761.  
  1762. /* Helper primitives.  */
  1763.  
  1764. /* Count leading zeros in a word.  */
  1765.  
  1766. #ifndef __FP_CLZ
  1767. /* GCC 3.4 and later provide the builtins for us.  */
  1768. # define __FP_CLZ(r, x)                                                 \
  1769.   do                                                                    \
  1770.     {                                                                   \
  1771.       if (sizeof (_FP_W_TYPE) == sizeof (unsigned int))                 \
  1772.         (r) = __builtin_clz (x);                                        \
  1773.       else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long))           \
  1774.         (r) = __builtin_clzl (x);                                       \
  1775.       else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long long))      \
  1776.         (r) = __builtin_clzll (x);                                      \
  1777.       else                                                              \
  1778.         abort ();                                                       \
  1779.     }                                                                   \
  1780.   while (0)
  1781. #endif /* ndef __FP_CLZ */
  1782.  
  1783. #define _FP_DIV_HELP_imm(q, r, n, d)            \
  1784.   do                                            \
  1785.     {                                           \
  1786.       (q) = (n) / (d), (r) = (n) % (d);         \
  1787.     }                                           \
  1788.   while (0)
  1789.  
  1790.  
  1791. /* A restoring bit-by-bit division primitive.  */
  1792.  
  1793. #define _FP_DIV_MEAT_N_loop(fs, wc, R, X, Y)                            \
  1794.   do                                                                    \
  1795.     {                                                                   \
  1796.       int _FP_DIV_MEAT_N_loop_count = _FP_WFRACBITS_##fs;               \
  1797.       _FP_FRAC_DECL_##wc (_FP_DIV_MEAT_N_loop_u);                       \
  1798.       _FP_FRAC_DECL_##wc (_FP_DIV_MEAT_N_loop_v);                       \
  1799.       _FP_FRAC_COPY_##wc (_FP_DIV_MEAT_N_loop_u, X);                    \
  1800.       _FP_FRAC_COPY_##wc (_FP_DIV_MEAT_N_loop_v, Y);                    \
  1801.       _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc);                         \
  1802.       /* Normalize _FP_DIV_MEAT_N_LOOP_U and _FP_DIV_MEAT_N_LOOP_V.  */ \
  1803.       _FP_FRAC_SLL_##wc (_FP_DIV_MEAT_N_loop_u, _FP_WFRACXBITS_##fs);   \
  1804.       _FP_FRAC_SLL_##wc (_FP_DIV_MEAT_N_loop_v, _FP_WFRACXBITS_##fs);   \
  1805.       /* First round.  Since the operands are normalized, either the    \
  1806.          first or second bit will be set in the fraction.  Produce a    \
  1807.          normalized result by checking which and adjusting the loop     \
  1808.          count and exponent accordingly.  */                            \
  1809.       if (_FP_FRAC_GE_1 (_FP_DIV_MEAT_N_loop_u, _FP_DIV_MEAT_N_loop_v)) \
  1810.         {                                                               \
  1811.           _FP_FRAC_SUB_##wc (_FP_DIV_MEAT_N_loop_u,                     \
  1812.                              _FP_DIV_MEAT_N_loop_u,                     \
  1813.                              _FP_DIV_MEAT_N_loop_v);                    \
  1814.           _FP_FRAC_LOW_##wc (R) |= 1;                                   \
  1815.           _FP_DIV_MEAT_N_loop_count--;                                  \
  1816.         }                                                               \
  1817.       else                                                              \
  1818.         R##_e--;                                                        \
  1819.       /* Subsequent rounds.  */                                         \
  1820.       do                                                                \
  1821.         {                                                               \
  1822.           int _FP_DIV_MEAT_N_loop_msb                                   \
  1823.             = (_FP_WS_TYPE) _FP_FRAC_HIGH_##wc (_FP_DIV_MEAT_N_loop_u) < 0; \
  1824.           _FP_FRAC_SLL_##wc (_FP_DIV_MEAT_N_loop_u, 1);                 \
  1825.           _FP_FRAC_SLL_##wc (R, 1);                                     \
  1826.           if (_FP_DIV_MEAT_N_loop_msb                                   \
  1827.               || _FP_FRAC_GE_1 (_FP_DIV_MEAT_N_loop_u,                  \
  1828.                                 _FP_DIV_MEAT_N_loop_v))                 \
  1829.             {                                                           \
  1830.               _FP_FRAC_SUB_##wc (_FP_DIV_MEAT_N_loop_u,                 \
  1831.                                  _FP_DIV_MEAT_N_loop_u,                 \
  1832.                                  _FP_DIV_MEAT_N_loop_v);                \
  1833.               _FP_FRAC_LOW_##wc (R) |= 1;                               \
  1834.             }                                                           \
  1835.         }                                                               \
  1836.       while (--_FP_DIV_MEAT_N_loop_count > 0);                          \
  1837.       /* If there's anything left in _FP_DIV_MEAT_N_LOOP_U, the result  \
  1838.          is inexact.  */                                                \
  1839.       _FP_FRAC_LOW_##wc (R)                                             \
  1840.         |= !_FP_FRAC_ZEROP_##wc (_FP_DIV_MEAT_N_loop_u);                \
  1841.     }                                                                   \
  1842.   while (0)
  1843.  
  1844. #define _FP_DIV_MEAT_1_loop(fs, R, X, Y)  _FP_DIV_MEAT_N_loop (fs, 1, R, X, Y)
  1845. #define _FP_DIV_MEAT_2_loop(fs, R, X, Y)  _FP_DIV_MEAT_N_loop (fs, 2, R, X, Y)
  1846. #define _FP_DIV_MEAT_4_loop(fs, R, X, Y)  _FP_DIV_MEAT_N_loop (fs, 4, R, X, Y)
  1847.