1 #define _FP_DECL(wc, X) \ 2 _FP_I_TYPE X##_c, X##_s, X##_e; \ 3 _FP_FRAC_DECL_##wc(X) 4 5 /* 6 * Finish truely unpacking a native fp value by classifying the kind 7 * of fp value and normalizing both the exponent and the fraction. 8 */ 9 10 #define _FP_UNPACK_CANONICAL(fs, wc, X) \ 11 do { \ 12 switch (X##_e) \ 13 { \ 14 default: \ 15 _FP_FRAC_HIGH_##wc(X) |= _FP_IMPLBIT_##fs; \ 16 _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \ 17 X##_e -= _FP_EXPBIAS_##fs; \ 18 X##_c = FP_CLS_NORMAL; \ 19 break; \ 20 \ 21 case 0: \ 22 if (_FP_FRAC_ZEROP_##wc(X)) \ 23 X##_c = FP_CLS_ZERO; \ 24 else \ 25 { \ 26 /* a denormalized number */ \ 27 _FP_I_TYPE _shift; \ 28 _FP_FRAC_CLZ_##wc(_shift, X); \ 29 _shift -= _FP_FRACXBITS_##fs; \ 30 _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS)); \ 31 X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \ 32 X##_c = FP_CLS_NORMAL; \ 33 } \ 34 break; \ 35 \ 36 case _FP_EXPMAX_##fs: \ 37 if (_FP_FRAC_ZEROP_##wc(X)) \ 38 X##_c = FP_CLS_INF; \ 39 else \ 40 /* we don't differentiate between signaling and quiet nans */ \ 41 X##_c = FP_CLS_NAN; \ 42 break; \ 43 } \ 44 } while (0) 45 46 47 /* 48 * Before packing the bits back into the native fp result, take care 49 * of such mundane things as rounding and overflow. Also, for some 50 * kinds of fp values, the original parts may not have been fully 51 * extracted -- but that is ok, we can regenerate them now. 52 */ 53 54 #define _FP_PACK_CANONICAL(fs, wc, X) \ 55 ({int __ret = 0; \ 56 switch (X##_c) \ 57 { \ 58 case FP_CLS_NORMAL: \ 59 X##_e += _FP_EXPBIAS_##fs; \ 60 if (X##_e > 0) \ 61 { \ 62 __ret |= _FP_ROUND(wc, X); \ 63 if (_FP_FRAC_OVERP_##wc(fs, X)) \ 64 { \ 65 _FP_FRAC_SRL_##wc(X, (_FP_WORKBITS+1)); \ 66 X##_e++; \ 67 } \ 68 else \ 69 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ 70 if (X##_e >= _FP_EXPMAX_##fs) \ 71 { \ 72 /* overflow to infinity */ \ 73 X##_e = _FP_EXPMAX_##fs; \ 74 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ 75 __ret |= EFLAG_OVERFLOW; \ 76 } \ 77 } \ 78 else \ 79 { \ 80 /* we've got a denormalized number */ \ 81 X##_e = -X##_e + 1; \ 82 if (X##_e <= _FP_WFRACBITS_##fs) \ 83 { \ 84 _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \ 85 __ret |= _FP_ROUND(wc, X); \ 86 _FP_FRAC_SLL_##wc(X, 1); \ 87 if (_FP_FRAC_OVERP_##wc(fs, X)) \ 88 { \ 89 X##_e = 1; \ 90 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ 91 } \ 92 else \ 93 { \ 94 X##_e = 0; \ 95 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS+1); \ 96 __ret |= EFLAG_UNDERFLOW; \ 97 } \ 98 } \ 99 else \ 100 { \ 101 /* underflow to zero */ \ 102 X##_e = 0; \ 103 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ 104 __ret |= EFLAG_UNDERFLOW; \ 105 } \ 106 } \ 107 break; \ 108 \ 109 case FP_CLS_ZERO: \ 110 X##_e = 0; \ 111 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ 112 break; \ 113 \ 114 case FP_CLS_INF: \ 115 X##_e = _FP_EXPMAX_##fs; \ 116 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ 117 break; \ 118 \ 119 case FP_CLS_NAN: \ 120 X##_e = _FP_EXPMAX_##fs; \ 121 if (!_FP_KEEPNANFRACP) \ 122 { \ 123 _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ 124 X##_s = 0; \ 125 } \ 126 else \ 127 _FP_FRAC_HIGH_##wc(X) |= _FP_QNANBIT_##fs; \ 128 break; \ 129 } \ 130 __ret; \ 131 }) 132 133 134 /* 135 * Main addition routine. The input values should be cooked. 136 */ 137 138 #define _FP_ADD(fs, wc, R, X, Y) \ 139 do { \ 140 switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ 141 { \ 142 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ 143 { \ 144 /* shift the smaller number so that its exponent matches the larger */ \ 145 _FP_I_TYPE diff = X##_e - Y##_e; \ 146 \ 147 if (diff < 0) \ 148 { \ 149 diff = -diff; \ 150 if (diff <= _FP_WFRACBITS_##fs) \ 151 _FP_FRAC_SRS_##wc(X, diff, _FP_WFRACBITS_##fs); \ 152 else if (!_FP_FRAC_ZEROP_##wc(X)) \ 153 _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ 154 else \ 155 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ 156 R##_e = Y##_e; \ 157 } \ 158 else \ 159 { \ 160 if (diff > 0) \ 161 { \ 162 if (diff <= _FP_WFRACBITS_##fs) \ 163 _FP_FRAC_SRS_##wc(Y, diff, _FP_WFRACBITS_##fs); \ 164 else if (!_FP_FRAC_ZEROP_##wc(Y)) \ 165 _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \ 166 else \ 167 _FP_FRAC_SET_##wc(Y, _FP_ZEROFRAC_##wc); \ 168 } \ 169 R##_e = X##_e; \ 170 } \ 171 \ 172 R##_c = FP_CLS_NORMAL; \ 173 \ 174 if (X##_s == Y##_s) \ 175 { \ 176 R##_s = X##_s; \ 177 _FP_FRAC_ADD_##wc(R, X, Y); \ 178 if (_FP_FRAC_OVERP_##wc(fs, R)) \ 179 { \ 180 _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ 181 R##_e++; \ 182 } \ 183 } \ 184 else \ 185 { \ 186 R##_s = X##_s; \ 187 _FP_FRAC_SUB_##wc(R, X, Y); \ 188 if (_FP_FRAC_ZEROP_##wc(R)) \ 189 { \ 190 /* return an exact zero */ \ 191 if (FP_ROUNDMODE == FP_RND_MINF) \ 192 R##_s |= Y##_s; \ 193 else \ 194 R##_s &= Y##_s; \ 195 R##_c = FP_CLS_ZERO; \ 196 } \ 197 else \ 198 { \ 199 if (_FP_FRAC_NEGP_##wc(R)) \ 200 { \ 201 _FP_FRAC_SUB_##wc(R, Y, X); \ 202 R##_s = Y##_s; \ 203 } \ 204 \ 205 /* renormalize after subtraction */ \ 206 _FP_FRAC_CLZ_##wc(diff, R); \ 207 diff -= _FP_WFRACXBITS_##fs; \ 208 if (diff) \ 209 { \ 210 R##_e -= diff; \ 211 _FP_FRAC_SLL_##wc(R, diff); \ 212 } \ 213 } \ 214 } \ 215 break; \ 216 } \ 217 \ 218 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ 219 _FP_CHOOSENAN(fs, wc, R, X, Y); \ 220 break; \ 221 \ 222 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ 223 R##_e = X##_e; \ 224 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ 225 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ 226 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ 227 _FP_FRAC_COPY_##wc(R, X); \ 228 R##_s = X##_s; \ 229 R##_c = X##_c; \ 230 break; \ 231 \ 232 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ 233 R##_e = Y##_e; \ 234 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ 235 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ 236 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ 237 _FP_FRAC_COPY_##wc(R, Y); \ 238 R##_s = Y##_s; \ 239 R##_c = Y##_c; \ 240 break; \ 241 \ 242 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ 243 if (X##_s != Y##_s) \ 244 { \ 245 /* +INF + -INF => NAN */ \ 246 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ 247 R##_s = X##_s ^ Y##_s; \ 248 R##_c = FP_CLS_NAN; \ 249 break; \ 250 } \ 251 /* FALLTHRU */ \ 252 \ 253 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ 254 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ 255 R##_s = X##_s; \ 256 R##_c = FP_CLS_INF; \ 257 break; \ 258 \ 259 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ 260 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ 261 R##_s = Y##_s; \ 262 R##_c = FP_CLS_INF; \ 263 break; \ 264 \ 265 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ 266 /* make sure the sign is correct */ \ 267 if (FP_ROUNDMODE == FP_RND_MINF) \ 268 R##_s = X##_s | Y##_s; \ 269 else \ 270 R##_s = X##_s & Y##_s; \ 271 R##_c = FP_CLS_ZERO; \ 272 break; \ 273 \ 274 default: \ 275 abort(); \ 276 } \ 277 } while (0) 278 279 280 /* 281 * Main negation routine. FIXME -- when we care about setting exception 282 * bits reliably, this will not do. We should examine all of the fp classes. 283 */ 284 285 #define _FP_NEG(fs, wc, R, X) \ 286 do { \ 287 _FP_FRAC_COPY_##wc(R, X); \ 288 R##_c = X##_c; \ 289 R##_e = X##_e; \ 290 R##_s = 1 ^ X##_s; \ 291 } while (0) 292 293 294 /* 295 * Main multiplication routine. The input values should be cooked. 296 */ 297 298 #define _FP_MUL(fs, wc, R, X, Y) \ 299 do { \ 300 R##_s = X##_s ^ Y##_s; \ 301 switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ 302 { \ 303 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ 304 R##_c = FP_CLS_NORMAL; \ 305 R##_e = X##_e + Y##_e + 1; \ 306 \ 307 _FP_MUL_MEAT_##fs(R,X,Y); \ 308 \ 309 if (_FP_FRAC_OVERP_##wc(fs, R)) \ 310 _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ 311 else \ 312 R##_e--; \ 313 break; \ 314 \ 315 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ 316 _FP_CHOOSENAN(fs, wc, R, X, Y); \ 317 break; \ 318 \ 319 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ 320 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ 321 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ 322 R##_s = X##_s; \ 323 \ 324 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ 325 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ 326 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ 327 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ 328 _FP_FRAC_COPY_##wc(R, X); \ 329 R##_c = X##_c; \ 330 break; \ 331 \ 332 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ 333 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ 334 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ 335 R##_s = Y##_s; \ 336 \ 337 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ 338 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ 339 _FP_FRAC_COPY_##wc(R, Y); \ 340 R##_c = Y##_c; \ 341 break; \ 342 \ 343 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ 344 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ 345 R##_c = FP_CLS_NAN; \ 346 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ 347 break; \ 348 \ 349 default: \ 350 abort(); \ 351 } \ 352 } while (0) 353 354 355 /* 356 * Main division routine. The input values should be cooked. 357 */ 358 359 #define _FP_DIV(fs, wc, R, X, Y) \ 360 do { \ 361 R##_s = X##_s ^ Y##_s; \ 362 switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ 363 { \ 364 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ 365 R##_c = FP_CLS_NORMAL; \ 366 R##_e = X##_e - Y##_e; \ 367 \ 368 _FP_DIV_MEAT_##fs(R,X,Y); \ 369 break; \ 370 \ 371 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ 372 _FP_CHOOSENAN(fs, wc, R, X, Y); \ 373 break; \ 374 \ 375 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ 376 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ 377 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ 378 R##_s = X##_s; \ 379 _FP_FRAC_COPY_##wc(R, X); \ 380 R##_c = X##_c; \ 381 break; \ 382 \ 383 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ 384 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ 385 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ 386 R##_s = Y##_s; \ 387 _FP_FRAC_COPY_##wc(R, Y); \ 388 R##_c = Y##_c; \ 389 break; \ 390 \ 391 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ 392 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ 393 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ 394 R##_c = FP_CLS_ZERO; \ 395 break; \ 396 \ 397 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ 398 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ 399 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ 400 R##_c = FP_CLS_INF; \ 401 break; \ 402 \ 403 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ 404 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ 405 R##_c = FP_CLS_NAN; \ 406 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ 407 break; \ 408 \ 409 default: \ 410 abort(); \ 411 } \ 412 } while (0) 413 414 415 /* 416 * Main differential comparison routine. The inputs should be raw not 417 * cooked. The return is -1,0,1 for normal values, 2 otherwise. 418 */ 419 420 #define _FP_CMP(fs, wc, ret, X, Y, un) \ 421 do { \ 422 /* NANs are unordered */ \ 423 if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ 424 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \ 425 { \ 426 ret = un; \ 427 } \ 428 else \ 429 { \ 430 int __x_zero = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0; \ 431 int __y_zero = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0; \ 432 \ 433 if (__x_zero && __y_zero) \ 434 ret = 0; \ 435 else if (__x_zero) \ 436 ret = Y##_s ? 1 : -1; \ 437 else if (__y_zero) \ 438 ret = X##_s ? -1 : 1; \ 439 else if (X##_s != Y##_s) \ 440 ret = X##_s ? -1 : 1; \ 441 else if (X##_e > Y##_e) \ 442 ret = X##_s ? -1 : 1; \ 443 else if (X##_e < Y##_e) \ 444 ret = X##_s ? 1 : -1; \ 445 else if (_FP_FRAC_GT_##wc(X, Y)) \ 446 ret = X##_s ? -1 : 1; \ 447 else if (_FP_FRAC_GT_##wc(Y, X)) \ 448 ret = X##_s ? 1 : -1; \ 449 else \ 450 ret = 0; \ 451 } \ 452 } while (0) 453 454 455 /* Simplification for strict equality. */ 456 457 #define _FP_CMP_EQ(fs, wc, ret, X, Y) \ 458 do { \ 459 /* NANs are unordered */ \ 460 if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ 461 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \ 462 { \ 463 ret = 1; \ 464 } \ 465 else \ 466 { \ 467 ret = !(X##_e == Y##_e \ 468 && _FP_FRAC_EQ_##wc(X, Y) \ 469 && (X##_s == Y##_s || !X##_e && _FP_FRAC_ZEROP_##wc(X))); \ 470 } \ 471 } while (0) 472 473 /* 474 * Main square root routine. The input value should be cooked. 475 */ 476 477 #define _FP_SQRT(fs, wc, R, X) \ 478 do { \ 479 _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S); \ 480 _FP_W_TYPE q; \ 481 switch (X##_c) \ 482 { \ 483 case FP_CLS_NAN: \ 484 R##_s = 0; \ 485 R##_c = FP_CLS_NAN; \ 486 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ 487 break; \ 488 case FP_CLS_INF: \ 489 if (X##_s) \ 490 { \ 491 R##_s = 0; \ 492 R##_c = FP_CLS_NAN; /* sNAN */ \ 493 } \ 494 else \ 495 { \ 496 R##_s = 0; \ 497 R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \ 498 } \ 499 break; \ 500 case FP_CLS_ZERO: \ 501 R##_s = X##_s; \ 502 R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \ 503 break; \ 504 case FP_CLS_NORMAL: \ 505 R##_s = 0; \ 506 if (X##_s) \ 507 { \ 508 R##_c = FP_CLS_NAN; /* sNAN */ \ 509 break; \ 510 } \ 511 R##_c = FP_CLS_NORMAL; \ 512 if (X##_e & 1) \ 513 _FP_FRAC_SLL_##wc(X, 1); \ 514 R##_e = X##_e >> 1; \ 515 _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc); \ 516 _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \ 517 q = _FP_OVERFLOW_##fs; \ 518 _FP_FRAC_SLL_##wc(X, 1); \ 519 _FP_SQRT_MEAT_##wc(R, S, T, X, q); \ 520 _FP_FRAC_SRL_##wc(R, 1); \ 521 } \ 522 } while (0) 523 524 /* 525 * Convert from FP to integer 526 */ 527 528 /* "When a NaN, infinity, large positive argument >= 2147483648.0, or 529 * large negative argument <= -2147483649.0 is converted to an integer, 530 * the invalid_current bit...should be set and fp_exception_IEEE_754 should 531 * be raised. If the floating point invalid trap is disabled, no trap occurs 532 * and a numerical result is generated: if the sign bit of the operand 533 * is 0, the result is 2147483647; if the sign bit of the operand is 1, 534 * the result is -2147483648." 535 * Similarly for conversion to extended ints, except that the boundaries 536 * are >= 2^63, <= -(2^63 + 1), and the results are 2^63 + 1 for s=0 and 537 * -2^63 for s=1. 538 * -- SPARC Architecture Manual V9, Appendix B, which specifies how 539 * SPARCs resolve implementation dependencies in the IEEE-754 spec. 540 * I don't believe that the code below follows this. I'm not even sure 541 * it's right! 542 * It doesn't cope with needing to convert to an n bit integer when there 543 * is no n bit integer type. Fortunately gcc provides long long so this 544 * isn't a problem for sparc32. 545 * I have, however, fixed its NaN handling to conform as above. 546 * -- PMM 02/1998 547 * NB: rsigned is not 'is r declared signed?' but 'should the value stored 548 * in r be signed or unsigned?'. r is always(?) declared unsigned. 549 * Comments below are mine, BTW -- PMM 550 */ 551 #define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \ 552 do { \ 553 switch (X##_c) \ 554 { \ 555 case FP_CLS_NORMAL: \ 556 if (X##_e < 0) \ 557 { \ 558 /* case FP_CLS_NAN: see above! */ \ 559 case FP_CLS_ZERO: \ 560 r = 0; \ 561 } \ 562 else if (X##_e >= rsize - (rsigned != 0)) \ 563 { /* overflow */ \ 564 case FP_CLS_NAN: \ 565 case FP_CLS_INF: \ 566 if (rsigned) \ 567 { \ 568 r = 1; \ 569 r <<= rsize - 1; \ 570 r -= 1 - X##_s; \ 571 } \ 572 else \ 573 { \ 574 r = 0; \ 575 if (!X##_s) \ 576 r = ~r; \ 577 } \ 578 } \ 579 else \ 580 { \ 581 if (_FP_W_TYPE_SIZE*wc < rsize) \ 582 { \ 583 _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \ 584 r <<= X##_e - _FP_WFRACBITS_##fs; \ 585 } \ 586 else \ 587 { \ 588 if (X##_e >= _FP_WFRACBITS_##fs) \ 589 _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1));\ 590 else \ 591 _FP_FRAC_SRL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1));\ 592 _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \ 593 } \ 594 if (rsigned && X##_s) \ 595 r = -r; \ 596 } \ 597 break; \ 598 } \ 599 } while (0) 600 601 #define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \ 602 do { \ 603 if (r) \ 604 { \ 605 X##_c = FP_CLS_NORMAL; \ 606 \ 607 if ((X##_s = (r < 0))) \ 608 r = -r; \ 609 /* Note that `r' is now considered unsigned, so we don't have \ 610 to worry about the single signed overflow case. */ \ 611 \ 612 if (rsize <= _FP_W_TYPE_SIZE) \ 613 __FP_CLZ(X##_e, r); \ 614 else \ 615 __FP_CLZ_2(X##_e, (_FP_W_TYPE)(r >> _FP_W_TYPE_SIZE), \ 616 (_FP_W_TYPE)r); \ 617 if (rsize < _FP_W_TYPE_SIZE) \ 618 X##_e -= (_FP_W_TYPE_SIZE - rsize); \ 619 X##_e = rsize - X##_e - 1; \ 620 \ 621 if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs < X##_e) \ 622 __FP_FRAC_SRS_1(r, (X##_e - _FP_WFRACBITS_##fs), rsize); \ 623 r &= ~((_FP_W_TYPE)1 << X##_e); \ 624 _FP_FRAC_DISASSEMBLE_##wc(X, ((unsigned rtype)r), rsize); \ 625 _FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1)); \ 626 } \ 627 else \ 628 { \ 629 X##_c = FP_CLS_ZERO, X##_s = 0; \ 630 } \ 631 } while (0) 632 633 634 #define FP_CONV(dfs,sfs,dwc,swc,D,S) \ 635 do { \ 636 _FP_FRAC_CONV_##dwc##_##swc(dfs, sfs, D, S); \ 637 D##_e = S##_e; \ 638 D##_c = S##_c; \ 639 D##_s = S##_s; \ 640 } while (0) 641 642 /* 643 * Helper primitives. 644 */ 645 646 /* Count leading zeros in a word. */ 647 648 #ifndef __FP_CLZ 649 #if _FP_W_TYPE_SIZE < 64 650 /* this is just to shut the compiler up about shifts > word length -- PMM 02/1998 */ 651 #define __FP_CLZ(r, x) \ 652 do { \ 653 _FP_W_TYPE _t = (x); \ 654 r = _FP_W_TYPE_SIZE - 1; \ 655 if (_t > 0xffff) r -= 16; \ 656 if (_t > 0xffff) _t >>= 16; \ 657 if (_t > 0xff) r -= 8; \ 658 if (_t > 0xff) _t >>= 8; \ 659 if (_t & 0xf0) r -= 4; \ 660 if (_t & 0xf0) _t >>= 4; \ 661 if (_t & 0xc) r -= 2; \ 662 if (_t & 0xc) _t >>= 2; \ 663 if (_t & 0x2) r -= 1; \ 664 } while (0) 665 #else /* not _FP_W_TYPE_SIZE < 64 */ 666 #define __FP_CLZ(r, x) \ 667 do { \ 668 _FP_W_TYPE _t = (x); \ 669 r = _FP_W_TYPE_SIZE - 1; \ 670 if (_t > 0xffffffff) r -= 32; \ 671 if (_t > 0xffffffff) _t >>= 32; \ 672 if (_t > 0xffff) r -= 16; \ 673 if (_t > 0xffff) _t >>= 16; \ 674 if (_t > 0xff) r -= 8; \ 675 if (_t > 0xff) _t >>= 8; \ 676 if (_t & 0xf0) r -= 4; \ 677 if (_t & 0xf0) _t >>= 4; \ 678 if (_t & 0xc) r -= 2; \ 679 if (_t & 0xc) _t >>= 2; \ 680 if (_t & 0x2) r -= 1; \ 681 } while (0) 682 #endif /* not _FP_W_TYPE_SIZE < 64 */ 683 #endif /* ndef __FP_CLZ */ 684 685 #define _FP_DIV_HELP_imm(q, r, n, d) \ 686 do { \ 687 q = n / d, r = n % d; \ 688 } while (0) 689 690