11fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan/* ===-- floatuntidf.c - Implement __floatuntidf ---------------------------=== 21fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * 31fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * The LLVM Compiler Infrastructure 41fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward 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. 71fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * 81fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * ===----------------------------------------------------------------------=== 91fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * 101fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * This file implements __floatuntidf for the compiler_rt library. 111fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * 121fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * ===----------------------------------------------------------------------=== 131fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan */ 14b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 15b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include "int_lib.h" 16b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifdef CRT_HAS_128BIT 187f2d7c75e713d778106d01a54e7aef40227bbf2dChandler Carruth 191fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan/* Returns: convert a to a double, rounding toward even. */ 20b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 21c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar/* Assumption: double is a IEEE 64 bit floating point type 221fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * tu_int is a 128 bit integral type 231fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan */ 24b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 251fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */ 26b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCOMPILER_RT_ABI double 28b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar__floatuntidf(tu_int a) 29b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar{ 30b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (a == 0) 31b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return 0.0; 32b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar const unsigned N = sizeof(tu_int) * CHAR_BIT; 331fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan int sd = N - __clzti2(a); /* number of significant digits */ 341fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan int e = sd - 1; /* exponent */ 35b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (sd > DBL_MANT_DIG) 36b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 371fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx 381fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR 391fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * 12345678901234567890123456 401fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * 1 = msb 1 bit 411fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * P = bit DBL_MANT_DIG-1 bits to the right of 1 421fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * Q = bit DBL_MANT_DIG bits to the right of 1 431fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * R = "or" of all bits to the right of Q 442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines */ 45b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar switch (sd) 46b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 47b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar case DBL_MANT_DIG + 1: 48b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar a <<= 1; 49b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar break; 50b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar case DBL_MANT_DIG + 2: 51b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar break; 52b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar default: 53b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar a = (a >> (sd - (DBL_MANT_DIG+2))) | 54b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar ((a & ((tu_int)(-1) >> ((N + DBL_MANT_DIG+2) - sd))) != 0); 55b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar }; 561fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan /* finish: */ 571fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan a |= (a & 4) != 0; /* Or P into R */ 581fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan ++a; /* round - this step may add a significant bit */ 591fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan a >>= 2; /* dump Q and R */ 601fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan /* a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits */ 61b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (a & ((tu_int)1 << DBL_MANT_DIG)) 62b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 63b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar a >>= 1; 64b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar ++e; 65b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 661fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan /* a is now rounded to DBL_MANT_DIG bits */ 67b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 68b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar else 69b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 70b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar a <<= (DBL_MANT_DIG - sd); 711fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan /* a is now rounded to DBL_MANT_DIG bits */ 72b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 73b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar double_bits fb; 74aabd961cc27f5d05f441375e5ba4242d63fea11fEdward O'Callaghan fb.u.s.high = ((e + 1023) << 20) | /* exponent */ 751fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan ((su_int)(a >> 32) & 0x000FFFFF); /* mantissa-high */ 76aabd961cc27f5d05f441375e5ba4242d63fea11fEdward O'Callaghan fb.u.s.low = (su_int)a; /* mantissa-low */ 77b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return fb.f; 78b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar} 79b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif /* CRT_HAS_128BIT */ 81