diff options
Diffstat (limited to 'lib/builtins/floatuntidf.c')
| -rw-r--r-- | lib/builtins/floatuntidf.c | 128 | 
1 files changed, 59 insertions, 69 deletions
diff --git a/lib/builtins/floatuntidf.c b/lib/builtins/floatuntidf.c index 960265d80772..e69e65c1ace4 100644 --- a/lib/builtins/floatuntidf.c +++ b/lib/builtins/floatuntidf.c @@ -1,80 +1,70 @@ -/* ===-- floatuntidf.c - Implement __floatuntidf ---------------------------=== - * - *                     The LLVM Compiler Infrastructure - * - * This file is dual licensed under the MIT and the University of Illinois Open - * Source Licenses. See LICENSE.TXT for details. - * - * ===----------------------------------------------------------------------=== - * - * This file implements __floatuntidf for the compiler_rt library. - * - * ===----------------------------------------------------------------------=== - */ +//===-- floatuntidf.c - Implement __floatuntidf ---------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements __floatuntidf for the compiler_rt library. +// +//===----------------------------------------------------------------------===//  #include "int_lib.h"  #ifdef CRT_HAS_128BIT -/* Returns: convert a to a double, rounding toward even. */ +// Returns: convert a to a double, rounding toward even. -/* Assumption: double is a IEEE 64 bit floating point type - *             tu_int is a 128 bit integral type - */ +// Assumption: double is a IEEE 64 bit floating point type +//             tu_int is a 128 bit integral type -/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */ +// seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm +// mmmm -COMPILER_RT_ABI double -__floatuntidf(tu_int a) -{ -    if (a == 0) -        return 0.0; -    const unsigned N = sizeof(tu_int) * CHAR_BIT; -    int sd = N - __clzti2(a);  /* number of significant digits */ -    int e = sd - 1;             /* exponent */ -    if (sd > DBL_MANT_DIG) -    { -        /*  start:  0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx -         *  finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR -         *                                                12345678901234567890123456 -         *  1 = msb 1 bit -         *  P = bit DBL_MANT_DIG-1 bits to the right of 1 -         *  Q = bit DBL_MANT_DIG bits to the right of 1 -         *  R = "or" of all bits to the right of Q -         */ -        switch (sd) -        { -        case DBL_MANT_DIG + 1: -            a <<= 1; -            break; -        case DBL_MANT_DIG + 2: -            break; -        default: -            a = (a >> (sd - (DBL_MANT_DIG+2))) | -                ((a & ((tu_int)(-1) >> ((N + DBL_MANT_DIG+2) - sd))) != 0); -        }; -        /* finish: */ -        a |= (a & 4) != 0;  /* Or P into R */ -        ++a;  /* round - this step may add a significant bit */ -        a >>= 2;  /* dump Q and R */ -        /* a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits */ -        if (a & ((tu_int)1 << DBL_MANT_DIG)) -        { -            a >>= 1; -            ++e; -        } -        /* a is now rounded to DBL_MANT_DIG bits */ +COMPILER_RT_ABI double __floatuntidf(tu_int a) { +  if (a == 0) +    return 0.0; +  const unsigned N = sizeof(tu_int) * CHAR_BIT; +  int sd = N - __clzti2(a); // number of significant digits +  int e = sd - 1;           // exponent +  if (sd > DBL_MANT_DIG) { +    //  start:  0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx +    //  finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR +    //                                                12345678901234567890123456 +    //  1 = msb 1 bit +    //  P = bit DBL_MANT_DIG-1 bits to the right of 1 +    //  Q = bit DBL_MANT_DIG bits to the right of 1 +    //  R = "or" of all bits to the right of Q +    switch (sd) { +    case DBL_MANT_DIG + 1: +      a <<= 1; +      break; +    case DBL_MANT_DIG + 2: +      break; +    default: +      a = (a >> (sd - (DBL_MANT_DIG + 2))) | +          ((a & ((tu_int)(-1) >> ((N + DBL_MANT_DIG + 2) - sd))) != 0); +    }; +    // finish: +    a |= (a & 4) != 0; // Or P into R +    ++a;               // round - this step may add a significant bit +    a >>= 2;           // dump Q and R +    // a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits +    if (a & ((tu_int)1 << DBL_MANT_DIG)) { +      a >>= 1; +      ++e;      } -    else -    { -        a <<= (DBL_MANT_DIG - sd); -        /* a is now rounded to DBL_MANT_DIG bits */ -    } -    double_bits fb; -    fb.u.s.high = ((e + 1023) << 20)      |        /* exponent */ -                ((su_int)(a >> 32) & 0x000FFFFF); /* mantissa-high */ -    fb.u.s.low = (su_int)a;                         /* mantissa-low */ -    return fb.f; +    // a is now rounded to DBL_MANT_DIG bits +  } else { +    a <<= (DBL_MANT_DIG - sd); +    // a is now rounded to DBL_MANT_DIG bits +  } +  double_bits fb; +  fb.u.s.high = ((e + 1023) << 20) |              // exponent +                ((su_int)(a >> 32) & 0x000FFFFF); // mantissa-high +  fb.u.s.low = (su_int)a;                         // mantissa-low +  return fb.f;  } -#endif /* CRT_HAS_128BIT */ +#endif // CRT_HAS_128BIT  | 
