137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/* ===-- fixdfti.c - Implement __fixdfti -----------------------------------===
237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan *
337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan *                     The LLVM Compiler Infrastructure
437a6a455466e5b197311771a777ab241e471ed8aEdward 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.
737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan *
837a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * ===----------------------------------------------------------------------===
937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan *
1037a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * This file implements __fixdfti for the compiler_rt library.
1137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan *
1237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * ===----------------------------------------------------------------------===
1337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */
14b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
15b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#if __x86_64
16b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
17b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include "int_lib.h"
18b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
1937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/* Returns: convert a to a signed long long, rounding toward zero. */
20b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
2137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/* Assumption: double is a IEEE 64 bit floating point type
2237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan *             su_int is a 32 bit integral type
2337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan *             value in double is representable in ti_int (no range checking performed)
2437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */
25b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
2637a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
27b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
28b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbarti_int
29b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar__fixdfti(double a)
30b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar{
31b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    double_bits fb;
32b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    fb.f = a;
33aabd961cc27f5d05f441375e5ba4242d63fea11fEdward O'Callaghan    int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023;
34b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    if (e < 0)
35b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        return 0;
36aabd961cc27f5d05f441375e5ba4242d63fea11fEdward O'Callaghan    ti_int s = (si_int)(fb.u.s.high & 0x80000000) >> 31;
37b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    ti_int r = 0x0010000000000000uLL | (0x000FFFFFFFFFFFFFuLL & fb.u.all);
38b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    if (e > 52)
39b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        r <<= (e - 52);
40b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    else
41b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        r >>= (52 - e);
42b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    return (r ^ s) - s;
43b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar}
44b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
45b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#endif
46