12bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan/* ===-- floattixf.c - Implement __floattixf -------------------------------=== 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 __floattixf 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 long double, rounding toward even. */ 20b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 212bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan/* Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits 222bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan * ti_int is a 128 bit integral type 232bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan */ 24b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 252bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee | 262bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm 272bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan */ 28b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCOMPILER_RT_ABI long double 30b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar__floattixf(ti_int a) 31b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar{ 32b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (a == 0) 33b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return 0.0; 34b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar const unsigned N = sizeof(ti_int) * CHAR_BIT; 35b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar const ti_int s = a >> (N-1); 36b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar a = (a ^ s) - s; 3737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan int sd = N - __clzti2(a); /* number of significant digits */ 3837a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan int e = sd - 1; /* exponent */ 39b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (sd > LDBL_MANT_DIG) 40b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 412bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx 422bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR 432bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan * 12345678901234567890123456 442bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan * 1 = msb 1 bit 452bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan * P = bit LDBL_MANT_DIG-1 bits to the right of 1 462bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan * Q = bit LDBL_MANT_DIG bits to the right of 1 472bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan * R = "or" of all bits to the right of Q 482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines */ 49b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar switch (sd) 50b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 51b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar case LDBL_MANT_DIG + 1: 52b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar a <<= 1; 53b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar break; 54b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar case LDBL_MANT_DIG + 2: 55b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar break; 56b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar default: 57b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar a = ((tu_int)a >> (sd - (LDBL_MANT_DIG+2))) | 58b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar ((a & ((tu_int)(-1) >> ((N + LDBL_MANT_DIG+2) - sd))) != 0); 59b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar }; 602bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan /* finish: */ 612bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan a |= (a & 4) != 0; /* Or P into R */ 622bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan ++a; /* round - this step may add a significant bit */ 632bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan a >>= 2; /* dump Q and R */ 642bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan /* a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits */ 65b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (a & ((tu_int)1 << LDBL_MANT_DIG)) 66b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 67b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar a >>= 1; 68b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar ++e; 69b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 702bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan /* a is now rounded to LDBL_MANT_DIG bits */ 71b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 72b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar else 73b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 74b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar a <<= (LDBL_MANT_DIG - sd); 752bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan /* a is now rounded to LDBL_MANT_DIG bits */ 76b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 77b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar long_double_bits fb; 78aabd961cc27f5d05f441375e5ba4242d63fea11fEdward O'Callaghan fb.u.high.s.low = ((su_int)s & 0x8000) | /* sign */ 792bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan (e + 16383); /* exponent */ 802bf62728b8ce00e295c7bf0fb328427496cc85aaEdward O'Callaghan fb.u.low.all = (du_int)a; /* mantissa */ 81b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return fb.f; 82b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar} 83b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif /* CRT_HAS_128BIT */ 85