[compiler-rt] r217901 - Implement floatsitf, floatunstfsi, which perform

Joerg Sonnenberger joerg at bec.de
Tue Sep 16 13:34:42 PDT 2014


Author: joerg
Date: Tue Sep 16 15:34:41 2014
New Revision: 217901

URL: http://llvm.org/viewvc/llvm-project?rev=217901&view=rev
Log:
Implement floatsitf, floatunstfsi, which perform
(signed/unsigned)integer to quad-precision conversion.

Submitted by GuanHong Liu.

Differential Revision: http://reviews.llvm.org/D2805

Added:
    compiler-rt/trunk/lib/builtins/floatsitf.c
    compiler-rt/trunk/lib/builtins/floatunsitf.c
    compiler-rt/trunk/test/builtins/Unit/floatsitf_test.c
    compiler-rt/trunk/test/builtins/Unit/floatunsitf_test.c

Added: compiler-rt/trunk/lib/builtins/floatsitf.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/floatsitf.c?rev=217901&view=auto
==============================================================================
--- compiler-rt/trunk/lib/builtins/floatsitf.c (added)
+++ compiler-rt/trunk/lib/builtins/floatsitf.c Tue Sep 16 15:34:41 2014
@@ -0,0 +1,52 @@
+//===-- lib/floatsitf.c - integer -> quad-precision 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 integer to quad-precision conversion for the
+// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even
+// mode.
+//
+//===----------------------------------------------------------------------===//
+
+#define QUAD_PRECISION
+#include "fp_lib.h"
+
+#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
+COMPILER_RT_ABI fp_t __floatsitf(int a) {
+
+    const int aWidth = sizeof a * CHAR_BIT;
+
+    // Handle zero as a special case to protect clz
+    if (a == 0)
+        return fromRep(0);
+
+    // All other cases begin by extracting the sign and absolute value of a
+    rep_t sign = 0;
+    unsigned aAbs = (unsigned)a;
+    if (a < 0) {
+        sign = signBit;
+        aAbs += 0x80000000;
+    }
+
+    // Exponent of (fp_t)a is the width of abs(a).
+    const int exponent = (aWidth - 1) - __builtin_clz(a);
+    rep_t result;
+
+    // Shift a into the significand field and clear the implicit bit.  Extra
+    // cast to unsigned int is necessary to get the correct behavior for
+    // the input INT_MIN.
+    const int shift = significandBits - exponent;
+    result = (rep_t)aAbs << shift ^ implicitBit;
+
+    // Insert the exponent
+    result += (rep_t)(exponent + exponentBias) << significandBits;
+    // Insert the sign bit and return
+    return fromRep(result | sign);
+}
+
+#endif

Added: compiler-rt/trunk/lib/builtins/floatunsitf.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/floatunsitf.c?rev=217901&view=auto
==============================================================================
--- compiler-rt/trunk/lib/builtins/floatunsitf.c (added)
+++ compiler-rt/trunk/lib/builtins/floatunsitf.c Tue Sep 16 15:34:41 2014
@@ -0,0 +1,40 @@
+//===-- lib/floatunsitf.c - uint -> quad-precision 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 unsigned integer to quad-precision conversion for the
+// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even
+// mode.
+//
+//===----------------------------------------------------------------------===//
+
+#define QUAD_PRECISION
+#include "fp_lib.h"
+
+#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
+COMPILER_RT_ABI fp_t __floatunsitf(unsigned int a) {
+
+    const int aWidth = sizeof a * CHAR_BIT;
+
+    // Handle zero as a special case to protect clz
+    if (a == 0) return fromRep(0);
+
+    // Exponent of (fp_t)a is the width of abs(a).
+    const int exponent = (aWidth - 1) - __builtin_clz(a);
+    rep_t result;
+
+    // Shift a into the significand field and clear the implicit bit.
+    const int shift = significandBits - exponent;
+    result = (rep_t)a << shift ^ implicitBit;
+
+    // Insert the exponent
+    result += (rep_t)(exponent + exponentBias) << significandBits;
+    return fromRep(result);
+}
+
+#endif

