| 1082 | *----------------------------------------------------------------------------*/ |
| 1083 | |
| 1084 | floatx80 floatx80_logn(floatx80 a, float_status *status) |
| 1085 | { |
| 1086 | flag aSign; |
| 1087 | int32_t aExp; |
| 1088 | uint64_t aSig, fSig; |
| 1089 | |
| 1090 | int32_t compact, j, k, adjk; |
| 1091 | floatx80 fp0, fp1, fp2, fp3, f, logof2, klog2, saveu; |
| 1092 | |
| 1093 | aSig = extractFloatx80Frac(a); |
| 1094 | aExp = extractFloatx80Exp(a); |
| 1095 | aSign = extractFloatx80Sign(a); |
| 1096 | |
| 1097 | if (aExp == 0x7FFF) { |
| 1098 | if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status); |
| 1099 | if (aSign == 0) |
| 1100 | return a; |
| 1101 | } |
| 1102 | |
| 1103 | adjk = 0; |
| 1104 | |
| 1105 | if (aExp == 0) { |
| 1106 | if (aSig == 0) { // zero |
| 1107 | float_raise(float_flag_divbyzero, status); |
| 1108 | return packFloatx80(1, 0x7FFF, floatx80_default_infinity_low); |
| 1109 | } |
| 1110 | #if 1 |
| 1111 | if ((aSig & one_sig) == 0) { // denormal |
| 1112 | normalizeFloatx80Subnormal(aSig, &aExp, &aSig); |
| 1113 | adjk = -100; |
| 1114 | aExp += 100; |
| 1115 | a = packFloatx80(aSign, aExp, aSig); |
| 1116 | } |
| 1117 | #else |
| 1118 | normalizeFloatx80Subnormal(aSig, &aExp, &aSig); |
| 1119 | #endif |
| 1120 | } |
| 1121 | |
| 1122 | if (aSign) { |
| 1123 | float_raise(float_flag_invalid, status); |
| 1124 | return floatx80_default_nan(status); |
| 1125 | } |
| 1126 | |
| 1127 | SET_PREC; |
| 1128 | |
| 1129 | compact = floatx80_make_compact(aExp, aSig); |
| 1130 | |
| 1131 | if (compact < 0x3FFEF07D || compact > 0x3FFF8841) { // |X| < 15/16 or |X| > 17/16 |
| 1132 | k = aExp - 0x3FFF; |
| 1133 | k += adjk; |
| 1134 | fp1 = int32_to_floatx80(k); |
| 1135 | |
| 1136 | fSig = (aSig & LIT64(0xFE00000000000000)) | LIT64(0x0100000000000000); |
| 1137 | j = (fSig >> 56) & 0x7E; // DISPLACEMENT FOR 1/F |
| 1138 | |
| 1139 | f = packFloatx80(0, 0x3FFF, fSig); // F |
| 1140 | fp0 = packFloatx80(0, 0x3FFF, aSig); // Y |
| 1141 |
no test coverage detected