[PATCH] [COMPILER-RT] Implement __fixtfsi, __fixunstfsi
GuanHong Liu
koviankevin at hotmail.com
Thu Feb 13 21:56:02 PST 2014
Implement __fixtfsi, __fixunstfsi, which perform quad-precision to (sign/unsigned)integer conversion
http://llvm-reviews.chandlerc.com/D2804
Files:
lib/fixtfsi.c
lib/fixunstfsi.c
Index: lib/fixtfsi.c
===================================================================
--- /dev/null
+++ lib/fixtfsi.c
@@ -0,0 +1,47 @@
+//===-- lib/fixtfsi.c - Quad-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 quad-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.
+//
+//===----------------------------------------------------------------------===//
+
+#define QUAD_PRECISION
+#include "fp_lib.h"
+
+#include "int_lib.h"
+
+int __fixtfsi(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));
+ }
+}
Index: lib/fixunstfsi.c
===================================================================
--- /dev/null
+++ lib/fixunstfsi.c
@@ -0,0 +1,43 @@
+/* ===-- 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.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __fixunstfsi 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: long double is a IEEE 128 bit floating point type
+ * su_int is a 32 bit integral type
+ * value in long double is representable in su_int or is negative
+ * (no range checking performed)
+ */
+
+/* seee eeee eeee eeee mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
+ mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
+
+COMPILER_RT_ABI su_int
+__fixunstfsi(long double a)
+{
+ long_double_bits fb;
+ fb.f = a;
+ int e = ((fb.u.high.s.high & 0x7FFF0000) >> 16) - 16383;
+ if (e < 0 || (fb.u.high.s.high & 0x80000000))
+ return 0;
+ return (
+ 0x80000000u |
+ ((fb.u.high.s.high & 0x0000FFFF) << 15) |
+ (fb.u.high.s.low >> 17)
+ ) >> (31 - e);
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2804.1.patch
Type: text/x-patch
Size: 3579 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140213/b484bae7/attachment.bin>
More information about the llvm-commits
mailing list