summaryrefslogtreecommitdiffstats
path: root/contrib/compiler-rt
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2015-03-14 12:40:19 +0000
committerdim <dim@FreeBSD.org>2015-03-14 12:40:19 +0000
commit73a5b102bba947d10e5dd482c1f14bc444d4fcb3 (patch)
tree22c96169e9ec91b9a5b31830347710371a91096d /contrib/compiler-rt
parentd202cb2c64432c785dfaf1544f77b27349d33d56 (diff)
downloadFreeBSD-src-73a5b102bba947d10e5dd482c1f14bc444d4fcb3.zip
FreeBSD-src-73a5b102bba947d10e5dd482c1f14bc444d4fcb3.tar.gz
Pull in r231965 from upstream compiler-rt trunk (by Jörg Sonnenberger):
Refactor float to integer conversion to share the same code. 80bit Intel/PPC long double is excluded due to lacking support for the abstraction. Consistently provide saturation logic. Extend to long double on 128bit IEEE extended platforms. Initial patch with test cases from GuanHong Liu. Reviewed by Steve Canon. Differential Revision: http://reviews.llvm.org/D2804 Pull in r232107 from upstream compiler-rt trunk (by Ed Maste): Use signed int implementation for __fixint Requested by: emaste
Diffstat (limited to 'contrib/compiler-rt')
-rw-r--r--contrib/compiler-rt/lib/builtins/fixdfdi.c41
-rw-r--r--contrib/compiler-rt/lib/builtins/fixdfsi.c56
-rw-r--r--contrib/compiler-rt/lib/builtins/fixdfti.c33
-rw-r--r--contrib/compiler-rt/lib/builtins/fixsfdi.c38
-rw-r--r--contrib/compiler-rt/lib/builtins/fixsfsi.c53
-rw-r--r--contrib/compiler-rt/lib/builtins/fixsfti.c33
-rw-r--r--contrib/compiler-rt/lib/builtins/fixtfdi.c23
-rw-r--r--contrib/compiler-rt/lib/builtins/fixtfsi.c23
-rw-r--r--contrib/compiler-rt/lib/builtins/fixtfti.c23
-rw-r--r--contrib/compiler-rt/lib/builtins/fixunsdfdi.c38
-rw-r--r--contrib/compiler-rt/lib/builtins/fixunsdfsi.c35
-rw-r--r--contrib/compiler-rt/lib/builtins/fixunsdfti.c36
-rw-r--r--contrib/compiler-rt/lib/builtins/fixunssfdi.c35
-rw-r--r--contrib/compiler-rt/lib/builtins/fixunssfsi.c32
-rw-r--r--contrib/compiler-rt/lib/builtins/fixunssfti.c36
-rw-r--r--contrib/compiler-rt/lib/builtins/fixunstfdi.c22
-rw-r--r--contrib/compiler-rt/lib/builtins/fixunstfsi.c22
-rw-r--r--contrib/compiler-rt/lib/builtins/fixunstfti.c22
-rw-r--r--contrib/compiler-rt/lib/builtins/fixunsxfdi.c2
-rw-r--r--contrib/compiler-rt/lib/builtins/fixunsxfsi.c3
-rw-r--r--contrib/compiler-rt/lib/builtins/fixunsxfti.c5
-rw-r--r--contrib/compiler-rt/lib/builtins/fixxfdi.c6
-rw-r--r--contrib/compiler-rt/lib/builtins/fixxfti.c8
-rw-r--r--contrib/compiler-rt/lib/builtins/fp_fixint_impl.inc41
-rw-r--r--contrib/compiler-rt/lib/builtins/fp_fixuint_impl.inc39
25 files changed, 329 insertions, 376 deletions
diff --git a/contrib/compiler-rt/lib/builtins/fixdfdi.c b/contrib/compiler-rt/lib/builtins/fixdfdi.c
index 86f9f6c..67b124a 100644
--- a/contrib/compiler-rt/lib/builtins/fixdfdi.c
+++ b/contrib/compiler-rt/lib/builtins/fixdfdi.c
@@ -6,40 +6,17 @@
* Source Licenses. See LICENSE.TXT for details.
*
* ===----------------------------------------------------------------------===
- *
- * This file implements __fixdfdi for the compiler_rt library.
- *
- * ===----------------------------------------------------------------------===
*/
-#include "int_lib.h"
-
-/* Returns: convert a to a signed long long, rounding toward zero. */
-
-/* Assumption: double is a IEEE 64 bit floating point type
- * su_int is a 32 bit integral type
- * value in double is representable in di_int (no range checking performed)
- */
-
-/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
-
+#define DOUBLE_PRECISION
+#include "fp_lib.h"
ARM_EABI_FNALIAS(d2lz, fixdfdi)
+typedef di_int fixint_t;
+typedef du_int fixuint_t;
+#include "fp_fixint_impl.inc"
+
COMPILER_RT_ABI di_int
-__fixdfdi(double a)
-{
- double_bits fb;
- fb.f = a;
- int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023;
- if (e < 0)
- return 0;
- di_int s = (si_int)(fb.u.s.high & 0x80000000) >> 31;
- dwords r;
- r.s.high = (fb.u.s.high & 0x000FFFFF) | 0x00100000;
- r.s.low = fb.u.s.low;
- if (e > 52)
- r.all <<= (e - 52);
- else
- r.all >>= (52 - e);
- return (r.all ^ s) - s;
-}
+__fixdfdi(fp_t a) {
+ return __fixint(a);
+}
diff --git a/contrib/compiler-rt/lib/builtins/fixdfsi.c b/contrib/compiler-rt/lib/builtins/fixdfsi.c
index 88b2ff5..704e65b 100644
--- a/contrib/compiler-rt/lib/builtins/fixdfsi.c
+++ b/contrib/compiler-rt/lib/builtins/fixdfsi.c
@@ -1,50 +1,22 @@
-//===-- lib/fixdfsi.c - Double-precision -> integer conversion ----*- C -*-===//
-//
-// 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 double-precision to integer conversion for the
-// compiler-rt library. No range checking is performed; the behavior of this
-// conversion is undefined for out of range values in the C standard.
-//
-//===----------------------------------------------------------------------===//
+/* ===-- fixdfsi.c - Implement __fixdfsi -----------------------------------===
+ *
+ * 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.
+ *
+ * ===----------------------------------------------------------------------===
+ */
#define DOUBLE_PRECISION
#include "fp_lib.h"
-
-#include "int_lib.h"
+typedef si_int fixint_t;
+typedef su_int fixuint_t;
+#include "fp_fixint_impl.inc"
ARM_EABI_FNALIAS(d2iz, fixdfsi)
-COMPILER_RT_ABI int
+COMPILER_RT_ABI si_int
__fixdfsi(fp_t a) {
-
- // Break a into sign, exponent, significand
- const rep_t aRep = toRep(a);
- const rep_t aAbs = aRep & absMask;
- const int sign = aRep & signBit ? -1 : 1;
- const int exponent = (aAbs >> significandBits) - exponentBias;
- const rep_t significand = (aAbs & significandMask) | implicitBit;
-
- // If 0 < exponent < significandBits, right shift to get the result.
- if ((unsigned int)exponent < significandBits) {
- return sign * (significand >> (significandBits - exponent));
- }
-
- // If exponent is negative, the result is zero.
- else if (exponent < 0) {
- return 0;
- }
-
- // If significandBits < exponent, left shift to get the result. This shift
- // may end up being larger than the type width, which incurs undefined
- // behavior, but the conversion itself is undefined in that case, so
- // whatever the compiler decides to do is fine.
- else {
- return sign * (significand << (exponent - significandBits));
- }
+ return __fixint(a);
}
diff --git a/contrib/compiler-rt/lib/builtins/fixdfti.c b/contrib/compiler-rt/lib/builtins/fixdfti.c
index 2c27f4b..aaf225e 100644
--- a/contrib/compiler-rt/lib/builtins/fixdfti.c
+++ b/contrib/compiler-rt/lib/builtins/fixdfti.c
@@ -6,40 +6,21 @@
* Source Licenses. See LICENSE.TXT for details.
*
* ===----------------------------------------------------------------------===
- *
- * This file implements __fixdfti for the compiler_rt library.
- *
- * ===----------------------------------------------------------------------===
*/
#include "int_lib.h"
#ifdef CRT_HAS_128BIT
+#define DOUBLE_PRECISION
+#include "fp_lib.h"
-/* Returns: convert a to a signed long long, rounding toward zero. */
-
-/* Assumption: double is a IEEE 64 bit floating point type
- * su_int is a 32 bit integral type
- * value in double is representable in ti_int (no range checking performed)
- */
-
-/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
+typedef ti_int fixint_t;
+typedef tu_int fixuint_t;
+#include "fp_fixint_impl.inc"
COMPILER_RT_ABI ti_int
-__fixdfti(double a)
-{
- double_bits fb;
- fb.f = a;
- int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023;
- if (e < 0)
- return 0;
- ti_int s = (si_int)(fb.u.s.high & 0x80000000) >> 31;
- ti_int r = 0x0010000000000000uLL | (0x000FFFFFFFFFFFFFuLL & fb.u.all);
- if (e > 52)
- r <<= (e - 52);
- else
- r >>= (52 - e);
- return (r ^ s) - s;
+__fixdfti(fp_t a) {
+ return __fixint(a);
}
#endif /* CRT_HAS_128BIT */
diff --git a/contrib/compiler-rt/lib/builtins/fixsfdi.c b/contrib/compiler-rt/lib/builtins/fixsfdi.c
index 4f6cfdd..835ff85 100644
--- a/contrib/compiler-rt/lib/builtins/fixsfdi.c
+++ b/contrib/compiler-rt/lib/builtins/fixsfdi.c
@@ -1,43 +1,23 @@
/* ===-- fixsfdi.c - Implement __fixsfdi -----------------------------------===
*
- * The LLVM Compiler Infrastructure
+ * 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 __fixsfdi for the compiler_rt library.
- *
- * ===----------------------------------------------------------------------===
- */
-
-#include "int_lib.h"
-
-/* Returns: convert a to a signed long long, rounding toward zero. */
-
-/* Assumption: float is a IEEE 32 bit floating point type
- * su_int is a 32 bit integral type
- * value in float is representable in di_int (no range checking performed)
*/
-/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
+#define SINGLE_PRECISION
+#include "fp_lib.h"
ARM_EABI_FNALIAS(f2lz, fixsfdi)
+typedef di_int fixint_t;
+typedef du_int fixuint_t;
+#include "fp_fixint_impl.inc"
+
COMPILER_RT_ABI di_int
-__fixsfdi(float a)
-{
- float_bits fb;
- fb.f = a;
- int e = ((fb.u & 0x7F800000) >> 23) - 127;
- if (e < 0)
- return 0;
- di_int s = (si_int)(fb.u & 0x80000000) >> 31;
- di_int r = (fb.u & 0x007FFFFF) | 0x00800000;
- if (e > 23)
- r <<= (e - 23);
- else
- r >>= (23 - e);
- return (r ^ s) - s;
+__fixsfdi(fp_t a) {
+ return __fixint(a);
}
diff --git a/contrib/compiler-rt/lib/builtins/fixsfsi.c b/contrib/compiler-rt/lib/builtins/fixsfsi.c
index e3cc42d..f045536 100644
--- a/contrib/compiler-rt/lib/builtins/fixsfsi.c
+++ b/contrib/compiler-rt/lib/builtins/fixsfsi.c
@@ -1,47 +1,22 @@
-//===-- lib/fixsfsi.c - Single-precision -> integer conversion ----*- C -*-===//
-//
-// 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 single-precision to integer conversion for the
-// compiler-rt library. No range checking is performed; the behavior of this
-// conversion is undefined for out of range values in the C standard.
-//
-//===----------------------------------------------------------------------===//
+/* ===-- fixsfsi.c - Implement __fixsfsi -----------------------------------===
+ *
+ * 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.
+ *
+ * ===----------------------------------------------------------------------===
+ */
#define SINGLE_PRECISION
#include "fp_lib.h"
+typedef si_int fixint_t;
+typedef su_int fixuint_t;
+#include "fp_fixint_impl.inc"
ARM_EABI_FNALIAS(f2iz, fixsfsi)
-COMPILER_RT_ABI int
+COMPILER_RT_ABI si_int
__fixsfsi(fp_t a) {
- // Break a into sign, exponent, significand
- const rep_t aRep = toRep(a);
- const rep_t aAbs = aRep & absMask;
- const int sign = aRep & signBit ? -1 : 1;
- const int exponent = (aAbs >> significandBits) - exponentBias;
- const rep_t significand = (aAbs & significandMask) | implicitBit;
-
- // If 0 < exponent < significandBits, right shift to get the result.
- if ((unsigned int)exponent < significandBits) {
- return sign * (significand >> (significandBits - exponent));
- }
-
- // If exponent is negative, the result is zero.
- else if (exponent < 0) {
- return 0;
- }
-
- // If significandBits < exponent, left shift to get the result. This shift
- // may end up being larger than the type width, which incurs undefined
- // behavior, but the conversion itself is undefined in that case, so
- // whatever the compiler decides to do is fine.
- else {
- return sign * (significand << (exponent - significandBits));
- }
+ return __fixint(a);
}
diff --git a/contrib/compiler-rt/lib/builtins/fixsfti.c b/contrib/compiler-rt/lib/builtins/fixsfti.c
index 6a1a1c6..3a159b3 100644
--- a/contrib/compiler-rt/lib/builtins/fixsfti.c
+++ b/contrib/compiler-rt/lib/builtins/fixsfti.c
@@ -6,40 +6,21 @@
* Source Licenses. See LICENSE.TXT for details.
*
* ===----------------------------------------------------------------------===
- *
- * This file implements __fixsfti for the compiler_rt library.
- *
- * ===----------------------------------------------------------------------===
*/
#include "int_lib.h"
#ifdef CRT_HAS_128BIT
+#define SINGLE_PRECISION
+#include "fp_lib.h"
-/* Returns: convert a to a signed long long, rounding toward zero. */
-
-/* Assumption: float is a IEEE 32 bit floating point type
- * su_int is a 32 bit integral type
- * value in float is representable in ti_int (no range checking performed)
- */
-
-/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
+typedef ti_int fixint_t;
+typedef tu_int fixuint_t;
+#include "fp_fixint_impl.inc"
COMPILER_RT_ABI ti_int
-__fixsfti(float a)
-{
- float_bits fb;
- fb.f = a;
- int e = ((fb.u & 0x7F800000) >> 23) - 127;
- if (e < 0)
- return 0;
- ti_int s = (si_int)(fb.u & 0x80000000) >> 31;
- ti_int r = (fb.u & 0x007FFFFF) | 0x00800000;
- if (e > 23)
- r <<= (e - 23);
- else
- r >>= (23 - e);
- return (r ^ s) - s;
+__fixsfti(fp_t a) {
+ return __fixint(a);
}
#endif /* CRT_HAS_128BIT */
diff --git a/contrib/compiler-rt/lib/builtins/fixtfdi.c b/contrib/compiler-rt/lib/builtins/fixtfdi.c
new file mode 100644
index 0000000..bc9dea1
--- /dev/null
+++ b/contrib/compiler-rt/lib/builtins/fixtfdi.c
@@ -0,0 +1,23 @@
+/* ===-- fixtfdi.c - Implement __fixtfdi -----------------------------------===
+ *
+ * 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.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#define QUAD_PRECISION
+#include "fp_lib.h"
+
+#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
+typedef di_int fixint_t;
+typedef du_int fixuint_t;
+#include "fp_fixint_impl.inc"
+
+COMPILER_RT_ABI di_int
+__fixtfdi(fp_t a) {
+ return __fixint(a);
+}
+#endif
diff --git a/contrib/compiler-rt/lib/builtins/fixtfsi.c b/contrib/compiler-rt/lib/builtins/fixtfsi.c
new file mode 100644
index 0000000..feb3de8
--- /dev/null
+++ b/contrib/compiler-rt/lib/builtins/fixtfsi.c
@@ -0,0 +1,23 @@
+/* ===-- fixtfsi.c - Implement __fixtfsi -----------------------------------===
+ *
+ * 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.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#define QUAD_PRECISION
+#include "fp_lib.h"
+
+#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
+typedef si_int fixint_t;
+typedef su_int fixuint_t;
+#include "fp_fixint_impl.inc"
+
+COMPILER_RT_ABI si_int
+__fixtfsi(fp_t a) {
+ return __fixint(a);
+}
+#endif
diff --git a/contrib/compiler-rt/lib/builtins/fixtfti.c b/contrib/compiler-rt/lib/builtins/fixtfti.c
new file mode 100644
index 0000000..ee4ada8
--- /dev/null
+++ b/contrib/compiler-rt/lib/builtins/fixtfti.c
@@ -0,0 +1,23 @@
+/* ===-- fixtfti.c - Implement __fixtfti -----------------------------------===
+ *
+ * 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.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#define QUAD_PRECISION
+#include "fp_lib.h"
+
+#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
+typedef ti_int fixint_t;
+typedef tu_int fixuint_t;
+#include "fp_fixint_impl.inc"
+
+COMPILER_RT_ABI ti_int
+__fixtfti(fp_t a) {
+ return __fixint(a);
+}
+#endif
diff --git a/contrib/compiler-rt/lib/builtins/fixunsdfdi.c b/contrib/compiler-rt/lib/builtins/fixunsdfdi.c
index 9e63713..f4f689e 100644
--- a/contrib/compiler-rt/lib/builtins/fixunsdfdi.c
+++ b/contrib/compiler-rt/lib/builtins/fixunsdfdi.c
@@ -6,42 +6,16 @@
* Source Licenses. See LICENSE.TXT for details.
*
* ===----------------------------------------------------------------------===
- *
- * This file implements __fixunsdfdi for the compiler_rt library.
- *
- * ===----------------------------------------------------------------------===
- */
-
-#include "int_lib.h"
-
-/* Returns: convert a to a unsigned long long, rounding toward zero.
- * Negative values all become zero.
- */
-
-/* Assumption: double is a IEEE 64 bit floating point type
- * du_int is a 64 bit integral type
- * value in double is representable in du_int or is negative
- * (no range checking performed)
*/
-/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
+#define DOUBLE_PRECISION
+#include "fp_lib.h"
+typedef du_int fixuint_t;
+#include "fp_fixuint_impl.inc"
ARM_EABI_FNALIAS(d2ulz, fixunsdfdi)
COMPILER_RT_ABI du_int
-__fixunsdfdi(double a)
-{
- double_bits fb;
- fb.f = a;
- int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023;
- if (e < 0 || (fb.u.s.high & 0x80000000))
- return 0;
- udwords r;
- r.s.high = (fb.u.s.high & 0x000FFFFF) | 0x00100000;
- r.s.low = fb.u.s.low;
- if (e > 52)
- r.all <<= (e - 52);
- else
- r.all >>= (52 - e);
- return r.all;
+__fixunsdfdi(fp_t a) {
+ return __fixuint(a);
}
diff --git a/contrib/compiler-rt/lib/builtins/fixunsdfsi.c b/contrib/compiler-rt/lib/builtins/fixunsdfsi.c
index c6a3c75..232d342 100644
--- a/contrib/compiler-rt/lib/builtins/fixunsdfsi.c
+++ b/contrib/compiler-rt/lib/builtins/fixunsdfsi.c
@@ -6,39 +6,16 @@
* Source Licenses. See LICENSE.TXT for details.
*
* ===----------------------------------------------------------------------===
- *
- * This file implements __fixunsdfsi for the compiler_rt library.
- *
- * ===----------------------------------------------------------------------===
- */
-
-#include "int_lib.h"
-
-/* Returns: convert a to a unsigned int, rounding toward zero.
- * Negative values all become zero.
- */
-
-/* Assumption: double is a IEEE 64 bit floating point type
- * su_int is a 32 bit integral type
- * value in double is representable in su_int or is negative
- * (no range checking performed)
*/
-/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
+#define DOUBLE_PRECISION
+#include "fp_lib.h"
+typedef su_int fixuint_t;
+#include "fp_fixuint_impl.inc"
ARM_EABI_FNALIAS(d2uiz, fixunsdfsi)
COMPILER_RT_ABI su_int
-__fixunsdfsi(double a)
-{
- double_bits fb;
- fb.f = a;
- int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023;
- if (e < 0 || (fb.u.s.high & 0x80000000))
- return 0;
- return (
- 0x80000000u |
- ((fb.u.s.high & 0x000FFFFF) << 11) |
- (fb.u.s.low >> 21)
- ) >> (31 - e);
+__fixunsdfsi(fp_t a) {
+ return __fixuint(a);
}
diff --git a/contrib/compiler-rt/lib/builtins/fixunsdfti.c b/contrib/compiler-rt/lib/builtins/fixunsdfti.c
index cc6c84f..c3d7df9 100644
--- a/contrib/compiler-rt/lib/builtins/fixunsdfti.c
+++ b/contrib/compiler-rt/lib/builtins/fixunsdfti.c
@@ -6,42 +6,18 @@
* Source Licenses. See LICENSE.TXT for details.
*
* ===----------------------------------------------------------------------===
- *
- * This file implements __fixunsdfti for the compiler_rt library.
- *
- * ===----------------------------------------------------------------------===
*/
#include "int_lib.h"
#ifdef CRT_HAS_128BIT
-
-/* Returns: convert a to a unsigned long long, rounding toward zero.
- * Negative values all become zero.
- */
-
-/* Assumption: double is a IEEE 64 bit floating point type
- * tu_int is a 64 bit integral type
- * value in double is representable in tu_int or is negative
- * (no range checking performed)
- */
-
-/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
+#define DOUBLE_PRECISION
+#include "fp_lib.h"
+typedef tu_int fixuint_t;
+#include "fp_fixuint_impl.inc"
COMPILER_RT_ABI tu_int
-__fixunsdfti(double a)
-{
- double_bits fb;
- fb.f = a;
- int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023;
- if (e < 0 || (fb.u.s.high & 0x80000000))
- return 0;
- tu_int r = 0x0010000000000000uLL | (fb.u.all & 0x000FFFFFFFFFFFFFuLL);
- if (e > 52)
- r <<= (e - 52);
- else
- r >>= (52 - e);
- return r;
+__fixunsdftti(fp_t a) {
+ return __fixuint(a);
}
-
#endif /* CRT_HAS_128BIT */
diff --git a/contrib/compiler-rt/lib/builtins/fixunssfdi.c b/contrib/compiler-rt/lib/builtins/fixunssfdi.c
index 69d5952..cd21cfd 100644
--- a/contrib/compiler-rt/lib/builtins/fixunssfdi.c
+++ b/contrib/compiler-rt/lib/builtins/fixunssfdi.c
@@ -6,39 +6,16 @@
* Source Licenses. See LICENSE.TXT for details.
*
* ===----------------------------------------------------------------------===
- *
- * This file implements __fixunssfdi for the compiler_rt library.
- *
- * ===----------------------------------------------------------------------===
- */
-
-#include "int_lib.h"
-/* Returns: convert a to a unsigned long long, rounding toward zero.
- * Negative values all become zero.
- */
-
-/* Assumption: float is a IEEE 32 bit floating point type
- * du_int is a 64 bit integral type
- * value in float is representable in du_int or is negative
- * (no range checking performed)
*/
-/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
+#define SINGLE_PRECISION
+#include "fp_lib.h"
+typedef du_int fixuint_t;
+#include "fp_fixuint_impl.inc"
ARM_EABI_FNALIAS(f2ulz, fixunssfdi)
COMPILER_RT_ABI du_int
-__fixunssfdi(float a)
-{
- float_bits fb;
- fb.f = a;
- int e = ((fb.u & 0x7F800000) >> 23) - 127;
- if (e < 0 || (fb.u & 0x80000000))
- return 0;
- du_int r = (fb.u & 0x007FFFFF) | 0x00800000;
- if (e > 23)
- r <<= (e - 23);
- else
- r >>= (23 - e);
- return r;
+__fixunssfdi(fp_t a) {
+ return __fixuint(a);
}
diff --git a/contrib/compiler-rt/lib/builtins/fixunssfsi.c b/contrib/compiler-rt/lib/builtins/fixunssfsi.c
index e034139..cc2b05b 100644
--- a/contrib/compiler-rt/lib/builtins/fixunssfsi.c
+++ b/contrib/compiler-rt/lib/builtins/fixunssfsi.c
@@ -12,34 +12,14 @@
* ===----------------------------------------------------------------------===
*/
-#include "int_lib.h"
-
-/* Returns: convert a to a unsigned int, rounding toward zero.
- * Negative values all become zero.
- */
-
-/* Assumption: float is a IEEE 32 bit floating point type
- * su_int is a 32 bit integral type
- * value in float is representable in su_int or is negative
- * (no range checking performed)
- */
-
-/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
+#define SINGLE_PRECISION
+#include "fp_lib.h"
+typedef su_int fixuint_t;
+#include "fp_fixuint_impl.inc"
ARM_EABI_FNALIAS(f2uiz, fixunssfsi)
COMPILER_RT_ABI su_int
-__fixunssfsi(float a)
-{
- float_bits fb;
- fb.f = a;
- int e = ((fb.u & 0x7F800000) >> 23) - 127;
- if (e < 0 || (fb.u & 0x80000000))
- return 0;
- su_int r = (fb.u & 0x007FFFFF) | 0x00800000;
- if (e > 23)
- r <<= (e - 23);
- else
- r >>= (23 - e);
- return r;
+__fixunssfsi(fp_t a) {
+ return __fixuint(a);
}
diff --git a/contrib/compiler-rt/lib/builtins/fixunssfti.c b/contrib/compiler-rt/lib/builtins/fixunssfti.c
index 4da9e24..9593153 100644
--- a/contrib/compiler-rt/lib/builtins/fixunssfti.c
+++ b/contrib/compiler-rt/lib/builtins/fixunssfti.c
@@ -12,36 +12,12 @@
* ===----------------------------------------------------------------------===
*/
-#include "int_lib.h"
-
-#ifdef CRT_HAS_128BIT
-
-/* Returns: convert a to a unsigned long long, rounding toward zero.
- * Negative values all become zero.
- */
-
-/* Assumption: float is a IEEE 32 bit floating point type
- * tu_int is a 64 bit integral type
- * value in float is representable in tu_int or is negative
- * (no range checking performed)
- */
-
-/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
+#if defined(CRT_HAS_128BIT)
+typedef tu_int fixuint_t;
+#include "fp_fixuint_impl.inc"
COMPILER_RT_ABI tu_int
-__fixunssfti(float a)
-{
- float_bits fb;
- fb.f = a;
- int e = ((fb.u & 0x7F800000) >> 23) - 127;
- if (e < 0 || (fb.u & 0x80000000))
- return 0;
- tu_int r = (fb.u & 0x007FFFFF) | 0x00800000;
- if (e > 23)
- r <<= (e - 23);
- else
- r >>= (23 - e);
- return r;
+__fixunssfti(fp_t a) {
+ return __fixuint(a);
}
-
-#endif /* CRT_HAS_128BIT */
+#endif
diff --git a/contrib/compiler-rt/lib/builtins/fixunstfdi.c b/contrib/compiler-rt/lib/builtins/fixunstfdi.c
new file mode 100644
index 0000000..b2995f6
--- /dev/null
+++ b/contrib/compiler-rt/lib/builtins/fixunstfdi.c
@@ -0,0 +1,22 @@
+/* ===-- fixunstfdi.c - Implement __fixunstfdi -----------------------------===
+ *
+ * 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.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#define QUAD_PRECISION
+#include "fp_lib.h"
+
+#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
+typedef du_int fixuint_t;
+#include "fp_fixuint_impl.inc"
+
+COMPILER_RT_ABI du_int
+__fixunstfdi(fp_t a) {
+ return __fixuint(a);
+}
+#endif
diff --git a/contrib/compiler-rt/lib/builtins/fixunstfsi.c b/contrib/compiler-rt/lib/builtins/fixunstfsi.c
new file mode 100644
index 0000000..b5d3f6a
--- /dev/null
+++ b/contrib/compiler-rt/lib/builtins/fixunstfsi.c
@@ -0,0 +1,22 @@
+/* ===-- fixunstfsi.c - Implement __fixunstfsi -----------------------------===
+ *
+ * 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.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#define QUAD_PRECISION
+#include "fp_lib.h"
+
+#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
+typedef su_int fixuint_t;
+#include "fp_fixuint_impl.inc"
+
+COMPILER_RT_ABI su_int
+__fixunstfsi(fp_t a) {
+ return __fixuint(a);
+}
+#endif
diff --git a/contrib/compiler-rt/lib/builtins/fixunstfti.c b/contrib/compiler-rt/lib/builtins/fixunstfti.c
new file mode 100644
index 0000000..22ff9df
--- /dev/null
+++ b/contrib/compiler-rt/lib/builtins/fixunstfti.c
@@ -0,0 +1,22 @@
+/* ===-- fixunstfsi.c - Implement __fixunstfsi -----------------------------===
+ *
+ * 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.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#define QUAD_PRECISION
+#include "fp_lib.h"
+
+#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
+typedef tu_int fixuint_t;
+#include "fp_fixuint_impl.inc"
+
+COMPILER_RT_ABI tu_int
+__fixunstfti(fp_t a) {
+ return __fixuint(a);
+}
+#endif
diff --git a/contrib/compiler-rt/lib/builtins/fixunsxfdi.c b/contrib/compiler-rt/lib/builtins/fixunsxfdi.c
index 7224d46..075304e 100644
--- a/contrib/compiler-rt/lib/builtins/fixunsxfdi.c
+++ b/contrib/compiler-rt/lib/builtins/fixunsxfdi.c
@@ -38,6 +38,8 @@ __fixunsxfdi(long double a)
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
if (e < 0 || (fb.u.high.s.low & 0x00008000))
return 0;
+ if ((unsigned)e > sizeof(du_int) * CHAR_BIT)
+ return ~(du_int)0;
return fb.u.low.all >> (63 - e);
}
diff --git a/contrib/compiler-rt/lib/builtins/fixunsxfsi.c b/contrib/compiler-rt/lib/builtins/fixunsxfsi.c
index df0a18e..c3c70f7 100644
--- a/contrib/compiler-rt/lib/builtins/fixunsxfsi.c
+++ b/contrib/compiler-rt/lib/builtins/fixunsxfsi.c
@@ -23,7 +23,6 @@
/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
* su_int is a 32 bit integral type
* value in long double is representable in su_int or is negative
- * (no range checking performed)
*/
/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
@@ -38,6 +37,8 @@ __fixunsxfsi(long double a)
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
if (e < 0 || (fb.u.high.s.low & 0x00008000))
return 0;
+ if ((unsigned)e > sizeof(su_int) * CHAR_BIT)
+ return ~(su_int)0;
return fb.u.low.s.high >> (31 - e);
}
diff --git a/contrib/compiler-rt/lib/builtins/fixunsxfti.c b/contrib/compiler-rt/lib/builtins/fixunsxfti.c
index 42e5073..fb39d00 100644
--- a/contrib/compiler-rt/lib/builtins/fixunsxfti.c
+++ b/contrib/compiler-rt/lib/builtins/fixunsxfti.c
@@ -21,9 +21,8 @@
*/
/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
- * tu_int is a 64 bit integral type
+ * tu_int is a 128 bit integral type
* value in long double is representable in tu_int or is negative
- * (no range checking performed)
*/
/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
@@ -38,6 +37,8 @@ __fixunsxfti(long double a)
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
if (e < 0 || (fb.u.high.s.low & 0x00008000))
return 0;
+ if ((unsigned)e > sizeof(tu_int) * CHAR_BIT)
+ return ~(tu_int)0;
tu_int r = fb.u.low.all;
if (e > 63)
r <<= (e - 63);
diff --git a/contrib/compiler-rt/lib/builtins/fixxfdi.c b/contrib/compiler-rt/lib/builtins/fixxfdi.c
index afc79d8..011787f 100644
--- a/contrib/compiler-rt/lib/builtins/fixxfdi.c
+++ b/contrib/compiler-rt/lib/builtins/fixxfdi.c
@@ -19,7 +19,7 @@
/* Returns: convert a to a signed long long, rounding toward zero. */
/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
- * su_int is a 32 bit integral type
+ * di_int is a 64 bit integral type
* value in long double is representable in di_int (no range checking performed)
*/
@@ -30,11 +30,15 @@
COMPILER_RT_ABI di_int
__fixxfdi(long double a)
{
+ const di_int di_max = (di_int)((~(du_int)0) / 2);
+ const di_int di_min = -di_max - 1;
long_double_bits fb;
fb.f = a;
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
if (e < 0)
return 0;
+ if ((unsigned)e >= sizeof(di_int) * CHAR_BIT)
+ return a > 0 ? di_max : di_min;
di_int s = -(si_int)((fb.u.high.s.low & 0x00008000) >> 15);
di_int r = fb.u.low.all;
r = (du_int)r >> (63 - e);
diff --git a/contrib/compiler-rt/lib/builtins/fixxfti.c b/contrib/compiler-rt/lib/builtins/fixxfti.c
index 3d0a279..968a4f0 100644
--- a/contrib/compiler-rt/lib/builtins/fixxfti.c
+++ b/contrib/compiler-rt/lib/builtins/fixxfti.c
@@ -19,8 +19,8 @@
/* Returns: convert a to a signed long long, rounding toward zero. */
/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes
- * su_int is a 32 bit integral type
- * value in long double is representable in ti_int (no range checking performed)
+ * ti_int is a 128 bit integral type
+ * value in long double is representable in ti_int
*/
/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
@@ -30,6 +30,8 @@
COMPILER_RT_ABI ti_int
__fixxfti(long double a)
{
+ const ti_int ti_max = (ti_int)((~(tu_int)0) / 2);
+ const ti_int ti_min = -ti_max - 1;
long_double_bits fb;
fb.f = a;
int e = (fb.u.high.s.low & 0x00007FFF) - 16383;
@@ -37,6 +39,8 @@ __fixxfti(long double a)
return 0;
ti_int s = -(si_int)((fb.u.high.s.low & 0x00008000) >> 15);
ti_int r = fb.u.low.all;
+ if ((unsigned)e >= sizeof(ti_int) * CHAR_BIT)
+ return a > 0 ? ti_max : ti_min;
if (e > 63)
r <<= (e - 63);
else
diff --git a/contrib/compiler-rt/lib/builtins/fp_fixint_impl.inc b/contrib/compiler-rt/lib/builtins/fp_fixint_impl.inc
new file mode 100644
index 0000000..035e87c
--- /dev/null
+++ b/contrib/compiler-rt/lib/builtins/fp_fixint_impl.inc
@@ -0,0 +1,41 @@
+//===-- lib/fixdfsi.c - Double-precision -> integer conversion ----*- C -*-===//
+//
+// 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 float to integer conversion for the
+// compiler-rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "fp_lib.h"
+
+static inline fixint_t __fixint(fp_t a) {
+ const fixint_t fixint_max = (fixint_t)((~(fixuint_t)0) / 2);
+ const fixint_t fixint_min = -fixint_max - 1;
+ // Break a into sign, exponent, significand
+ const rep_t aRep = toRep(a);
+ const rep_t aAbs = aRep & absMask;
+ const fixint_t sign = aRep & signBit ? -1 : 1;
+ const int exponent = (aAbs >> significandBits) - exponentBias;
+ const rep_t significand = (aAbs & significandMask) | implicitBit;
+
+ // If exponent is negative, the result is zero.
+ if (exponent < 0)
+ return 0;
+
+ // If the value is too large for the integer type, saturate.
+ if ((unsigned)exponent >= sizeof(fixint_t) * CHAR_BIT)
+ return sign == 1 ? fixint_max : fixint_min;
+
+ // If 0 <= exponent < significandBits, right shift to get the result.
+ // Otherwise, shift left.
+ if (exponent < significandBits)
+ return sign * (significand >> (significandBits - exponent));
+ else
+ return sign * ((fixint_t)significand << (exponent - significandBits));
+}
diff --git a/contrib/compiler-rt/lib/builtins/fp_fixuint_impl.inc b/contrib/compiler-rt/lib/builtins/fp_fixuint_impl.inc
new file mode 100644
index 0000000..5fefab0
--- /dev/null
+++ b/contrib/compiler-rt/lib/builtins/fp_fixuint_impl.inc
@@ -0,0 +1,39 @@
+//===-- lib/fixdfsi.c - Double-precision -> integer conversion ----*- C -*-===//
+//
+// 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 float to unsigned integer conversion for the
+// compiler-rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "fp_lib.h"
+
+static inline fixuint_t __fixuint(fp_t a) {
+ // Break a into sign, exponent, significand
+ const rep_t aRep = toRep(a);
+ const rep_t aAbs = aRep & absMask;
+ const int sign = aRep & signBit ? -1 : 1;
+ const int exponent = (aAbs >> significandBits) - exponentBias;
+ const rep_t significand = (aAbs & significandMask) | implicitBit;
+
+ // If either the value or the exponent is negative, the result is zero.
+ if (sign == -1 || exponent < 0)
+ return 0;
+
+ // If the value is too large for the integer type, saturate.
+ if ((unsigned)exponent > sizeof(fixuint_t) * CHAR_BIT)
+ return ~(fixuint_t)0;
+
+ // If 0 <= exponent < significandBits, right shift to get the result.
+ // Otherwise, shift left.
+ if (exponent < significandBits)
+ return significand >> (significandBits - exponent);
+ else
+ return (fixuint_t)significand << (exponent - significandBits);
+}
OpenPOWER on IntegriCloud