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