//===-- runtime/numeric.cpp -----------------------------------------------===// // // 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 // //===----------------------------------------------------------------------===// #include "flang/Runtime/numeric.h" #include "numeric-templates.h" #include "terminator.h" #include "tools.h" #include "flang/Common/float128.h" #include #include #include #include namespace Fortran::runtime { template inline RT_API_ATTRS RES GetIntArgValue(const char *source, int line, const void *arg, int kind, std::int64_t defaultValue, int resKind) { RES res; if (!arg) { res = static_cast(defaultValue); } else if (kind == 1) { res = static_cast( *static_cast *>(arg)); } else if (kind == 2) { res = static_cast( *static_cast *>(arg)); } else if (kind == 4) { res = static_cast( *static_cast *>(arg)); } else if (kind == 8) { res = static_cast( *static_cast *>(arg)); #ifdef __SIZEOF_INT128__ } else if (kind == 16) { if (resKind != 16) { Terminator{source, line}.Crash("Unexpected integer kind in runtime"); } res = static_cast( *static_cast *>(arg)); #endif } else { Terminator{source, line}.Crash("Unexpected integer kind in runtime"); } return res; } // NINT (16.9.141) template inline RT_API_ATTRS RESULT Nint(ARG x) { if (x >= 0) { return std::trunc(x + ARG{0.5}); } else { return std::trunc(x - ARG{0.5}); } } // CEILING & FLOOR (16.9.43, .79) template inline RT_API_ATTRS RESULT Ceiling(ARG x) { return std::ceil(x); } template inline RT_API_ATTRS RESULT Floor(ARG x) { return std::floor(x); } // MOD & MODULO (16.9.135, .136) template inline RT_API_ATTRS T IntMod(T x, T p, const char *sourceFile, int sourceLine) { if (p == 0) { Terminator{sourceFile, sourceLine}.Crash( IS_MODULO ? "MODULO with P==0" : "MOD with P==0"); } auto mod{x - (x / p) * p}; if (IS_MODULO && (x > 0) != (p > 0)) { mod += p; } return mod; } // SCALE (16.9.166) template inline RT_API_ATTRS T Scale(T x, std::int64_t p) { auto ip{static_cast(p)}; if (ip != p) { ip = p < 0 ? std::numeric_limits::min() : std::numeric_limits::max(); } return std::ldexp(x, ip); // x*2**p } // SELECTED_INT_KIND (16.9.169) and SELECTED_UNSIGNED_KIND extension template inline RT_API_ATTRS CppTypeFor SelectedIntKind( X x, M mask) { #if !defined __SIZEOF_INT128__ || defined FLANG_RUNTIME_NO_INTEGER_16 mask &= ~(1 << 16); #endif if (x <= 2 && (mask & (1 << 1))) { return 1; } else if (x <= 4 && (mask & (1 << 2))) { return 2; } else if (x <= 9 && (mask & (1 << 4))) { return 4; } else if (x <= 18 && (mask & (1 << 8))) { return 8; } else if (x <= 38 && (mask & (1 << 16))) { return 16; } return -1; } // SELECTED_LOGICAL_KIND (F'2023 16.9.182) template inline RT_API_ATTRS CppTypeFor SelectedLogicalKind( T x) { if (x <= 8) { return 1; } else if (x <= 16) { return 2; } else if (x <= 32) { return 4; } else if (x <= 64) { return 8; } return -1; } // SELECTED_REAL_KIND (16.9.170) template inline RT_API_ATTRS CppTypeFor SelectedRealKind( P p, R r, D d, M mask) { if (d != 2) { return -5; } #ifdef FLANG_RUNTIME_NO_REAL_2 mask &= ~(1 << 2); #endif #ifdef FLANG_RUNTIME_NO_REAL_3 mask &= ~(1 << 3); #endif #if !HAS_FLOAT80 || defined FLANG_RUNTIME_NO_REAL_10 mask &= ~(1 << 10); #endif #if LDBL_MANT_DIG < 64 || defined FLANG_RUNTIME_NO_REAL_16 mask &= ~(1 << 16); #endif int error{0}; int kind{0}; if (p <= 3 && (mask & (1 << 2))) { kind = 2; } else if (p <= 6 && (mask & (1 << 4))) { kind = 4; } else if (p <= 15 && (mask & (1 << 8))) { kind = 8; } else if (p <= 18 && (mask & (1 << 10))) { kind = 10; } else if (p <= 33 && (mask & (1 << 16))) { kind = 16; } else { error -= 1; } if (r <= 4 && (mask & (1 << 2))) { kind = kind < 2 ? 2 : kind; } else if (r <= 37 && p != 3 && (mask & (1 << 3))) { kind = kind < 3 ? 3 : kind; } else if (r <= 37 && (mask & (1 << 4))) { kind = kind < 4 ? 4 : kind; } else if (r <= 307 && (mask & (1 << 8))) { kind = kind < 8 ? 8 : kind; } else if (r <= 4931 && (mask & (1 << 10))) { kind = kind < 10 ? 10 : kind; } else if (r <= 4931 && (mask & (1 << 16))) { kind = kind < 16 ? 16 : kind; } else { error -= 2; } return error ? error : kind; } // NEAREST (16.9.139) template inline RT_API_ATTRS T Nearest(T x, bool positive) { if (positive) { return std::nextafter(x, std::numeric_limits::infinity()); } else { return std::nextafter(x, -std::numeric_limits::infinity()); } } // Exponentiation operator for (Real ** Integer) cases (10.1.5.2.1). template RT_API_ATTRS BTy FPowI(BTy base, ETy exp) { if (exp == ETy{0}) return BTy{1}; bool isNegativePower{exp < ETy{0}}; bool isMinPower{exp == std::numeric_limits::min()}; if (isMinPower) { exp = std::numeric_limits::max(); } else if (isNegativePower) { exp = -exp; } BTy result{1}; BTy origBase{base}; while (true) { if (exp & ETy{1}) { result *= base; } exp >>= 1; if (exp == ETy{0}) { break; } base *= base; } if (isMinPower) { result *= origBase; } if (isNegativePower) { result = BTy{1} / result; } return result; } extern "C" { RT_EXT_API_GROUP_BEGIN CppTypeFor RTDEF(Ceiling4_1)( CppTypeFor x) { return Ceiling>(x); } CppTypeFor RTDEF(Ceiling4_2)( CppTypeFor x) { return Ceiling>(x); } CppTypeFor RTDEF(Ceiling4_4)( CppTypeFor x) { return Ceiling>(x); } CppTypeFor RTDEF(Ceiling4_8)( CppTypeFor x) { return Ceiling>(x); } #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T CppTypeFor RTDEF(Ceiling4_16)( CppTypeFor x) { return Ceiling>(x); } #endif CppTypeFor RTDEF(Ceiling8_1)( CppTypeFor x) { return Ceiling>(x); } CppTypeFor RTDEF(Ceiling8_2)( CppTypeFor x) { return Ceiling>(x); } CppTypeFor RTDEF(Ceiling8_4)( CppTypeFor x) { return Ceiling>(x); } CppTypeFor RTDEF(Ceiling8_8)( CppTypeFor x) { return Ceiling>(x); } #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T CppTypeFor RTDEF(Ceiling8_16)( CppTypeFor x) { return Ceiling>(x); } #endif #if HAS_FLOAT80 CppTypeFor RTDEF(Ceiling10_1)( CppTypeFor x) { return Ceiling>(x); } CppTypeFor RTDEF(Ceiling10_2)( CppTypeFor x) { return Ceiling>(x); } CppTypeFor RTDEF(Ceiling10_4)( CppTypeFor x) { return Ceiling>(x); } CppTypeFor RTDEF(Ceiling10_8)( CppTypeFor x) { return Ceiling>(x); } #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T CppTypeFor RTDEF(Ceiling10_16)( CppTypeFor x) { return Ceiling>(x); } #endif #elif HAS_LDBL128 CppTypeFor RTDEF(Ceiling16_1)( CppTypeFor x) { return Ceiling>(x); } CppTypeFor RTDEF(Ceiling16_2)( CppTypeFor x) { return Ceiling>(x); } CppTypeFor RTDEF(Ceiling16_4)( CppTypeFor x) { return Ceiling>(x); } CppTypeFor RTDEF(Ceiling16_8)( CppTypeFor x) { return Ceiling>(x); } #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T CppTypeFor RTDEF(Ceiling16_16)( CppTypeFor x) { return Ceiling>(x); } #endif #endif CppTypeFor RTDEF(ErfcScaled4)( CppTypeFor x) { return ErfcScaled(x); } CppTypeFor RTDEF(ErfcScaled8)( CppTypeFor x) { return ErfcScaled(x); } #if HAS_FLOAT80 CppTypeFor RTDEF(ErfcScaled10)( CppTypeFor x) { return ErfcScaled(x); } #endif #if HAS_LDBL128 CppTypeFor RTDEF(ErfcScaled16)( CppTypeFor x) { return ErfcScaled(x); } #endif CppTypeFor RTDEF(Exponent4_4)( CppTypeFor x) { return Exponent>(x); } CppTypeFor RTDEF(Exponent4_8)( CppTypeFor x) { return Exponent>(x); } CppTypeFor RTDEF(Exponent8_4)( CppTypeFor x) { return Exponent>(x); } CppTypeFor RTDEF(Exponent8_8)( CppTypeFor x) { return Exponent>(x); } #if HAS_FLOAT80 CppTypeFor RTDEF(Exponent10_4)( CppTypeFor x) { return Exponent>(x); } CppTypeFor RTDEF(Exponent10_8)( CppTypeFor x) { return Exponent>(x); } #endif CppTypeFor RTDEF(Floor4_1)( CppTypeFor x) { return Floor>(x); } CppTypeFor RTDEF(Floor4_2)( CppTypeFor x) { return Floor>(x); } CppTypeFor RTDEF(Floor4_4)( CppTypeFor x) { return Floor>(x); } CppTypeFor RTDEF(Floor4_8)( CppTypeFor x) { return Floor>(x); } #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T CppTypeFor RTDEF(Floor4_16)( CppTypeFor x) { return Floor>(x); } #endif CppTypeFor RTDEF(Floor8_1)( CppTypeFor x) { return Floor>(x); } CppTypeFor RTDEF(Floor8_2)( CppTypeFor x) { return Floor>(x); } CppTypeFor RTDEF(Floor8_4)( CppTypeFor x) { return Floor>(x); } CppTypeFor RTDEF(Floor8_8)( CppTypeFor x) { return Floor>(x); } #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T CppTypeFor RTDEF(Floor8_16)( CppTypeFor x) { return Floor>(x); } #endif #if HAS_FLOAT80 CppTypeFor RTDEF(Floor10_1)( CppTypeFor x) { return Floor>(x); } CppTypeFor RTDEF(Floor10_2)( CppTypeFor x) { return Floor>(x); } CppTypeFor RTDEF(Floor10_4)( CppTypeFor x) { return Floor>(x); } CppTypeFor RTDEF(Floor10_8)( CppTypeFor x) { return Floor>(x); } #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T CppTypeFor RTDEF(Floor10_16)( CppTypeFor x) { return Floor>(x); } #endif #elif HAS_LDBL128 CppTypeFor RTDEF(Floor16_1)( CppTypeFor x) { return Floor>(x); } CppTypeFor RTDEF(Floor16_2)( CppTypeFor x) { return Floor>(x); } CppTypeFor RTDEF(Floor16_4)( CppTypeFor x) { return Floor>(x); } CppTypeFor RTDEF(Floor16_8)( CppTypeFor x) { return Floor>(x); } #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T CppTypeFor RTDEF(Floor16_16)( CppTypeFor x) { return Floor>(x); } #endif #endif CppTypeFor RTDEF(Fraction4)( CppTypeFor x) { return Fraction(x); } CppTypeFor RTDEF(Fraction8)( CppTypeFor x) { return Fraction(x); } #if HAS_FLOAT80 CppTypeFor RTDEF(Fraction10)( CppTypeFor x) { return Fraction(x); } #endif bool RTDEF(IsFinite4)(CppTypeFor x) { return std::isfinite(x); } bool RTDEF(IsFinite8)(CppTypeFor x) { return std::isfinite(x); } #if HAS_FLOAT80 bool RTDEF(IsFinite10)(CppTypeFor x) { return std::isfinite(x); } #elif HAS_LDBL128 bool RTDEF(IsFinite16)(CppTypeFor x) { return std::isfinite(x); } #endif bool RTDEF(IsNaN4)(CppTypeFor x) { return std::isnan(x); } bool RTDEF(IsNaN8)(CppTypeFor x) { return std::isnan(x); } #if HAS_FLOAT80 bool RTDEF(IsNaN10)(CppTypeFor x) { return std::isnan(x); } #elif HAS_LDBL128 bool RTDEF(IsNaN16)(CppTypeFor x) { return std::isnan(x); } #endif CppTypeFor RTDEF(ModInteger1)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return IntMod(x, p, sourceFile, sourceLine); } CppTypeFor RTDEF(ModInteger2)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return IntMod(x, p, sourceFile, sourceLine); } CppTypeFor RTDEF(ModInteger4)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return IntMod(x, p, sourceFile, sourceLine); } CppTypeFor RTDEF(ModInteger8)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return IntMod(x, p, sourceFile, sourceLine); } #ifdef __SIZEOF_INT128__ CppTypeFor RTDEF(ModInteger16)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return IntMod(x, p, sourceFile, sourceLine); } #endif CppTypeFor RTDEF(ModReal4)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return RealMod(x, p, sourceFile, sourceLine); } CppTypeFor RTDEF(ModReal8)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return RealMod(x, p, sourceFile, sourceLine); } #if HAS_FLOAT80 CppTypeFor RTDEF(ModReal10)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return RealMod(x, p, sourceFile, sourceLine); } #endif CppTypeFor RTDEF(ModuloInteger1)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return IntMod(x, p, sourceFile, sourceLine); } CppTypeFor RTDEF(ModuloInteger2)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return IntMod(x, p, sourceFile, sourceLine); } CppTypeFor RTDEF(ModuloInteger4)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return IntMod(x, p, sourceFile, sourceLine); } CppTypeFor RTDEF(ModuloInteger8)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return IntMod(x, p, sourceFile, sourceLine); } #ifdef __SIZEOF_INT128__ CppTypeFor RTDEF(ModuloInteger16)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return IntMod(x, p, sourceFile, sourceLine); } #endif CppTypeFor RTDEF(ModuloReal4)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return RealMod(x, p, sourceFile, sourceLine); } CppTypeFor RTDEF(ModuloReal8)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return RealMod(x, p, sourceFile, sourceLine); } #if HAS_FLOAT80 CppTypeFor RTDEF(ModuloReal10)( CppTypeFor x, CppTypeFor p, const char *sourceFile, int sourceLine) { return RealMod(x, p, sourceFile, sourceLine); } #endif CppTypeFor RTDEF(Nearest4)( CppTypeFor x, bool positive) { return Nearest<24>(x, positive); } CppTypeFor RTDEF(Nearest8)( CppTypeFor x, bool positive) { return Nearest<53>(x, positive); } #if HAS_FLOAT80 CppTypeFor RTDEF(Nearest10)( CppTypeFor x, bool positive) { return Nearest<64>(x, positive); } #endif CppTypeFor RTDEF(Nint4_1)( CppTypeFor x) { return Nint>(x); } CppTypeFor RTDEF(Nint4_2)( CppTypeFor x) { return Nint>(x); } CppTypeFor RTDEF(Nint4_4)( CppTypeFor x) { return Nint>(x); } CppTypeFor RTDEF(Nint4_8)( CppTypeFor x) { return Nint>(x); } #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T CppTypeFor RTDEF(Nint4_16)( CppTypeFor x) { return Nint>(x); } #endif CppTypeFor RTDEF(Nint8_1)( CppTypeFor x) { return Nint>(x); } CppTypeFor RTDEF(Nint8_2)( CppTypeFor x) { return Nint>(x); } CppTypeFor RTDEF(Nint8_4)( CppTypeFor x) { return Nint>(x); } CppTypeFor RTDEF(Nint8_8)( CppTypeFor x) { return Nint>(x); } #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T CppTypeFor RTDEF(Nint8_16)( CppTypeFor x) { return Nint>(x); } #endif #if HAS_FLOAT80 CppTypeFor RTDEF(Nint10_1)( CppTypeFor x) { return Nint>(x); } CppTypeFor RTDEF(Nint10_2)( CppTypeFor x) { return Nint>(x); } CppTypeFor RTDEF(Nint10_4)( CppTypeFor x) { return Nint>(x); } CppTypeFor RTDEF(Nint10_8)( CppTypeFor x) { return Nint>(x); } #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T CppTypeFor RTDEF(Nint10_16)( CppTypeFor x) { return Nint>(x); } #endif #elif HAS_LDBL128 CppTypeFor RTDEF(Nint16_1)( CppTypeFor x) { return Nint>(x); } CppTypeFor RTDEF(Nint16_2)( CppTypeFor x) { return Nint>(x); } CppTypeFor RTDEF(Nint16_4)( CppTypeFor x) { return Nint>(x); } CppTypeFor RTDEF(Nint16_8)( CppTypeFor x) { return Nint>(x); } #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T CppTypeFor RTDEF(Nint16_16)( CppTypeFor x) { return Nint>(x); } #endif #endif CppTypeFor RTDEF(RRSpacing4)( CppTypeFor x) { return RRSpacing<24>(x); } CppTypeFor RTDEF(RRSpacing8)( CppTypeFor x) { return RRSpacing<53>(x); } #if HAS_FLOAT80 CppTypeFor RTDEF(RRSpacing10)( CppTypeFor x) { return RRSpacing<64>(x); } #endif CppTypeFor RTDEF(SetExponent4)( CppTypeFor x, std::int64_t p) { return SetExponent(x, p); } CppTypeFor RTDEF(SetExponent8)( CppTypeFor x, std::int64_t p) { return SetExponent(x, p); } #if HAS_FLOAT80 CppTypeFor RTDEF(SetExponent10)( CppTypeFor x, std::int64_t p) { return SetExponent(x, p); } #endif CppTypeFor RTDEF(Scale4)( CppTypeFor x, std::int64_t p) { return Scale(x, p); } CppTypeFor RTDEF(Scale8)( CppTypeFor x, std::int64_t p) { return Scale(x, p); } #if HAS_FLOAT80 CppTypeFor RTDEF(Scale10)( CppTypeFor x, std::int64_t p) { return Scale(x, p); } #endif // SELECTED_CHAR_KIND CppTypeFor RTDEF(SelectedCharKind)( const char *source, int line, const char *x, std::size_t length) { static const char *keywords[]{ "ASCII", "DEFAULT", "UCS-2", "ISO_10646", "UCS-4", nullptr}; switch (IdentifyValue(x, length, keywords)) { case 0: // ASCII case 1: // DEFAULT return 1; case 2: // UCS-2 return 2; case 3: // ISO_10646 case 4: // UCS-4 return 4; default: return -1; } } // SELECTED_INT_KIND and SELECTED_UNSIGNED_KIND extension CppTypeFor RTDEF(SelectedIntKind)( const char *source, int line, void *x, int xKind) { return RTNAME(SelectedIntKindMasked)(source, line, x, xKind, (1 << 1) | (1 << 2) | (1 << 4) | (1 << 8) | (1 << 16)); } CppTypeFor RTDEF(SelectedIntKindMasked)( const char *source, int line, void *x, int xKind, int mask) { #ifdef __SIZEOF_INT128__ CppTypeFor r = GetIntArgValue>( source, line, x, xKind, /*defaultValue*/ 0, /*resKind*/ 16); #else std::int64_t r = GetIntArgValue( source, line, x, xKind, /*defaultValue*/ 0, /*resKind*/ 8); #endif return SelectedIntKind(r, mask); } // SELECTED_LOGICAL_KIND CppTypeFor RTDEF(SelectedLogicalKind)( const char *source, int line, void *x, int xKind) { #ifdef __SIZEOF_INT128__ CppTypeFor r = GetIntArgValue>( source, line, x, xKind, /*defaultValue*/ 0, /*resKind*/ 16); #else std::int64_t r = GetIntArgValue( source, line, x, xKind, /*defaultValue*/ 0, /*resKind*/ 8); #endif return SelectedLogicalKind(r); } // SELECTED_REAL_KIND CppTypeFor RTDEF(SelectedRealKind)(const char *source, int line, void *precision, int pKind, void *range, int rKind, void *radix, int dKind) { return RTNAME(SelectedRealKindMasked)(source, line, precision, pKind, range, rKind, radix, dKind, (1 << 2) | (1 << 3) | (1 << 4) | (1 << 8) | (1 << 10) | (1 << 16)); } CppTypeFor RTDEF(SelectedRealKindMasked)( const char *source, int line, void *precision, int pKind, void *range, int rKind, void *radix, int dKind, int mask) { #ifdef __SIZEOF_INT128__ CppTypeFor p = GetIntArgValue>( source, line, precision, pKind, /*defaultValue*/ 0, /*resKind*/ 16); CppTypeFor r = GetIntArgValue>( source, line, range, rKind, /*defaultValue*/ 0, /*resKind*/ 16); CppTypeFor d = GetIntArgValue>( source, line, radix, dKind, /*defaultValue*/ 2, /*resKind*/ 16); #else std::int64_t p = GetIntArgValue( source, line, precision, pKind, /*defaultValue*/ 0, /*resKind*/ 8); std::int64_t r = GetIntArgValue( source, line, range, rKind, /*defaultValue*/ 0, /*resKind*/ 8); std::int64_t d = GetIntArgValue( source, line, radix, dKind, /*defaultValue*/ 2, /*resKind*/ 8); #endif return SelectedRealKind(p, r, d, mask); } #if HAS_FP16 CppTypeFor RTDEF(Spacing2)( CppTypeFor x) { return Spacing<11>(x); } #endif CppTypeFor RTDEF(Spacing2By4)( CppTypeFor x) { return Spacing<11>(x); } #if HAS_BF16 CppTypeFor RTDEF(Spacing3)( CppTypeFor x) { return Spacing<8>(x); } #endif CppTypeFor RTDEF(Spacing3By4)( CppTypeFor x) { return Spacing<8>(x); } CppTypeFor RTDEF(Spacing4)( CppTypeFor x) { return Spacing<24>(x); } CppTypeFor RTDEF(Spacing8)( CppTypeFor x) { return Spacing<53>(x); } #if HAS_FLOAT80 CppTypeFor RTDEF(Spacing10)( CppTypeFor x) { return Spacing<64>(x); } #endif CppTypeFor RTDEF(FPow4i)( CppTypeFor b, CppTypeFor e) { return FPowI(b, e); } CppTypeFor RTDEF(FPow8i)( CppTypeFor b, CppTypeFor e) { return FPowI(b, e); } #if HAS_FLOAT80 CppTypeFor RTDEF(FPow10i)( CppTypeFor b, CppTypeFor e) { return FPowI(b, e); } #endif #if HAS_LDBL128 || HAS_FLOAT128 CppTypeFor RTDEF(FPow16i)( CppTypeFor b, CppTypeFor e) { return FPowI(b, e); } #endif CppTypeFor RTDEF(FPow4k)( CppTypeFor b, CppTypeFor e) { return FPowI(b, e); } CppTypeFor RTDEF(FPow8k)( CppTypeFor b, CppTypeFor e) { return FPowI(b, e); } #if HAS_FLOAT80 CppTypeFor RTDEF(FPow10k)( CppTypeFor b, CppTypeFor e) { return FPowI(b, e); } #endif #if HAS_LDBL128 || HAS_FLOAT128 CppTypeFor RTDEF(FPow16k)( CppTypeFor b, CppTypeFor e) { return FPowI(b, e); } #endif RT_EXT_API_GROUP_END } // extern "C" } // namespace Fortran::runtime