xref: /llvm-project/compiler-rt/lib/builtins/floatunsidf.c (revision 4d41df64828195aa24cddc5d34d3f446ca7bb6d1)
1a6b264b5SAlexey Samsonov //===-- lib/floatunsidf.c - uint -> double-precision conversion ---*- C -*-===//
2a6b264b5SAlexey Samsonov //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a6b264b5SAlexey Samsonov //
7a6b264b5SAlexey Samsonov //===----------------------------------------------------------------------===//
8a6b264b5SAlexey Samsonov //
9a6b264b5SAlexey Samsonov // This file implements unsigned integer to double-precision conversion for the
10a6b264b5SAlexey Samsonov // compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even
11a6b264b5SAlexey Samsonov // mode.
12a6b264b5SAlexey Samsonov //
13a6b264b5SAlexey Samsonov //===----------------------------------------------------------------------===//
14a6b264b5SAlexey Samsonov 
15a6b264b5SAlexey Samsonov #define DOUBLE_PRECISION
16a6b264b5SAlexey Samsonov #include "fp_lib.h"
17a6b264b5SAlexey Samsonov 
18a6b264b5SAlexey Samsonov #include "int_lib.h"
19a6b264b5SAlexey Samsonov 
__floatunsidf(su_int a)20*4d41df64SAyke van Laethem COMPILER_RT_ABI fp_t __floatunsidf(su_int a) {
21a6b264b5SAlexey Samsonov 
22a6b264b5SAlexey Samsonov   const int aWidth = sizeof a * CHAR_BIT;
23a6b264b5SAlexey Samsonov 
24a6b264b5SAlexey Samsonov   // Handle zero as a special case to protect clz
25082b89b2SPetr Hosek   if (a == 0)
26082b89b2SPetr Hosek     return fromRep(0);
27a6b264b5SAlexey Samsonov 
28a6b264b5SAlexey Samsonov   // Exponent of (fp_t)a is the width of abs(a).
29*4d41df64SAyke van Laethem   const int exponent = (aWidth - 1) - clzsi(a);
30a6b264b5SAlexey Samsonov   rep_t result;
31a6b264b5SAlexey Samsonov 
32a6b264b5SAlexey Samsonov   // Shift a into the significand field and clear the implicit bit.
33a6b264b5SAlexey Samsonov   const int shift = significandBits - exponent;
34a6b264b5SAlexey Samsonov   result = (rep_t)a << shift ^ implicitBit;
35a6b264b5SAlexey Samsonov 
36a6b264b5SAlexey Samsonov   // Insert the exponent
37a6b264b5SAlexey Samsonov   result += (rep_t)(exponent + exponentBias) << significandBits;
38a6b264b5SAlexey Samsonov   return fromRep(result);
39a6b264b5SAlexey Samsonov }
4036ac5ddfSSaleem Abdulrasool 
4136ac5ddfSSaleem Abdulrasool #if defined(__ARM_EABI__)
420d586d06SEli Friedman #if defined(COMPILER_RT_ARMHF_TARGET)
__aeabi_ui2d(su_int a)43*4d41df64SAyke van Laethem AEABI_RTABI fp_t __aeabi_ui2d(su_int a) { return __floatunsidf(a); }
440d586d06SEli Friedman #else
4584da0e1bSPetr Hosek COMPILER_RT_ALIAS(__floatunsidf, __aeabi_ui2d)
4636ac5ddfSSaleem Abdulrasool #endif
470d586d06SEli Friedman #endif
48