fixunssfdi.c revision 296373
134355Sjb/* ===-- fixunssfdi.c - Implement __fixunssfdi -----------------------------=== 234355Sjb * 346155Sphk * The LLVM Compiler Infrastructure 434355Sjb * 534355Sjb * This file is dual licensed under the MIT and the University of Illinois Open 634355Sjb * Source Licenses. See LICENSE.TXT for details. 734355Sjb * 834355Sjb * ===----------------------------------------------------------------------=== 934355Sjb * 1034355Sjb * This file implements __fixunssfdi for the compiler_rt library. 1134355Sjb * 1234355Sjb * ===----------------------------------------------------------------------=== 1334355Sjb */ 1434355Sjb 1534355Sjb#include "int_lib.h" 1634355Sjb/* Returns: convert a to a unsigned long long, rounding toward zero. 1734355Sjb * Negative values all become zero. 1834355Sjb */ 1934355Sjb 2034355Sjb/* Assumption: float is a IEEE 32 bit floating point type 2134355Sjb * du_int is a 64 bit integral type 2234355Sjb * value in float is representable in du_int or is negative 2334355Sjb * (no range checking performed) 2434355Sjb */ 2534355Sjb 2634355Sjb/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */ 2734355Sjb 2834355SjbARM_EABI_FNALIAS(f2ulz, fixunssfdi) 2934355Sjb 3034355SjbCOMPILER_RT_ABI du_int 3134355Sjb__fixunssfdi(float a) 3234355Sjb{ 3334355Sjb float_bits fb; 3434355Sjb fb.f = a; 3534355Sjb int e = ((fb.u & 0x7F800000) >> 23) - 127; 3634355Sjb if (e < 0 || (fb.u & 0x80000000)) 3734355Sjb return 0; 3834355Sjb du_int r = (fb.u & 0x007FFFFF) | 0x00800000; 3934355Sjb if (e > 23) 4034355Sjb r <<= (e - 23); 4134355Sjb else 4234355Sjb r >>= (23 - e); 4334355Sjb return r; 4434355Sjb} 4534355Sjb