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; }
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; }
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; }