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