12bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan/* ===-- fixxfti.c - Implement __fixxfti -----------------------------------===
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 __fixxfti for the compiler_rt library.
112bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan *
122bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan * ===----------------------------------------------------------------------===
132bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan */
14b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
15b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include "int_lib.h"
16b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifdef CRT_HAS_128BIT
187f2d7c75e713d778106d01a54e7aef40227bbf2dChandler Carruth
192bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan/* Returns: convert a to a signed long long, rounding toward zero. */
20b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
212bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
222bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan *             su_int is a 32 bit integral type
232bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan *             value in long double is representable in ti_int (no range checking performed)
242bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan */
25b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
262bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
272bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
282bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan */
29b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCOMPILER_RT_ABI ti_int
31b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar__fixxfti(long double a)
32b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar{
33b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    long_double_bits fb;
34b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    fb.f = a;
35aabd961cc27f5d05f441375e5ba4242d63fea11fEdward O'Callaghan    int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
36b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    if (e < 0)
37b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        return 0;
38aabd961cc27f5d05f441375e5ba4242d63fea11fEdward O'Callaghan    ti_int s = -(si_int)((fb.u.high.s.low & 0x00008000) >> 15);
39b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    ti_int r = fb.u.low.all;
40b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    if (e > 63)
41b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        r <<= (e - 63);
42b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    else
43b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        r >>= (63 - e);
44b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    return (r ^ s) - s;
45b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar}
46b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif /* CRT_HAS_128BIT */
48