10b57cec5SDimitry Andric //===-- lib/floatunsisf.c - uint -> single-precision conversion ---*- C -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements unsigned integer to single-precision conversion for the 100b57cec5SDimitry Andric // compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even 110b57cec5SDimitry Andric // mode. 120b57cec5SDimitry Andric // 130b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #define SINGLE_PRECISION 160b57cec5SDimitry Andric #include "fp_lib.h" 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric #include "int_lib.h" 190b57cec5SDimitry Andric __floatunsisf(su_int a)20*1fd87a68SDimitry AndricCOMPILER_RT_ABI fp_t __floatunsisf(su_int a) { 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric const int aWidth = sizeof a * CHAR_BIT; 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric // Handle zero as a special case to protect clz 250b57cec5SDimitry Andric if (a == 0) 260b57cec5SDimitry Andric return fromRep(0); 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric // Exponent of (fp_t)a is the width of abs(a). 29*1fd87a68SDimitry Andric const int exponent = (aWidth - 1) - clzsi(a); 300b57cec5SDimitry Andric rep_t result; 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric // Shift a into the significand field, rounding if it is a right-shift 330b57cec5SDimitry Andric if (exponent <= significandBits) { 340b57cec5SDimitry Andric const int shift = significandBits - exponent; 350b57cec5SDimitry Andric result = (rep_t)a << shift ^ implicitBit; 360b57cec5SDimitry Andric } else { 370b57cec5SDimitry Andric const int shift = exponent - significandBits; 380b57cec5SDimitry Andric result = (rep_t)a >> shift ^ implicitBit; 390b57cec5SDimitry Andric rep_t round = (rep_t)a << (typeWidth - shift); 400b57cec5SDimitry Andric if (round > signBit) 410b57cec5SDimitry Andric result++; 420b57cec5SDimitry Andric if (round == signBit) 430b57cec5SDimitry Andric result += result & 1; 440b57cec5SDimitry Andric } 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric // Insert the exponent 470b57cec5SDimitry Andric result += (rep_t)(exponent + exponentBias) << significandBits; 480b57cec5SDimitry Andric return fromRep(result); 490b57cec5SDimitry Andric } 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric #if defined(__ARM_EABI__) 520b57cec5SDimitry Andric #if defined(COMPILER_RT_ARMHF_TARGET) __aeabi_ui2f(unsigned int a)530b57cec5SDimitry AndricAEABI_RTABI fp_t __aeabi_ui2f(unsigned int a) { return __floatunsisf(a); } 540b57cec5SDimitry Andric #else 550b57cec5SDimitry Andric COMPILER_RT_ALIAS(__floatunsisf, __aeabi_ui2f) 560b57cec5SDimitry Andric #endif 570b57cec5SDimitry Andric #endif 58