[flang][runtime] Use __float128 where possible & needed in runtime

On targets with __float128 available and distinct from long double,
use it to support more kind=16 entry points.  This affects mostly
x86-64 targets.  This means that more runtime entry points are
defined for lowering to call.

Delete Common/long-double.h and its LONG_DOUBLE macro in favor of
testing the standard macro LDBL_MANT_DIG.

Differential Revision: https://reviews.llvm.org/D127025
This commit is contained in:
Peter Klausler 2022-05-31 14:06:11 -07:00
parent 30f19382c6
commit 4daa33f6d1
16 changed files with 306 additions and 139 deletions

View File

@ -1,23 +0,0 @@
/*===-- include/flang/Common/config.h -------------------------------*- C -*-===
*
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
* See https://llvm.org/LICENSE.txt for license information.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*
* ===-----------------------------------------------------------------------===
*/
/* This header can be used by both C and C++. */
#ifndef FORTRAN_COMMON_LONG_DOUBLE_H
#define FORTRAN_COMMON_LONG_DOUBLE_H
#ifdef _MSC_VER /* no long double */
#undef LONG_DOUBLE
#elif __x86_64__ /* x87 extended precision */
#define LONG_DOUBLE 80
#else
#define LONG_DOUBLE 128
#endif
#endif /* FORTRAN_COMMON_LONG_DOUBLE_H */

View File

