fixunsdfsi.c revision 222656
1178580Simp/* ===-- fixunsdfsi.c - Implement __fixunsdfsi -----------------------------===
2178580Simp *
3178580Simp *                     The LLVM Compiler Infrastructure
4178580Simp *
5178580Simp * This file is dual licensed under the MIT and the University of Illinois Open
6178580Simp * Source Licenses. See LICENSE.TXT for details.
7178580Simp *
8178580Simp * ===----------------------------------------------------------------------===
9178580Simp *
10178580Simp * This file implements __fixunsdfsi for the compiler_rt library.
11178580Simp *
12178580Simp * ===----------------------------------------------------------------------===
13178580Simp */
14178580Simp#include "abi.h"
15178580Simp
16178580Simp#include "int_lib.h"
17178580Simp
18178580Simp/* Returns: convert a to a unsigned int, rounding toward zero.
19178580Simp *          Negative values all become zero.
20178580Simp */
21178580Simp
22178580Simp/* Assumption: double is a IEEE 64 bit floating point type
23178580Simp *             su_int is a 32 bit integral type
24178580Simp *             value in double is representable in su_int or is negative
25178580Simp *                 (no range checking performed)
26178580Simp */
27178580Simp
28178580Simp/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
29178580Simp
30178580SimpARM_EABI_FNALIAS(d2uiz, fixunsdfsi);
31178580Simp
32178580SimpCOMPILER_RT_ABI su_int
33178580Simp__fixunsdfsi(double a)
34178580Simp{
35178580Simp    double_bits fb;
36178580Simp    fb.f = a;
37178580Simp    int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023;
38178580Simp    if (e < 0 || (fb.u.s.high & 0x80000000))
39178580Simp        return 0;
40178580Simp    return (
41178580Simp                0x80000000u                      |
42178580Simp                ((fb.u.s.high & 0x000FFFFF) << 11) |
43178580Simp                (fb.u.s.low >> 21)
44178580Simp           ) >> (31 - e);
45178580Simp}
46178580Simp