aboutsummaryrefslogtreecommitdiff
path: root/contrib/compiler-rt/lib/builtins/muldc3.c
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-01-08 19:47:10 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-01-08 19:47:10 +0000
commitf4341a5a66d0fa0f3c9599ea5c5d2d7b2b240c1d (patch)
treef47eabbd2a48be6d6fec3ddeeefae5b4aeb87dbc /contrib/compiler-rt/lib/builtins/muldc3.c
parentbbf686ed602a158a5d2fcf9dd90f4bda25feef5e (diff)
parentca9211ecdede9bdedb812b2243a4abdb8dacd1b9 (diff)
Update compiler-rt to trunk r224034. This brings a number of new
builtins, and also the various sanitizers. Support for these will be added in a later commit.
Notes
Notes: svn path=/head/; revision=276851
Diffstat (limited to 'contrib/compiler-rt/lib/builtins/muldc3.c')
-rw-r--r--contrib/compiler-rt/lib/builtins/muldc3.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/contrib/compiler-rt/lib/builtins/muldc3.c b/contrib/compiler-rt/lib/builtins/muldc3.c
new file mode 100644
index 000000000000..3bfae2c52224
--- /dev/null
+++ b/contrib/compiler-rt/lib/builtins/muldc3.c
@@ -0,0 +1,73 @@
+/* ===-- muldc3.c - Implement __muldc3 -------------------------------------===
+ *
+ * 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 __muldc3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+#include "int_math.h"
+
+/* Returns: the product of a + ib and c + id */
+
+COMPILER_RT_ABI double _Complex
+__muldc3(double __a, double __b, double __c, double __d)
+{
+ double __ac = __a * __c;
+ double __bd = __b * __d;
+ double __ad = __a * __d;
+ double __bc = __b * __c;
+ double _Complex z;
+ __real__ z = __ac - __bd;
+ __imag__ z = __ad + __bc;
+ if (crt_isnan(__real__ z) && crt_isnan(__imag__ z))
+ {
+ int __recalc = 0;
+ if (crt_isinf(__a) || crt_isinf(__b))
+ {
+ __a = crt_copysign(crt_isinf(__a) ? 1 : 0, __a);
+ __b = crt_copysign(crt_isinf(__b) ? 1 : 0, __b);
+ if (crt_isnan(__c))
+ __c = crt_copysign(0, __c);
+ if (crt_isnan(__d))
+ __d = crt_copysign(0, __d);
+ __recalc = 1;
+ }
+ if (crt_isinf(__c) || crt_isinf(__d))
+ {
+ __c = crt_copysign(crt_isinf(__c) ? 1 : 0, __c);
+ __d = crt_copysign(crt_isinf(__d) ? 1 : 0, __d);
+ if (crt_isnan(__a))
+ __a = crt_copysign(0, __a);
+ if (crt_isnan(__b))
+ __b = crt_copysign(0, __b);
+ __recalc = 1;
+ }
+ if (!__recalc && (crt_isinf(__ac) || crt_isinf(__bd) ||
+ crt_isinf(__ad) || crt_isinf(__bc)))
+ {
+ if (crt_isnan(__a))
+ __a = crt_copysign(0, __a);
+ if (crt_isnan(__b))
+ __b = crt_copysign(0, __b);
+ if (crt_isnan(__c))
+ __c = crt_copysign(0, __c);
+ if (crt_isnan(__d))
+ __d = crt_copysign(0, __d);
+ __recalc = 1;
+ }
+ if (__recalc)
+ {
+ __real__ z = CRT_INFINITY * (__a * __c - __b * __d);
+ __imag__ z = CRT_INFINITY * (__a * __d + __b * __c);
+ }
+ }
+ return z;
+}