@ -13,8 +13,11 @@
#include "flang/Common/Fortran.h"
#include "flang/Common/uint128.h"
#include "flang/Runtime/float128.h"
#include <cfloat>
#include <complex>
#include <cstdint>
#include <type_traits>
namespace Fortran::runtime {
@ -24,6 +27,12 @@ template <TypeCategory CAT, int KIND> struct CppTypeForHelper {};
template <TypeCategory CAT, int KIND>
using CppTypeFor = typename CppTypeForHelper<CAT, KIND>::type;
template <TypeCategory CAT, int KIND, bool SFINAE = false>
constexpr bool HasCppTypeFor{false};
template <TypeCategory CAT, int KIND>
constexpr bool HasCppTypeFor<CAT, KIND, true>{
!std::is_void_v<typename CppTypeForHelper<CAT, KIND>::type>};
template <int KIND> struct CppTypeForHelper<TypeCategory::Integer, KIND> {
using type = common::HostSignedIntType<8 * KIND>;
};
@ -35,12 +44,21 @@ template <> struct CppTypeForHelper<TypeCategory::Real, 4> {
template <> struct CppTypeForHelper<TypeCategory::Real, 8> {
using type = double;
};
#if LDBL_MANT_DIG == 64
template <> struct CppTypeForHelper<TypeCategory::Real, 10> {
using type = long double;
};
#endif
#if LDBL_MANT_DIG == 113
using CppFloat128Type = long double;
#elif HAS_FLOAT128
using CppFloat128Type = __float128;
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
template <> struct CppTypeForHelper<TypeCategory::Real, 16> {
using type = long double;
using type = CppFloat128Type;
};
#endif
template <int KIND> struct CppTypeForHelper<TypeCategory::Complex, KIND> {
using type = std::complex<CppTypeFor<TypeCategory::Real, KIND>>;

View File

@ -0,0 +1,32 @@
/*===-- flang/Runtime/float128.h ----------------------------------*- C -*-===
*
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
* See https://llvm.org/LICENSE.txt for license information.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*
*===----------------------------------------------------------------------===*/
/* This header is usable in both C and C++ code.
* Isolates build compiler checks to determine the presence of an IEEE-754
* quad-precision type named __float128 type that isn't __ibm128
* (double/double). We don't care whether the type has underlying hardware
* support or is emulated.
*
* 128-bit arithmetic may be available via "long double"; this can
* be determined by LDBL_MANT_DIG == 113. A machine may have both 128-bit
* long double and __float128; prefer long double by testing for it first.
*/
#ifndef FORTRAN_RUNTIME_FLOAT128_H_
#define FORTRAN_RUNTIME_FLOAT128_H_
#undef HAS_FLOAT128
#if __x86_64__
#if __GNUC__ >= 7 || __clang_major >= 7
#define HAS_FLOAT128 1
#endif
#elif defined __PPC__ && __GNUC__ >= 8
#define HAS_FLOAT128 1
#endif
#endif /* FORTRAN_RUNTIME_FLOAT128_H_ */

View File

@ -23,60 +23,84 @@ CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint4_4)(
CppTypeFor<TypeCategory::Real, 4>);
CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint4_8)(
CppTypeFor<TypeCategory::Real, 4>);
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint4_10)(
CppTypeFor<TypeCategory::Real, 4>);
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint4_16)(
CppTypeFor<TypeCategory::Real, 4>);
#endif
CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint8_4)(
CppTypeFor<TypeCategory::Real, 8>);
CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint8_8)(
CppTypeFor<TypeCategory::Real, 8>);
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint8_10)(
CppTypeFor<TypeCategory::Real, 8>);
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint8_16)(
CppTypeFor<TypeCategory::Real, 8>);
#endif
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint10_4)(
CppTypeFor<TypeCategory::Real, 10>);
CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint10_8)(
CppTypeFor<TypeCategory::Real, 10>);
CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint10_10)(
CppTypeFor<TypeCategory::Real, 10>);
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint16_4)(
CppTypeFor<TypeCategory::Real, 16>);
CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint16_8)(
CppTypeFor<TypeCategory::Real, 16>);
CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint16_16)(
CppTypeFor<TypeCategory::Real, 16>);
#endif
// ANINT
CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint4_4)(
CppTypeFor<TypeCategory::Real, 4>);
CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint4_8)(
CppTypeFor<TypeCategory::Real, 4>);
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint4_10)(
CppTypeFor<TypeCategory::Real, 4>);
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint4_16)(
CppTypeFor<TypeCategory::Real, 4>);
#endif
CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint8_4)(
CppTypeFor<TypeCategory::Real, 8>);
CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint8_8)(
CppTypeFor<TypeCategory::Real, 8>);
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint8_10)(
CppTypeFor<TypeCategory::Real, 8>);
#endif
#if LDBL_MANT_DIG == 113
CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint8_16)(
CppTypeFor<TypeCategory::Real, 8>);
#endif
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint10_4)(
CppTypeFor<TypeCategory::Real, 10>);
CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint10_8)(
CppTypeFor<TypeCategory::Real, 10>);
CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint10_10)(
CppTypeFor<TypeCategory::Real, 10>);
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint16_4)(
CppTypeFor<TypeCategory::Real, 16>);
CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint16_8)(
CppTypeFor<TypeCategory::Real, 16>);
CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint16_16)(
CppTypeFor<TypeCategory::Real, 16>);
#endif
// CEILING
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling4_1)(
@ -103,6 +127,7 @@ CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling8_8)(
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling8_16)(
CppTypeFor<TypeCategory::Real, 8>);
#endif
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling10_1)(
CppTypeFor<TypeCategory::Real, 10>);
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Ceiling10_2)(
@ -115,6 +140,8 @@ CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling10_8)(
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling10_16)(
CppTypeFor<TypeCategory::Real, 10>);
#endif
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling16_1)(
CppTypeFor<TypeCategory::Real, 16>);
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Ceiling16_2)(
@ -127,6 +154,7 @@ CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling16_8)(
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling16_16)(
CppTypeFor<TypeCategory::Real, 16>);
#endif
#endif
// EXPONENT is defined to return default INTEGER; support INTEGER(4 & 8)
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent4_4)(
@ -137,14 +165,18 @@ CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent8_4)(
CppTypeFor<TypeCategory::Real, 8>);
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent8_8)(
CppTypeFor<TypeCategory::Real, 8>);
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent10_4)(
CppTypeFor<TypeCategory::Real, 10>);
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent10_8)(
CppTypeFor<TypeCategory::Real, 10>);
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent16_4)(
CppTypeFor<TypeCategory::Real, 16>);
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent16_8)(
CppTypeFor<TypeCategory::Real, 16>);
#endif
// FLOOR
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor4_1)(
@ -171,6 +203,7 @@ CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor8_8)(
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor8_16)(
CppTypeFor<TypeCategory::Real, 8>);
#endif
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor10_1)(
CppTypeFor<TypeCategory::Real, 10>);
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Floor10_2)(
@ -183,6 +216,8 @@ CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor10_8)(
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor10_16)(
CppTypeFor<TypeCategory::Real, 10>);
#endif
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor16_1)(
CppTypeFor<TypeCategory::Real, 16>);
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Floor16_2)(
@ -195,22 +230,31 @@ CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor16_8)(
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor16_16)(
CppTypeFor<TypeCategory::Real, 16>);
#endif
#endif
// FRACTION
CppTypeFor<TypeCategory::Real, 4> RTNAME(Fraction4)(
CppTypeFor<TypeCategory::Real, 4>);
CppTypeFor<TypeCategory::Real, 8> RTNAME(Fraction8)(
CppTypeFor<TypeCategory::Real, 8>);
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(Fraction10)(
CppTypeFor<TypeCategory::Real, 10>);
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppTypeFor<TypeCategory::Real, 16> RTNAME(Fraction16)(
CppTypeFor<TypeCategory::Real, 16>);
#endif
// ISNAN / IEEE_IS_NAN
bool RTNAME(IsNaN4)(CppTypeFor<TypeCategory::Real, 4>);
bool RTNAME(IsNaN8)(CppTypeFor<TypeCategory::Real, 8>);
#if LDBL_MANT_DIG == 64
bool RTNAME(IsNaN10)(CppTypeFor<TypeCategory::Real, 10>);
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
bool RTNAME(IsNaN16)(CppTypeFor<TypeCategory::Real, 16>);
#endif
// MOD & MODULO
CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModInteger1)(
@ -237,12 +281,16 @@ CppTypeFor<TypeCategory::Real, 4> RTNAME(ModReal4)(
CppTypeFor<TypeCategory::Real, 8> RTNAME(ModReal8)(
CppTypeFor<TypeCategory::Real, 8>, CppTypeFor<TypeCategory::Real, 8>,
const char *sourceFile = nullptr, int sourceLine = 0);
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(ModReal10)(
CppTypeFor<TypeCategory::Real, 10>, CppTypeFor<TypeCategory::Real, 10>,
const char *sourceFile = nullptr, int sourceLine = 0);
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppTypeFor<TypeCategory::Real, 16> RTNAME(ModReal16)(
CppTypeFor<TypeCategory::Real, 16>, CppTypeFor<TypeCategory::Real, 16>,
const char *sourceFile = nullptr, int sourceLine = 0);
#endif
CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModuloInteger1)(
CppTypeFor<TypeCategory::Integer, 1>, CppTypeFor<TypeCategory::Integer, 1>,
@ -268,12 +316,16 @@ CppTypeFor<TypeCategory::Real, 4> RTNAME(ModuloReal4)(
CppTypeFor<TypeCategory::Real, 8> RTNAME(ModuloReal8)(
CppTypeFor<TypeCategory::Real, 8>, CppTypeFor<TypeCategory::Real, 8>,
const char *sourceFile = nullptr, int sourceLine = 0);
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(ModuloReal10)(
CppTypeFor<TypeCategory::Real, 10>, CppTypeFor<TypeCategory::Real, 10>,
const char *sourceFile = nullptr, int sourceLine = 0);
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppTypeFor<TypeCategory::Real, 16> RTNAME(ModuloReal16)(
CppTypeFor<TypeCategory::Real, 16>, CppTypeFor<TypeCategory::Real, 16>,
const char *sourceFile = nullptr, int sourceLine = 0);
#endif
// NINT
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint4_1)(
@ -300,6 +352,7 @@ CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint8_8)(
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint8_16)(
CppTypeFor<TypeCategory::Real, 8>);
#endif
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint10_1)(
CppTypeFor<TypeCategory::Real, 10>);
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint10_2)(
@ -312,6 +365,8 @@ CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint10_8)(
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint10_16)(
CppTypeFor<TypeCategory::Real, 10>);
#endif
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint16_1)(
CppTypeFor<TypeCategory::Real, 16>);
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint16_2)(
@ -320,10 +375,11 @@ CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint16_4)(
CppTypeFor<TypeCategory::Real, 16>);
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint16_8)(
CppTypeFor<TypeCategory::Real, 16>);
#ifdef __SIZEOF_INT128__
#if defined __SIZEOF_INT128__
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint16_16)(
CppTypeFor<TypeCategory::Real, 16>);
#endif
#endif
// NEAREST
// The second argument to NEAREST is the result of a comparison
@ -332,50 +388,71 @@ CppTypeFor<TypeCategory::Real, 4> RTNAME(Nearest4)(
CppTypeFor<TypeCategory::Real, 4>, bool positive);
CppTypeFor<TypeCategory::Real, 8> RTNAME(Nearest8)(
CppTypeFor<TypeCategory::Real, 8>, bool positive);
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(Nearest10)(
CppTypeFor<TypeCategory::Real, 10>, bool positive);
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppTypeFor<TypeCategory::Real, 16> RTNAME(Nearest16)(
CppTypeFor<TypeCategory::Real, 16>, bool positive);
#endif
// RRSPACING
CppTypeFor<TypeCategory::Real, 4> RTNAME(RRSpacing4)(
CppTypeFor<TypeCategory::Real, 4>);
CppTypeFor<TypeCategory::Real, 8> RTNAME(RRSpacing8)(
CppTypeFor<TypeCategory::Real, 8>);
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(RRSpacing10)(
CppTypeFor<TypeCategory::Real, 10>);
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppTypeFor<TypeCategory::Real, 16> RTNAME(RRSpacing16)(
CppTypeFor<TypeCategory::Real, 16>);
#endif
// SET_EXPONENT's I= argument can be any INTEGER kind; upcast it to 64-bit
CppTypeFor<TypeCategory::Real, 4> RTNAME(SetExponent4)(
CppTypeFor<TypeCategory::Real, 4>, std::int64_t);
CppTypeFor<TypeCategory::Real, 8> RTNAME(SetExponent8)(
CppTypeFor<TypeCategory::Real, 8>, std::int64_t);
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(SetExponent10)(
CppTypeFor<TypeCategory::Real, 10>, std::int64_t);
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppTypeFor<TypeCategory::Real, 16> RTNAME(SetExponent16)(
CppTypeFor<TypeCategory::Real, 16>, std::int64_t);
#endif
// SCALE
CppTypeFor<TypeCategory::Real, 4> RTNAME(Scale4)(
CppTypeFor<TypeCategory::Real, 4>, std::int64_t);
CppTypeFor<TypeCategory::Real, 8> RTNAME(Scale8)(
CppTypeFor<TypeCategory::Real, 8>, std::int64_t);
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(Scale10)(
CppTypeFor<TypeCategory::Real, 10>, std::int64_t);
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppTypeFor<TypeCategory::Real, 16> RTNAME(Scale16)(
CppTypeFor<TypeCategory::Real, 16>, std::int64_t);
#endif
// SPACING
CppTypeFor<TypeCategory::Real, 4> RTNAME(Spacing4)(
CppTypeFor<TypeCategory::Real, 4>);
CppTypeFor<TypeCategory::Real, 8> RTNAME(Spacing8)(
CppTypeFor<TypeCategory::Real, 8>);
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(Spacing10)(
CppTypeFor<TypeCategory::Real, 10>);
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppTypeFor<TypeCategory::Real, 16> RTNAME(Spacing16)(
CppTypeFor<TypeCategory::Real, 16>);
#endif
} // extern "C"
} // namespace Fortran::runtime
#endif // FORTRAN_RUNTIME_NUMERIC_H_

