xref: /netbsd-src/sys/external/bsd/compiler_rt/dist/lib/builtins/floatsitf.c (revision ef84fd3bd8895f4e6be1e38baf19e6dc3255bc64)
1*ef84fd3bSjoerg //===-- lib/floatsitf.c - integer -> quad-precision conversion ----*- C -*-===//
2*ef84fd3bSjoerg //
3*ef84fd3bSjoerg //                     The LLVM Compiler Infrastructure
4*ef84fd3bSjoerg //
5*ef84fd3bSjoerg // This file is dual licensed under the MIT and the University of Illinois Open
6*ef84fd3bSjoerg // Source Licenses. See LICENSE.TXT for details.
7*ef84fd3bSjoerg //
8*ef84fd3bSjoerg //===----------------------------------------------------------------------===//
9*ef84fd3bSjoerg //
10*ef84fd3bSjoerg // This file implements integer to quad-precision conversion for the
11*ef84fd3bSjoerg // compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even
12*ef84fd3bSjoerg // mode.
13*ef84fd3bSjoerg //
14*ef84fd3bSjoerg //===----------------------------------------------------------------------===//
15*ef84fd3bSjoerg 
16*ef84fd3bSjoerg #define QUAD_PRECISION
17*ef84fd3bSjoerg #include "fp_lib.h"
18*ef84fd3bSjoerg 
19*ef84fd3bSjoerg #if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
__floatsitf(int a)20*ef84fd3bSjoerg COMPILER_RT_ABI fp_t __floatsitf(int a) {
21*ef84fd3bSjoerg 
22*ef84fd3bSjoerg     const int aWidth = sizeof a * CHAR_BIT;
23*ef84fd3bSjoerg 
24*ef84fd3bSjoerg     // Handle zero as a special case to protect clz
25*ef84fd3bSjoerg     if (a == 0)
26*ef84fd3bSjoerg         return fromRep(0);
27*ef84fd3bSjoerg 
28*ef84fd3bSjoerg     // All other cases begin by extracting the sign and absolute value of a
29*ef84fd3bSjoerg     rep_t sign = 0;
30*ef84fd3bSjoerg     unsigned aAbs = (unsigned)a;
31*ef84fd3bSjoerg     if (a < 0) {
32*ef84fd3bSjoerg         sign = signBit;
33*ef84fd3bSjoerg         aAbs = ~(unsigned)a + 1U;
34*ef84fd3bSjoerg     }
35*ef84fd3bSjoerg 
36*ef84fd3bSjoerg     // Exponent of (fp_t)a is the width of abs(a).
37*ef84fd3bSjoerg     const int exponent = (aWidth - 1) - __builtin_clz(aAbs);
38*ef84fd3bSjoerg     rep_t result;
39*ef84fd3bSjoerg 
40*ef84fd3bSjoerg     // Shift a into the significand field and clear the implicit bit.
41*ef84fd3bSjoerg     const int shift = significandBits - exponent;
42*ef84fd3bSjoerg     result = (rep_t)aAbs << shift ^ implicitBit;
43*ef84fd3bSjoerg 
44*ef84fd3bSjoerg     // Insert the exponent
45*ef84fd3bSjoerg     result += (rep_t)(exponent + exponentBias) << significandBits;
46*ef84fd3bSjoerg     // Insert the sign bit and return
47*ef84fd3bSjoerg     return fromRep(result | sign);
48*ef84fd3bSjoerg }
49*ef84fd3bSjoerg 
50*ef84fd3bSjoerg #endif
51