| 2998 | *----------------------------------------------------------------------------*/ |
| 2999 | |
| 3000 | floatx80 floatx80_mod(floatx80 a, floatx80 b, uint64_t *q, flag *s, float_status *status) |
| 3001 | { |
| 3002 | flag aSign, bSign, zSign; |
| 3003 | int32_t aExp, bExp, expDiff; |
| 3004 | uint64_t aSig0, aSig1, bSig; |
| 3005 | uint64_t qTemp, term0, term1; |
| 3006 | |
| 3007 | aSig0 = extractFloatx80Frac(a); |
| 3008 | aExp = extractFloatx80Exp(a); |
| 3009 | aSign = extractFloatx80Sign(a); |
| 3010 | bSig = extractFloatx80Frac(b); |
| 3011 | bExp = extractFloatx80Exp(b); |
| 3012 | bSign = extractFloatx80Sign(b); |
| 3013 | |
| 3014 | *s = 0; |
| 3015 | *q = 0; |
| 3016 | |
| 3017 | if (aExp == 0x7FFF) { |
| 3018 | if ((uint64_t)(aSig0 << 1) |
| 3019 | || ((bExp == 0x7FFF) && (uint64_t)(bSig << 1))) { |
| 3020 | return propagateFloatx80NaN(a, b, status); |
| 3021 | } |
| 3022 | goto invalid; |
| 3023 | } |
| 3024 | if (bExp == 0x7FFF) { |
| 3025 | if ((uint64_t)(bSig << 1)) return propagateFloatx80NaN(a, b, status); |
| 3026 | *s = (aSign != bSign); |
| 3027 | return normalizeRoundAndPackFloatx80(status->floatx80_rounding_precision, aSign, aExp, aSig0, 0, status); |
| 3028 | } |
| 3029 | if (bExp == 0) { |
| 3030 | if (bSig == 0) { |
| 3031 | invalid: |
| 3032 | float_raise(float_flag_invalid, status); |
| 3033 | return floatx80_default_nan(status); |
| 3034 | } |
| 3035 | normalizeFloatx80Subnormal(bSig, &bExp, &bSig); |
| 3036 | } |
| 3037 | if (aExp == 0) { |
| 3038 | if (aSig0 == 0) { |
| 3039 | *s = (aSign != bSign); |
| 3040 | return a; |
| 3041 | } |
| 3042 | normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0); |
| 3043 | } |
| 3044 | bSig |= LIT64(0x8000000000000000); |
| 3045 | zSign = aSign; |
| 3046 | expDiff = aExp - bExp; |
| 3047 | *s = (aSign != bSign); |
| 3048 | aSig1 = 0; |
| 3049 | if (expDiff < 0) return roundAndPackFloatx80(status->floatx80_rounding_precision, aSign, aExp, aSig0, 0, status); |
| 3050 | qTemp = (bSig <= aSig0); |
| 3051 | if (qTemp) aSig0 -= bSig; |
| 3052 | *q = (expDiff > 63) ? 0 : (qTemp << expDiff); |
| 3053 | expDiff -= 64; |
| 3054 | while (0 < expDiff) { |
| 3055 | qTemp = estimateDiv128To64(aSig0, aSig1, bSig); |
| 3056 | qTemp = (2 < qTemp) ? qTemp - 2 : 0; |
| 3057 | mul64To128(bSig, qTemp, &term0, &term1); |
no test coverage detected