View File

@ -12,7 +12,10 @@
#define FORTRAN_RUNTIME_REDUCTION_H_
#include "flang/Common/uint128.h"
#include "flang/Runtime/cpp-type.h"
#include "flang/Runtime/entry-names.h"
#include "flang/Runtime/float128.h"
#include <cfloat>
#include <cinttypes>
#include <complex>
#include <cstdint>
@ -65,10 +68,14 @@ float RTNAME(SumReal4)(const Descriptor &, const char *source, int line,
int dim = 0, const Descriptor *mask = nullptr);
double RTNAME(SumReal8)(const Descriptor &, const char *source, int line,
int dim = 0, const Descriptor *mask = nullptr);
#if LDBL_MANT_DIG == 64
long double RTNAME(SumReal10)(const Descriptor &, const char *source, int line,
int dim = 0, const Descriptor *mask = nullptr);
long double RTNAME(SumReal16)(const Descriptor &, const char *source, int line,
int dim = 0, const Descriptor *mask = nullptr);
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppFloat128Type RTNAME(SumReal16)(const Descriptor &, const char *source,
int line, int dim = 0, const Descriptor *mask = nullptr);
#endif
void RTNAME(CppSumComplex2)(std::complex<float> &, const Descriptor &,
const char *source, int line, int dim = 0,
@ -117,10 +124,14 @@ float RTNAME(ProductReal4)(const Descriptor &, const char *source, int line,
int dim = 0, const Descriptor *mask = nullptr);
double RTNAME(ProductReal8)(const Descriptor &, const char *source, int line,
int dim = 0, const Descriptor *mask = nullptr);
#if LDBL_MANT_DIG == 64
long double RTNAME(ProductReal10)(const Descriptor &, const char *source,
int line, int dim = 0, const Descriptor *mask = nullptr);
long double RTNAME(ProductReal16)(const Descriptor &, const char *source,
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppFloat128Type RTNAME(ProductReal16)(const Descriptor &, const char *source,
int line, int dim = 0, const Descriptor *mask = nullptr);
#endif
void RTNAME(CppProductComplex2)(std::complex<float> &, const Descriptor &,
const char *source, int line, int dim = 0,
@ -234,10 +245,14 @@ float RTNAME(MaxvalReal4)(const Descriptor &, const char *source, int line,
int dim = 0, const Descriptor *mask = nullptr);
double RTNAME(MaxvalReal8)(const Descriptor &, const char *source, int line,
int dim = 0, const Descriptor *mask = nullptr);
#if LDBL_MANT_DIG == 64
long double RTNAME(MaxvalReal10)(const Descriptor &, const char *source,
int line, int dim = 0, const Descriptor *mask = nullptr);
long double RTNAME(MaxvalReal16)(const Descriptor &, const char *source,
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppFloat128Type RTNAME(MaxvalReal16)(const Descriptor &, const char *source,
int line, int dim = 0, const Descriptor *mask = nullptr);
#endif
void RTNAME(MaxvalCharacter)(Descriptor &, const Descriptor &,
const char *source, int line, const Descriptor *mask = nullptr);
@ -261,10 +276,14 @@ float RTNAME(MinvalReal4)(const Descriptor &, const char *source, int line,
int dim = 0, const Descriptor *mask = nullptr);
double RTNAME(MinvalReal8)(const Descriptor &, const char *source, int line,
int dim = 0, const Descriptor *mask = nullptr);
#if LDBL_MANT_DIG == 64
long double RTNAME(MinvalReal10)(const Descriptor &, const char *source,
int line, int dim = 0, const Descriptor *mask = nullptr);
long double RTNAME(MinvalReal16)(const Descriptor &, const char *source,
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppFloat128Type RTNAME(MinvalReal16)(const Descriptor &, const char *source,
int line, int dim = 0, const Descriptor *mask = nullptr);
#endif
void RTNAME(MinvalCharacter)(Descriptor &, const Descriptor &,
const char *source, int line, const Descriptor *mask = nullptr);
@ -282,10 +301,13 @@ float RTNAME(Norm2_4)(const Descriptor &, const char *source, int line,
int dim = 0, const Descriptor *mask = nullptr);
double RTNAME(Norm2_8)(const Descriptor &, const char *source, int line,
int dim = 0, const Descriptor *mask = nullptr);
#if LDBL_MANT_DIG == 64
long double RTNAME(Norm2_10)(const Descriptor &, const char *source, int line,
int dim = 0, const Descriptor *mask = nullptr);
#elif LDBL_MANT_DIG == 113
long double RTNAME(Norm2_16)(const Descriptor &, const char *source, int line,
int dim = 0, const Descriptor *mask = nullptr);
#endif
void RTNAME(Norm2Dim)(Descriptor &, const Descriptor &, int dim,
const char *source, int line, const Descriptor *mask = nullptr);
@ -326,10 +348,14 @@ float RTNAME(DotProductReal4)(const Descriptor &, const Descriptor &,
const char *source = nullptr, int line = 0);
double RTNAME(DotProductReal8)(const Descriptor &, const Descriptor &,
const char *source = nullptr, int line = 0);
#if LDBL_MANT_DIG == 64
long double RTNAME(DotProductReal10)(const Descriptor &, const Descriptor &,
const char *source = nullptr, int line = 0);
long double RTNAME(DotProductReal16)(const Descriptor &, const Descriptor &,
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppFloat128Type RTNAME(DotProductReal16)(const Descriptor &, const Descriptor &,
const char *source = nullptr, int line = 0);
#endif
void RTNAME(CppDotProductComplex2)(std::complex<float> &, const Descriptor &,
const Descriptor &, const char *source = nullptr, int line = 0);
void RTNAME(CppDotProductComplex3)(std::complex<float> &, const Descriptor &,
@ -338,12 +364,16 @@ void RTNAME(CppDotProductComplex4)(std::complex<float> &, const Descriptor &,
const Descriptor &, const char *source = nullptr, int line = 0);
void RTNAME(CppDotProductComplex8)(std::complex<double> &, const Descriptor &,
const Descriptor &, const char *source = nullptr, int line = 0);
#if LDBL_MANT_DIG == 64
void RTNAME(CppDotProductComplex10)(std::complex<long double> &,
const Descriptor &, const Descriptor &, const char *source = nullptr,
int line = 0);
void RTNAME(CppDotProductComplex16)(std::complex<long double> &,
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
void RTNAME(CppDotProductComplex16)(std::complex<CppFloat128Type> &,
const Descriptor &, const Descriptor &, const char *source = nullptr,
int line = 0);
#endif
bool RTNAME(DotProductLogical)(const Descriptor &, const Descriptor &,
const char *source = nullptr, int line = 0);

View File

@ -9,6 +9,7 @@
#include "big-radix-floating-point.h"
#include "flang/Decimal/decimal.h"
#include <cassert>
#include <cfloat>
#include <string>
namespace Fortran::decimal {
@ -349,14 +350,14 @@ ConversionToDecimalResult ConvertDoubleToDecimal(char *buffer, std::size_t size,
rounding, Fortran::decimal::BinaryFloatingPointNumber<53>(x));
}
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
ConversionToDecimalResult ConvertLongDoubleToDecimal(char *buffer,
std::size_t size, enum DecimalConversionFlags flags, int digits,
enum FortranRounding rounding, long double x) {
return Fortran::decimal::ConvertToDecimal(buffer, size, flags, digits,
rounding, Fortran::decimal::BinaryFloatingPointNumber<64>(x));
}
#elif LONG_DOUBLE == 128
#elif LDBL_MANT_DIG == 113
ConversionToDecimalResult ConvertLongDoubleToDecimal(char *buffer,
std::size_t size, enum DecimalConversionFlags flags, int digits,
enum FortranRounding rounding, long double x) {

View File

@ -16,6 +16,7 @@
#include "host.h"
#include "flang/Common/static-multimap-view.h"
#include "flang/Evaluate/expression.h"
#include <cfloat>
#include <cmath>
#include <complex>
#include <functional>
@ -324,8 +325,7 @@ template <> struct HostRuntimeLibrary<double, LibraryVersion::LibmExtensions> {
static_assert(map.Verify(), "map must be sorted");
};
#if !defined(__PPC__) || defined(__LONG_DOUBLE_IEEE128__)
// TODO: use HostTypeExists instead?
#if LDBL_MANT_DIG == 80 || LDBL_MANT_DIG == 113
template <>
struct HostRuntimeLibrary<long double, LibraryVersion::LibmExtensions> {
using F = FuncPointer<long double, long double>;
@ -341,7 +341,7 @@ struct HostRuntimeLibrary<long double, LibraryVersion::LibmExtensions> {
static constexpr HostRuntimeMap map{table};
static_assert(map.Verify(), "map must be sorted");
};
#endif // !defined(__PPC__) || defined(__LONG_DOUBLE_IEEE128__)
#endif // LDBL_MANT_DIG == 80 || LDBL_MANT_DIG == 113
#endif
/// Define pgmath description

View File

@ -8,7 +8,7 @@
*/
#include "complex-reduction.h"
#include "flang/Common/long-double.h"
#include <float.h>
struct CppComplexFloat {
float r, i;
@ -90,10 +90,10 @@ ADAPT_REDUCTION(SumComplex4, float_Complex_t, CppComplexFloat, CMPLXF,
REDUCTION_ARGS, REDUCTION_ARG_NAMES)
ADAPT_REDUCTION(SumComplex8, double_Complex_t, CppComplexDouble, CMPLX,
REDUCTION_ARGS, REDUCTION_ARG_NAMES)
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
ADAPT_REDUCTION(SumComplex10, long_double_Complex_t, CppComplexLongDouble,
CMPLXL, REDUCTION_ARGS, REDUCTION_ARG_NAMES)
#elif LONG_DOUBLE == 128
#elif LDBL_MANT_DIG == 113
ADAPT_REDUCTION(SumComplex16, long_double_Complex_t, CppComplexLongDouble,
CMPLXL, REDUCTION_ARGS, REDUCTION_ARG_NAMES)
#endif
@ -103,10 +103,10 @@ ADAPT_REDUCTION(ProductComplex4, float_Complex_t, CppComplexFloat, CMPLXF,
REDUCTION_ARGS, REDUCTION_ARG_NAMES)
ADAPT_REDUCTION(ProductComplex8, double_Complex_t, CppComplexDouble, CMPLX,
REDUCTION_ARGS, REDUCTION_ARG_NAMES)
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
ADAPT_REDUCTION(ProductComplex10, long_double_Complex_t, CppComplexLongDouble,
CMPLXL, REDUCTION_ARGS, REDUCTION_ARG_NAMES)
#elif LONG_DOUBLE == 128
#elif LDBL_MANT_DIG == 113
ADAPT_REDUCTION(ProductComplex16, long_double_Complex_t, CppComplexLongDouble,
CMPLXL, REDUCTION_ARGS, REDUCTION_ARG_NAMES)
#endif
@ -116,10 +116,10 @@ ADAPT_REDUCTION(DotProductComplex4, float_Complex_t, CppComplexFloat, CMPLXF,
DOT_PRODUCT_ARGS, DOT_PRODUCT_ARG_NAMES)
ADAPT_REDUCTION(DotProductComplex8, double_Complex_t, CppComplexDouble, CMPLX,
DOT_PRODUCT_ARGS, DOT_PRODUCT_ARG_NAMES)
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
ADAPT_REDUCTION(DotProductComplex10, long_double_Complex_t,
CppComplexLongDouble, CMPLXL, DOT_PRODUCT_ARGS, DOT_PRODUCT_ARG_NAMES)
#elif LONG_DOUBLE == 128
#elif LDBL_MANT_DIG == 113
ADAPT_REDUCTION(DotProductComplex16, long_double_Complex_t,
CppComplexLongDouble, CMPLXL, DOT_PRODUCT_ARGS, DOT_PRODUCT_ARG_NAMES)
#endif

View File

@ -6,11 +6,13 @@
//
//===----------------------------------------------------------------------===//
#include "float.h"
#include "terminator.h"
#include "tools.h"
#include "flang/Runtime/cpp-type.h"
#include "flang/Runtime/descriptor.h"
#include "flang/Runtime/reduction.h"
#include <cfloat>
#include <cinttypes>
namespace Fortran::runtime {
@ -178,13 +180,14 @@ double RTNAME(DotProductReal8)(
const Descriptor &x, const Descriptor &y, const char *source, int line) {
return DotProduct<TypeCategory::Real, 8>{}(x, y, source, line);
}
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
long double RTNAME(DotProductReal10)(
const Descriptor &x, const Descriptor &y, const char *source, int line) {
return DotProduct<TypeCategory::Real, 10>{}(x, y, source, line);
}
#elif LONG_DOUBLE == 128
long double RTNAME(DotProductReal16)(
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppTypeFor<TypeCategory::Real, 16> RTNAME(DotProductReal16)(
const Descriptor &x, const Descriptor &y, const char *source, int line) {
return DotProduct<TypeCategory::Real, 16>{}(x, y, source, line);
}
@ -200,13 +203,13 @@ void RTNAME(CppDotProductComplex8)(std::complex<double> &result,
const Descriptor &x, const Descriptor &y, const char *source, int line) {
result = DotProduct<TypeCategory::Complex, 8>{}(x, y, source, line);
}
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
void RTNAME(CppDotProductComplex10)(std::complex<long double> &result,
const Descriptor &x, const Descriptor &y, const char *source, int line) {
result = DotProduct<TypeCategory::Complex, 10>{}(x, y, source, line);
}
#elif LONG_DOUBLE == 128
void RTNAME(CppDotProductComplex16)(std::complex<long double> &result,
#elif LDBL_MANT_DIG == 113
void RTNAME(CppDotProductComplex16)(std::complex<CppFloat128Type> &result,
const Descriptor &x, const Descriptor &y, const char *source, int line) {
result = DotProduct<TypeCategory::Complex, 16>{}(x, y, source, line);
}

View File

@ -11,10 +11,11 @@
// NORM2 using common infrastructure.
#include "reduction-templates.h"
#include "flang/Common/long-double.h"
#include "flang/Runtime/character.h"
#include "flang/Runtime/float128.h"
#include "flang/Runtime/reduction.h"
#include <algorithm>
#include <cfloat>
#include <cinttypes>
#include <cmath>
#include <optional>
@ -511,13 +512,14 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(MaxvalReal8)(const Descriptor &x,
return TotalNumericMaxOrMin<TypeCategory::Real, 8, true>(
x, source, line, dim, mask, "MAXVAL");
}
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(MaxvalReal10)(const Descriptor &x,
const char *source, int line, int dim, const Descriptor *mask) {
return TotalNumericMaxOrMin<TypeCategory::Real, 10, true>(
x, source, line, dim, mask, "MAXVAL");
}
#elif LONG_DOUBLE == 128
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppTypeFor<TypeCategory::Real, 16> RTNAME(MaxvalReal16)(const Descriptor &x,
const char *source, int line, int dim, const Descriptor *mask) {
return TotalNumericMaxOrMin<TypeCategory::Real, 16, true>(
@ -570,13 +572,14 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(MinvalReal8)(const Descriptor &x,
return TotalNumericMaxOrMin<TypeCategory::Real, 8, false>(
x, source, line, dim, mask, "MINVAL");
}
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(MinvalReal10)(const Descriptor &x,
const char *source, int line, int dim, const Descriptor *mask) {
return TotalNumericMaxOrMin<TypeCategory::Real, 10, false>(
x, source, line, dim, mask, "MINVAL");
}
#elif LONG_DOUBLE == 128
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppTypeFor<TypeCategory::Real, 16> RTNAME(MinvalReal16)(const Descriptor &x,
const char *source, int line, int dim, const Descriptor *mask) {
return TotalNumericMaxOrMin<TypeCategory::Real, 16, false>(
@ -612,8 +615,19 @@ void RTNAME(MinvalDim)(Descriptor &result, const Descriptor &x, int dim,
template <int KIND> class Norm2Accumulator {
public:
using Type = CppTypeFor<TypeCategory::Real, KIND>;
// Use at least double precision for accumulators
using AccumType = CppTypeFor<TypeCategory::Real, std::max(KIND, 8)>;
// Use at least double precision for accumulators.
// Don't use __float128, it doesn't work with abs() or sqrt() yet.
static constexpr int largestLDKind {
#if LDBL_MANT_DIG == 113
16
#elif LDBL_MANT_DIG == 64
10
#else
8
#endif
};
using AccumType = CppTypeFor<TypeCategory::Real,
std::max(std::min(largestLDKind, KIND), 8)>;
explicit Norm2Accumulator(const Descriptor &array) : array_{array} {}
void Reinitialize() { max_ = sum_ = 0; }
template <typename A> void GetResult(A *p, int /*zeroBasedDim*/ = -1) const {
@ -621,7 +635,7 @@ public:
*p = static_cast<Type>(max_ * std::sqrt(1 + sum_));
}
bool Accumulate(Type x) {
auto absX{AccumType{std::abs(x)}};
auto absX{std::abs(static_cast<AccumType>(x))};
if (!max_) {
max_ = x;
} else if (absX > max_) {
@ -666,13 +680,14 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(Norm2_8)(const Descriptor &x,
return GetTotalReduction<TypeCategory::Real, 8>(
x, source, line, dim, mask, Norm2Accumulator<8>{x}, "NORM2");
}
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(Norm2_10)(const Descriptor &x,
const char *source, int line, int dim, const Descriptor *mask) {
return GetTotalReduction<TypeCategory::Real, 10>(
x, source, line, dim, mask, Norm2Accumulator<10>{x}, "NORM2");
}
#elif LONG_DOUBLE == 128
#endif
#if LDBL_MANT_DIG == 113
CppTypeFor<TypeCategory::Real, 16> RTNAME(Norm2_16)(const Descriptor &x,
const char *source, int line, int dim, const Descriptor *mask) {
return GetTotalReduction<TypeCategory::Real, 16>(

View File

@ -10,7 +10,6 @@
// integer kinds.
#include "reduction-templates.h"
#include "flang/Common/long-double.h"
#include "flang/Runtime/character.h"
#include "flang/Runtime/reduction.h"
#include <cinttypes>

View File

@ -6,9 +6,10 @@
//
//===----------------------------------------------------------------------===//
#include "terminator.h"
#include "flang/Runtime/numeric.h"
#include "flang/Common/long-double.h"
#include "terminator.h"
#include "flang/Runtime/float128.h"
#include <cfloat>
#include <climits>
#include <cmath>
#include <limits>
@ -175,7 +176,7 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint8_8)(
CppTypeFor<TypeCategory::Real, 8> x) {
return Aint<CppTypeFor<TypeCategory::Real, 8>>(x);
}
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint4_10)(
CppTypeFor<TypeCategory::Real, 4> x) {
return Aint<CppTypeFor<TypeCategory::Real, 10>>(x);
@ -196,7 +197,7 @@ CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint10_10)(
CppTypeFor<TypeCategory::Real, 10> x) {
return Aint<CppTypeFor<TypeCategory::Real, 10>>(x);
}
#elif LONG_DOUBLE == 128
#elif LDBL_MANT_DIG == 113
CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint4_16)(
CppTypeFor<TypeCategory::Real, 4> x) {
return Aint<CppTypeFor<TypeCategory::Real, 16>>(x);
@ -235,7 +236,7 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint8_8)(
CppTypeFor<TypeCategory::Real, 8> x) {
return Anint<CppTypeFor<TypeCategory::Real, 8>>(x);
}
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint4_10)(
CppTypeFor<TypeCategory::Real, 4> x) {
return Anint<CppTypeFor<TypeCategory::Real, 10>>(x);
@ -256,7 +257,7 @@ CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint10_10)(
CppTypeFor<TypeCategory::Real, 10> x) {
return Anint<CppTypeFor<TypeCategory::Real, 10>>(x);
}
#elif LONG_DOUBLE == 128
#elif LDBL_MANT_DIG == 113
CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint4_16)(
CppTypeFor<TypeCategory::Real, 4> x) {
return Anint<CppTypeFor<TypeCategory::Real, 16>>(x);
@ -323,7 +324,7 @@ CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling8_16)(
return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x);
}
#endif
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling10_1)(
CppTypeFor<TypeCategory::Real, 10> x) {
return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x);
@ -346,7 +347,7 @@ CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling10_16)(
return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x);
}
#endif
#else
#elif LDBL_MANT_DIG == 113
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling16_1)(
CppTypeFor<TypeCategory::Real, 16> x) {
return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x);
@ -387,7 +388,7 @@ CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent8_8)(
CppTypeFor<TypeCategory::Real, 8> x) {
return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x);
}
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent10_4)(
CppTypeFor<TypeCategory::Real, 10> x) {
return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x);
@ -396,7 +397,7 @@ CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent10_8)(
CppTypeFor<TypeCategory::Real, 10> x) {
return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x);
}
#elif LONG_DOUBLE == 128
#elif LDBL_MANT_DIG == 113
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent16_4)(
CppTypeFor<TypeCategory::Real, 16> x) {
return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x);
@ -451,7 +452,7 @@ CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor8_16)(
return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x);
}
#endif
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor10_1)(
CppTypeFor<TypeCategory::Real, 10> x) {
return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x);
@ -474,7 +475,7 @@ CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor10_16)(
return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x);
}
#endif
#else
#elif LDBL_MANT_DIG == 113
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor16_1)(
CppTypeFor<TypeCategory::Real, 16> x) {
return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x);
@ -507,12 +508,12 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(Fraction8)(
CppTypeFor<TypeCategory::Real, 8> x) {
return Fraction(x);
}
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(Fraction10)(
CppTypeFor<TypeCategory::Real, 10> x) {
return Fraction(x);
}
#elif LONG_DOUBLE == 128
#elif LDBL_MANT_DIG == 113
CppTypeFor<TypeCategory::Real, 16> RTNAME(Fraction16)(
CppTypeFor<TypeCategory::Real, 16> x) {
return Fraction(x);
@ -525,11 +526,11 @@ bool RTNAME(IsFinite4)(CppTypeFor<TypeCategory::Real, 4> x) {
bool RTNAME(IsFinite8)(CppTypeFor<TypeCategory::Real, 8> x) {
return std::isfinite(x);
}
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
bool RTNAME(IsFinite10)(CppTypeFor<TypeCategory::Real, 10> x) {
return std::isfinite(x);
}
#elif LONG_DOUBLE == 128
#elif LDBL_MANT_DIG == 113
bool RTNAME(IsFinite16)(CppTypeFor<TypeCategory::Real, 16> x) {
return std::isfinite(x);
}
@ -541,11 +542,11 @@ bool RTNAME(IsNaN4)(CppTypeFor<TypeCategory::Real, 4> x) {
bool RTNAME(IsNaN8)(CppTypeFor<TypeCategory::Real, 8> x) {
return std::isnan(x);
}
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
bool RTNAME(IsNaN10)(CppTypeFor<TypeCategory::Real, 10> x) {
return std::isnan(x);
}
#elif LONG_DOUBLE == 128
#elif LDBL_MANT_DIG == 113
bool RTNAME(IsNaN16)(CppTypeFor<TypeCategory::Real, 16> x) {
return std::isnan(x);
}
@ -593,13 +594,13 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(ModReal8)(
const char *sourceFile, int sourceLine) {
return RealMod<false>(x, p, sourceFile, sourceLine);
}
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(ModReal10)(
CppTypeFor<TypeCategory::Real, 10> x, CppTypeFor<TypeCategory::Real, 10> p,
const char *sourceFile, int sourceLine) {
return RealMod<false>(x, p, sourceFile, sourceLine);
}
#elif LONG_DOUBLE == 128
#elif LDBL_MANT_DIG == 113
CppTypeFor<TypeCategory::Real, 16> RTNAME(ModReal16)(
CppTypeFor<TypeCategory::Real, 16> x, CppTypeFor<TypeCategory::Real, 16> p,
const char *sourceFile, int sourceLine) {
@ -649,13 +650,13 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(ModuloReal8)(
const char *sourceFile, int sourceLine) {
return RealMod<true>(x, p, sourceFile, sourceLine);
}
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(ModuloReal10)(
CppTypeFor<TypeCategory::Real, 10> x, CppTypeFor<TypeCategory::Real, 10> p,
const char *sourceFile, int sourceLine) {
return RealMod<true>(x, p, sourceFile, sourceLine);
}
#elif LONG_DOUBLE == 128
#elif LDBL_MANT_DIG == 113
CppTypeFor<TypeCategory::Real, 16> RTNAME(ModuloReal16)(
CppTypeFor<TypeCategory::Real, 16> x, CppTypeFor<TypeCategory::Real, 16> p,
const char *sourceFile, int sourceLine) {
@ -671,12 +672,12 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(Nearest8)(
CppTypeFor<TypeCategory::Real, 8> x, bool positive) {
return Nearest<53>(x, positive);
}
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(Nearest10)(
CppTypeFor<TypeCategory::Real, 10> x, bool positive) {
return Nearest<64>(x, positive);
}
#elif LONG_DOUBLE == 128
#elif LDBL_MANT_DIG == 113
CppTypeFor<TypeCategory::Real, 16> RTNAME(Nearest16)(
CppTypeFor<TypeCategory::Real, 16> x, bool positive) {
return Nearest<113>(x, positive);
@ -727,7 +728,7 @@ CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint8_16)(
return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x);
}
#endif
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint10_1)(
CppTypeFor<TypeCategory::Real, 10> x) {
return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x);
@ -750,7 +751,7 @@ CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint10_16)(
return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x);
}
#endif
#else
#elif LDBL_MANT_DIG == 113
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint16_1)(
CppTypeFor<TypeCategory::Real, 16> x) {
return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x);
@ -783,12 +784,12 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(RRSpacing8)(
CppTypeFor<TypeCategory::Real, 8> x) {
return RRSpacing<53>(x);
}
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(RRSpacing10)(
CppTypeFor<TypeCategory::Real, 10> x) {
return RRSpacing<64>(x);
}
#elif LONG_DOUBLE == 128
#elif LDBL_MANT_DIG == 113
CppTypeFor<TypeCategory::Real, 16> RTNAME(RRSpacing16)(
CppTypeFor<TypeCategory::Real, 16> x) {
return RRSpacing<113>(x);
@ -803,12 +804,12 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(SetExponent8)(
CppTypeFor<TypeCategory::Real, 8> x, std::int64_t p) {
return SetExponent(x, p);
}
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(SetExponent10)(
CppTypeFor<TypeCategory::Real, 10> x, std::int64_t p) {
return SetExponent(x, p);
}
#elif LONG_DOUBLE == 128
#elif LDBL_MANT_DIG == 113
CppTypeFor<TypeCategory::Real, 16> RTNAME(SetExponent16)(
CppTypeFor<TypeCategory::Real, 16> x, std::int64_t p) {
return SetExponent(x, p);
@ -823,12 +824,12 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(Scale8)(
CppTypeFor<TypeCategory::Real, 8> x, std::int64_t p) {
return Scale(x, p);
}
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(Scale10)(
CppTypeFor<TypeCategory::Real, 10> x, std::int64_t p) {
return Scale(x, p);
}
#elif LONG_DOUBLE == 128
#elif LDBL_MANT_DIG == 113
CppTypeFor<TypeCategory::Real, 16> RTNAME(Scale16)(
CppTypeFor<TypeCategory::Real, 16> x, std::int64_t p) {
return Scale(x, p);
@ -843,12 +844,12 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(Spacing8)(
CppTypeFor<TypeCategory::Real, 8> x) {
return Spacing<53>(x);
}
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(Spacing10)(
CppTypeFor<TypeCategory::Real, 10> x) {
return Spacing<64>(x);
}
#elif LONG_DOUBLE == 128
#elif LDBL_MANT_DIG == 113
CppTypeFor<TypeCategory::Real, 16> RTNAME(Spacing16)(
CppTypeFor<TypeCategory::Real, 16> x) {
return Spacing<113>(x);

View File

@ -9,8 +9,9 @@
// Implements PRODUCT for all required operand types and shapes.
#include "reduction-templates.h"
#include "flang/Common/long-double.h"
#include "flang/Runtime/float128.h"
#include "flang/Runtime/reduction.h"
#include <cfloat>
#include <cinttypes>
#include <complex>
@ -105,14 +106,14 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(ProductReal8)(const Descriptor &x,
NonComplexProductAccumulator<CppTypeFor<TypeCategory::Real, 8>>{x},
"PRODUCT");
}
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(ProductReal10)(const Descriptor &x,
const char *source, int line, int dim, const Descriptor *mask) {
return GetTotalReduction<TypeCategory::Real, 10>(x, source, line, dim, mask,
NonComplexProductAccumulator<CppTypeFor<TypeCategory::Real, 10>>{x},
"PRODUCT");
}
#elif LONG_DOUBLE == 128
#elif LDBL_MANT_DIG == 113
CppTypeFor<TypeCategory::Real, 16> RTNAME(ProductReal16)(const Descriptor &x,
const char *source, int line, int dim, const Descriptor *mask) {
return GetTotalReduction<TypeCategory::Real, 16>(x, source, line, dim, mask,
@ -135,7 +136,7 @@ void RTNAME(CppProductComplex8)(CppTypeFor<TypeCategory::Complex, 8> &result,
mask, ComplexProductAccumulator<CppTypeFor<TypeCategory::Real, 8>>{x},
"PRODUCT");
}
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
void RTNAME(CppProductComplex10)(CppTypeFor<TypeCategory::Complex, 10> &result,
const Descriptor &x, const char *source, int line, int dim,
const Descriptor *mask) {
@ -143,7 +144,7 @@ void RTNAME(CppProductComplex10)(CppTypeFor<TypeCategory::Complex, 10> &result,
mask, ComplexProductAccumulator<CppTypeFor<TypeCategory::Real, 10>>{x},
"PRODUCT");
}
#elif LONG_DOUBLE == 128
#elif LDBL_MANT_DIG == 113
void RTNAME(CppProductComplex16)(CppTypeFor<TypeCategory::Complex, 16> &result,
const Descriptor &x, const char *source, int line, int dim,
const Descriptor *mask) {

View File

@ -15,6 +15,7 @@
#include "flang/Common/uint128.h"
#include "flang/Runtime/cpp-type.h"
#include "flang/Runtime/descriptor.h"
#include "flang/Runtime/float128.h"
#include <algorithm>
#include <cmath>
#include <cstdint>
@ -113,23 +114,28 @@ void RTNAME(RandomNumber)(
// TODO: REAL (2 & 3)
case 4:
Generate<CppTypeFor<TypeCategory::Real, 4>, 24>(harvest);
break;
return;
case 8:
Generate<CppTypeFor<TypeCategory::Real, 8>, 53>(harvest);
break;
#if LONG_DOUBLE == 80
return;
case 10:
Generate<CppTypeFor<TypeCategory::Real, 10>, 64>(harvest);
break;
#elif LONG_DOUBLE == 128
case 16:
Generate<CppTypeFor<TypeCategory::Real, 16>, 113>(harvest);
break;
if constexpr (HasCppTypeFor<TypeCategory::Real, 10>) {
#if LDBL_MANT_DIG == 64
Generate<CppTypeFor<TypeCategory::Real, 10>, 64>(harvest);
return;
#endif
default:
terminator.Crash(
"not yet implemented: RANDOM_NUMBER(): REAL kind %d", kind);
}
break;
case 16:
if constexpr (HasCppTypeFor<TypeCategory::Real, 16>) {
#if LDBL_MANT_DIG == 113
Generate<CppTypeFor<TypeCategory::Real, 16>, 113>(harvest);
return;
#endif
}
break;
}
terminator.Crash("not yet implemented: RANDOM_NUMBER(): REAL kind %d", kind);
}
void RTNAME(RandomSeedSize)(

View File

@ -13,8 +13,9 @@
// (basically the same as manual "double-double").
#include "reduction-templates.h"
#include "flang/Common/long-double.h"
#include "flang/Runtime/float128.h"
#include "flang/Runtime/reduction.h"
#include <cfloat>
#include <cinttypes>
#include <complex>
@ -129,13 +130,14 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(SumReal8)(const Descriptor &x,
return GetTotalReduction<TypeCategory::Real, 8>(
x, source, line, dim, mask, RealSumAccumulator<double>{x}, "SUM");
}
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Real, 10> RTNAME(SumReal10)(const Descriptor &x,
const char *source, int line, int dim, const Descriptor *mask) {
return GetTotalReduction<TypeCategory::Real, 10>(
x, source, line, dim, mask, RealSumAccumulator<long double>{x}, "SUM");
}
#elif LONG_DOUBLE == 128
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
CppTypeFor<TypeCategory::Real, 16> RTNAME(SumReal16)(const Descriptor &x,
const char *source, int line, int dim, const Descriptor *mask) {
return GetTotalReduction<TypeCategory::Real, 16>(
@ -155,14 +157,14 @@ void RTNAME(CppSumComplex8)(CppTypeFor<TypeCategory::Complex, 8> &result,
result = GetTotalReduction<TypeCategory::Complex, 8>(
x, source, line, dim, mask, ComplexSumAccumulator<double>{x}, "SUM");
}
#if LONG_DOUBLE == 80
#if LDBL_MANT_DIG == 64
void RTNAME(CppSumComplex10)(CppTypeFor<TypeCategory::Complex, 10> &result,
const Descriptor &x, const char *source, int line, int dim,
const Descriptor *mask) {
result = GetTotalReduction<TypeCategory::Complex, 10>(
x, source, line, dim, mask, ComplexSumAccumulator<long double>{x}, "SUM");
}
#elif LONG_DOUBLE == 128
#elif LDBL_MANT_DIG == 113
void RTNAME(CppSumComplex16)(CppTypeFor<TypeCategory::Complex, 16> &result,
const Descriptor &x, const char *source, int line, int dim,
const Descriptor *mask) {

View File

@ -10,7 +10,6 @@
#define FORTRAN_RUNTIME_TOOLS_H_
#include "terminator.h"
#include "flang/Common/long-double.h"
#include "flang/Runtime/cpp-type.h"
#include "flang/Runtime/descriptor.h"
#include "flang/Runtime/memory.h"
@ -148,16 +147,18 @@ inline RESULT ApplyType(
return FUNC<TypeCategory::Real, 4>{}(std::forward<A>(x)...);
case 8:
return FUNC<TypeCategory::Real, 8>{}(std::forward<A>(x)...);
#if LONG_DOUBLE == 80
case 10:
return FUNC<TypeCategory::Real, 10>{}(std::forward<A>(x)...);
#elif LONG_DOUBLE == 128
if constexpr (HasCppTypeFor<TypeCategory::Real, 10>) {
return FUNC<TypeCategory::Real, 10>{}(std::forward<A>(x)...);
}
break;
case 16:
return FUNC<TypeCategory::Real, 16>{}(std::forward<A>(x)...);
#endif
default:
terminator.Crash("not yet implemented: REAL(KIND=%d)", kind);
if constexpr (HasCppTypeFor<TypeCategory::Real, 16>) {
return FUNC<TypeCategory::Real, 16>{}(std::forward<A>(x)...);
}
break;
}
terminator.Crash("not yet implemented: REAL(KIND=%d)", kind);
case TypeCategory::Complex:
switch (kind) {
#if 0 // TODO: COMPLEX(2 & 3)
@ -170,16 +171,18 @@ inline RESULT ApplyType(
return FUNC<TypeCategory::Complex, 4>{}(std::forward<A>(x)...);
case 8:
return FUNC<TypeCategory::Complex, 8>{}(std::forward<A>(x)...);
#if LONG_DOUBLE == 80
case 10:
return FUNC<TypeCategory::Complex, 10>{}(std::forward<A>(x)...);
#elif LONG_DOUBLE == 128
if constexpr (HasCppTypeFor<TypeCategory::Real, 10>) {
return FUNC<TypeCategory::Complex, 10>{}(std::forward<A>(x)...);
}
break;
case 16:
return FUNC<TypeCategory::Complex, 16>{}(std::forward<A>(x)...);
#endif
default:
terminator.Crash("not yet implemented: COMPLEX(KIND=%d)", kind);
if constexpr (HasCppTypeFor<TypeCategory::Real, 16>) {
return FUNC<TypeCategory::Complex, 16>{}(std::forward<A>(x)...);
}
break;
}
terminator.Crash("not yet implemented: COMPLEX(KIND=%d)", kind);
case TypeCategory::Character:
switch (kind) {
case 1:
@ -246,16 +249,18 @@ inline RESULT ApplyFloatingPointKind(
return FUNC<4>{}(std::forward<A>(x)...);
case 8:
return FUNC<8>{}(std::forward<A>(x)...);
#if LONG_DOUBLE == 80
case 10:
return FUNC<10>{}(std::forward<A>(x)...);
#elif LONG_DOUBLE == 128
if constexpr (HasCppTypeFor<TypeCategory::Real, 10>) {
return FUNC<10>{}(std::forward<A>(x)...);
}
break;
case 16:
return FUNC<16>{}(std::forward<A>(x)...);
#endif
default:
terminator.Crash("not yet implemented: REAL/COMPLEX(KIND=%d)", kind);
if constexpr (HasCppTypeFor<TypeCategory::Real, 16>) {
return FUNC<16>{}(std::forward<A>(x)...);
}
break;
}
terminator.Crash("not yet implemented: REAL/COMPLEX(KIND=%d)", kind);
}
template <template <int KIND> class FUNC, typename RESULT, typename... A>