diff options
Diffstat (limited to 'gcc-4.2.1-5666.3/gcc/config/arm/_fixunsdfdi.c')
-rw-r--r-- | gcc-4.2.1-5666.3/gcc/config/arm/_fixunsdfdi.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/gcc-4.2.1-5666.3/gcc/config/arm/_fixunsdfdi.c b/gcc-4.2.1-5666.3/gcc/config/arm/_fixunsdfdi.c new file mode 100644 index 000000000..98fcc8f53 --- /dev/null +++ b/gcc-4.2.1-5666.3/gcc/config/arm/_fixunsdfdi.c @@ -0,0 +1,64 @@ +/* APPLE LOCAL file 5316398 improved float/double -> int64 functions */ +#include <stdint.h> + +uint64_t +__fixunsdfdi (double x) +{ + union { double d; uint64_t u; uint32_t u32[2]; } u = {x}; + uint32_t hi = u.u >> 32; + uint32_t lo; + + /* Early out for the common case: +0 <= x < 0x1.0p32 */ + if (__builtin_expect (hi < 0x41f00000U, 1)) + return (uint64_t) ((uint32_t) x); + + /* 0x1.0p32 <= x < 0x1.0p64 */ + if (__builtin_expect (hi < 0x43f00000U, 1)) + { + /* if x < 0x1.0p52 */ + if (__builtin_expect (hi < 0x43400000U, 1)) + { + if (__builtin_expect (hi < 0x43300000U, 1)) + { + uint32_t shift = (1023 + 52) - (hi >> 20); + uint32_t unitBit = 1U << shift; + uint32_t fractMask = unitBit - 1; + u.u32[0] = lo = (uint32_t) u.u & ~fractMask; + x -= u.d; + hi &= 0x000FFFFFU; + hi |= 0x00100000U; + lo = (lo >> shift) | (hi << (32 - shift)); + /* (int32_t) x is always zero here. This sets the inexact + flag. */ + hi = (hi >> shift) + (int32_t) x; + } + else + { + u.u &= 0x000FFFFFFFFFFFFFULL; + u.u |= 0x0010000000000000ULL; + return u.u; + } + } + else + { + uint32_t shift = (hi >> 20) - (1023 + 52); + hi &= 0x000FFFFFU; + lo = u.u; + hi |= 0x00100000U; + + hi = (hi << shift) | (lo >> (32 - shift)); + lo = lo << shift; + } + + /* return the result; */ + return ((uint64_t) hi << 32) | lo; + } + + /* x <= -0 or x >= 0x1.0p64 or x is NaN. set invalid as necessary. + Pin according to ARM rules. */ + hi = x; + + /* promote to 64-bits */ + lo = (hi << 1) | (hi & 1); + return ((uint64_t) hi << 32) | lo; +} |