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