1b6d4e2e3a87eb3c9a6dec0ad21d4c1dec545c137Stephen Canon//===-- lib/floatunsisf.c - uint -> single-precision conversion ---*- C -*-===// 209009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon// 309009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon// The LLVM Compiler Infrastructure 409009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon// 59ad441ffec97db647fee3725b3424284fb913e14Howard Hinnant// This file is dual licensed under the MIT and the University of Illinois Open 69ad441ffec97db647fee3725b3424284fb913e14Howard Hinnant// Source Licenses. See LICENSE.TXT for details. 709009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon// 809009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon//===----------------------------------------------------------------------===// 909009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon// 1009009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon// This file implements unsigned integer to single-precision conversion for the 1109009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even 1209009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon// mode. 1309009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon// 1409009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon//===----------------------------------------------------------------------===// 1509009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon 1609009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon#define SINGLE_PRECISION 1709009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon#include "fp_lib.h" 1809009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon 1937b97d1cf4501b94347e0b4e880f4b25825a289fAnton Korobeynikov#include "int_lib.h" 2037b97d1cf4501b94347e0b4e880f4b25825a289fAnton Korobeynikov 210193b74976719b8aea4cb8874ba36b75836a8d6eChandler CarruthARM_EABI_FNALIAS(ui2f, floatunsisf) 2237b97d1cf4501b94347e0b4e880f4b25825a289fAnton Korobeynikov 23b6d4e2e3a87eb3c9a6dec0ad21d4c1dec545c137Stephen Canonfp_t __floatunsisf(unsigned int a) { 2409009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon 2509009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon const int aWidth = sizeof a * CHAR_BIT; 2609009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon 2709009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon // Handle zero as a special case to protect clz 2809009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon if (a == 0) return fromRep(0); 2909009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon 3009009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon // Exponent of (fp_t)a is the width of abs(a). 3109009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon const int exponent = (aWidth - 1) - __builtin_clz(a); 3209009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon rep_t result; 3309009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon 3409009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon // Shift a into the significand field, rounding if it is a right-shift 3509009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon if (exponent <= significandBits) { 3609009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon const int shift = significandBits - exponent; 3709009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon result = (rep_t)a << shift ^ implicitBit; 3809009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon } else { 3909009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon const int shift = exponent - significandBits; 4009009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon result = (rep_t)a >> shift ^ implicitBit; 4109009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon rep_t round = (rep_t)a << (typeWidth - shift); 4209009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon if (round > signBit) result++; 4309009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon if (round == signBit) result += result & 1; 4409009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon } 4509009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon 4609009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon // Insert the exponent 4709009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon result += (rep_t)(exponent + exponentBias) << significandBits; 4809009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon return fromRep(result); 4909009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon} 50