10b57cec5SDimitry Andric //===-- multc3.c - Implement __multc3 -------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements __multc3 for the compiler_rt library.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
135f757f3fSDimitry Andric #define QUAD_PRECISION
145f757f3fSDimitry Andric #include "fp_lib.h"
150b57cec5SDimitry Andric #include "int_lib.h"
160b57cec5SDimitry Andric #include "int_math.h"
170b57cec5SDimitry Andric
18*c80e69b0SDimitry Andric #if defined(CRT_HAS_128BIT) && defined(CRT_HAS_F128)
195f757f3fSDimitry Andric
200b57cec5SDimitry Andric // Returns: the product of a + ib and c + id
210b57cec5SDimitry Andric
__multc3(fp_t a,fp_t b,fp_t c,fp_t d)225f757f3fSDimitry Andric COMPILER_RT_ABI Qcomplex __multc3(fp_t a, fp_t b, fp_t c, fp_t d) {
235f757f3fSDimitry Andric fp_t ac = a * c;
245f757f3fSDimitry Andric fp_t bd = b * d;
255f757f3fSDimitry Andric fp_t ad = a * d;
265f757f3fSDimitry Andric fp_t bc = b * c;
275f757f3fSDimitry Andric Qcomplex z;
285f757f3fSDimitry Andric COMPLEXTF_REAL(z) = ac - bd;
295f757f3fSDimitry Andric COMPLEXTF_IMAGINARY(z) = ad + bc;
305f757f3fSDimitry Andric if (crt_isnan(COMPLEXTF_REAL(z)) && crt_isnan(COMPLEXTF_IMAGINARY(z))) {
310b57cec5SDimitry Andric int recalc = 0;
320b57cec5SDimitry Andric if (crt_isinf(a) || crt_isinf(b)) {
335f757f3fSDimitry Andric a = crt_copysigntf(crt_isinf(a) ? 1 : 0, a);
345f757f3fSDimitry Andric b = crt_copysigntf(crt_isinf(b) ? 1 : 0, b);
350b57cec5SDimitry Andric if (crt_isnan(c))
365f757f3fSDimitry Andric c = crt_copysigntf(0, c);
370b57cec5SDimitry Andric if (crt_isnan(d))
385f757f3fSDimitry Andric d = crt_copysigntf(0, d);
390b57cec5SDimitry Andric recalc = 1;
400b57cec5SDimitry Andric }
410b57cec5SDimitry Andric if (crt_isinf(c) || crt_isinf(d)) {
425f757f3fSDimitry Andric c = crt_copysigntf(crt_isinf(c) ? 1 : 0, c);
435f757f3fSDimitry Andric d = crt_copysigntf(crt_isinf(d) ? 1 : 0, d);
440b57cec5SDimitry Andric if (crt_isnan(a))
455f757f3fSDimitry Andric a = crt_copysigntf(0, a);
460b57cec5SDimitry Andric if (crt_isnan(b))
475f757f3fSDimitry Andric b = crt_copysigntf(0, b);
480b57cec5SDimitry Andric recalc = 1;
490b57cec5SDimitry Andric }
500b57cec5SDimitry Andric if (!recalc &&
510b57cec5SDimitry Andric (crt_isinf(ac) || crt_isinf(bd) || crt_isinf(ad) || crt_isinf(bc))) {
520b57cec5SDimitry Andric if (crt_isnan(a))
535f757f3fSDimitry Andric a = crt_copysigntf(0, a);
540b57cec5SDimitry Andric if (crt_isnan(b))
555f757f3fSDimitry Andric b = crt_copysigntf(0, b);
560b57cec5SDimitry Andric if (crt_isnan(c))
575f757f3fSDimitry Andric c = crt_copysigntf(0, c);
580b57cec5SDimitry Andric if (crt_isnan(d))
595f757f3fSDimitry Andric d = crt_copysigntf(0, d);
600b57cec5SDimitry Andric recalc = 1;
610b57cec5SDimitry Andric }
620b57cec5SDimitry Andric if (recalc) {
635f757f3fSDimitry Andric COMPLEXTF_REAL(z) = CRT_INFINITY * (a * c - b * d);
645f757f3fSDimitry Andric COMPLEXTF_IMAGINARY(z) = CRT_INFINITY * (a * d + b * c);
650b57cec5SDimitry Andric }
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric return z;
680b57cec5SDimitry Andric }
695f757f3fSDimitry Andric
705f757f3fSDimitry Andric #endif
71