xref: /freebsd/contrib/llvm-project/compiler-rt/lib/builtins/multc3.c (revision 7ab1a32cd43cbae61ad4dd435d6a482bbf61cb52)
1 //===-- multc3.c - Implement __multc3 -------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements __multc3 for the compiler_rt library.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #define QUAD_PRECISION
14 #include "fp_lib.h"
15 #include "int_lib.h"
16 #include "int_math.h"
17 
18 #if defined(CRT_HAS_128BIT) && defined(CRT_HAS_F128)
19 
20 // Returns: the product of a + ib and c + id
21 
22 COMPILER_RT_ABI Qcomplex __multc3(fp_t a, fp_t b, fp_t c, fp_t d) {
23   fp_t ac = a * c;
24   fp_t bd = b * d;
25   fp_t ad = a * d;
26   fp_t bc = b * c;
27   Qcomplex z;
28   COMPLEXTF_REAL(z) = ac - bd;
29   COMPLEXTF_IMAGINARY(z) = ad + bc;
30   if (crt_isnan(COMPLEXTF_REAL(z)) && crt_isnan(COMPLEXTF_IMAGINARY(z))) {
31     int recalc = 0;
32     if (crt_isinf(a) || crt_isinf(b)) {
33       a = crt_copysigntf(crt_isinf(a) ? 1 : 0, a);
34       b = crt_copysigntf(crt_isinf(b) ? 1 : 0, b);
35       if (crt_isnan(c))
36         c = crt_copysigntf(0, c);
37       if (crt_isnan(d))
38         d = crt_copysigntf(0, d);
39       recalc = 1;
40     }
41     if (crt_isinf(c) || crt_isinf(d)) {
42       c = crt_copysigntf(crt_isinf(c) ? 1 : 0, c);
43       d = crt_copysigntf(crt_isinf(d) ? 1 : 0, d);
44       if (crt_isnan(a))
45         a = crt_copysigntf(0, a);
46       if (crt_isnan(b))
47         b = crt_copysigntf(0, b);
48       recalc = 1;
49     }
50     if (!recalc &&
51         (crt_isinf(ac) || crt_isinf(bd) || crt_isinf(ad) || crt_isinf(bc))) {
52       if (crt_isnan(a))
53         a = crt_copysigntf(0, a);
54       if (crt_isnan(b))
55         b = crt_copysigntf(0, b);
56       if (crt_isnan(c))
57         c = crt_copysigntf(0, c);
58       if (crt_isnan(d))
59         d = crt_copysigntf(0, d);
60       recalc = 1;
61     }
62     if (recalc) {
63       COMPLEXTF_REAL(z) = CRT_INFINITY * (a * c - b * d);
64       COMPLEXTF_IMAGINARY(z) = CRT_INFINITY * (a * d + b * c);
65     }
66   }
67   return z;
68 }
69 
70 #endif
71