floattidf.c revision 2d1fdb26e458c4ddc04155c1d421bced3ba90cd0
1b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham/* ===-- floattidf.c - Implement __floattidf -------------------------------=== 224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * 324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * The LLVM Compiler Infrastructure 424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * 524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * This file is dual licensed under the MIT and the University of Illinois Open 624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * Source Licenses. See LICENSE.TXT for details. 724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * 824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * ===----------------------------------------------------------------------=== 924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * 10d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea * This file implements __floattidf for the compiler_rt library. 11d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea * 12b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham * ===----------------------------------------------------------------------=== 1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner */ 1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "int_lib.h" 1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifdef CRT_HAS_128BIT 18b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham 19b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham/* Returns: convert a to a double, rounding toward even.*/ 204f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner/* Assumption: double is a IEEE 64 bit floating point type 224f385f181467701d2c5225f2c954ed5771e0763fJim Ingham * ti_int is a 128 bit integral type 23b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham */ 24b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham 2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */ 266e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton 276e0101c86555a06b3bd4cb6104b35abfae0b0057Greg ClaytonCOMPILER_RT_ABI double 286e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton__floattidf(ti_int a) 2973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton{ 30b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham if (a == 0) 3149ce8969d3154e1560106cfe530444c09410f217Greg Clayton return 0.0; 32b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham const unsigned N = sizeof(ti_int) * CHAR_BIT; 33b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham const ti_int s = a >> (N-1); 34b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham a = (a ^ s) - s; 35b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham int sd = N - __clzti2(a); /* number of significant digits */ 36b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham int e = sd - 1; /* exponent */ 3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (sd > DBL_MANT_DIG) 3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx 40ce0575750c7180a2fdf06220d0d75c1d7dc9608bDaniel Dunbar * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR 41ce0575750c7180a2fdf06220d0d75c1d7dc9608bDaniel Dunbar * 12345678901234567890123456 4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * 1 = msb 1 bit 4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * P = bit DBL_MANT_DIG-1 bits to the right of 1 4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * Q = bit DBL_MANT_DIG bits to the right of 1 456507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham * R = "or" of all bits to the right of Q 4612f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham */ 4712f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham switch (sd) 486507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham { 496507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham case DBL_MANT_DIG + 1: 506507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham a <<= 1; 516507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham break; 526507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham case DBL_MANT_DIG + 2: 536507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham break; 546507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham default: 556507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham a = ((tu_int)a >> (sd - (DBL_MANT_DIG+2))) | 566507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham ((a & ((tu_int)(-1) >> ((N + DBL_MANT_DIG+2) - sd))) != 0); 576507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham }; 586507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham /* finish: */ 596507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham a |= (a & 4) != 0; /* Or P into R */ 606507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham ++a; /* round - this step may add a significant bit */ 616507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham a >>= 2; /* dump Q and R */ 626507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham /* a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits */ 636507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham if (a & ((tu_int)1 << DBL_MANT_DIG)) 646507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham { 656507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham a >>= 1; 666507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham ++e; 676507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham } 686507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham /* a is now rounded to DBL_MANT_DIG bits */ 696507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham } 706507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham else 716507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham { 726507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham a <<= (DBL_MANT_DIG - sd); 736507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham /* a is now rounded to DBL_MANT_DIG bits */ 746507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham } 756507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham double_bits fb; 766507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham fb.u.s.high = ((su_int)s & 0x80000000) | /* sign */ 776507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham ((e + 1023) << 20) | /* exponent */ 786507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham ((su_int)(a >> 32) & 0x000FFFFF); /* mantissa-high */ 796507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham fb.u.s.low = (su_int)a; /* mantissa-low */ 806507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham return fb.f; 816507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham} 826507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 836507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham#endif /* CRT_HAS_128BIT */ 846507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham