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 13 struct CppComplexFloat { 14 float r, i; 15 }; 16 struct CppComplexDouble { 17 double r, i; 18 }; 19 struct CppComplexLongDouble { 20 long double r, i; 21 }; 22 #if HAS_LDBL128 || HAS_FLOAT128 23 struct CppComplexFloat128 { 24 CFloat128Type r, i; 25 }; 26 #endif 27 28 /* Not all environments define CMPLXF, CMPLX, CMPLXL. */ 29 30 #ifndef CMPLXF 31 #if defined(__clang_major__) && (__clang_major__ >= 12) 32 #define CMPLXF __builtin_complex 33 #else 34 static float_Complex_t CMPLXF(float r, float i) { 35 union { 36 struct CppComplexFloat x; 37 float_Complex_t result; 38 } u; 39 u.x.r = r; 40 u.x.i = i; 41 return u.result; 42 } 43 #endif 44 #endif 45 46 #ifndef CMPLX 47 #if defined(__clang_major__) && (__clang_major__ >= 12) 48 #define CMPLX __builtin_complex 49 #else 50 static double_Complex_t CMPLX(double r, double i) { 51 union { 52 struct CppComplexDouble x; 53 double_Complex_t result; 54 } u; 55 u.x.r = r; 56 u.x.i = i; 57 return u.result; 58 } 59 #endif 60 #endif 61 62 #ifndef CMPLXL 63 #if defined(__clang_major__) && (__clang_major__ >= 12) 64 #define CMPLXL __builtin_complex 65 #else 66 static long_double_Complex_t CMPLXL(long double r, long double i) { 67 union { 68 struct CppComplexLongDouble x; 69 long_double_Complex_t result; 70 } u; 71 u.x.r = r; 72 u.x.i = i; 73 return u.result; 74 } 75 #endif 76 #endif 77 78 #if HAS_LDBL128 || HAS_FLOAT128 79 #ifndef CMPLXF128 80 /* 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. 84 */ 85 #if (defined(__clang_major__) && (__clang_major__ >= 12)) || \ 86 (defined(__GNUC__) && !defined(__clang__)) 87 #define CMPLXF128 __builtin_complex 88 #else 89 static CFloat128ComplexType CMPLXF128(CFloat128Type r, CFloat128Type i) { 90 union { 91 struct CppComplexFloat128 x; 92 CFloat128ComplexType result; 93 } u; 94 u.x.r = r; 95 u.x.i = i; 96 return u.result; 97 } 98 #endif 99 #endif 100 #endif 101 102 /* RTNAME(SumComplex4) calls RTNAME(CppSumComplex4) with the same arguments 103 * and converts the members of its C++ complex result to C _Complex. 104 */ 105 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); \ 113 } 114 115 /* TODO: COMPLEX(2 & 3) */ 116 117 /* SUM() */ 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) 122 #if HAS_FLOAT80 123 ADAPT_REDUCTION(SumComplex10, long_double_Complex_t, CppComplexLongDouble, 124 CMPLXL, REDUCTION_ARGS, REDUCTION_ARG_NAMES) 125 #endif 126 #if HAS_LDBL128 || HAS_FLOAT128 127 ADAPT_REDUCTION(SumComplex16, CFloat128ComplexType, CppComplexFloat128, 128 CMPLXF128, REDUCTION_ARGS, REDUCTION_ARG_NAMES) 129 #endif 130 131 /* PRODUCT() */ 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) 136 #if HAS_FLOAT80 137 ADAPT_REDUCTION(ProductComplex10, long_double_Complex_t, CppComplexLongDouble, 138 CMPLXL, REDUCTION_ARGS, REDUCTION_ARG_NAMES) 139 #endif 140 #if HAS_LDBL128 || HAS_FLOAT128 141 ADAPT_REDUCTION(ProductComplex16, CFloat128ComplexType, CppComplexFloat128, 142 CMPLXF128, REDUCTION_ARGS, REDUCTION_ARG_NAMES) 143 #endif 144 145 /* DOT_PRODUCT() */ 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) 150 #if HAS_FLOAT80 151 ADAPT_REDUCTION(DotProductComplex10, long_double_Complex_t, 152 CppComplexLongDouble, CMPLXL, DOT_PRODUCT_ARGS, DOT_PRODUCT_ARG_NAMES) 153 #endif 154 #if HAS_LDBL128 || HAS_FLOAT128 155 ADAPT_REDUCTION(DotProductComplex16, CFloat128ComplexType, CppComplexFloat128, 156 CMPLXF128, DOT_PRODUCT_ARGS, DOT_PRODUCT_ARG_NAMES) 157 #endif 158 159 /* REDUCE() */ 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) 163 #undef RARGS 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) 167 #undef RARGS 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) 171 #undef RARGS 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) 175 #undef RARGS 176 #if HAS_FLOAT80 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) 180 #undef RARGS 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) 184 #undef RARGS 185 #endif 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) 190 #undef RARGS 191 #define RARGS REDUCE_ARGS(CFloat128ComplexType, CFloat128ComplexType_value_op) 192 ADAPT_REDUCTION(ReduceComplex16Value, CFloat128ComplexType, CppComplexFloat128, 193 CMPLXF128, RARGS, REDUCE_ARG_NAMES) 194 #undef RARGS 195 #endif 196