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 227c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar * ti_int is a 128 bit integral type 237c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar * value in long double is representable in ti_int 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{ 337c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar const ti_int ti_max = (ti_int)((~(tu_int)0) / 2); 347c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar const ti_int ti_min = -ti_max - 1; 35b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar long_double_bits fb; 36b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar fb.f = a; 37aabd961cc27f5d05f441375e5ba4242d63fea11fEdward O'Callaghan int e = (fb.u.high.s.low & 0x00007FFF) - 16383; 38b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (e < 0) 39b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return 0; 40aabd961cc27f5d05f441375e5ba4242d63fea11fEdward O'Callaghan ti_int s = -(si_int)((fb.u.high.s.low & 0x00008000) >> 15); 41b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar ti_int r = fb.u.low.all; 427c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar if ((unsigned)e >= sizeof(ti_int) * CHAR_BIT) 437c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar return a > 0 ? ti_max : ti_min; 44b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (e > 63) 45b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar r <<= (e - 63); 46b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar else 47b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar r >>= (63 - e); 48b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return (r ^ s) - s; 49b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar} 50b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif /* CRT_HAS_128BIT */ 52