137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/* ===-- fixdfdi.c - Implement __fixdfdi -----------------------------------=== 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 __fixdfdi for the compiler_rt library. 1137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 1237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * ===----------------------------------------------------------------------=== 1337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */ 14b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 15b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include "int_lib.h" 16b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 1737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/* Returns: convert a to a signed long long, rounding toward zero. */ 18b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 1937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/* Assumption: double is a IEEE 64 bit floating point type 2037a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * su_int is a 32 bit integral type 2137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * value in double is representable in di_int (no range checking performed) 2237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */ 23b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 2437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */ 25b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 260193b74976719b8aea4cb8874ba36b75836a8d6eChandler CarruthARM_EABI_FNALIAS(d2lz, fixdfdi) 2737b97d1cf4501b94347e0b4e880f4b25825a289fAnton Korobeynikov 282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCOMPILER_RT_ABI di_int 29b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar__fixdfdi(double a) 30b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar{ 31b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar double_bits fb; 32b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar fb.f = a; 338bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023; 34b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (e < 0) 35b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return 0; 368bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan di_int s = (si_int)(fb.u.s.high & 0x80000000) >> 31; 37b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar dwords r; 388bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan r.s.high = (fb.u.s.high & 0x000FFFFF) | 0x00100000; 398bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan r.s.low = fb.u.s.low; 40b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (e > 52) 41b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar r.all <<= (e - 52); 42b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar else 43b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar r.all >>= (52 - e); 44b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return (r.all ^ s) - s; 4537a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan} 46