/* _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); }
_f_int4 _FP_CLASS_I4_D(_f_real16 x) { #if defined(__mips) || (defined(_LITTLE_ENDIAN) && defined(__sv2)) int x_result; x_result = fp_class_l(x); switch(x_result) { case FP_NEG_ZERO: { return (FOR_K_FP_NEG_ZERO); break; } case FP_POS_ZERO: { return (FOR_K_FP_POS_ZERO); break; } case FP_NEG_DENORM: { return (FOR_K_FP_NEG_DENORM); break; } case FP_POS_DENORM: { return (FOR_K_FP_POS_DENORM); break; } case FP_NEG_INF: { return (FOR_K_FP_NEG_INF); break; } case FP_POS_INF: { return (FOR_K_FP_POS_INF); break; } case FP_SNAN: { return (FOR_K_FP_SNAN); break; } case FP_QNAN: { return (FOR_K_FP_QNAN); break; } case FP_NEG_NORM: { return (FOR_K_FP_NEG_NORM); break; } case FP_POS_NORM: { return (FOR_K_FP_POS_NORM); break; } default: { return -1; break; } } /* Switch(x_result) */ #elif (defined(_CRAYIEEE) && !defined(__mips)) || defined(_SOLARIS) #if _F_REAL16 == 1 int x_result; union _uval_d x_val; x_result = fpclassify(x); x_val.dwd = x; switch(x_result) { case FP_ZERO: { /* Test for pos/neg */ if(x_val.parts.sign) { return (FOR_K_FP_NEG_ZERO); } else { return (FOR_K_FP_POS_ZERO); } break; } case FP_SUBNORMAL: { /* Test for pos/neg */ if(x_val.parts.sign) { return (FOR_K_FP_NEG_DENORM); } else { return (FOR_K_FP_POS_DENORM); } break; } case FP_INFINITE: { /* Test for pos/neg */ if(x_val.parts.sign) { return (FOR_K_FP_NEG_INF); } else { return (FOR_K_FP_POS_INF); } break; } case FP_NAN: { #ifdef _CRAYT3E /* on the t3e, all NaNs are signal NaNs */ return (FOR_K_FP_SNAN); #else /* test for quiet/signal on others */ if(x_val.parts.q_bit) { return (FOR_K_FP_QNAN); } else { return (FOR_K_FP_SNAN); } #endif /* #ifdef _CRAYT3E */ break; } case FP_NORMAL: { /* Test for pos/neg */ if(x_val.parts.sign) { return (FOR_K_FP_NEG_NORM); } else { return (FOR_K_FP_POS_NORM); } break; } default: { return -1; break; } } /* End switch(x_result); */ #endif /* #if F_REAL16 == 1 */ #elif defined(_LITTLE_ENDIAN) && !defined(__sv2) union _uval_d x_val; x_val.dwd = x; if(x_val.parts.exp == 0) { if(x_val.parts.up1 == 0 && x_val.parts.lo1 == 0 && x_val.parts.q_bit == 0) { if(x_val.parts.sign) return (FOR_K_FP_NEG_ZERO); else return (FOR_K_FP_POS_ZERO); } else { if(x_val.parts.sign) return (FOR_K_FP_NEG_DENORM); else return (FOR_K_FP_POS_DENORM); } } else if(x_val.parts.exp == IEEE_128_EXPO_MAX) { if(x_val.parts.up1 == 0 && x_val.parts.lo1 == 0 && x_val.parts.q_bit == 0) { if(x_val.parts.sign) return (FOR_K_FP_NEG_INF); else return (FOR_K_FP_POS_INF); } else { if(x_val.parts.q_bit) return (FOR_K_FP_QNAN); else return (FOR_K_FP_SNAN); } } else if(x_val.parts.sign) return (FOR_K_FP_NEG_NORM); else return (FOR_K_FP_POS_NORM); #endif /* #if defined(__mips) ... #elif defined(_CRAYT3E) && defined(__mips) */ return -1; }