12bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan/* ===-- fixunsdfdi.c - Implement __fixunsdfdi -----------------------------=== 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 __fixunsdfdi for the compiler_rt library. 112bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan * 122bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan * ===----------------------------------------------------------------------=== 132bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan */ 14b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 15b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include "int_lib.h" 16b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 172bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan/* Returns: convert a to a unsigned long long, rounding toward zero. 182bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan * Negative values all become zero. 192bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan */ 20b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 212bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan/* Assumption: double is a IEEE 64 bit floating point type 222bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan * du_int is a 64 bit integral type 232bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan * value in double is representable in du_int or is negative 242bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan * (no range checking performed) 252bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan */ 26b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 272bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */ 28b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 290193b74976719b8aea4cb8874ba36b75836a8d6eChandler CarruthARM_EABI_FNALIAS(d2ulz, fixunsdfdi) 3037b97d1cf4501b94347e0b4e880f4b25825a289fAnton Korobeynikov 311c5f89b1dd741135a4007ab577723d422f421eecAnton KorobeynikovCOMPILER_RT_ABI du_int 32b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar__fixunsdfdi(double a) 33b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar{ 34b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar double_bits fb; 35b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar fb.f = a; 368bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023; 378bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan if (e < 0 || (fb.u.s.high & 0x80000000)) 38b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return 0; 39b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar udwords r; 408bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan r.s.high = (fb.u.s.high & 0x000FFFFF) | 0x00100000; 418bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan r.s.low = fb.u.s.low; 42b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (e > 52) 43b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar r.all <<= (e - 52); 44b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar else 45b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar r.all >>= (52 - e); 46b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return r.all; 47b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar} 48