1214152Sed/* ===-- floattixf.c - Implement __floattixf -------------------------------=== 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 __floattixf 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 * ti_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__floattixf(ti_int a) 33214152Sed{ 34214152Sed if (a == 0) 35214152Sed return 0.0; 36214152Sed const unsigned N = sizeof(ti_int) * CHAR_BIT; 37214152Sed const ti_int s = a >> (N-1); 38214152Sed a = (a ^ s) - s; 39214152Sed int sd = N - __clzti2(a); /* number of significant digits */ 40214152Sed int e = sd - 1; /* exponent */ 41214152Sed if (sd > LDBL_MANT_DIG) 42214152Sed { 43214152Sed /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx 44214152Sed * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR 45214152Sed * 12345678901234567890123456 46214152Sed * 1 = msb 1 bit 47214152Sed * P = bit LDBL_MANT_DIG-1 bits to the right of 1 48214152Sed * Q = bit LDBL_MANT_DIG bits to the right of 1 49214152Sed * R = "or" of all bits to the right of Q 50263764Sdim */ 51214152Sed switch (sd) 52214152Sed { 53214152Sed case LDBL_MANT_DIG + 1: 54214152Sed a <<= 1; 55214152Sed break; 56214152Sed case LDBL_MANT_DIG + 2: 57214152Sed break; 58214152Sed default: 59214152Sed a = ((tu_int)a >> (sd - (LDBL_MANT_DIG+2))) | 60214152Sed ((a & ((tu_int)(-1) >> ((N + LDBL_MANT_DIG+2) - sd))) != 0); 61214152Sed }; 62214152Sed /* finish: */ 63214152Sed a |= (a & 4) != 0; /* Or P into R */ 64214152Sed ++a; /* round - this step may add a significant bit */ 65214152Sed a >>= 2; /* dump Q and R */ 66214152Sed /* a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits */ 67214152Sed if (a & ((tu_int)1 << LDBL_MANT_DIG)) 68214152Sed { 69214152Sed a >>= 1; 70214152Sed ++e; 71214152Sed } 72214152Sed /* a is now rounded to LDBL_MANT_DIG bits */ 73214152Sed } 74214152Sed else 75214152Sed { 76214152Sed a <<= (LDBL_MANT_DIG - sd); 77214152Sed /* a is now rounded to LDBL_MANT_DIG bits */ 78214152Sed } 79214152Sed long_double_bits fb; 80214152Sed fb.u.high.s.low = ((su_int)s & 0x8000) | /* sign */ 81214152Sed (e + 16383); /* exponent */ 82214152Sed fb.u.low.all = (du_int)a; /* mantissa */ 83214152Sed return fb.f; 84214152Sed} 85214152Sed 86263764Sdim#endif /* CRT_HAS_128BIT */ 87