floatunsisf.c revision 327952
1276789Sdim//===-- lib/floatunsisf.c - uint -> single-precision conversion ---*- C -*-===// 2276789Sdim// 3276789Sdim// The LLVM Compiler Infrastructure 4276789Sdim// 5276789Sdim// This file is dual licensed under the MIT and the University of Illinois Open 6276789Sdim// Source Licenses. See LICENSE.TXT for details. 7276789Sdim// 8276789Sdim//===----------------------------------------------------------------------===// 9276789Sdim// 10276789Sdim// This file implements unsigned integer to single-precision conversion for the 11276789Sdim// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even 12276789Sdim// mode. 13276789Sdim// 14276789Sdim//===----------------------------------------------------------------------===// 15276789Sdim 16276789Sdim#define SINGLE_PRECISION 17276789Sdim#include "fp_lib.h" 18276789Sdim 19276789Sdim#include "int_lib.h" 20276789Sdim 21276789SdimCOMPILER_RT_ABI fp_t 22276789Sdim__floatunsisf(unsigned int a) { 23276789Sdim 24276789Sdim const int aWidth = sizeof a * CHAR_BIT; 25276789Sdim 26276789Sdim // Handle zero as a special case to protect clz 27276789Sdim if (a == 0) return fromRep(0); 28276789Sdim 29276789Sdim // Exponent of (fp_t)a is the width of abs(a). 30276789Sdim const int exponent = (aWidth - 1) - __builtin_clz(a); 31276789Sdim rep_t result; 32276789Sdim 33276789Sdim // Shift a into the significand field, rounding if it is a right-shift 34276789Sdim if (exponent <= significandBits) { 35276789Sdim const int shift = significandBits - exponent; 36276789Sdim result = (rep_t)a << shift ^ implicitBit; 37276789Sdim } else { 38276789Sdim const int shift = exponent - significandBits; 39276789Sdim result = (rep_t)a >> shift ^ implicitBit; 40276789Sdim rep_t round = (rep_t)a << (typeWidth - shift); 41276789Sdim if (round > signBit) result++; 42276789Sdim if (round == signBit) result += result & 1; 43276789Sdim } 44276789Sdim 45276789Sdim // Insert the exponent 46276789Sdim result += (rep_t)(exponent + exponentBias) << significandBits; 47276789Sdim return fromRep(result); 48276789Sdim} 49321369Sdim 50321369Sdim#if defined(__ARM_EABI__) 51327952Sdim#if defined(COMPILER_RT_ARMHF_TARGET) 52321369SdimAEABI_RTABI fp_t __aeabi_ui2f(unsigned int a) { 53321369Sdim return __floatunsisf(a); 54321369Sdim} 55327952Sdim#else 56327952SdimAEABI_RTABI fp_t __aeabi_ui2f(unsigned int a) COMPILER_RT_ALIAS(__floatunsisf); 57321369Sdim#endif 58327952Sdim#endif 59