Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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