diff options
| author | Devtools Arcadia <[email protected]> | 2022-02-07 18:08:42 +0300 | 
|---|---|---|
| committer | Devtools Arcadia <[email protected]> | 2022-02-07 18:08:42 +0300 | 
| commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
| tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /contrib/libs/cxxsupp/builtins/floatuntisf.c | |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'contrib/libs/cxxsupp/builtins/floatuntisf.c')
| -rw-r--r-- | contrib/libs/cxxsupp/builtins/floatuntisf.c | 79 | 
1 files changed, 79 insertions, 0 deletions
diff --git a/contrib/libs/cxxsupp/builtins/floatuntisf.c b/contrib/libs/cxxsupp/builtins/floatuntisf.c new file mode 100644 index 00000000000..c0dd0275ddb --- /dev/null +++ b/contrib/libs/cxxsupp/builtins/floatuntisf.c @@ -0,0 +1,79 @@ +/* ===-- floatuntisf.c - Implement __floatuntisf ---------------------------=== + * + *                     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 __floatuntisf for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +#include "int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: convert a to a float, rounding toward even. */ + +/* Assumption: float is a IEEE 32 bit floating point type  + *             tu_int is a 128 bit integral type + */ + +/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */ + +COMPILER_RT_ABI float +__floatuntisf(tu_int a) +{ +    if (a == 0) +        return 0.0F; +    const unsigned N = sizeof(tu_int) * CHAR_BIT; +    int sd = N - __clzti2(a);  /* number of significant digits */ +    int e = sd - 1;             /* exponent */ +    if (sd > FLT_MANT_DIG) +    { +        /*  start:  0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx +         *  finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR +         *                                                12345678901234567890123456 +         *  1 = msb 1 bit +         *  P = bit FLT_MANT_DIG-1 bits to the right of 1 +         *  Q = bit FLT_MANT_DIG bits to the right of 1 +         *  R = "or" of all bits to the right of Q +	 */ +        switch (sd) +        { +        case FLT_MANT_DIG + 1: +            a <<= 1; +            break; +        case FLT_MANT_DIG + 2: +            break; +        default: +            a = (a >> (sd - (FLT_MANT_DIG+2))) | +                ((a & ((tu_int)(-1) >> ((N + FLT_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 FLT_MANT_DIG or FLT_MANT_DIG+1 bits */ +        if (a & ((tu_int)1 << FLT_MANT_DIG)) +        { +            a >>= 1; +            ++e; +        } +        /* a is now rounded to FLT_MANT_DIG bits */ +    } +    else +    { +        a <<= (FLT_MANT_DIG - sd); +        /* a is now rounded to FLT_MANT_DIG bits */ +    } +    float_bits fb; +    fb.u = ((e + 127) << 23)       |  /* exponent */ +           ((su_int)a & 0x007FFFFF);  /* mantissa */ +    return fb.f; +} + +#endif /* CRT_HAS_128BIT */  | 
