1214152Sed/* ===-- floatuntixf.c - Implement __floatuntixf ---------------------------=== 2214152Sed * 3214152Sed * The LLVM Compiler Infrastructure 4214152Sed * 5222656Sed * This file is dual licensed under the MIT and the University of Illinois Open 6222656Sed * Source Licenses. See LICENSE.TXT for details. 7214152Sed * 8214152Sed * ===----------------------------------------------------------------------=== 9214152Sed * 10214152Sed * This file implements __floatuntixf for the compiler_rt library. 11214152Sed * 12214152Sed * ===----------------------------------------------------------------------=== 13214152Sed */ 14214152Sed 15263560Sdim#include "int_lib.h" 16263560Sdim 17263764Sdim#ifdef CRT_HAS_128BIT 18214152Sed 19214152Sed/* Returns: convert a to a long double, rounding toward even. */ 20214152Sed 21214152Sed/* Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits 22214152Sed * tu_int is a 128 bit integral type 23214152Sed */ 24214152Sed 25214152Sed/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee | 26214152Sed * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm 27214152Sed */ 28214152Sed 29214152Sedsi_int __clzti2(ti_int a); 30214152Sed 31214152Sedlong double 32214152Sed__floatuntixf(tu_int a) 33214152Sed{ 34214152Sed if (a == 0) 35214152Sed return 0.0; 36214152Sed const unsigned N = sizeof(tu_int) * CHAR_BIT; 37214152Sed int sd = N - __clzti2(a); /* number of significant digits */ 38214152Sed int e = sd - 1; /* exponent */ 39214152Sed if (sd > LDBL_MANT_DIG) 40214152Sed { 41214152Sed /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx 42214152Sed * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR 43214152Sed * 12345678901234567890123456 44214152Sed * 1 = msb 1 bit 45214152Sed * P = bit LDBL_MANT_DIG-1 bits to the right of 1 46214152Sed * Q = bit LDBL_MANT_DIG bits to the right of 1 47214152Sed * R = "or" of all bits to the right of Q 48214152Sed */ 49214152Sed switch (sd) 50214152Sed { 51214152Sed case LDBL_MANT_DIG + 1: 52214152Sed a <<= 1; 53214152Sed break; 54214152Sed case LDBL_MANT_DIG + 2: 55214152Sed break; 56214152Sed default: 57214152Sed a = (a >> (sd - (LDBL_MANT_DIG+2))) | 58214152Sed ((a & ((tu_int)(-1) >> ((N + LDBL_MANT_DIG+2) - sd))) != 0); 59214152Sed }; 60214152Sed /* finish: */ 61214152Sed a |= (a & 4) != 0; /* Or P into R */ 62214152Sed ++a; /* round - this step may add a significant bit */ 63214152Sed a >>= 2; /* dump Q and R */ 64214152Sed /* a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits */ 65214152Sed if (a & ((tu_int)1 << LDBL_MANT_DIG)) 66214152Sed { 67214152Sed a >>= 1; 68214152Sed ++e; 69214152Sed } 70214152Sed /* a is now rounded to LDBL_MANT_DIG bits */ 71214152Sed } 72214152Sed else 73214152Sed { 74214152Sed a <<= (LDBL_MANT_DIG - sd); 75214152Sed /* a is now rounded to LDBL_MANT_DIG bits */ 76214152Sed } 77214152Sed long_double_bits fb; 78214152Sed fb.u.high.s.low = (e + 16383); /* exponent */ 79214152Sed fb.u.low.all = (du_int)a; /* mantissa */ 80214152Sed return fb.f; 81214152Sed} 82214152Sed 83214152Sed#endif 84