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