Path: blob/master/libs/compiler-rt/lib/builtins/floatundisf.c
4395 views
/*===-- floatundisf.c - Implement __floatundisf ---------------------------===1*2* The LLVM Compiler Infrastructure3*4* This file is dual licensed under the MIT and the University of Illinois Open5* Source Licenses. See LICENSE.TXT for details.6*7* ===----------------------------------------------------------------------===8*9* This file implements __floatundisf for the compiler_rt library.10*11*===----------------------------------------------------------------------===12*/1314/* Returns: convert a to a float, rounding toward even. */1516/* Assumption: float is a IEEE 32 bit floating point type17* du_int is a 64 bit integral type18*/1920/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */2122#include "int_lib.h"2324COMPILER_RT_ABI float25__floatundisf(du_int a)26{27if (a == 0)28return 0.0F;29const unsigned N = sizeof(du_int) * CHAR_BIT;30int sd = N - __builtin_clzll(a); /* number of significant digits */31int e = sd - 1; /* 8 exponent */32if (sd > FLT_MANT_DIG)33{34/* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx35* finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR36* 1234567890123456789012345637* 1 = msb 1 bit38* P = bit FLT_MANT_DIG-1 bits to the right of 139* Q = bit FLT_MANT_DIG bits to the right of 140* R = "or" of all bits to the right of Q41*/42switch (sd)43{44case FLT_MANT_DIG + 1:45a <<= 1;46break;47case FLT_MANT_DIG + 2:48break;49default:50a = (a >> (sd - (FLT_MANT_DIG+2))) |51((a & ((du_int)(-1) >> ((N + FLT_MANT_DIG+2) - sd))) != 0);52};53/* finish: */54a |= (a & 4) != 0; /* Or P into R */55++a; /* round - this step may add a significant bit */56a >>= 2; /* dump Q and R */57/* a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits */58if (a & ((du_int)1 << FLT_MANT_DIG))59{60a >>= 1;61++e;62}63/* a is now rounded to FLT_MANT_DIG bits */64}65else66{67a <<= (FLT_MANT_DIG - sd);68/* a is now rounded to FLT_MANT_DIG bits */69}70float_bits fb;71fb.u = ((e + 127) << 23) | /* exponent */72((su_int)a & 0x007FFFFF); /* mantissa */73return fb.f;74}7576#if defined(__ARM_EABI__)77#if defined(COMPILER_RT_ARMHF_TARGET)78AEABI_RTABI float __aeabi_ul2f(du_int a) {79return __floatundisf(a);80}81#else82AEABI_RTABI float __aeabi_ul2f(du_int a) COMPILER_RT_ALIAS(__floatundisf);83#endif84#endif858687