[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