1 /*===-- flang/runtime/complex-reduction.c ---------------------------*- C -*-===
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
7 * ===-----------------------------------------------------------------------===
10 #include "complex-reduction.h"
13 struct CppComplexFloat
{
16 struct CppComplexDouble
{
19 struct CppComplexLongDouble
{
22 #if HAS_LDBL128 || HAS_FLOAT128
23 struct CppComplexFloat128
{
28 /* Not all environments define CMPLXF, CMPLX, CMPLXL. */
31 #if defined(__clang_major__) && (__clang_major__ >= 12)
32 #define CMPLXF __builtin_complex
34 static float_Complex_t
CMPLXF(float r
, float i
) {
36 struct CppComplexFloat x
;
37 float_Complex_t result
;
47 #if defined(__clang_major__) && (__clang_major__ >= 12)
48 #define CMPLX __builtin_complex
50 static double_Complex_t
CMPLX(double r
, double i
) {
52 struct CppComplexDouble x
;
53 double_Complex_t result
;
63 #if defined(__clang_major__) && (__clang_major__ >= 12)
64 #define CMPLXL __builtin_complex
66 static long_double_Complex_t
CMPLXL(long double r
, long double i
) {
68 struct CppComplexLongDouble x
;
69 long_double_Complex_t result
;
78 #if HAS_LDBL128 || HAS_FLOAT128
81 * GCC 7.4.0 (currently minimum GCC version for llvm builds)
82 * supports __builtin_complex. For Clang, require >=12.0.
83 * Otherwise, rely on the memory layout compatibility.
85 #if (defined(__clang_major__) && (__clang_major__ >= 12)) || \
86 (defined(__GNUC__) && !defined(__clang__))
87 #define CMPLXF128 __builtin_complex
89 static CFloat128ComplexType
CMPLXF128(CFloat128Type r
, CFloat128Type i
) {
91 struct CppComplexFloat128 x
;
92 CFloat128ComplexType result
;
102 /* RTNAME(SumComplex4) calls RTNAME(CppSumComplex4) with the same arguments
103 * and converts the members of its C++ complex result to C _Complex.
106 #define CPP_NAME(name) Cpp##name
107 #define ADAPT_REDUCTION(name, cComplex, cpptype, cmplxMacro, ARGS, ARG_NAMES) \
108 struct cpptype RTNAME(CPP_NAME(name))(struct cpptype *, ARGS); \
109 cComplex RTNAME(name)(ARGS) { \
110 struct cpptype result; \
111 RTNAME(CPP_NAME(name))(&result, ARG_NAMES); \
112 return cmplxMacro(result.r, result.i); \
115 /* TODO: COMPLEX(2 & 3) */
118 ADAPT_REDUCTION(SumComplex4
, float_Complex_t
, CppComplexFloat
, CMPLXF
,
119 REDUCTION_ARGS
, REDUCTION_ARG_NAMES
)
120 ADAPT_REDUCTION(SumComplex8
, double_Complex_t
, CppComplexDouble
, CMPLX
,
121 REDUCTION_ARGS
, REDUCTION_ARG_NAMES
)
123 ADAPT_REDUCTION(SumComplex10
, long_double_Complex_t
, CppComplexLongDouble
,
124 CMPLXL
, REDUCTION_ARGS
, REDUCTION_ARG_NAMES
)
126 #if HAS_LDBL128 || HAS_FLOAT128
127 ADAPT_REDUCTION(SumComplex16
, CFloat128ComplexType
, CppComplexFloat128
,
128 CMPLXF128
, REDUCTION_ARGS
, REDUCTION_ARG_NAMES
)
132 ADAPT_REDUCTION(ProductComplex4
, float_Complex_t
, CppComplexFloat
, CMPLXF
,
133 REDUCTION_ARGS
, REDUCTION_ARG_NAMES
)
134 ADAPT_REDUCTION(ProductComplex8
, double_Complex_t
, CppComplexDouble
, CMPLX
,
135 REDUCTION_ARGS
, REDUCTION_ARG_NAMES
)
137 ADAPT_REDUCTION(ProductComplex10
, long_double_Complex_t
, CppComplexLongDouble
,
138 CMPLXL
, REDUCTION_ARGS
, REDUCTION_ARG_NAMES
)
140 #if HAS_LDBL128 || HAS_FLOAT128
141 ADAPT_REDUCTION(ProductComplex16
, CFloat128ComplexType
, CppComplexFloat128
,
142 CMPLXF128
, REDUCTION_ARGS
, REDUCTION_ARG_NAMES
)
146 ADAPT_REDUCTION(DotProductComplex4
, float_Complex_t
, CppComplexFloat
, CMPLXF
,
147 DOT_PRODUCT_ARGS
, DOT_PRODUCT_ARG_NAMES
)
148 ADAPT_REDUCTION(DotProductComplex8
, double_Complex_t
, CppComplexDouble
, CMPLX
,
149 DOT_PRODUCT_ARGS
, DOT_PRODUCT_ARG_NAMES
)
151 ADAPT_REDUCTION(DotProductComplex10
, long_double_Complex_t
,
152 CppComplexLongDouble
, CMPLXL
, DOT_PRODUCT_ARGS
, DOT_PRODUCT_ARG_NAMES
)
154 #if HAS_LDBL128 || HAS_FLOAT128
155 ADAPT_REDUCTION(DotProductComplex16
, CFloat128ComplexType
, CppComplexFloat128
,
156 CMPLXF128
, DOT_PRODUCT_ARGS
, DOT_PRODUCT_ARG_NAMES
)
160 #define RARGS REDUCE_ARGS(float_Complex_t, float_Complex_t_ref_op)
161 ADAPT_REDUCTION(ReduceComplex4Ref
, float_Complex_t
, CppComplexFloat
, CMPLXF
,
162 RARGS
, REDUCE_ARG_NAMES
)
164 #define RARGS REDUCE_ARGS(float_Complex_t, float_Complex_t_value_op)
165 ADAPT_REDUCTION(ReduceComplex4Value
, float_Complex_t
, CppComplexFloat
, CMPLXF
,
166 RARGS
, REDUCE_ARG_NAMES
)
168 #define RARGS REDUCE_ARGS(double_Complex_t, double_Complex_t_ref_op)
169 ADAPT_REDUCTION(ReduceComplex8Ref
, double_Complex_t
, CppComplexDouble
, CMPLX
,
170 RARGS
, REDUCE_ARG_NAMES
)
172 #define RARGS REDUCE_ARGS(double_Complex_t, double_Complex_t_value_op)
173 ADAPT_REDUCTION(ReduceComplex8Value
, double_Complex_t
, CppComplexDouble
, CMPLX
,
174 RARGS
, REDUCE_ARG_NAMES
)
177 #define RARGS REDUCE_ARGS(long_double_Complex_t, long_double_Complex_t_ref_op)
178 ADAPT_REDUCTION(ReduceComplex10Ref
, long_double_Complex_t
, CppComplexLongDouble
,
179 CMPLXL
, RARGS
, REDUCE_ARG_NAMES
)
181 #define RARGS REDUCE_ARGS(long_double_Complex_t, long_double_Complex_t_value_op)
182 ADAPT_REDUCTION(ReduceComplex10Value
, long_double_Complex_t
,
183 CppComplexLongDouble
, CMPLXL
, RARGS
, REDUCE_ARG_NAMES
)
186 #if HAS_LDBL128 || HAS_FLOAT128
187 #define RARGS REDUCE_ARGS(CFloat128ComplexType, CFloat128ComplexType_ref_op)
188 ADAPT_REDUCTION(ReduceComplex16Ref
, CFloat128ComplexType
, CppComplexFloat128
,
189 CMPLXF128
, RARGS
, REDUCE_ARG_NAMES
)
191 #define RARGS REDUCE_ARGS(CFloat128ComplexType, CFloat128ComplexType_value_op)
192 ADAPT_REDUCTION(ReduceComplex16Value
, CFloat128ComplexType
, CppComplexFloat128
,
193 CMPLXF128
, RARGS
, REDUCE_ARG_NAMES
)