fixunsdfsi.c revision 215125
1129198Scognet/* ===-- fixunsdfsi.c - Implement __fixunsdfsi -----------------------------===
2129198Scognet *
3139735Simp *                     The LLVM Compiler Infrastructure
4129198Scognet *
5129198Scognet * This file is distributed under the University of Illinois Open Source
6129198Scognet * License. See LICENSE.TXT for details.
7129198Scognet *
8129198Scognet * ===----------------------------------------------------------------------===
9129198Scognet *
10129198Scognet * This file implements __fixunsdfsi for the compiler_rt library.
11129198Scognet *
12129198Scognet * ===----------------------------------------------------------------------===
13129198Scognet */
14129198Scognet
15129198Scognet#include "int_lib.h"
16129198Scognet
17129198Scognet/* Returns: convert a to a unsigned int, rounding toward zero.
18129198Scognet *          Negative values all become zero.
19129198Scognet */
20129198Scognet
21129198Scognet/* Assumption: double is a IEEE 64 bit floating point type
22129198Scognet *             su_int is a 32 bit integral type
23129198Scognet *             value in double is representable in su_int or is negative
24129198Scognet *                 (no range checking performed)
25129198Scognet */
26129198Scognet
27129198Scognet/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
28129198Scognet
29129198Scognetsu_int
30129198Scognet__fixunsdfsi(double a)
31129198Scognet{
32129198Scognet    double_bits fb;
33129198Scognet    fb.f = a;
34129198Scognet    int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023;
35129198Scognet    if (e < 0 || (fb.u.s.high & 0x80000000))
36129198Scognet        return 0;
37129198Scognet    return (
38129198Scognet                0x80000000u                      |
39129198Scognet                ((fb.u.s.high & 0x000FFFFF) << 11) |
40129198Scognet                (fb.u.s.low >> 21)
41129198Scognet           ) >> (31 - e);
42129198Scognet}
43129198Scognet