1/*===-- flang/runtime/complex-reduction.c ---------------------------*- C -*-===
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
10#include "complex-reduction.h"
11#include <float.h>
12
13struct CppComplexFloat {
14 float r, i;
15};
16struct CppComplexDouble {
17 double r, i;
18};
19struct CppComplexLongDouble {
20 long double r, i;
21};
22
23/* Not all environments define CMPLXF, CMPLX, CMPLXL. */
24
25#ifndef CMPLXF
26#if defined(__clang_major__) && (__clang_major__ >= 12)
27#define CMPLXF __builtin_complex
28#else
29static float_Complex_t CMPLXF(float r, float i) {
30 union {
31 struct CppComplexFloat x;
32 float_Complex_t result;
33 } u;
34 u.x.r = r;
35 u.x.i = i;
36 return u.result;
37}
38#endif
39#endif
40
41#ifndef CMPLX
42#if defined(__clang_major__) && (__clang_major__ >= 12)
43#define CMPLX __builtin_complex
44#else
45static double_Complex_t CMPLX(double r, double i) {
46 union {
47 struct CppComplexDouble x;
48 double_Complex_t result;
49 } u;
50 u.x.r = r;
51 u.x.i = i;
52 return u.result;
53}
54#endif
55#endif
56
57#ifndef CMPLXL
58#if defined(__clang_major__) && (__clang_major__ >= 12)
59#define CMPLXL __builtin_complex
60#else
61static long_double_Complex_t CMPLXL(long double r, long double i) {
62 union {
63 struct CppComplexLongDouble x;
64 long_double_Complex_t result;
65 } u;
66 u.x.r = r;
67 u.x.i = i;
68 return u.result;
69}
70#endif
71#endif
72
73/* RTNAME(SumComplex4) calls RTNAME(CppSumComplex4) with the same arguments
74 * and converts the members of its C++ complex result to C _Complex.
75 */
76
77#define CPP_NAME(name) Cpp##name
78#define ADAPT_REDUCTION(name, cComplex, cpptype, cmplxMacro, ARGS, ARG_NAMES) \
79 struct cpptype RTNAME(CPP_NAME(name))(struct cpptype *, ARGS); \
80 cComplex RTNAME(name)(ARGS) { \
81 struct cpptype result; \
82 RTNAME(CPP_NAME(name))(&result, ARG_NAMES); \
83 return cmplxMacro(result.r, result.i); \
84 }
85
86/* TODO: COMPLEX(2 & 3) */
87
88/* SUM() */
89ADAPT_REDUCTION(SumComplex4, float_Complex_t, CppComplexFloat, CMPLXF,
90 REDUCTION_ARGS, REDUCTION_ARG_NAMES)
91ADAPT_REDUCTION(SumComplex8, double_Complex_t, CppComplexDouble, CMPLX,
92 REDUCTION_ARGS, REDUCTION_ARG_NAMES)
93#if LDBL_MANT_DIG == 64
94ADAPT_REDUCTION(SumComplex10, long_double_Complex_t, CppComplexLongDouble,
95 CMPLXL, REDUCTION_ARGS, REDUCTION_ARG_NAMES)
96#elif LDBL_MANT_DIG == 113
97ADAPT_REDUCTION(SumComplex16, long_double_Complex_t, CppComplexLongDouble,
98 CMPLXL, REDUCTION_ARGS, REDUCTION_ARG_NAMES)
99#endif
100
101/* PRODUCT() */
102ADAPT_REDUCTION(ProductComplex4, float_Complex_t, CppComplexFloat, CMPLXF,
103 REDUCTION_ARGS, REDUCTION_ARG_NAMES)
104ADAPT_REDUCTION(ProductComplex8, double_Complex_t, CppComplexDouble, CMPLX,
105 REDUCTION_ARGS, REDUCTION_ARG_NAMES)
106#if LDBL_MANT_DIG == 64
107ADAPT_REDUCTION(ProductComplex10, long_double_Complex_t, CppComplexLongDouble,
108 CMPLXL, REDUCTION_ARGS, REDUCTION_ARG_NAMES)
109#elif LDBL_MANT_DIG == 113
110ADAPT_REDUCTION(ProductComplex16, long_double_Complex_t, CppComplexLongDouble,
111 CMPLXL, REDUCTION_ARGS, REDUCTION_ARG_NAMES)
112#endif
113
114/* DOT_PRODUCT() */
115ADAPT_REDUCTION(DotProductComplex4, float_Complex_t, CppComplexFloat, CMPLXF,
116 DOT_PRODUCT_ARGS, DOT_PRODUCT_ARG_NAMES)
117ADAPT_REDUCTION(DotProductComplex8, double_Complex_t, CppComplexDouble, CMPLX,
118 DOT_PRODUCT_ARGS, DOT_PRODUCT_ARG_NAMES)
119#if LDBL_MANT_DIG == 64
120ADAPT_REDUCTION(DotProductComplex10, long_double_Complex_t,
121 CppComplexLongDouble, CMPLXL, DOT_PRODUCT_ARGS, DOT_PRODUCT_ARG_NAMES)
122#elif LDBL_MANT_DIG == 113
123ADAPT_REDUCTION(DotProductComplex16, long_double_Complex_t,
124 CppComplexLongDouble, CMPLXL, DOT_PRODUCT_ARGS, DOT_PRODUCT_ARG_NAMES)
125#endif
126

source code of flang/runtime/complex-reduction.c