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