12bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan/* ===-- fixxfdi.c - Implement __fixxfdi -----------------------------------===
22bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan *
32bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan *      	       The LLVM Compiler Infrastructure
42bf62728b8ce00e295c7bf0fb328427496cc85aaEdward 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.
72bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan *
82bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan * ===----------------------------------------------------------------------===
92bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan *
102bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan * This file implements __fixxfdi for the compiler_rt library.
112bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan *
122bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan * ===----------------------------------------------------------------------===
132bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan */
14b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
15b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#if !_ARCH_PPC
16b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
17b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include "int_lib.h"
18b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
192bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan/* Returns: convert a to a signed long long, rounding toward zero. */
20b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
212bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
222bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan *             su_int is a 32 bit integral type
232bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan *             value in long double is representable in di_int (no range checking performed)
242bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan */
25b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
262bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
272bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
282bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan */
29b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCOMPILER_RT_ABI di_int
31b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar__fixxfdi(long double a)
32b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar{
33b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    long_double_bits fb;
34b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    fb.f = a;
358bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan    int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
36b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    if (e < 0)
37b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        return 0;
388bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan    di_int s = -(si_int)((fb.u.high.s.low & 0x00008000) >> 15);
39b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    di_int r = fb.u.low.all;
40b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    r = (du_int)r >> (63 - e);
41b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    return (r ^ s) - s;
42b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar}
43b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
448bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan#endif /* !_ARCH_PPC */
45