float frexp(float _a, int32_t* _outExp) { const uint32_t ftob = floatToBits(_a); const uint32_t masked0 = uint32_and(ftob, UINT32_C(0x7f800000) ); const uint32_t exp0 = uint32_srl(masked0, 23); const uint32_t masked1 = uint32_and(ftob, UINT32_C(0x807fffff) ); const uint32_t bits = uint32_or(masked1, UINT32_C(0x3f000000) ); const float result = bitsToFloat(bits); *_outExp = int32_t(exp0 - 0x7e); return result; }
BX_CONST_FUNC float ldexp(float _a, int32_t _b) { const uint32_t ftob = floatToBits(_a); const uint32_t masked = uint32_and(ftob, UINT32_C(0xff800000) ); const uint32_t expsign0 = uint32_sra(masked, 23); const uint32_t tmp = uint32_iadd(expsign0, _b); const uint32_t expsign1 = uint32_sll(tmp, 23); const uint32_t mantissa = uint32_and(ftob, UINT32_C(0x007fffff) ); const uint32_t bits = uint32_or(mantissa, expsign1); const float result = bitsToFloat(bits); return result; }
uint32_t cp_float_is_snan( uint32_t a ) { uint32_t flag_mask = 0x1ff; uint32_t flag_expected = 0x1fe; uint32_t flag_bits = uint32_srl( a, 22 ); uint32_t flag_unsigned = uint32_and( flag_bits, flag_mask ); uint32_t is_flagged = uint32_cmpeq( flag_unsigned, flag_expected ); uint32_t m_lo = uint32_and( a, 0x003fffff ); uint32_t is_m_lo_nez = uint32_cmpnez( m_lo ); uint32_t is_snan = uint32_and( is_flagged, is_m_lo_nez ); return (is_snan); }
static uint32_t cp_float_select_nan( uint32_t a, uint32_t b ) { uint32_t a_is_nan, a_is_snan, b_is_nan, b_is_snan; a_is_nan = cp_float_is_nan( a ); a_is_snan = cp_float_is_snan( a ); b_is_nan = cp_float_is_nan( b ); b_is_snan = cp_float_is_snan( b ); a |= 0x00400000; b |= 0x00400000; uint32_t is_both_snan = uint32_and( a_is_snan, b_is_snan ); uint32_t is_both_nan = uint32_and( a_is_nan, b_is_nan ); uint32_t is_either_snan = uint32_or( a_is_snan, b_is_snan ); uint32_t is_either_snan_mask = uint32_cmpnez( is_either_snan ); uint32_t exception_flags = uint32_and( is_either_snan_mask, float_flag_invalid ); cp_float_raise( exception_flags ); // if ( a_is_snan | b_is_snan ) cp_float_raise( float_flag_invalid ); if ( ( a_is_snan && b_is_snan ) || ( a_is_nan && b_is_nan ) ) { if ( (uint32_t) ( a<<1 ) < (uint32_t) ( b<<1 ) ) return b; if ( (uint32_t) ( b<<1 ) < (uint32_t) ( a<<1 ) ) return a; return ( a < b ) ? a : b; } if ( a_is_snan ) { // if ( b_is_snan ) goto returnLarger_sificand; return b_is_nan ? b : a; } else if ( a_is_nan ) { if ( b_is_snan | ! b_is_nan ) return a; // returnLarger_sificand: // if ( (uint32_t) ( a<<1 ) < (uint32_t) ( b<<1 ) ) return b; // if ( (uint32_t) ( b<<1 ) < (uint32_t) ( a<<1 ) ) return a; // return ( a < b ) ? a : b; } else { return b; } printf("FAIL\n"); return 0; }
static inline uint32_t cp_float_extract_m( uint32_t a ) { const uint32_t m_mask = 0x007fffff; const uint32_t m = uint32_and( a, m_mask ); return (m); }
static inline uint32_t cp_float_extract_e( uint32_t a ) { const uint32_t e_pos = 23; const uint32_t e_mask = 0x000000ff; const uint32_t es = uint32_srl( a, e_pos ); const uint32_t e = uint32_and( es, e_mask ); return (e); }