floatsisf.c revision 303975
1254721Semaste//===-- lib/floatsisf.c - integer -> single-precision conversion --*- C -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is dual licensed under the MIT and the University of Illinois Open
6254721Semaste// Source Licenses. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste//
10254721Semaste// This file implements integer to single-precision conversion for the
11254721Semaste// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even
12254721Semaste// mode.
13254721Semaste//
14254721Semaste//===----------------------------------------------------------------------===//
15254721Semaste
16254721Semaste#define SINGLE_PRECISION
17254721Semaste#include "fp_lib.h"
18254721Semaste
19254721Semaste#include "int_lib.h"
20254721Semaste
21254721SemasteARM_EABI_FNALIAS(i2f, floatsisf)
22254721Semaste
23254721SemasteCOMPILER_RT_ABI fp_t
24254721Semaste__floatsisf(int a) {
25254721Semaste
26254721Semaste    const int aWidth = sizeof a * CHAR_BIT;
27254721Semaste
28254721Semaste    // Handle zero as a special case to protect clz
29254721Semaste    if (a == 0)
30254721Semaste        return fromRep(0);
31254721Semaste
32254721Semaste    // All other cases begin by extracting the sign and absolute value of a
33254721Semaste    rep_t sign = 0;
34254721Semaste    if (a < 0) {
35254721Semaste        sign = signBit;
36254721Semaste        a = -a;
37254721Semaste    }
38254721Semaste
39254721Semaste    // Exponent of (fp_t)a is the width of abs(a).
40254721Semaste    const int exponent = (aWidth - 1) - __builtin_clz(a);
41254721Semaste    rep_t result;
42254721Semaste
43254721Semaste    // Shift a into the significand field, rounding if it is a right-shift
44254721Semaste    if (exponent <= significandBits) {
45254721Semaste        const int shift = significandBits - exponent;
46254721Semaste        result = (rep_t)a << shift ^ implicitBit;
47254721Semaste    } else {
48        const int shift = exponent - significandBits;
49        result = (rep_t)a >> shift ^ implicitBit;
50        rep_t round = (rep_t)a << (typeWidth - shift);
51        if (round > signBit) result++;
52        if (round == signBit) result += result & 1;
53    }
54
55    // Insert the exponent
56    result += (rep_t)(exponent + exponentBias) << significandBits;
57    // Insert the sign bit and return
58    return fromRep(result | sign);
59}
60