195 lines · c
1/*===-- lib/flang_rt/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-exception6 *7 *===----------------------------------------------------------------------===*/8 9#include "complex-reduction.h"10#include <float.h>11 12struct CppComplexFloat {13 float r, i;14};15struct CppComplexDouble {16 double r, i;17};18struct CppComplexLongDouble {19 long double r, i;20};21#if HAS_LDBL128 || HAS_FLOAT12822struct CppComplexFloat128 {23 CFloat128Type r, i;24};25#endif26 27/* Not all environments define CMPLXF, CMPLX, CMPLXL. */28 29#ifndef CMPLXF30#if defined(__clang_major__) && (__clang_major__ >= 12)31#define CMPLXF __builtin_complex32#else33static float_Complex_t CMPLXF(float r, float i) {34 union {35 struct CppComplexFloat x;36 float_Complex_t result;37 } u;38 u.x.r = r;39 u.x.i = i;40 return u.result;41}42#endif43#endif44 45#ifndef CMPLX46#if defined(__clang_major__) && (__clang_major__ >= 12)47#define CMPLX __builtin_complex48#else49static double_Complex_t CMPLX(double r, double i) {50 union {51 struct CppComplexDouble x;52 double_Complex_t result;53 } u;54 u.x.r = r;55 u.x.i = i;56 return u.result;57}58#endif59#endif60 61#ifndef CMPLXL62#if defined(__clang_major__) && (__clang_major__ >= 12)63#define CMPLXL __builtin_complex64#else65static long_double_Complex_t CMPLXL(long double r, long double i) {66 union {67 struct CppComplexLongDouble x;68 long_double_Complex_t result;69 } u;70 u.x.r = r;71 u.x.i = i;72 return u.result;73}74#endif75#endif76 77#if HAS_LDBL128 || HAS_FLOAT12878#ifndef CMPLXF12879/*80 * GCC 7.4.0 (currently minimum GCC version for llvm builds)81 * supports __builtin_complex. For Clang, require >=12.0.82 * Otherwise, rely on the memory layout compatibility.83 */84#if (defined(__clang_major__) && (__clang_major__ >= 12)) || \85 (defined(__GNUC__) && !defined(__clang__))86#define CMPLXF128 __builtin_complex87#else88static CFloat128ComplexType CMPLXF128(CFloat128Type r, CFloat128Type i) {89 union {90 struct CppComplexFloat128 x;91 CFloat128ComplexType result;92 } u;93 u.x.r = r;94 u.x.i = i;95 return u.result;96}97#endif98#endif99#endif100 101/* RTNAME(SumComplex4) calls RTNAME(CppSumComplex4) with the same arguments102 * and converts the members of its C++ complex result to C _Complex.103 */104 105#define CPP_NAME(name) Cpp##name106#define ADAPT_REDUCTION(name, cComplex, cpptype, cmplxMacro, ARGS, ARG_NAMES) \107 struct cpptype RTNAME(CPP_NAME(name))(struct cpptype *, ARGS); \108 cComplex RTNAME(name)(ARGS) { \109 struct cpptype result; \110 RTNAME(CPP_NAME(name))(&result, ARG_NAMES); \111 return cmplxMacro(result.r, result.i); \112 }113 114/* TODO: COMPLEX(2 & 3) */115 116/* SUM() */117ADAPT_REDUCTION(SumComplex4, float_Complex_t, CppComplexFloat, CMPLXF,118 REDUCTION_ARGS, REDUCTION_ARG_NAMES)119ADAPT_REDUCTION(SumComplex8, double_Complex_t, CppComplexDouble, CMPLX,120 REDUCTION_ARGS, REDUCTION_ARG_NAMES)121#if HAS_FLOAT80122ADAPT_REDUCTION(SumComplex10, long_double_Complex_t, CppComplexLongDouble,123 CMPLXL, REDUCTION_ARGS, REDUCTION_ARG_NAMES)124#endif125#if HAS_LDBL128 || HAS_FLOAT128126ADAPT_REDUCTION(SumComplex16, CFloat128ComplexType, CppComplexFloat128,127 CMPLXF128, REDUCTION_ARGS, REDUCTION_ARG_NAMES)128#endif129 130/* PRODUCT() */131ADAPT_REDUCTION(ProductComplex4, float_Complex_t, CppComplexFloat, CMPLXF,132 REDUCTION_ARGS, REDUCTION_ARG_NAMES)133ADAPT_REDUCTION(ProductComplex8, double_Complex_t, CppComplexDouble, CMPLX,134 REDUCTION_ARGS, REDUCTION_ARG_NAMES)135#if HAS_FLOAT80136ADAPT_REDUCTION(ProductComplex10, long_double_Complex_t, CppComplexLongDouble,137 CMPLXL, REDUCTION_ARGS, REDUCTION_ARG_NAMES)138#endif139#if HAS_LDBL128 || HAS_FLOAT128140ADAPT_REDUCTION(ProductComplex16, CFloat128ComplexType, CppComplexFloat128,141 CMPLXF128, REDUCTION_ARGS, REDUCTION_ARG_NAMES)142#endif143 144/* DOT_PRODUCT() */145ADAPT_REDUCTION(DotProductComplex4, float_Complex_t, CppComplexFloat, CMPLXF,146 DOT_PRODUCT_ARGS, DOT_PRODUCT_ARG_NAMES)147ADAPT_REDUCTION(DotProductComplex8, double_Complex_t, CppComplexDouble, CMPLX,148 DOT_PRODUCT_ARGS, DOT_PRODUCT_ARG_NAMES)149#if HAS_FLOAT80150ADAPT_REDUCTION(DotProductComplex10, long_double_Complex_t,151 CppComplexLongDouble, CMPLXL, DOT_PRODUCT_ARGS, DOT_PRODUCT_ARG_NAMES)152#endif153#if HAS_LDBL128 || HAS_FLOAT128154ADAPT_REDUCTION(DotProductComplex16, CFloat128ComplexType, CppComplexFloat128,155 CMPLXF128, DOT_PRODUCT_ARGS, DOT_PRODUCT_ARG_NAMES)156#endif157 158/* REDUCE() */159#define RARGS REDUCE_ARGS(float_Complex_t, float_Complex_t_ref_op)160ADAPT_REDUCTION(ReduceComplex4Ref, float_Complex_t, CppComplexFloat, CMPLXF,161 RARGS, REDUCE_ARG_NAMES)162#undef RARGS163#define RARGS REDUCE_ARGS(float_Complex_t, float_Complex_t_value_op)164ADAPT_REDUCTION(ReduceComplex4Value, float_Complex_t, CppComplexFloat, CMPLXF,165 RARGS, REDUCE_ARG_NAMES)166#undef RARGS167#define RARGS REDUCE_ARGS(double_Complex_t, double_Complex_t_ref_op)168ADAPT_REDUCTION(ReduceComplex8Ref, double_Complex_t, CppComplexDouble, CMPLX,169 RARGS, REDUCE_ARG_NAMES)170#undef RARGS171#define RARGS REDUCE_ARGS(double_Complex_t, double_Complex_t_value_op)172ADAPT_REDUCTION(ReduceComplex8Value, double_Complex_t, CppComplexDouble, CMPLX,173 RARGS, REDUCE_ARG_NAMES)174#undef RARGS175#if HAS_FLOAT80176#define RARGS REDUCE_ARGS(long_double_Complex_t, long_double_Complex_t_ref_op)177ADAPT_REDUCTION(ReduceComplex10Ref, long_double_Complex_t, CppComplexLongDouble,178 CMPLXL, RARGS, REDUCE_ARG_NAMES)179#undef RARGS180#define RARGS REDUCE_ARGS(long_double_Complex_t, long_double_Complex_t_value_op)181ADAPT_REDUCTION(ReduceComplex10Value, long_double_Complex_t,182 CppComplexLongDouble, CMPLXL, RARGS, REDUCE_ARG_NAMES)183#undef RARGS184#endif185#if HAS_LDBL128 || HAS_FLOAT128186#define RARGS REDUCE_ARGS(CFloat128ComplexType, CFloat128ComplexType_ref_op)187ADAPT_REDUCTION(ReduceComplex16Ref, CFloat128ComplexType, CppComplexFloat128,188 CMPLXF128, RARGS, REDUCE_ARG_NAMES)189#undef RARGS190#define RARGS REDUCE_ARGS(CFloat128ComplexType, CFloat128ComplexType_value_op)191ADAPT_REDUCTION(ReduceComplex16Value, CFloat128ComplexType, CppComplexFloat128,192 CMPLXF128, RARGS, REDUCE_ARG_NAMES)193#undef RARGS194#endif195