Path: blob/master/libs/compiler-rt/lib/builtins/floatdisf.c
4395 views
/*===-- floatdisf.c - Implement __floatdisf -------------------------------===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 __floatdisf 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* di_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__floatdisf(di_int a)26{27if (a == 0)28return 0.0F;29const unsigned N = sizeof(di_int) * CHAR_BIT;30const di_int s = a >> (N-1);31a = (a ^ s) - s;32int sd = N - __builtin_clzll(a); /* number of significant digits */33int e = sd - 1; /* exponent */34if (sd > FLT_MANT_DIG)35{36/* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx37* finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR38* 1234567890123456789012345639* 1 = msb 1 bit40* P = bit FLT_MANT_DIG-1 bits to the right of 141* Q = bit FLT_MANT_DIG bits to the right of 142* R = "or" of all bits to the right of Q43*/44switch (sd)45{46case FLT_MANT_DIG + 1:47a <<= 1;48break;49case FLT_MANT_DIG + 2:50break;51default:52a = ((du_int)a >> (sd - (FLT_MANT_DIG+2))) |53((a & ((du_int)(-1) >> ((N + FLT_MANT_DIG+2) - sd))) != 0);54};55/* finish: */56a |= (a & 4) != 0; /* Or P into R */57++a; /* round - this step may add a significant bit */58a >>= 2; /* dump Q and R */59/* a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits */60if (a & ((du_int)1 << FLT_MANT_DIG))61{62a >>= 1;63++e;64}65/* a is now rounded to FLT_MANT_DIG bits */66}67else68{69a <<= (FLT_MANT_DIG - sd);70/* a is now rounded to FLT_MANT_DIG bits */71}72float_bits fb;73fb.u = ((su_int)s & 0x80000000) | /* sign */74((e + 127) << 23) | /* exponent */75((su_int)a & 0x007FFFFF); /* mantissa */76return fb.f;77}7879#if defined(__ARM_EABI__)80#if defined(COMPILER_RT_ARMHF_TARGET)81AEABI_RTABI float __aeabi_l2f(di_int a) {82return __floatdisf(a);83}84#else85AEABI_RTABI float __aeabi_l2f(di_int a) COMPILER_RT_ALIAS(__floatdisf);86#endif87#endif888990