/* _IEEE_EXPONENT_I6_R - IEEE EXPONENT returns the exponent part of the * 64-bit argument in 46-bit integer. */ _f_int6 _IEEE_EXPONENT_I6_R(_f_real8 x) { int i; REGISTER_8 s1, s2; /* if x is a NaN, return HUGE */ if (isnan64(x)) return HUGE_INT6_F90; s1.f = x; /* clear sign bit */ s1.ui &= ~IEEE_64_SIGN_BIT; /* if x is + or - infinity, return HUGE */ if (s1.ui == IEEE_64_INFINITY) return HUGE_INT6_F90; /* if x is zero, return -HUGE */ if (x == 0.0e0) return -HUGE_INT6_F90; /* shift exponent bits to right. */ s1.ui >>= IEEE_64_MANT_BITS; if (s1.ui == 0) { /* x is a subnormal number (implicit leading bit is zero * and the exponent is zero). Calculate the exponent * based on normalized x. * * get mantissa */ s2.f = x; s2.ui = IEEE_64_MANTISSA & s2.ui; /* get leading zeros in mantissa part. */ i = _leadz8(s2.ui) - IEEE_64_EXPO_BITS; /* calculate exponent. */ s1.i -= (IEEE_64_EXPO_BIAS + i); } else { /* subtract exponent bias. */ s1.i -= (IEEE_64_EXPO_BIAS); } return (_f_int6) s1.i; }
inline static /* for the inline version of this function. */ #endif _f_real8 _FRACTION(_f_real8 x) { int lz; REGISTER_8 s1, sign_bit, mantissa, exponent; if (x == 0.0) return 0.0; /* if x is either infinity or a NaN, return a Nan */ if (x == IEEE_64_INFINITY) return _SGL_NaN; if (isnan64(x)) return x; s1.f = x; /* get sign bit. */ sign_bit.ui = IEEE_64_SIGN_BIT & s1.ui; /* get mantissa. */ mantissa.ui = IEEE_64_MANTISSA & s1.ui; /* get exponent. */ exponent.ui = IEEE_64_EXPONENT & s1.ui; if (exponent.ui == LL_CONST(0x0)) { /* 1. number is subnormal. normalize mantissa. * Get leading zeros of mantissa. */ lz = _leadz8(mantissa.ui) - IEEE_64_EXPO_BITS; /* 2. normalize by shifting out all leading zeros * and first 1 bit. */ mantissa.ui = (mantissa.ui << lz) & IEEE_64_MANTISSA; } /* position exponent bias less the implicit bit. */ exponent.ui = IEEE_64_EXPO_BIAS - 1; exponent.ui = exponent.ui << IEEE_64_MANT_BITS; /* extract fraction. */ s1.ui = exponent.ui | mantissa.ui | sign_bit.ui; return s1.f; }
inline static /* for the inline version of this function. */ #endif #define MIN(a,b) ((a) < (b) ? (a) : (b)) /*** Algorithm for f90 FRACTION * FRACTION - return the fractional part of the 128-bit model * representation of the argument value. **/ _f_real16 _FRACTION_16(_f_real16 x) { int lz, ileadzcnt, loopn; #if defined(_WORD32) union ldble_float { _f_real16 whole; unsigned long long ui[1]; } f, result, mantissa; unsigned long long sign_bit, exponent; #else union ldble_float { _f_real16 whole; unsigned long ui[1]; } f, result; unsigned long sign_bit, exponent; #endif static int word_size = 64; if (x == 0.0) return 0.0; f.whole = x; /* if x is either infinity or a NaN, return a Nan */ if ((f.ui[0] == IEEE_128_64_EXPO) && (f.ui[1] == 0)) return _DBL_NaN; if (isnan128(x)) return x; /* get sign bit. */ sign_bit = IEEE_128_64_SIGN_BIT & f.ui[0]; /* Get the absolute value of x by ANDing the upper half * with the NOT of 0x8000000000000000 (the sign bit mask). */ f.ui[0] &= ~IEEE_128_64_SIGN_BIT; /* get exponent. */ exponent = f.ui[0] & IEEE_128_64_EXPO; /* get mantissa and zero out exponent portion */ f.ui[0] &= IEEE_128_64_MANT1; result.whole = f.whole; if (exponent == LL_CONST(0x0)) { /* 1. Number is subnormal. Normalize mantissa and * get leading zeros in mantissa */ lz = 0; for (loopn = 0; loopn < 2; loopn++) { ileadzcnt = _leadz8(f.ui[loopn]); lz += ileadzcnt; if (ileadzcnt < word_size) break; } lz = lz - IEEE_128_EXPO_BITS; /* 2. Normalize by shifting out all leading zeros * and first 1 bit. * Determine number of mantissa bits in first 64 bits * of the mantissa plus the implicit bit. */ ileadzcnt = word_size - IEEE_128_EXPO_BITS; if (lz >= ileadzcnt) { /* The first 48 bits of the mantissa are zero. */ result.ui[0] = (f.ui[1] << (lz - ileadzcnt)) >> IEEE_128_EXPO_BITS; result.ui[1] = f.ui[1] << (MIN(word_size,lz)); } else {
/* _IEEE_EXPONENT_I6_D - IEEE EXPONENT returns the exponent part of the * 128-bit argument in 46-bit integer. */ _f_int6 _IEEE_EXPONENT_I6_D(_f_real16 x) { int i, ileadzcnt, loopn; #if defined(_WORD32) union ldble_float { _f_real16 whole; unsigned long long ui[2]; long long si[2]; } f, result; #else union ldble_float { _f_real16 whole; unsigned long ui[2]; long si[2]; } f, result; #endif static int word_size = 64; /* if x is a NaN, return a HUGE */ if (isnan128(x)) return HUGE_INT6_F90; f.whole = x; /* Get the absolute value of x by ANDing the upper half * with the NOT of 0x8000000000000000 (the sign bit mask). */ f.ui[0] &= ~IEEE_128_64_SIGN_BIT; /* if x is + or -infinity, return a HUGE */ if ((f.ui[0] == IEEE_128_64_EXPO) && (f.ui[1] == 0)) return HUGE_INT6_F90; /* if x is zero, return -HUGE */ if (x == 0.0e0) return -HUGE_INT6_F90; /* Separate the exponent from the 128-bit float value and * right justify it. */ result.ui[0] = f.ui[0] >> (IEEE_128_MANT_BITS - word_size); if (result.ui[0] == 0) { /* x is a subnormal number (implicit leading bit is zero * and the exponent is zero). Calculate the exponent * based on normalized x. * * get mantissa */ f.ui[0] &= IEEE_128_64_MANT1; i = 0; /* get leading zeros in mantissa part */ for (loopn = 0; loopn < 2; loopn++) { ileadzcnt = _leadz8(f.ui[loopn]); i += ileadzcnt; if (ileadzcnt < word_size) break; } i = i - IEEE_128_EXPO_BITS; /* calculate exponent. */ result.si[0] -= (IEEE_128_EXPO_BIAS + i); } else { /* subtract exponent bias. */ result.si[0] -= (IEEE_128_EXPO_BIAS); } return (_f_int6) result.si[0]; }
/* _IEEE_EXPONENT_I2_D - IEEE EXPONENT returns the exponent part of the * 128-bit argument in 16-bit integer. */ _f_int2 _IEEE_EXPONENT_I2_D(_f_real16 x) { union _ieee_ldouble { _f_real16 ldword; _f_real8 dbword[2]; }; #if __BYTE_ORDER == __LITTLE_ENDIAN const int dbword_hi = 1; const int dbword_lo = 0; #else const int dbword_hi = 0; const int dbword_lo = 1; #endif union _ieee_double { _f_real8 dword; _f_int8 lword; unsigned long long ull; struct { #if __BYTE_ORDER == __LITTLE_ENDIAN unsigned int mantissa2 : IEEE_64_MANT_BTS2; unsigned int mantissa1 : IEEE_64_MANT_BTS1; unsigned int exponent : IEEE_64_EXPO_BITS; unsigned int sign : 1; #else unsigned int sign : 1; unsigned int exponent : IEEE_64_EXPO_BITS; unsigned int mantissa1 : IEEE_64_MANT_BTS1; unsigned int mantissa2 : IEEE_64_MANT_BTS2; #endif } parts; }; _f_int2 iresult = 0; switch(fp_class_l(x)) { case FP_SNAN: case FP_QNAN: case FP_POS_INF: case FP_NEG_INF: { /* return positive huge for NaN or infinity. */ return(HUGE_INT2_F90); } case FP_POS_NORM: case FP_NEG_NORM: { #pragma weak logbl return((_f_int2) logbl(x)); } case FP_POS_DENORM: case FP_NEG_DENORM: { /* return exponent from first 64-bit double. */ union _ieee_ldouble x_val; x_val.ldword = x; switch(fp_class_d(x_val.dbword[dbword_hi])) { case FP_POS_NORM: case FP_NEG_NORM: { union _ieee_double db_x; db_x.dword = x_val.dbword[dbword_hi]; return((_f_int2)(db_x.parts.exponent - IEEE_64_EXPO_BIAS)); } case FP_POS_DENORM: case FP_NEG_DENORM: { union _ieee_double db_x; db_x.dword = x_val.dbword[dbword_hi]; db_x.ull = IEEE_64_MANTISSA & db_x.ull; return((_f_int2)(-IEEE_64_EXPO_BIAS - (_leadz8(db_x.ull) + IEEE_64_EXPO_BITS))); } } } case FP_POS_ZERO: case FP_NEG_ZERO: { /* return negative huge for zero. */ return(-HUGE_INT2_F90); } } return(iresult); }
/* _IEEE_EXPONENT_I2_R - IEEE EXPONENT returns the exponent part of the * 64-bit argument in 16-bit integer. */ _f_int2 _IEEE_EXPONENT_I2_R(_f_real8 x) { union _ieee_double { _f_real8 dword; _f_int8 lword; unsigned long long ull; struct { #if __BYTE_ORDER == __LITTLE_ENDIAN unsigned int mantissa2 : IEEE_64_MANT_BTS2; unsigned int mantissa1 : IEEE_64_MANT_BTS1; unsigned int exponent : IEEE_64_EXPO_BITS; unsigned int sign : 1; #else unsigned int sign : 1; unsigned int exponent : IEEE_64_EXPO_BITS; unsigned int mantissa1 : IEEE_64_MANT_BTS1; unsigned int mantissa2 : IEEE_64_MANT_BTS2; #endif } parts; }; _f_int2 iresult = 0; switch(fp_class_d(x)) { case FP_SNAN: case FP_QNAN: case FP_POS_INF: case FP_NEG_INF: { /* return positive huge for NaN or infinity. */ return(HUGE_INT2_F90); } case FP_POS_NORM: case FP_NEG_NORM: { union _ieee_double x_val; x_val.dword = x; return((_f_int2)(x_val.parts.exponent - IEEE_64_EXPO_BIAS)); } case FP_POS_DENORM: case FP_NEG_DENORM: { union _ieee_double x_val; x_val.dword = x; x_val.ull = IEEE_64_MANTISSA & x_val.ull;; /* _leadz returns number of zeros before first 1 * in mantissa. Add 8 to exclude exponent bits, * but count sign bit since implicit bit needs to * be counted. */ return((_f_int2)(-IEEE_64_EXPO_BIAS - (_leadz8(x_val.ull) + IEEE_64_EXPO_BITS))); } case FP_POS_ZERO: case FP_NEG_ZERO: { /* return negative huge for zero. */ return(-HUGE_INT2_F90); } } return(iresult); }
_f_real8 _IEEE_BINARY_SCALE_I8(_f_real8 orig_number, _f_int8 orig_scale_factor) { int lz, lzm, shift; REGISTER_8 number, scale_factor, expon, exponent, orig_mantissa, mantissa, sign_bit; /* if x is a NaN, return a Nan */ if (isnan64(orig_number)) return orig_number; number.f = orig_number; /* extract sign bit. */ sign_bit.ui = IEEE_64_SIGN_BIT & number.ui; /* extract exponent. */ exponent.ui = IEEE_64_EXPONENT & number.ui; /* extract mantissa. */ orig_mantissa.ui = IEEE_64_MANTISSA & number.ui; /* if x is + or -infinity, return same infinity */ number.ui &= ~IEEE_64_SIGN_BIT; if (number.ui == IEEE_64_INFINITY) return orig_number; /* if x is zero, return zero. */ if (orig_number == 0) return orig_number; scale_factor.i = orig_scale_factor; /* check for unnormalized number */ if (exponent.ui == 0) { /* Denormmal. Get leading zeros in original mantissa */ lz = _leadz8(orig_mantissa.ui); if (scale_factor.i > 0) { /* Scale number by a positive power of 2. The * result may need to be normalized. Get * leading zeros in mantissa = lzm. */ lzm = lz - IEEE_64_EXPO_BITS - 1; /* Any leading zeros in mantissa? */ if (lzm > 0) { /* check if number of leading zeros in * mantissa allows scaling by shifting. */ if (scale_factor.i <= lzm) { /* Enough lead zeros to shift. * Exponent is unaffected. */ shift = scale_factor.i; expon.i = 0; } else { /* Scale by shifting what we can * and adjust exponent for rest. * The result is a normalized * number. */ shift = lzm + 1; expon.i = scale_factor.i - lzm; } /* No leading zeros in mantissa. */ } else { /* Shift by 1 to normalize mantissa. Do * rest of scaling through exponent. */ shift = 1; expon.i = scale_factor.i; } /* position the exponent. */ exponent.ui = expon.ui << IEEE_64_MANT_BITS; /* scale the mantissa. */ mantissa.ui = orig_mantissa.ui << shift; /* Scale_factor LE 0. */ } else { /* scale mantissa. */ mantissa.ui = orig_mantissa.ui >> (-scale_factor.i); if ((-scale_factor.ui != 0) && (orig_mantissa.ui & (0x1 << (-scale_factor.i - 1)))) { mantissa.ui++; } } /* mask out any bits that may have shifted to the left of * the mantissa area. */ mantissa.ui &= IEEE_64_MANTISSA; /* OR the new mantissa, the new exponent, and the original * sign bit together to create the result. */ number.ui = mantissa.ui | exponent.ui | sign_bit.ui; } else {