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 "flang/Common/long-double.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 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 29 static 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 45 static 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 61 static 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() */ 89 ADAPT_REDUCTION(SumComplex4, float_Complex_t, CppComplexFloat, CMPLXF, 90 REDUCTION_ARGS, REDUCTION_ARG_NAMES) 91 ADAPT_REDUCTION(SumComplex8, double_Complex_t, CppComplexDouble, CMPLX, 92 REDUCTION_ARGS, REDUCTION_ARG_NAMES) 93 #if LONG_DOUBLE == 80 94 ADAPT_REDUCTION(SumComplex10, long_double_Complex_t, CppComplexLongDouble, 95 CMPLXL, REDUCTION_ARGS, REDUCTION_ARG_NAMES) 96 #elif LONG_DOUBLE == 128 97 ADAPT_REDUCTION(SumComplex16, long_double_Complex_t, CppComplexLongDouble, 98 CMPLXL, REDUCTION_ARGS, REDUCTION_ARG_NAMES) 99 #endif 100 101 /* PRODUCT() */ 102 ADAPT_REDUCTION(ProductComplex4, float_Complex_t, CppComplexFloat, CMPLXF, 103 REDUCTION_ARGS, REDUCTION_ARG_NAMES) 104 ADAPT_REDUCTION(ProductComplex8, double_Complex_t, CppComplexDouble, CMPLX, 105 REDUCTION_ARGS, REDUCTION_ARG_NAMES) 106 #if LONG_DOUBLE == 80 107 ADAPT_REDUCTION(ProductComplex10, long_double_Complex_t, CppComplexLongDouble, 108 CMPLXL, REDUCTION_ARGS, REDUCTION_ARG_NAMES) 109 #elif LONG_DOUBLE == 128 110 ADAPT_REDUCTION(ProductComplex16, long_double_Complex_t, CppComplexLongDouble, 111 CMPLXL, REDUCTION_ARGS, REDUCTION_ARG_NAMES) 112 #endif 113 114 /* DOT_PRODUCT() */ 115 ADAPT_REDUCTION(DotProductComplex4, float_Complex_t, CppComplexFloat, CMPLXF, 116 DOT_PRODUCT_ARGS, DOT_PRODUCT_ARG_NAMES) 117 ADAPT_REDUCTION(DotProductComplex8, double_Complex_t, CppComplexDouble, CMPLX, 118 DOT_PRODUCT_ARGS, DOT_PRODUCT_ARG_NAMES) 119 #if LONG_DOUBLE == 80 120 ADAPT_REDUCTION(DotProductComplex10, long_double_Complex_t, 121 CppComplexLongDouble, CMPLXL, DOT_PRODUCT_ARGS, DOT_PRODUCT_ARG_NAMES) 122 #elif LONG_DOUBLE == 128 123 ADAPT_REDUCTION(DotProductComplex16, long_double_Complex_t, 124 CppComplexLongDouble, CMPLXL, DOT_PRODUCT_ARGS, DOT_PRODUCT_ARG_NAMES) 125 #endif 126