1169689Skan/* Software floating-point emulation. Common operations. 2169689Skan Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. 3169689Skan This file is part of the GNU C Library. 4169689Skan Contributed by Richard Henderson (rth@cygnus.com), 5169689Skan Jakub Jelinek (jj@ultra.linux.cz), 6169689Skan David S. Miller (davem@redhat.com) and 7169689Skan Peter Maydell (pmaydell@chiark.greenend.org.uk). 8169689Skan 9169689Skan The GNU C Library is free software; you can redistribute it and/or 10169689Skan modify it under the terms of the GNU Lesser General Public 11169689Skan License as published by the Free Software Foundation; either 12169689Skan version 2.1 of the License, or (at your option) any later version. 13169689Skan 14169689Skan In addition to the permissions in the GNU Lesser General Public 15169689Skan License, the Free Software Foundation gives you unlimited 16169689Skan permission to link the compiled version of this file into 17169689Skan combinations with other programs, and to distribute those 18169689Skan combinations without any restriction coming from the use of this 19169689Skan file. (The Lesser General Public License restrictions do apply in 20169689Skan other respects; for example, they cover modification of the file, 21169689Skan and distribution when not linked into a combine executable.) 22169689Skan 23169689Skan The GNU C Library is distributed in the hope that it will be useful, 24169689Skan but WITHOUT ANY WARRANTY; without even the implied warranty of 25169689Skan MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 26169689Skan Lesser General Public License for more details. 27169689Skan 28169689Skan You should have received a copy of the GNU Lesser General Public 29169689Skan License along with the GNU C Library; if not, write to the Free 30169689Skan Software Foundation, 51 Franklin Street, Fifth Floor, Boston, 31169689Skan MA 02110-1301, USA. */ 32169689Skan 33169689Skan#define _FP_DECL(wc, X) \ 34169689Skan _FP_I_TYPE X##_c __attribute__((unused)), X##_s, X##_e; \ 35169689Skan _FP_FRAC_DECL_##wc(X) 36169689Skan 37169689Skan/* 38169689Skan * Finish truely unpacking a native fp value by classifying the kind 39169689Skan * of fp value and normalizing both the exponent and the fraction. 40169689Skan */ 41169689Skan 42169689Skan#define _FP_UNPACK_CANONICAL(fs, wc, X) \ 43169689Skando { \ 44169689Skan switch (X##_e) \ 45169689Skan { \ 46169689Skan default: \ 47169689Skan _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \ 48169689Skan _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \ 49169689Skan X##_e -= _FP_EXPBIAS_##fs; \ 50169689Skan X##_c = FP_CLS_NORMAL; \ 51169689Skan break; \ 52169689Skan \ 53169689Skan case 0: \ 54169689Skan if (_FP_FRAC_ZEROP_##wc(X)) \ 55169689Skan X##_c = FP_CLS_ZERO; \ 56169689Skan else \ 57169689Skan { \ 58169689Skan /* a denormalized number */ \ 59169689Skan _FP_I_TYPE _shift; \ 60169689Skan _FP_FRAC_CLZ_##wc(_shift, X); \ 61169689Skan _shift -= _FP_FRACXBITS_##fs; \ 62169689Skan _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS)); \ 63169689Skan X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \ 64169689Skan X##_c = FP_CLS_NORMAL; \ 65169689Skan FP_SET_EXCEPTION(FP_EX_DENORM); \ 66169689Skan } \ 67169689Skan break; \ 68169689Skan \ 69169689Skan case _FP_EXPMAX_##fs: \ 70169689Skan if (_FP_FRAC_ZEROP_##wc(X)) \ 71169689Skan X##_c = FP_CLS_INF; \ 72169689Skan else \ 73169689Skan { \ 74169689Skan X##_c = FP_CLS_NAN; \ 75169689Skan /* Check for signaling NaN */ \ 76169689Skan if (!(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \ 77169689Skan FP_SET_EXCEPTION(FP_EX_INVALID); \ 78169689Skan } \ 79169689Skan break; \ 80169689Skan } \ 81169689Skan} while (0) 82169689Skan 83169689Skan/* Finish unpacking an fp value in semi-raw mode: the mantissa is 84169689Skan shifted by _FP_WORKBITS but the implicit MSB is not inserted and 85169689Skan other classification is not done. */ 86169689Skan#define _FP_UNPACK_SEMIRAW(fs, wc, X) _FP_FRAC_SLL_##wc(X, _FP_WORKBITS) 87169689Skan 88169689Skan/* A semi-raw value has overflowed to infinity. Adjust the mantissa 89169689Skan and exponent appropriately. */ 90169689Skan#define _FP_OVERFLOW_SEMIRAW(fs, wc, X) \ 91169689Skando { \ 92169689Skan if (FP_ROUNDMODE == FP_RND_NEAREST \ 93169689Skan || (FP_ROUNDMODE == FP_RND_PINF && !X##_s) \ 94169689Skan || (FP_ROUNDMODE == FP_RND_MINF && X##_s)) \ 95169689Skan { \ 96169689Skan X##_e = _FP_EXPMAX_##fs; \ 97169689Skan _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ 98169689Skan } \ 99169689Skan else \ 100169689Skan { \ 101169689Skan X##_e = _FP_EXPMAX_##fs - 1; \ 102169689Skan _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \ 103169689Skan } \ 104169689Skan FP_SET_EXCEPTION(FP_EX_INEXACT); \ 105169689Skan FP_SET_EXCEPTION(FP_EX_OVERFLOW); \ 106169689Skan} while (0) 107169689Skan 108169689Skan/* Check for a semi-raw value being a signaling NaN and raise the 109169689Skan invalid exception if so. */ 110169689Skan#define _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X) \ 111169689Skando { \ 112169689Skan if (X##_e == _FP_EXPMAX_##fs \ 113169689Skan && !_FP_FRAC_ZEROP_##wc(X) \ 114169689Skan && !(_FP_FRAC_HIGH_##fs(X) & _FP_QNANBIT_SH_##fs)) \ 115169689Skan FP_SET_EXCEPTION(FP_EX_INVALID); \ 116169689Skan} while (0) 117169689Skan 118169689Skan/* Choose a NaN result from an operation on two semi-raw NaN 119169689Skan values. */ 120169689Skan#define _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP) \ 121169689Skando { \ 122169689Skan /* _FP_CHOOSENAN expects raw values, so shift as required. */ \ 123169689Skan _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ 124169689Skan _FP_FRAC_SRL_##wc(Y, _FP_WORKBITS); \ 125169689Skan _FP_CHOOSENAN(fs, wc, R, X, Y, OP); \ 126169689Skan _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \ 127169689Skan} while (0) 128169689Skan 129169689Skan/* Test whether a biased exponent is normal (not zero or maximum). */ 130169689Skan#define _FP_EXP_NORMAL(fs, wc, X) (((X##_e + 1) & _FP_EXPMAX_##fs) > 1) 131169689Skan 132169689Skan/* Prepare to pack an fp value in semi-raw mode: the mantissa is 133169689Skan rounded and shifted right, with the rounding possibly increasing 134169689Skan the exponent (including changing a finite value to infinity). */ 135169689Skan#define _FP_PACK_SEMIRAW(fs, wc, X) \ 136169689Skando { \ 137169689Skan _FP_ROUND(wc, X); \ 138169689Skan if (_FP_FRAC_HIGH_##fs(X) \ 139169689Skan & (_FP_OVERFLOW_##fs >> 1)) \ 140169689Skan { \ 141169689Skan _FP_FRAC_HIGH_##fs(X) &= ~(_FP_OVERFLOW_##fs >> 1); \ 142169689Skan X##_e++; \ 143169689Skan if (X##_e == _FP_EXPMAX_##fs) \ 144169689Skan _FP_OVERFLOW_SEMIRAW(fs, wc, X); \ 145169689Skan } \ 146169689Skan _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ 147169689Skan if (!_FP_EXP_NORMAL(fs, wc, X) && !_FP_FRAC_ZEROP_##wc(X)) \ 148169689Skan { \ 149169689Skan if (X##_e == 0) \ 150169689Skan FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ 151169689Skan else \ 152169689Skan { \ 153169689Skan if (!_FP_KEEPNANFRACP) \ 154169689Skan { \ 155169689Skan _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ 156169689Skan X##_s = _FP_NANSIGN_##fs; \ 157169689Skan } \ 158169689Skan else \ 159169689Skan _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \ 160169689Skan } \ 161169689Skan } \ 162169689Skan} while (0) 163169689Skan 164169689Skan/* 165169689Skan * Before packing the bits back into the native fp result, take care 166169689Skan * of such mundane things as rounding and overflow. Also, for some 167169689Skan * kinds of fp values, the original parts may not have been fully 168169689Skan * extracted -- but that is ok, we can regenerate them now. 169169689Skan */ 170169689Skan 171169689Skan#define _FP_PACK_CANONICAL(fs, wc, X) \ 172169689Skando { \ 173169689Skan switch (X##_c) \ 174169689Skan { \ 175169689Skan case FP_CLS_NORMAL: \ 176169689Skan X##_e += _FP_EXPBIAS_##fs; \ 177169689Skan if (X##_e > 0) \ 178169689Skan { \ 179169689Skan _FP_ROUND(wc, X); \ 180169689Skan if (_FP_FRAC_OVERP_##wc(fs, X)) \ 181169689Skan { \ 182169689Skan _FP_FRAC_CLEAR_OVERP_##wc(fs, X); \ 183169689Skan X##_e++; \ 184169689Skan } \ 185169689Skan _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ 186169689Skan if (X##_e >= _FP_EXPMAX_##fs) \ 187169689Skan { \ 188169689Skan /* overflow */ \ 189169689Skan switch (FP_ROUNDMODE) \ 190169689Skan { \ 191169689Skan case FP_RND_NEAREST: \ 192169689Skan X##_c = FP_CLS_INF; \ 193169689Skan break; \ 194169689Skan case FP_RND_PINF: \ 195169689Skan if (!X##_s) X##_c = FP_CLS_INF; \ 196169689Skan break; \ 197169689Skan case FP_RND_MINF: \ 198169689Skan if (X##_s) X##_c = FP_CLS_INF; \ 199169689Skan break; \ 200169689Skan } \ 201169689Skan if (X##_c == FP_CLS_INF) \ 202169689Skan { \ 203169689Skan /* Overflow to infinity */ \ 204169689Skan X##_e = _FP_EXPMAX_##fs; \ 205169689Skan _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ 206169689Skan } \ 207169689Skan else \ 208169689Skan { \ 209169689Skan /* Overflow to maximum normal */ \ 210169689Skan X##_e = _FP_EXPMAX_##fs - 1; \ 211169689Skan _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \ 212169689Skan } \ 213169689Skan FP_SET_EXCEPTION(FP_EX_OVERFLOW); \ 214169689Skan FP_SET_EXCEPTION(FP_EX_INEXACT); \ 215169689Skan } \ 216169689Skan } \ 217169689Skan else \ 218169689Skan { \ 219169689Skan /* we've got a denormalized number */ \ 220169689Skan X##_e = -X##_e + 1; \ 221169689Skan if (X##_e <= _FP_WFRACBITS_##fs) \ 222169689Skan { \ 223169689Skan _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \ 224169689Skan _FP_ROUND(wc, X); \ 225169689Skan if (_FP_FRAC_HIGH_##fs(X) \ 226169689Skan & (_FP_OVERFLOW_##fs >> 1)) \ 227169689Skan { \ 228169689Skan X##_e = 1; \ 229169689Skan _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ 230169689Skan } \ 231169689Skan else \ 232169689Skan { \ 233169689Skan X##_e = 0; \ 234169689Skan _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ 235169689Skan FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ 236169689Skan } \ 237169689Skan } \ 238169689Skan else \ 239169689Skan { \ 240169689Skan /* underflow to zero */ \ 241169689Skan X##_e = 0; \ 242169689Skan if (!_FP_FRAC_ZEROP_##wc(X)) \ 243169689Skan { \ 244169689Skan _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ 245169689Skan _FP_ROUND(wc, X); \ 246169689Skan _FP_FRAC_LOW_##wc(X) >>= (_FP_WORKBITS); \ 247169689Skan } \ 248169689Skan FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ 249169689Skan } \ 250169689Skan } \ 251169689Skan break; \ 252169689Skan \ 253169689Skan case FP_CLS_ZERO: \ 254169689Skan X##_e = 0; \ 255169689Skan _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ 256169689Skan break; \ 257169689Skan \ 258169689Skan case FP_CLS_INF: \ 259169689Skan X##_e = _FP_EXPMAX_##fs; \ 260169689Skan _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ 261169689Skan break; \ 262169689Skan \ 263169689Skan case FP_CLS_NAN: \ 264169689Skan X##_e = _FP_EXPMAX_##fs; \ 265169689Skan if (!_FP_KEEPNANFRACP) \ 266169689Skan { \ 267169689Skan _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ 268169689Skan X##_s = _FP_NANSIGN_##fs; \ 269169689Skan } \ 270169689Skan else \ 271169689Skan _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \ 272169689Skan break; \ 273169689Skan } \ 274169689Skan} while (0) 275169689Skan 276169689Skan/* This one accepts raw argument and not cooked, returns 277169689Skan * 1 if X is a signaling NaN. 278169689Skan */ 279169689Skan#define _FP_ISSIGNAN(fs, wc, X) \ 280169689Skan({ \ 281169689Skan int __ret = 0; \ 282169689Skan if (X##_e == _FP_EXPMAX_##fs) \ 283169689Skan { \ 284169689Skan if (!_FP_FRAC_ZEROP_##wc(X) \ 285169689Skan && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \ 286169689Skan __ret = 1; \ 287169689Skan } \ 288169689Skan __ret; \ 289169689Skan}) 290169689Skan 291169689Skan 292169689Skan 293169689Skan 294169689Skan 295169689Skan/* Addition on semi-raw values. */ 296169689Skan#define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP) \ 297169689Skando { \ 298169689Skan if (X##_s == Y##_s) \ 299169689Skan { \ 300169689Skan /* Addition. */ \ 301169689Skan R##_s = X##_s; \ 302169689Skan int ediff = X##_e - Y##_e; \ 303169689Skan if (ediff > 0) \ 304169689Skan { \ 305169689Skan R##_e = X##_e; \ 306169689Skan if (Y##_e == 0) \ 307169689Skan { \ 308169689Skan /* Y is zero or denormalized. */ \ 309169689Skan if (_FP_FRAC_ZEROP_##wc(Y)) \ 310169689Skan { \ 311169689Skan _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ 312169689Skan _FP_FRAC_COPY_##wc(R, X); \ 313169689Skan goto add_done; \ 314169689Skan } \ 315169689Skan else \ 316169689Skan { \ 317169689Skan FP_SET_EXCEPTION(FP_EX_DENORM); \ 318169689Skan ediff--; \ 319169689Skan if (ediff == 0) \ 320169689Skan { \ 321169689Skan _FP_FRAC_ADD_##wc(R, X, Y); \ 322169689Skan goto add3; \ 323169689Skan } \ 324169689Skan if (X##_e == _FP_EXPMAX_##fs) \ 325169689Skan { \ 326169689Skan _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ 327169689Skan _FP_FRAC_COPY_##wc(R, X); \ 328169689Skan goto add_done; \ 329169689Skan } \ 330169689Skan goto add1; \ 331169689Skan } \ 332169689Skan } \ 333169689Skan else if (X##_e == _FP_EXPMAX_##fs) \ 334169689Skan { \ 335169689Skan /* X is NaN or Inf, Y is normal. */ \ 336169689Skan _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ 337169689Skan _FP_FRAC_COPY_##wc(R, X); \ 338169689Skan goto add_done; \ 339169689Skan } \ 340169689Skan \ 341169689Skan /* Insert implicit MSB of Y. */ \ 342169689Skan _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \ 343169689Skan \ 344169689Skan add1: \ 345169689Skan /* Shift the mantissa of Y to the right EDIFF steps; \ 346169689Skan remember to account later for the implicit MSB of X. */ \ 347169689Skan if (ediff <= _FP_WFRACBITS_##fs) \ 348169689Skan _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \ 349169689Skan else if (!_FP_FRAC_ZEROP_##wc(Y)) \ 350169689Skan _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \ 351169689Skan _FP_FRAC_ADD_##wc(R, X, Y); \ 352169689Skan } \ 353169689Skan else if (ediff < 0) \ 354169689Skan { \ 355169689Skan ediff = -ediff; \ 356169689Skan R##_e = Y##_e; \ 357169689Skan if (X##_e == 0) \ 358169689Skan { \ 359169689Skan /* X is zero or denormalized. */ \ 360169689Skan if (_FP_FRAC_ZEROP_##wc(X)) \ 361169689Skan { \ 362169689Skan _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ 363169689Skan _FP_FRAC_COPY_##wc(R, Y); \ 364169689Skan goto add_done; \ 365169689Skan } \ 366169689Skan else \ 367169689Skan { \ 368169689Skan FP_SET_EXCEPTION(FP_EX_DENORM); \ 369169689Skan ediff--; \ 370169689Skan if (ediff == 0) \ 371169689Skan { \ 372169689Skan _FP_FRAC_ADD_##wc(R, Y, X); \ 373169689Skan goto add3; \ 374169689Skan } \ 375169689Skan if (Y##_e == _FP_EXPMAX_##fs) \ 376169689Skan { \ 377169689Skan _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ 378169689Skan _FP_FRAC_COPY_##wc(R, Y); \ 379169689Skan goto add_done; \ 380169689Skan } \ 381169689Skan goto add2; \ 382169689Skan } \ 383169689Skan } \ 384169689Skan else if (Y##_e == _FP_EXPMAX_##fs) \ 385169689Skan { \ 386169689Skan /* Y is NaN or Inf, X is normal. */ \ 387169689Skan _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ 388169689Skan _FP_FRAC_COPY_##wc(R, Y); \ 389169689Skan goto add_done; \ 390169689Skan } \ 391169689Skan \ 392169689Skan /* Insert implicit MSB of X. */ \ 393169689Skan _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \ 394169689Skan \ 395169689Skan add2: \ 396169689Skan /* Shift the mantissa of X to the right EDIFF steps; \ 397169689Skan remember to account later for the implicit MSB of Y. */ \ 398169689Skan if (ediff <= _FP_WFRACBITS_##fs) \ 399169689Skan _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \ 400169689Skan else if (!_FP_FRAC_ZEROP_##wc(X)) \ 401169689Skan _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ 402169689Skan _FP_FRAC_ADD_##wc(R, Y, X); \ 403169689Skan } \ 404169689Skan else \ 405169689Skan { \ 406169689Skan /* ediff == 0. */ \ 407169689Skan if (!_FP_EXP_NORMAL(fs, wc, X)) \ 408169689Skan { \ 409169689Skan if (X##_e == 0) \ 410169689Skan { \ 411169689Skan /* X and Y are zero or denormalized. */ \ 412169689Skan R##_e = 0; \ 413169689Skan if (_FP_FRAC_ZEROP_##wc(X)) \ 414169689Skan { \ 415169689Skan if (!_FP_FRAC_ZEROP_##wc(Y)) \ 416169689Skan FP_SET_EXCEPTION(FP_EX_DENORM); \ 417169689Skan _FP_FRAC_COPY_##wc(R, Y); \ 418169689Skan goto add_done; \ 419169689Skan } \ 420169689Skan else if (_FP_FRAC_ZEROP_##wc(Y)) \ 421169689Skan { \ 422169689Skan FP_SET_EXCEPTION(FP_EX_DENORM); \ 423169689Skan _FP_FRAC_COPY_##wc(R, X); \ 424169689Skan goto add_done; \ 425169689Skan } \ 426169689Skan else \ 427169689Skan { \ 428169689Skan FP_SET_EXCEPTION(FP_EX_DENORM); \ 429169689Skan _FP_FRAC_ADD_##wc(R, X, Y); \ 430169689Skan if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ 431169689Skan { \ 432169689Skan /* Normalized result. */ \ 433169689Skan _FP_FRAC_HIGH_##fs(R) \ 434169689Skan &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ 435169689Skan R##_e = 1; \ 436169689Skan } \ 437169689Skan goto add_done; \ 438169689Skan } \ 439169689Skan } \ 440169689Skan else \ 441169689Skan { \ 442169689Skan /* X and Y are NaN or Inf. */ \ 443169689Skan _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ 444169689Skan _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ 445169689Skan R##_e = _FP_EXPMAX_##fs; \ 446169689Skan if (_FP_FRAC_ZEROP_##wc(X)) \ 447169689Skan _FP_FRAC_COPY_##wc(R, Y); \ 448169689Skan else if (_FP_FRAC_ZEROP_##wc(Y)) \ 449169689Skan _FP_FRAC_COPY_##wc(R, X); \ 450169689Skan else \ 451169689Skan _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \ 452169689Skan goto add_done; \ 453169689Skan } \ 454169689Skan } \ 455169689Skan /* The exponents of X and Y, both normal, are equal. The \ 456169689Skan implicit MSBs will always add to increase the \ 457169689Skan exponent. */ \ 458169689Skan _FP_FRAC_ADD_##wc(R, X, Y); \ 459169689Skan R##_e = X##_e + 1; \ 460169689Skan _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ 461169689Skan if (R##_e == _FP_EXPMAX_##fs) \ 462169689Skan /* Overflow to infinity (depending on rounding mode). */ \ 463169689Skan _FP_OVERFLOW_SEMIRAW(fs, wc, R); \ 464169689Skan goto add_done; \ 465169689Skan } \ 466169689Skan add3: \ 467169689Skan if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ 468169689Skan { \ 469169689Skan /* Overflow. */ \ 470169689Skan _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ 471169689Skan R##_e++; \ 472169689Skan _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ 473169689Skan if (R##_e == _FP_EXPMAX_##fs) \ 474169689Skan /* Overflow to infinity (depending on rounding mode). */ \ 475169689Skan _FP_OVERFLOW_SEMIRAW(fs, wc, R); \ 476169689Skan } \ 477169689Skan add_done: ; \ 478169689Skan } \ 479169689Skan else \ 480169689Skan { \ 481169689Skan /* Subtraction. */ \ 482169689Skan int ediff = X##_e - Y##_e; \ 483169689Skan if (ediff > 0) \ 484169689Skan { \ 485169689Skan R##_e = X##_e; \ 486169689Skan R##_s = X##_s; \ 487169689Skan if (Y##_e == 0) \ 488169689Skan { \ 489169689Skan /* Y is zero or denormalized. */ \ 490169689Skan if (_FP_FRAC_ZEROP_##wc(Y)) \ 491169689Skan { \ 492169689Skan _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ 493169689Skan _FP_FRAC_COPY_##wc(R, X); \ 494169689Skan goto sub_done; \ 495169689Skan } \ 496169689Skan else \ 497169689Skan { \ 498169689Skan FP_SET_EXCEPTION(FP_EX_DENORM); \ 499169689Skan ediff--; \ 500169689Skan if (ediff == 0) \ 501169689Skan { \ 502169689Skan _FP_FRAC_SUB_##wc(R, X, Y); \ 503169689Skan goto sub3; \ 504169689Skan } \ 505169689Skan if (X##_e == _FP_EXPMAX_##fs) \ 506169689Skan { \ 507169689Skan _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ 508169689Skan _FP_FRAC_COPY_##wc(R, X); \ 509169689Skan goto sub_done; \ 510169689Skan } \ 511169689Skan goto sub1; \ 512169689Skan } \ 513169689Skan } \ 514169689Skan else if (X##_e == _FP_EXPMAX_##fs) \ 515169689Skan { \ 516169689Skan /* X is NaN or Inf, Y is normal. */ \ 517169689Skan _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ 518169689Skan _FP_FRAC_COPY_##wc(R, X); \ 519169689Skan goto sub_done; \ 520169689Skan } \ 521169689Skan \ 522169689Skan /* Insert implicit MSB of Y. */ \ 523169689Skan _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \ 524169689Skan \ 525169689Skan sub1: \ 526169689Skan /* Shift the mantissa of Y to the right EDIFF steps; \ 527169689Skan remember to account later for the implicit MSB of X. */ \ 528169689Skan if (ediff <= _FP_WFRACBITS_##fs) \ 529169689Skan _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \ 530169689Skan else if (!_FP_FRAC_ZEROP_##wc(Y)) \ 531169689Skan _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \ 532169689Skan _FP_FRAC_SUB_##wc(R, X, Y); \ 533169689Skan } \ 534169689Skan else if (ediff < 0) \ 535169689Skan { \ 536169689Skan ediff = -ediff; \ 537169689Skan R##_e = Y##_e; \ 538169689Skan R##_s = Y##_s; \ 539169689Skan if (X##_e == 0) \ 540169689Skan { \ 541169689Skan /* X is zero or denormalized. */ \ 542169689Skan if (_FP_FRAC_ZEROP_##wc(X)) \ 543169689Skan { \ 544169689Skan _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ 545169689Skan _FP_FRAC_COPY_##wc(R, Y); \ 546169689Skan goto sub_done; \ 547169689Skan } \ 548169689Skan else \ 549169689Skan { \ 550169689Skan FP_SET_EXCEPTION(FP_EX_DENORM); \ 551169689Skan ediff--; \ 552169689Skan if (ediff == 0) \ 553169689Skan { \ 554169689Skan _FP_FRAC_SUB_##wc(R, Y, X); \ 555169689Skan goto sub3; \ 556169689Skan } \ 557169689Skan if (Y##_e == _FP_EXPMAX_##fs) \ 558169689Skan { \ 559169689Skan _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ 560169689Skan _FP_FRAC_COPY_##wc(R, Y); \ 561169689Skan goto sub_done; \ 562169689Skan } \ 563169689Skan goto sub2; \ 564169689Skan } \ 565169689Skan } \ 566169689Skan else if (Y##_e == _FP_EXPMAX_##fs) \ 567169689Skan { \ 568169689Skan /* Y is NaN or Inf, X is normal. */ \ 569169689Skan _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ 570169689Skan _FP_FRAC_COPY_##wc(R, Y); \ 571169689Skan goto sub_done; \ 572169689Skan } \ 573169689Skan \ 574169689Skan /* Insert implicit MSB of X. */ \ 575169689Skan _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \ 576169689Skan \ 577169689Skan sub2: \ 578169689Skan /* Shift the mantissa of X to the right EDIFF steps; \ 579169689Skan remember to account later for the implicit MSB of Y. */ \ 580169689Skan if (ediff <= _FP_WFRACBITS_##fs) \ 581169689Skan _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \ 582169689Skan else if (!_FP_FRAC_ZEROP_##wc(X)) \ 583169689Skan _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ 584169689Skan _FP_FRAC_SUB_##wc(R, Y, X); \ 585169689Skan } \ 586169689Skan else \ 587169689Skan { \ 588169689Skan /* ediff == 0. */ \ 589169689Skan if (!_FP_EXP_NORMAL(fs, wc, X)) \ 590169689Skan { \ 591169689Skan if (X##_e == 0) \ 592169689Skan { \ 593169689Skan /* X and Y are zero or denormalized. */ \ 594169689Skan R##_e = 0; \ 595169689Skan if (_FP_FRAC_ZEROP_##wc(X)) \ 596169689Skan { \ 597169689Skan _FP_FRAC_COPY_##wc(R, Y); \ 598169689Skan if (_FP_FRAC_ZEROP_##wc(Y)) \ 599169689Skan R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ 600169689Skan else \ 601169689Skan { \ 602169689Skan FP_SET_EXCEPTION(FP_EX_DENORM); \ 603169689Skan R##_s = Y##_s; \ 604169689Skan } \ 605169689Skan goto sub_done; \ 606169689Skan } \ 607169689Skan else if (_FP_FRAC_ZEROP_##wc(Y)) \ 608169689Skan { \ 609169689Skan FP_SET_EXCEPTION(FP_EX_DENORM); \ 610169689Skan _FP_FRAC_COPY_##wc(R, X); \ 611169689Skan R##_s = X##_s; \ 612169689Skan goto sub_done; \ 613169689Skan } \ 614169689Skan else \ 615169689Skan { \ 616169689Skan FP_SET_EXCEPTION(FP_EX_DENORM); \ 617169689Skan _FP_FRAC_SUB_##wc(R, X, Y); \ 618169689Skan R##_s = X##_s; \ 619169689Skan if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ 620169689Skan { \ 621169689Skan /* |X| < |Y|, negate result. */ \ 622169689Skan _FP_FRAC_SUB_##wc(R, Y, X); \ 623169689Skan R##_s = Y##_s; \ 624169689Skan } \ 625169689Skan else if (_FP_FRAC_ZEROP_##wc(R)) \ 626169689Skan R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ 627169689Skan goto sub_done; \ 628169689Skan } \ 629169689Skan } \ 630169689Skan else \ 631169689Skan { \ 632169689Skan /* X and Y are NaN or Inf, of opposite signs. */ \ 633169689Skan _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ 634169689Skan _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ 635169689Skan R##_e = _FP_EXPMAX_##fs; \ 636169689Skan if (_FP_FRAC_ZEROP_##wc(X)) \ 637169689Skan { \ 638169689Skan if (_FP_FRAC_ZEROP_##wc(Y)) \ 639169689Skan { \ 640169689Skan /* Inf - Inf. */ \ 641169689Skan R##_s = _FP_NANSIGN_##fs; \ 642169689Skan _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ 643169689Skan _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \ 644169689Skan FP_SET_EXCEPTION(FP_EX_INVALID); \ 645169689Skan } \ 646169689Skan else \ 647169689Skan { \ 648169689Skan /* Inf - NaN. */ \ 649169689Skan R##_s = Y##_s; \ 650169689Skan _FP_FRAC_COPY_##wc(R, Y); \ 651169689Skan } \ 652169689Skan } \ 653169689Skan else \ 654169689Skan { \ 655169689Skan if (_FP_FRAC_ZEROP_##wc(Y)) \ 656169689Skan { \ 657169689Skan /* NaN - Inf. */ \ 658169689Skan R##_s = X##_s; \ 659169689Skan _FP_FRAC_COPY_##wc(R, X); \ 660169689Skan } \ 661169689Skan else \ 662169689Skan { \ 663169689Skan /* NaN - NaN. */ \ 664169689Skan _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \ 665169689Skan } \ 666169689Skan } \ 667169689Skan goto sub_done; \ 668169689Skan } \ 669169689Skan } \ 670169689Skan /* The exponents of X and Y, both normal, are equal. The \ 671169689Skan implicit MSBs cancel. */ \ 672169689Skan R##_e = X##_e; \ 673169689Skan _FP_FRAC_SUB_##wc(R, X, Y); \ 674169689Skan R##_s = X##_s; \ 675169689Skan if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ 676169689Skan { \ 677169689Skan /* |X| < |Y|, negate result. */ \ 678169689Skan _FP_FRAC_SUB_##wc(R, Y, X); \ 679169689Skan R##_s = Y##_s; \ 680169689Skan } \ 681169689Skan else if (_FP_FRAC_ZEROP_##wc(R)) \ 682169689Skan { \ 683169689Skan R##_e = 0; \ 684169689Skan R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ 685169689Skan goto sub_done; \ 686169689Skan } \ 687169689Skan goto norm; \ 688169689Skan } \ 689169689Skan sub3: \ 690169689Skan if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ 691169689Skan { \ 692169689Skan int diff; \ 693169689Skan /* Carry into most significant bit of larger one of X and Y, \ 694169689Skan canceling it; renormalize. */ \ 695169689Skan _FP_FRAC_HIGH_##fs(R) &= _FP_IMPLBIT_SH_##fs - 1; \ 696169689Skan norm: \ 697169689Skan _FP_FRAC_CLZ_##wc(diff, R); \ 698169689Skan diff -= _FP_WFRACXBITS_##fs; \ 699169689Skan _FP_FRAC_SLL_##wc(R, diff); \ 700169689Skan if (R##_e <= diff) \ 701169689Skan { \ 702169689Skan /* R is denormalized. */ \ 703169689Skan diff = diff - R##_e + 1; \ 704169689Skan _FP_FRAC_SRS_##wc(R, diff, _FP_WFRACBITS_##fs); \ 705169689Skan R##_e = 0; \ 706169689Skan } \ 707169689Skan else \ 708169689Skan { \ 709169689Skan R##_e -= diff; \ 710169689Skan _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ 711169689Skan } \ 712169689Skan } \ 713169689Skan sub_done: ; \ 714169689Skan } \ 715169689Skan} while (0) 716169689Skan 717169689Skan#define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL(fs, wc, R, X, Y, '+') 718169689Skan#define _FP_SUB(fs, wc, R, X, Y) \ 719169689Skan do { \ 720169689Skan if (!(Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) Y##_s ^= 1; \ 721169689Skan _FP_ADD_INTERNAL(fs, wc, R, X, Y, '-'); \ 722169689Skan } while (0) 723169689Skan 724169689Skan 725169689Skan/* 726169689Skan * Main negation routine. FIXME -- when we care about setting exception 727169689Skan * bits reliably, this will not do. We should examine all of the fp classes. 728169689Skan */ 729169689Skan 730169689Skan#define _FP_NEG(fs, wc, R, X) \ 731169689Skan do { \ 732169689Skan _FP_FRAC_COPY_##wc(R, X); \ 733169689Skan R##_c = X##_c; \ 734169689Skan R##_e = X##_e; \ 735169689Skan R##_s = 1 ^ X##_s; \ 736169689Skan } while (0) 737169689Skan 738169689Skan 739169689Skan/* 740169689Skan * Main multiplication routine. The input values should be cooked. 741169689Skan */ 742169689Skan 743169689Skan#define _FP_MUL(fs, wc, R, X, Y) \ 744169689Skando { \ 745169689Skan R##_s = X##_s ^ Y##_s; \ 746169689Skan switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ 747169689Skan { \ 748169689Skan case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ 749169689Skan R##_c = FP_CLS_NORMAL; \ 750169689Skan R##_e = X##_e + Y##_e + 1; \ 751169689Skan \ 752169689Skan _FP_MUL_MEAT_##fs(R,X,Y); \ 753169689Skan \ 754169689Skan if (_FP_FRAC_OVERP_##wc(fs, R)) \ 755169689Skan _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ 756169689Skan else \ 757169689Skan R##_e--; \ 758169689Skan break; \ 759169689Skan \ 760169689Skan case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ 761169689Skan _FP_CHOOSENAN(fs, wc, R, X, Y, '*'); \ 762169689Skan break; \ 763169689Skan \ 764169689Skan case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ 765169689Skan case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ 766169689Skan case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ 767169689Skan R##_s = X##_s; \ 768169689Skan \ 769169689Skan case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ 770169689Skan case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ 771169689Skan case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ 772169689Skan case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ 773169689Skan _FP_FRAC_COPY_##wc(R, X); \ 774169689Skan R##_c = X##_c; \ 775169689Skan break; \ 776169689Skan \ 777169689Skan case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ 778169689Skan case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ 779169689Skan case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ 780169689Skan R##_s = Y##_s; \ 781169689Skan \ 782169689Skan case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ 783169689Skan case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ 784169689Skan _FP_FRAC_COPY_##wc(R, Y); \ 785169689Skan R##_c = Y##_c; \ 786169689Skan break; \ 787169689Skan \ 788169689Skan case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ 789169689Skan case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ 790169689Skan R##_s = _FP_NANSIGN_##fs; \ 791169689Skan R##_c = FP_CLS_NAN; \ 792169689Skan _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ 793169689Skan FP_SET_EXCEPTION(FP_EX_INVALID); \ 794169689Skan break; \ 795169689Skan \ 796169689Skan default: \ 797169689Skan abort(); \ 798169689Skan } \ 799169689Skan} while (0) 800169689Skan 801169689Skan 802169689Skan/* 803169689Skan * Main division routine. The input values should be cooked. 804169689Skan */ 805169689Skan 806169689Skan#define _FP_DIV(fs, wc, R, X, Y) \ 807169689Skando { \ 808169689Skan R##_s = X##_s ^ Y##_s; \ 809169689Skan switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ 810169689Skan { \ 811169689Skan case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ 812169689Skan R##_c = FP_CLS_NORMAL; \ 813169689Skan R##_e = X##_e - Y##_e; \ 814169689Skan \ 815169689Skan _FP_DIV_MEAT_##fs(R,X,Y); \ 816169689Skan break; \ 817169689Skan \ 818169689Skan case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ 819169689Skan _FP_CHOOSENAN(fs, wc, R, X, Y, '/'); \ 820169689Skan break; \ 821169689Skan \ 822169689Skan case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ 823169689Skan case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ 824169689Skan case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ 825169689Skan R##_s = X##_s; \ 826169689Skan _FP_FRAC_COPY_##wc(R, X); \ 827169689Skan R##_c = X##_c; \ 828169689Skan break; \ 829169689Skan \ 830169689Skan case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ 831169689Skan case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ 832169689Skan case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ 833169689Skan R##_s = Y##_s; \ 834169689Skan _FP_FRAC_COPY_##wc(R, Y); \ 835169689Skan R##_c = Y##_c; \ 836169689Skan break; \ 837169689Skan \ 838169689Skan case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ 839169689Skan case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ 840169689Skan case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ 841169689Skan R##_c = FP_CLS_ZERO; \ 842169689Skan break; \ 843169689Skan \ 844169689Skan case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ 845169689Skan FP_SET_EXCEPTION(FP_EX_DIVZERO); \ 846169689Skan case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ 847169689Skan case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ 848169689Skan R##_c = FP_CLS_INF; \ 849169689Skan break; \ 850169689Skan \ 851169689Skan case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ 852169689Skan case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ 853169689Skan R##_s = _FP_NANSIGN_##fs; \ 854169689Skan R##_c = FP_CLS_NAN; \ 855169689Skan _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ 856169689Skan FP_SET_EXCEPTION(FP_EX_INVALID); \ 857169689Skan break; \ 858169689Skan \ 859169689Skan default: \ 860169689Skan abort(); \ 861169689Skan } \ 862169689Skan} while (0) 863169689Skan 864169689Skan 865169689Skan/* 866169689Skan * Main differential comparison routine. The inputs should be raw not 867169689Skan * cooked. The return is -1,0,1 for normal values, 2 otherwise. 868169689Skan */ 869169689Skan 870169689Skan#define _FP_CMP(fs, wc, ret, X, Y, un) \ 871169689Skan do { \ 872169689Skan /* NANs are unordered */ \ 873169689Skan if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ 874169689Skan || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \ 875169689Skan { \ 876169689Skan ret = un; \ 877169689Skan } \ 878169689Skan else \ 879169689Skan { \ 880169689Skan int __is_zero_x; \ 881169689Skan int __is_zero_y; \ 882169689Skan \ 883169689Skan __is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0; \ 884169689Skan __is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0; \ 885169689Skan \ 886169689Skan if (__is_zero_x && __is_zero_y) \ 887169689Skan ret = 0; \ 888169689Skan else if (__is_zero_x) \ 889169689Skan ret = Y##_s ? 1 : -1; \ 890169689Skan else if (__is_zero_y) \ 891169689Skan ret = X##_s ? -1 : 1; \ 892169689Skan else if (X##_s != Y##_s) \ 893169689Skan ret = X##_s ? -1 : 1; \ 894169689Skan else if (X##_e > Y##_e) \ 895169689Skan ret = X##_s ? -1 : 1; \ 896169689Skan else if (X##_e < Y##_e) \ 897169689Skan ret = X##_s ? 1 : -1; \ 898169689Skan else if (_FP_FRAC_GT_##wc(X, Y)) \ 899169689Skan ret = X##_s ? -1 : 1; \ 900169689Skan else if (_FP_FRAC_GT_##wc(Y, X)) \ 901169689Skan ret = X##_s ? 1 : -1; \ 902169689Skan else \ 903169689Skan ret = 0; \ 904169689Skan } \ 905169689Skan } while (0) 906169689Skan 907169689Skan 908169689Skan/* Simplification for strict equality. */ 909169689Skan 910169689Skan#define _FP_CMP_EQ(fs, wc, ret, X, Y) \ 911169689Skan do { \ 912169689Skan /* NANs are unordered */ \ 913169689Skan if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ 914169689Skan || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \ 915169689Skan { \ 916169689Skan ret = 1; \ 917169689Skan } \ 918169689Skan else \ 919169689Skan { \ 920169689Skan ret = !(X##_e == Y##_e \ 921169689Skan && _FP_FRAC_EQ_##wc(X, Y) \ 922169689Skan && (X##_s == Y##_s || (!X##_e && _FP_FRAC_ZEROP_##wc(X)))); \ 923169689Skan } \ 924169689Skan } while (0) 925169689Skan 926169689Skan/* Version to test unordered. */ 927169689Skan 928169689Skan#define _FP_CMP_UNORD(fs, wc, ret, X, Y) \ 929169689Skan do { \ 930169689Skan ret = ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ 931169689Skan || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))); \ 932169689Skan } while (0) 933169689Skan 934169689Skan/* 935169689Skan * Main square root routine. The input value should be cooked. 936169689Skan */ 937169689Skan 938169689Skan#define _FP_SQRT(fs, wc, R, X) \ 939169689Skando { \ 940169689Skan _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S); \ 941169689Skan _FP_W_TYPE q; \ 942169689Skan switch (X##_c) \ 943169689Skan { \ 944169689Skan case FP_CLS_NAN: \ 945169689Skan _FP_FRAC_COPY_##wc(R, X); \ 946169689Skan R##_s = X##_s; \ 947169689Skan R##_c = FP_CLS_NAN; \ 948169689Skan break; \ 949169689Skan case FP_CLS_INF: \ 950169689Skan if (X##_s) \ 951169689Skan { \ 952169689Skan R##_s = _FP_NANSIGN_##fs; \ 953169689Skan R##_c = FP_CLS_NAN; /* NAN */ \ 954169689Skan _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ 955169689Skan FP_SET_EXCEPTION(FP_EX_INVALID); \ 956169689Skan } \ 957169689Skan else \ 958169689Skan { \ 959169689Skan R##_s = 0; \ 960169689Skan R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \ 961169689Skan } \ 962169689Skan break; \ 963169689Skan case FP_CLS_ZERO: \ 964169689Skan R##_s = X##_s; \ 965169689Skan R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \ 966169689Skan break; \ 967169689Skan case FP_CLS_NORMAL: \ 968169689Skan R##_s = 0; \ 969169689Skan if (X##_s) \ 970169689Skan { \ 971169689Skan R##_c = FP_CLS_NAN; /* sNAN */ \ 972169689Skan R##_s = _FP_NANSIGN_##fs; \ 973169689Skan _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ 974169689Skan FP_SET_EXCEPTION(FP_EX_INVALID); \ 975169689Skan break; \ 976169689Skan } \ 977169689Skan R##_c = FP_CLS_NORMAL; \ 978169689Skan if (X##_e & 1) \ 979169689Skan _FP_FRAC_SLL_##wc(X, 1); \ 980169689Skan R##_e = X##_e >> 1; \ 981169689Skan _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc); \ 982169689Skan _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \ 983169689Skan q = _FP_OVERFLOW_##fs >> 1; \ 984169689Skan _FP_SQRT_MEAT_##wc(R, S, T, X, q); \ 985169689Skan } \ 986169689Skan } while (0) 987169689Skan 988169689Skan/* 989169689Skan * Convert from FP to integer. Input is raw. 990169689Skan */ 991169689Skan 992169689Skan/* RSIGNED can have following values: 993169689Skan * 0: the number is required to be 0..(2^rsize)-1, if not, NV is set plus 994169689Skan * the result is either 0 or (2^rsize)-1 depending on the sign in such 995169689Skan * case. 996169689Skan * 1: the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, 997169689Skan * NV is set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 998169689Skan * depending on the sign in such case. 999169689Skan * -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is 1000169689Skan * set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 1001169689Skan * depending on the sign in such case. 1002169689Skan */ 1003169689Skan#define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \ 1004169689Skando { \ 1005169689Skan if (X##_e < _FP_EXPBIAS_##fs) \ 1006169689Skan { \ 1007169689Skan r = 0; \ 1008169689Skan if (X##_e == 0) \ 1009169689Skan { \ 1010169689Skan if (!_FP_FRAC_ZEROP_##wc(X)) \ 1011169689Skan { \ 1012169689Skan FP_SET_EXCEPTION(FP_EX_INEXACT); \ 1013169689Skan FP_SET_EXCEPTION(FP_EX_DENORM); \ 1014169689Skan } \ 1015169689Skan } \ 1016169689Skan else \ 1017169689Skan FP_SET_EXCEPTION(FP_EX_INEXACT); \ 1018169689Skan } \ 1019169689Skan else if (X##_e >= _FP_EXPBIAS_##fs + rsize - (rsigned > 0 || X##_s) \ 1020169689Skan || (!rsigned && X##_s)) \ 1021169689Skan { \ 1022169689Skan /* Overflow or converting to the most negative integer. */ \ 1023169689Skan if (rsigned) \ 1024169689Skan { \ 1025169689Skan r = 1; \ 1026169689Skan r <<= rsize - 1; \ 1027169689Skan r -= 1 - X##_s; \ 1028169689Skan } else { \ 1029169689Skan r = 0; \ 1030169689Skan if (X##_s) \ 1031169689Skan r = ~r; \ 1032169689Skan } \ 1033169689Skan \ 1034169689Skan if (rsigned && X##_s && X##_e == _FP_EXPBIAS_##fs + rsize - 1) \ 1035169689Skan { \ 1036169689Skan /* Possibly converting to most negative integer; check the \ 1037169689Skan mantissa. */ \ 1038169689Skan int inexact = 0; \ 1039169689Skan (void)((_FP_FRACBITS_##fs > rsize) \ 1040169689Skan ? ({ _FP_FRAC_SRST_##wc(X, inexact, \ 1041169689Skan _FP_FRACBITS_##fs - rsize, \ 1042169689Skan _FP_FRACBITS_##fs); 0; }) \ 1043169689Skan : 0); \ 1044169689Skan if (!_FP_FRAC_ZEROP_##wc(X)) \ 1045169689Skan FP_SET_EXCEPTION(FP_EX_INVALID); \ 1046169689Skan else if (inexact) \ 1047169689Skan FP_SET_EXCEPTION(FP_EX_INEXACT); \ 1048169689Skan } \ 1049169689Skan else \ 1050169689Skan FP_SET_EXCEPTION(FP_EX_INVALID); \ 1051169689Skan } \ 1052169689Skan else \ 1053169689Skan { \ 1054169689Skan _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \ 1055169689Skan if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1) \ 1056169689Skan { \ 1057169689Skan _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \ 1058169689Skan r <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \ 1059169689Skan } \ 1060169689Skan else \ 1061169689Skan { \ 1062169689Skan int inexact; \ 1063169689Skan _FP_FRAC_SRST_##wc(X, inexact, \ 1064169689Skan (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs - 1 \ 1065169689Skan - X##_e), \ 1066169689Skan _FP_FRACBITS_##fs); \ 1067169689Skan if (inexact) \ 1068169689Skan FP_SET_EXCEPTION(FP_EX_INEXACT); \ 1069169689Skan _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \ 1070169689Skan } \ 1071169689Skan if (rsigned && X##_s) \ 1072169689Skan r = -r; \ 1073169689Skan } \ 1074169689Skan} while (0) 1075169689Skan 1076169689Skan/* Convert integer to fp. Output is raw. RTYPE is unsigned even if 1077169689Skan input is signed. */ 1078169689Skan#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \ 1079169689Skan do { \ 1080169689Skan if (r) \ 1081169689Skan { \ 1082169689Skan rtype ur_; \ 1083169689Skan \ 1084169689Skan if ((X##_s = (r < 0))) \ 1085169689Skan r = -(rtype)r; \ 1086169689Skan \ 1087169689Skan ur_ = (rtype) r; \ 1088169689Skan (void)((rsize <= _FP_W_TYPE_SIZE) \ 1089169689Skan ? ({ \ 1090169689Skan int lz_; \ 1091169689Skan __FP_CLZ(lz_, (_FP_W_TYPE)ur_); \ 1092169689Skan X##_e = _FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1 - lz_; \ 1093169689Skan }) \ 1094169689Skan : ((rsize <= 2 * _FP_W_TYPE_SIZE) \ 1095169689Skan ? ({ \ 1096169689Skan int lz_; \ 1097169689Skan __FP_CLZ_2(lz_, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE), \ 1098169689Skan (_FP_W_TYPE)ur_); \ 1099169689Skan X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \ 1100169689Skan - lz_); \ 1101169689Skan }) \ 1102169689Skan : (abort(), 0))); \ 1103169689Skan \ 1104169689Skan if (rsize - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs \ 1105169689Skan && X##_e >= _FP_EXPMAX_##fs) \ 1106169689Skan { \ 1107169689Skan /* Exponent too big; overflow to infinity. (May also \ 1108169689Skan happen after rounding below.) */ \ 1109169689Skan _FP_OVERFLOW_SEMIRAW(fs, wc, X); \ 1110169689Skan goto pack_semiraw; \ 1111169689Skan } \ 1112169689Skan \ 1113169689Skan if (rsize <= _FP_FRACBITS_##fs \ 1114169689Skan || X##_e < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs) \ 1115169689Skan { \ 1116169689Skan /* Exactly representable; shift left. */ \ 1117169689Skan _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \ 1118169689Skan _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \ 1119169689Skan + _FP_FRACBITS_##fs - 1 - X##_e)); \ 1120169689Skan } \ 1121169689Skan else \ 1122169689Skan { \ 1123169689Skan /* More bits in integer than in floating type; need to \ 1124169689Skan round. */ \ 1125169689Skan if (_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 < X##_e) \ 1126169689Skan ur_ = ((ur_ >> (X##_e - _FP_EXPBIAS_##fs \ 1127169689Skan - _FP_WFRACBITS_##fs + 1)) \ 1128169689Skan | ((ur_ << (rsize - (X##_e - _FP_EXPBIAS_##fs \ 1129169689Skan - _FP_WFRACBITS_##fs + 1))) \ 1130169689Skan != 0)); \ 1131169689Skan _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \ 1132169689Skan if ((_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 - X##_e) > 0) \ 1133169689Skan _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \ 1134169689Skan + _FP_WFRACBITS_##fs - 1 - X##_e)); \ 1135169689Skan _FP_FRAC_HIGH_##fs(X) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ 1136169689Skan pack_semiraw: \ 1137169689Skan _FP_PACK_SEMIRAW(fs, wc, X); \ 1138169689Skan } \ 1139169689Skan } \ 1140169689Skan else \ 1141169689Skan { \ 1142169689Skan X##_s = 0; \ 1143169689Skan X##_e = 0; \ 1144169689Skan _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ 1145169689Skan } \ 1146169689Skan } while (0) 1147169689Skan 1148169689Skan 1149169689Skan/* Extend from a narrower floating-point format to a wider one. Input 1150169689Skan and output are raw. */ 1151169689Skan#define FP_EXTEND(dfs,sfs,dwc,swc,D,S) \ 1152169689Skando { \ 1153169689Skan if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs \ 1154169689Skan || (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs \ 1155169689Skan < _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs) \ 1156171825Skan || (_FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1 \ 1157171825Skan && _FP_EXPBIAS_##dfs != _FP_EXPBIAS_##sfs)) \ 1158169689Skan abort(); \ 1159169689Skan D##_s = S##_s; \ 1160169689Skan _FP_FRAC_COPY_##dwc##_##swc(D, S); \ 1161169689Skan if (_FP_EXP_NORMAL(sfs, swc, S)) \ 1162169689Skan { \ 1163169689Skan D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \ 1164169689Skan _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs - _FP_FRACBITS_##sfs)); \ 1165169689Skan } \ 1166169689Skan else \ 1167169689Skan { \ 1168169689Skan if (S##_e == 0) \ 1169169689Skan { \ 1170169689Skan if (_FP_FRAC_ZEROP_##swc(S)) \ 1171169689Skan D##_e = 0; \ 1172171825Skan else if (_FP_EXPBIAS_##dfs \ 1173171825Skan < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1) \ 1174171825Skan { \ 1175171825Skan FP_SET_EXCEPTION(FP_EX_DENORM); \ 1176171825Skan _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \ 1177171825Skan - _FP_FRACBITS_##sfs)); \ 1178171825Skan D##_e = 0; \ 1179171825Skan } \ 1180169689Skan else \ 1181169689Skan { \ 1182169689Skan int _lz; \ 1183169689Skan FP_SET_EXCEPTION(FP_EX_DENORM); \ 1184169689Skan _FP_FRAC_CLZ_##swc(_lz, S); \ 1185169689Skan _FP_FRAC_SLL_##dwc(D, \ 1186169689Skan _lz + _FP_FRACBITS_##dfs \ 1187169689Skan - _FP_FRACTBITS_##sfs); \ 1188169689Skan D##_e = (_FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs + 1 \ 1189169689Skan + _FP_FRACXBITS_##sfs - _lz); \ 1190169689Skan } \ 1191169689Skan } \ 1192169689Skan else \ 1193169689Skan { \ 1194169689Skan D##_e = _FP_EXPMAX_##dfs; \ 1195169689Skan if (!_FP_FRAC_ZEROP_##swc(S)) \ 1196169689Skan { \ 1197169689Skan if (!(_FP_FRAC_HIGH_RAW_##sfs(S) & _FP_QNANBIT_##sfs)) \ 1198169689Skan FP_SET_EXCEPTION(FP_EX_INVALID); \ 1199169689Skan _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \ 1200169689Skan - _FP_FRACBITS_##sfs)); \ 1201169689Skan } \ 1202169689Skan } \ 1203169689Skan } \ 1204169689Skan} while (0) 1205169689Skan 1206169689Skan/* Truncate from a wider floating-point format to a narrower one. 1207169689Skan Input and output are semi-raw. */ 1208169689Skan#define FP_TRUNC(dfs,sfs,dwc,swc,D,S) \ 1209169689Skando { \ 1210169689Skan if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs \ 1211171825Skan || (_FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1 \ 1212171825Skan && _FP_EXPBIAS_##sfs != _FP_EXPBIAS_##dfs)) \ 1213169689Skan abort(); \ 1214169689Skan D##_s = S##_s; \ 1215169689Skan if (_FP_EXP_NORMAL(sfs, swc, S)) \ 1216169689Skan { \ 1217169689Skan D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \ 1218169689Skan if (D##_e >= _FP_EXPMAX_##dfs) \ 1219169689Skan _FP_OVERFLOW_SEMIRAW(dfs, dwc, D); \ 1220169689Skan else \ 1221169689Skan { \ 1222169689Skan if (D##_e <= 0) \ 1223169689Skan { \ 1224171825Skan if (D##_e < 1 - _FP_FRACBITS_##dfs) \ 1225171825Skan { \ 1226171825Skan _FP_FRAC_SET_##swc(S, _FP_ZEROFRAC_##swc); \ 1227171825Skan _FP_FRAC_LOW_##swc(S) |= 1; \ 1228171825Skan } \ 1229169689Skan else \ 1230169689Skan { \ 1231169689Skan _FP_FRAC_HIGH_##sfs(S) |= _FP_IMPLBIT_SH_##sfs; \ 1232169689Skan _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ 1233169689Skan - _FP_WFRACBITS_##dfs + 1 - D##_e), \ 1234169689Skan _FP_WFRACBITS_##sfs); \ 1235169689Skan } \ 1236169689Skan D##_e = 0; \ 1237169689Skan } \ 1238169689Skan else \ 1239169689Skan _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ 1240169689Skan - _FP_WFRACBITS_##dfs), \ 1241169689Skan _FP_WFRACBITS_##sfs); \ 1242169689Skan _FP_FRAC_COPY_##dwc##_##swc(D, S); \ 1243169689Skan } \ 1244169689Skan } \ 1245169689Skan else \ 1246169689Skan { \ 1247169689Skan if (S##_e == 0) \ 1248169689Skan { \ 1249169689Skan D##_e = 0; \ 1250171825Skan if (_FP_FRAC_ZEROP_##swc(S)) \ 1251171825Skan _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ 1252171825Skan else \ 1253169689Skan { \ 1254169689Skan FP_SET_EXCEPTION(FP_EX_DENORM); \ 1255171825Skan if (_FP_EXPBIAS_##sfs \ 1256171825Skan < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1) \ 1257171825Skan { \ 1258171825Skan _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ 1259171825Skan - _FP_WFRACBITS_##dfs), \ 1260171825Skan _FP_WFRACBITS_##sfs); \ 1261171825Skan _FP_FRAC_COPY_##dwc##_##swc(D, S); \ 1262171825Skan } \ 1263171825Skan else \ 1264171825Skan { \ 1265171825Skan _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ 1266171825Skan _FP_FRAC_LOW_##dwc(D) |= 1; \ 1267171825Skan } \ 1268169689Skan } \ 1269169689Skan } \ 1270169689Skan else \ 1271169689Skan { \ 1272169689Skan D##_e = _FP_EXPMAX_##dfs; \ 1273169689Skan if (_FP_FRAC_ZEROP_##swc(S)) \ 1274169689Skan _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ 1275169689Skan else \ 1276169689Skan { \ 1277169689Skan _FP_CHECK_SIGNAN_SEMIRAW(sfs, swc, S); \ 1278169689Skan _FP_FRAC_SRL_##swc(S, (_FP_WFRACBITS_##sfs \ 1279169689Skan - _FP_WFRACBITS_##dfs)); \ 1280169689Skan _FP_FRAC_COPY_##dwc##_##swc(D, S); \ 1281169689Skan /* Semi-raw NaN must have all workbits cleared. */ \ 1282169689Skan _FP_FRAC_LOW_##dwc(D) \ 1283169689Skan &= ~(_FP_W_TYPE) ((1 << _FP_WORKBITS) - 1); \ 1284169689Skan _FP_FRAC_HIGH_##dfs(D) |= _FP_QNANBIT_SH_##dfs; \ 1285169689Skan } \ 1286169689Skan } \ 1287169689Skan } \ 1288169689Skan} while (0) 1289169689Skan 1290169689Skan/* 1291169689Skan * Helper primitives. 1292169689Skan */ 1293169689Skan 1294169689Skan/* Count leading zeros in a word. */ 1295169689Skan 1296169689Skan#ifndef __FP_CLZ 1297169689Skan/* GCC 3.4 and later provide the builtins for us. */ 1298169689Skan#define __FP_CLZ(r, x) \ 1299169689Skan do { \ 1300169689Skan if (sizeof (_FP_W_TYPE) == sizeof (unsigned int)) \ 1301169689Skan r = __builtin_clz (x); \ 1302169689Skan else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long)) \ 1303169689Skan r = __builtin_clzl (x); \ 1304169689Skan else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long long)) \ 1305169689Skan r = __builtin_clzll (x); \ 1306169689Skan else \ 1307169689Skan abort (); \ 1308169689Skan } while (0) 1309169689Skan#endif /* ndef __FP_CLZ */ 1310169689Skan 1311169689Skan#define _FP_DIV_HELP_imm(q, r, n, d) \ 1312169689Skan do { \ 1313169689Skan q = n / d, r = n % d; \ 1314169689Skan } while (0) 1315169689Skan 1316169689Skan 1317169689Skan/* A restoring bit-by-bit division primitive. */ 1318169689Skan 1319169689Skan#define _FP_DIV_MEAT_N_loop(fs, wc, R, X, Y) \ 1320169689Skan do { \ 1321169689Skan int count = _FP_WFRACBITS_##fs; \ 1322169689Skan _FP_FRAC_DECL_##wc (u); \ 1323169689Skan _FP_FRAC_DECL_##wc (v); \ 1324169689Skan _FP_FRAC_COPY_##wc (u, X); \ 1325169689Skan _FP_FRAC_COPY_##wc (v, Y); \ 1326169689Skan _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \ 1327169689Skan /* Normalize U and V. */ \ 1328169689Skan _FP_FRAC_SLL_##wc (u, _FP_WFRACXBITS_##fs); \ 1329169689Skan _FP_FRAC_SLL_##wc (v, _FP_WFRACXBITS_##fs); \ 1330169689Skan /* First round. Since the operands are normalized, either the \ 1331169689Skan first or second bit will be set in the fraction. Produce a \ 1332169689Skan normalized result by checking which and adjusting the loop \ 1333169689Skan count and exponent accordingly. */ \ 1334169689Skan if (_FP_FRAC_GE_1 (u, v)) \ 1335169689Skan { \ 1336169689Skan _FP_FRAC_SUB_##wc (u, u, v); \ 1337169689Skan _FP_FRAC_LOW_##wc (R) |= 1; \ 1338169689Skan count--; \ 1339169689Skan } \ 1340169689Skan else \ 1341169689Skan R##_e--; \ 1342169689Skan /* Subsequent rounds. */ \ 1343169689Skan do { \ 1344169689Skan int msb = (_FP_WS_TYPE) _FP_FRAC_HIGH_##wc (u) < 0; \ 1345169689Skan _FP_FRAC_SLL_##wc (u, 1); \ 1346169689Skan _FP_FRAC_SLL_##wc (R, 1); \ 1347169689Skan if (msb || _FP_FRAC_GE_1 (u, v)) \ 1348169689Skan { \ 1349169689Skan _FP_FRAC_SUB_##wc (u, u, v); \ 1350169689Skan _FP_FRAC_LOW_##wc (R) |= 1; \ 1351169689Skan } \ 1352169689Skan } while (--count > 0); \ 1353169689Skan /* If there's anything left in U, the result is inexact. */ \ 1354169689Skan _FP_FRAC_LOW_##wc (R) |= !_FP_FRAC_ZEROP_##wc (u); \ 1355169689Skan } while (0) 1356169689Skan 1357169689Skan#define _FP_DIV_MEAT_1_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 1, R, X, Y) 1358169689Skan#define _FP_DIV_MEAT_2_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 2, R, X, Y) 1359169689Skan#define _FP_DIV_MEAT_4_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 4, R, X, Y) 1360