aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.2.1-5666.3/gcc/config/arm/_fixunssfdi.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.2.1-5666.3/gcc/config/arm/_fixunssfdi.c')
-rw-r--r--gcc-4.2.1-5666.3/gcc/config/arm/_fixunssfdi.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/gcc-4.2.1-5666.3/gcc/config/arm/_fixunssfdi.c b/gcc-4.2.1-5666.3/gcc/config/arm/_fixunssfdi.c
new file mode 100644
index 000000000..08ffc6a6e
--- /dev/null
+++ b/gcc-4.2.1-5666.3/gcc/config/arm/_fixunssfdi.c
@@ -0,0 +1,41 @@
+/* APPLE LOCAL file 5316398 improved float/double -> int64 functions */
+#include <stdint.h>
+
+uint64_t
+__fixunssfdi (float x)
+{
+ union { float f; uint32_t u; } u = {x};
+ uint32_t hi, lo;
+
+ /* early out for common small positive numbers. */
+ if (__builtin_expect (u.u < 0x4f800000U, 1))
+ return (uint64_t) ((uint32_t) x);
+
+ /* larger non-overflowing cases are all exact, so we just need to do
+ the conversion in integer code */
+ /* if( 0x1.0p32f <= x < 0x1.0p63f ) */
+ if (__builtin_expect (u.u < 0x5f800000U, 1))
+ {
+ uint32_t bits = (u.u & 0x007fffffU) | 0x00800000U;
+ uint32_t shift = (u.u >> 23) - (127 + 23);
+ if (shift < 32)
+ {
+ hi = bits >> (32 - shift);
+ lo = bits << shift;
+ }
+ else
+ {
+ hi = bits << (shift - 32);
+ lo = 0;
+ }
+ return ((uint64_t) hi << 32) | lo;
+ }
+
+ /* Overflow or NaN: convert value to unsigned int, set invalid as
+ necessary */
+ hi = x;
+
+ /* extend to 64-bits. */
+ lo = (hi << 1) | (hi & 1);
+ return ((uint64_t) hi << 32) | lo;
+}