1b6d4e2e3a87eb3c9a6dec0ad21d4c1dec545c137Stephen Canon//===-- lib/floatunsidf.c - uint -> double-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 double-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 DOUBLE_PRECISION
1709009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon#include "fp_lib.h"
1809009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon
1937b97d1cf4501b94347e0b4e880f4b25825a289fAnton Korobeynikov#include "int_lib.h"
2037b97d1cf4501b94347e0b4e880f4b25825a289fAnton Korobeynikov
210193b74976719b8aea4cb8874ba36b75836a8d6eChandler CarruthARM_EABI_FNALIAS(ui2d, floatunsidf)
2237b97d1cf4501b94347e0b4e880f4b25825a289fAnton Korobeynikov
232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCOMPILER_RT_ABI fp_t
242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines__floatunsidf(unsigned int a) {
2509009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon
2609009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon    const int aWidth = sizeof a * CHAR_BIT;
2709009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon
2809009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon    // Handle zero as a special case to protect clz
2909009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon    if (a == 0) return fromRep(0);
3009009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon
3109009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon    // Exponent of (fp_t)a is the width of abs(a).
3209009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon    const int exponent = (aWidth - 1) - __builtin_clz(a);
3309009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon    rep_t result;
3409009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon
354d055d584cdc9c65e09092238a905c6f20b829ecStephen Canon    // Shift a into the significand field and clear the implicit bit.
364d055d584cdc9c65e09092238a905c6f20b829ecStephen Canon    const int shift = significandBits - exponent;
374d055d584cdc9c65e09092238a905c6f20b829ecStephen Canon    result = (rep_t)a << shift ^ implicitBit;
3809009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon
3909009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon    // Insert the exponent
4009009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon    result += (rep_t)(exponent + exponentBias) << significandBits;
4109009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon    return fromRep(result);
4209009c50dd7118ed0bdf97e5c37e23c25e443682Stephen Canon}
43