blob: bf3ea1da8b1e0b86f04df58b01ce04efc037c871 [file] [log] [blame]
Edward O'Callaghan37a6a452009-08-07 20:30:09 +00001/* ===-- mulsc3.c - Implement __mulsc3 -------------------------------------===
2 *
Chandler Carruth7a739a02019-01-19 10:56:40 +00003 * 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
Edward O'Callaghan37a6a452009-08-07 20:30:09 +00006 *
7 * ===----------------------------------------------------------------------===
8 *
9 * This file implements __mulsc3 for the compiler_rt library.
10 *
11 * ===----------------------------------------------------------------------===
12 */
Daniel Dunbarb3a69012009-06-26 16:47:03 +000013
14#include "int_lib.h"
Daniel Dunbar86030242011-11-16 07:33:00 +000015#include "int_math.h"
Daniel Dunbarb3a69012009-06-26 16:47:03 +000016
Edward O'Callaghan37a6a452009-08-07 20:30:09 +000017/* Returns: the product of a + ib and c + id */
Daniel Dunbarb3a69012009-06-26 16:47:03 +000018
Saleem Abdulrasool363d7352015-10-07 02:58:07 +000019COMPILER_RT_ABI Fcomplex
Daniel Dunbarb3a69012009-06-26 16:47:03 +000020__mulsc3(float __a, float __b, float __c, float __d)
21{
22 float __ac = __a * __c;
23 float __bd = __b * __d;
24 float __ad = __a * __d;
25 float __bc = __b * __c;
Saleem Abdulrasool363d7352015-10-07 02:58:07 +000026 Fcomplex z;
27 COMPLEX_REAL(z) = __ac - __bd;
28 COMPLEX_IMAGINARY(z) = __ad + __bc;
29 if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z)))
Daniel Dunbarb3a69012009-06-26 16:47:03 +000030 {
31 int __recalc = 0;
Daniel Dunbar86030242011-11-16 07:33:00 +000032 if (crt_isinf(__a) || crt_isinf(__b))
Daniel Dunbarb3a69012009-06-26 16:47:03 +000033 {
Daniel Dunbarc25c6d12011-11-16 07:33:06 +000034 __a = crt_copysignf(crt_isinf(__a) ? 1 : 0, __a);
35 __b = crt_copysignf(crt_isinf(__b) ? 1 : 0, __b);
Daniel Dunbar86030242011-11-16 07:33:00 +000036 if (crt_isnan(__c))
Daniel Dunbarc25c6d12011-11-16 07:33:06 +000037 __c = crt_copysignf(0, __c);
Daniel Dunbar86030242011-11-16 07:33:00 +000038 if (crt_isnan(__d))
Daniel Dunbarc25c6d12011-11-16 07:33:06 +000039 __d = crt_copysignf(0, __d);
Daniel Dunbarb3a69012009-06-26 16:47:03 +000040 __recalc = 1;
41 }
Daniel Dunbar86030242011-11-16 07:33:00 +000042 if (crt_isinf(__c) || crt_isinf(__d))
Daniel Dunbarb3a69012009-06-26 16:47:03 +000043 {
Daniel Dunbarc25c6d12011-11-16 07:33:06 +000044 __c = crt_copysignf(crt_isinf(__c) ? 1 : 0, __c);
45 __d = crt_copysignf(crt_isinf(__d) ? 1 : 0, __d);
Daniel Dunbar86030242011-11-16 07:33:00 +000046 if (crt_isnan(__a))
Daniel Dunbarc25c6d12011-11-16 07:33:06 +000047 __a = crt_copysignf(0, __a);
Daniel Dunbar86030242011-11-16 07:33:00 +000048 if (crt_isnan(__b))
Daniel Dunbarc25c6d12011-11-16 07:33:06 +000049 __b = crt_copysignf(0, __b);
Daniel Dunbarb3a69012009-06-26 16:47:03 +000050 __recalc = 1;
51 }
Daniel Dunbar86030242011-11-16 07:33:00 +000052 if (!__recalc && (crt_isinf(__ac) || crt_isinf(__bd) ||
53 crt_isinf(__ad) || crt_isinf(__bc)))
Daniel Dunbarb3a69012009-06-26 16:47:03 +000054 {
Daniel Dunbar86030242011-11-16 07:33:00 +000055 if (crt_isnan(__a))
Daniel Dunbarc25c6d12011-11-16 07:33:06 +000056 __a = crt_copysignf(0, __a);
Daniel Dunbar86030242011-11-16 07:33:00 +000057 if (crt_isnan(__b))
Daniel Dunbarc25c6d12011-11-16 07:33:06 +000058 __b = crt_copysignf(0, __b);
Daniel Dunbar86030242011-11-16 07:33:00 +000059 if (crt_isnan(__c))
Daniel Dunbarc25c6d12011-11-16 07:33:06 +000060 __c = crt_copysignf(0, __c);
Daniel Dunbar86030242011-11-16 07:33:00 +000061 if (crt_isnan(__d))
Daniel Dunbarc25c6d12011-11-16 07:33:06 +000062 __d = crt_copysignf(0, __d);
Daniel Dunbarb3a69012009-06-26 16:47:03 +000063 __recalc = 1;
64 }
65 if (__recalc)
66 {
Saleem Abdulrasool363d7352015-10-07 02:58:07 +000067 COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c - __b * __d);
68 COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__a * __d + __b * __c);
Daniel Dunbarb3a69012009-06-26 16:47:03 +000069 }
70 }
71 return z;
72}