1276789Sdim//===-- lib/floatunsisf.c - uint -> single-precision conversion ---*- C -*-===//
2276789Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6276789Sdim//
7276789Sdim//===----------------------------------------------------------------------===//
8276789Sdim//
9276789Sdim// This file implements unsigned integer to single-precision conversion for the
10276789Sdim// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even
11276789Sdim// mode.
12276789Sdim//
13276789Sdim//===----------------------------------------------------------------------===//
14276789Sdim
15276789Sdim#define SINGLE_PRECISION
16276789Sdim#include "fp_lib.h"
17276789Sdim
18276789Sdim#include "int_lib.h"
19276789Sdim
20353358SdimCOMPILER_RT_ABI fp_t __floatunsisf(unsigned int a) {
21353358Sdim
22353358Sdim  const int aWidth = sizeof a * CHAR_BIT;
23353358Sdim
24353358Sdim  // Handle zero as a special case to protect clz
25353358Sdim  if (a == 0)
26353358Sdim    return fromRep(0);
27353358Sdim
28353358Sdim  // Exponent of (fp_t)a is the width of abs(a).
29353358Sdim  const int exponent = (aWidth - 1) - __builtin_clz(a);
30353358Sdim  rep_t result;
31353358Sdim
32353358Sdim  // Shift a into the significand field, rounding if it is a right-shift
33353358Sdim  if (exponent <= significandBits) {
34353358Sdim    const int shift = significandBits - exponent;
35353358Sdim    result = (rep_t)a << shift ^ implicitBit;
36353358Sdim  } else {
37353358Sdim    const int shift = exponent - significandBits;
38353358Sdim    result = (rep_t)a >> shift ^ implicitBit;
39353358Sdim    rep_t round = (rep_t)a << (typeWidth - shift);
40353358Sdim    if (round > signBit)
41353358Sdim      result++;
42353358Sdim    if (round == signBit)
43353358Sdim      result += result & 1;
44353358Sdim  }
45353358Sdim
46353358Sdim  // Insert the exponent
47353358Sdim  result += (rep_t)(exponent + exponentBias) << significandBits;
48353358Sdim  return fromRep(result);
49276789Sdim}
50321369Sdim
51321369Sdim#if defined(__ARM_EABI__)
52327952Sdim#if defined(COMPILER_RT_ARMHF_TARGET)
53353358SdimAEABI_RTABI fp_t __aeabi_ui2f(unsigned int a) { return __floatunsisf(a); }
54327952Sdim#else
55353358SdimCOMPILER_RT_ALIAS(__floatunsisf, __aeabi_ui2f)
56321369Sdim#endif
57327952Sdim#endif
58