Added: compiler-rt/trunk/test/builtins/Unit/floatsitf_test.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/builtins/Unit/floatsitf_test.c?rev=217901&view=auto
==============================================================================
--- compiler-rt/trunk/test/builtins/Unit/floatsitf_test.c (added)
+++ compiler-rt/trunk/test/builtins/Unit/floatsitf_test.c Tue Sep 16 15:34:41 2014
@@ -0,0 +1,58 @@
+//===--------------- floatsitf_test.c - Test __floatsitf ------------------===//
+//
+//                     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 tests __floatsitf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+
+#if __LDBL_MANT_DIG__ == 113
+
+#include "fp_test.h"
+
+long double __floatsitf(int a);
+
+int test__floatsitf(int a, uint64_t expectedHi, uint64_t expectedLo)
+{
+    long double x = __floatsitf(a);
+    int ret = compareResultLD(x, expectedHi, expectedLo);
+
+    if (ret)
+    {
+        printf("error in test__floatsitf(%d) = %.20Lf, "
+               "expected %.20Lf\n", a, x, fromRep128(expectedHi, expectedLo));
+    }
+    return ret;
+}
+
+char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0};
+
+#endif
+
+int main()
+{
+#if __LDBL_MANT_DIG__ == 113
+    if (test__floatsitf(0x7fffffff, UINT64_C(0x401dfffffffc0000), UINT64_C(0x0)))
+        return 1;
+    if (test__floatsitf(0, UINT64_C(0x0), UINT64_C(0x0)))
+        return 1;
+    if (test__floatsitf(0xffffffff, UINT64_C(0xbfff000000000000), UINT64_C(0x0)))
+        return 1;
+    if (test__floatsitf(0x12345678, UINT64_C(0x401b234567800000), UINT64_C(0x0)))
+        return 1;
+    if (test__floatsitf(-0x12345678, UINT64_C(0xc01b234567800000), UINT64_C(0x0)))
+        return 1;
+
+#else
+    printf("skipped\n");
+
+#endif
+    return 0;
+}

Added: compiler-rt/trunk/test/builtins/Unit/floatunsitf_test.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/builtins/Unit/floatunsitf_test.c?rev=217901&view=auto
==============================================================================
--- compiler-rt/trunk/test/builtins/Unit/floatunsitf_test.c (added)
+++ compiler-rt/trunk/test/builtins/Unit/floatunsitf_test.c Tue Sep 16 15:34:41 2014
@@ -0,0 +1,55 @@
+//===--------------- floatunsitf_test.c - Test __floatunsitf --------------===//
+//
+//                     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 tests __floatunsitf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+
+#if __LDBL_MANT_DIG__ == 113
+
+#include "fp_test.h"
+
+long double __floatunsitf(unsigned int a);
+
+int test__floatunsitf(unsigned int a, uint64_t expectedHi, uint64_t expectedLo)
+{
+    long double x = __floatunsitf(a);
+    int ret = compareResultLD(x, expectedHi, expectedLo);
+
+    if (ret){
+        printf("error in test__floatunsitf(%u) = %.20Lf, "
+               "expected %.20Lf\n", a, x, fromRep128(expectedHi, expectedLo));
+    }
+    return ret;
+}
+
+char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0};
+
+#endif
+
+int main()
+{
+#if __LDBL_MANT_DIG__ == 113
+    if (test__floatunsitf(0x7fffffff, UINT64_C(0x401dfffffffc0000), UINT64_C(0x0)))
+        return 1;
+    if (test__floatunsitf(0, UINT64_C(0x0), UINT64_C(0x0)))
+        return 1;
+    if (test__floatunsitf(0xffffffff, UINT64_C(0x401efffffffe0000), UINT64_C(0x0)))
+        return 1;
+    if (test__floatunsitf(0x12345678, UINT64_C(0x401b234567800000), UINT64_C(0x0)))
+        return 1;
+
+#else
+    printf("skipped\n");
+
+#endif
+    return 0;
+}





More information about the llvm-commits mailing list