11fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan/* ===-- fixunsxfsi.c - Implement __fixunsxfsi -----------------------------=== 21fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * 31fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * The LLVM Compiler Infrastructure 41fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * 59ad441ffec97db647fee3725b3424284fb913e14Howard Hinnant * This file is dual licensed under the MIT and the University of Illinois Open 69ad441ffec97db647fee3725b3424284fb913e14Howard Hinnant * Source Licenses. See LICENSE.TXT for details. 71fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * 81fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * ===----------------------------------------------------------------------=== 91fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * 101fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * This file implements __fixunsxfsi for the compiler_rt library. 111fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * 121fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * ===----------------------------------------------------------------------=== 131fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan */ 14b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 15b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#if !_ARCH_PPC 16b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 17b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include "int_lib.h" 18b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 191fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan/* Returns: convert a to a unsigned int, rounding toward zero. 201fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * Negative values all become zero. 211fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan */ 22b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 231fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes 241fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * su_int is a 32 bit integral type 251fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * value in long double is representable in su_int or is negative 261fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * (no range checking performed) 271fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan */ 28b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 291fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee | 301fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm 311fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan */ 32b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCOMPILER_RT_ABI su_int 34b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar__fixunsxfsi(long double a) 35b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar{ 36b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar long_double_bits fb; 37b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar fb.f = a; 388bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan int e = (fb.u.high.s.low & 0x00007FFF) - 16383; 398bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan if (e < 0 || (fb.u.high.s.low & 0x00008000)) 40b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return 0; 418bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan return fb.u.low.s.high >> (31 - e); 42b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar} 43b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 448bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan#endif /* !_ARCH_PPC */ 45