[flang] Implement numeric intrinsic functions in runtime
Adds APIs, implementations, and unit tests for AINT, ANINT, CEILING, EXPONENT, FLOOR, FRACTION, MOD, MODULO, NEAREST, NINT, RRSPACING, SCALE, SET_EXPONENT, & SPACING. Differential Revision: https://reviews.llvm.org/D99764
This commit is contained in:
parent
43ceb74eb1
commit
5f6c5c63c7
|
@ -51,6 +51,7 @@ add_flang_library(FortranRuntime
|
|||
io-stmt.cpp
|
||||
main.cpp
|
||||
memory.cpp
|
||||
numeric.cpp
|
||||
reduction.cpp
|
||||
stat.cpp
|
||||
stop.cpp
|
||||
|
|
773
flang/runtime/numeric.cpp
Normal file
773
flang/runtime/numeric.cpp
Normal file
|
@ -0,0 +1,773 @@
|
|||
//===-- runtime/numeric.cpp -------------------------------------*- 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "numeric.h"
|
||||
#include "flang/Common/long-double.h"
|
||||
#include <climits>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
|
||||
namespace Fortran::runtime {
|
||||
|
||||
// AINT
|
||||
template <typename RESULT, typename ARG> inline RESULT Aint(ARG x) {
|
||||
return std::trunc(x);
|
||||
}
|
||||
|
||||
// ANINT & NINT
|
||||
template <typename RESULT, typename ARG> inline RESULT Anint(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 <typename RESULT, typename ARG> inline RESULT Ceiling(ARG x) {
|
||||
return std::ceil(x);
|
||||
}
|
||||
template <typename RESULT, typename ARG> inline RESULT Floor(ARG x) {
|
||||
return std::floor(x);
|
||||
}
|
||||
|
||||
// EXPONENT (16.9.75)
|
||||
template <typename RESULT, typename ARG> inline RESULT Exponent(ARG x) {
|
||||
if (std::isinf(x) || std::isnan(x)) {
|
||||
return std::numeric_limits<RESULT>::max(); // +/-Inf, NaN -> HUGE(0)
|
||||
} else if (x == 0) {
|
||||
return 0; // 0 -> 0
|
||||
} else {
|
||||
return std::ilogb(x) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// FRACTION (16.9.80)
|
||||
template <typename T> inline T Fraction(T x) {
|
||||
if (std::isnan(x)) {
|
||||
return x; // NaN -> same NaN
|
||||
} else if (std::isinf(x)) {
|
||||
return std::numeric_limits<T>::quiet_NaN(); // +/-Inf -> NaN
|
||||
} else if (x == 0) {
|
||||
return 0; // 0 -> 0
|
||||
} else {
|
||||
int ignoredExp;
|
||||
return std::frexp(x, &ignoredExp);
|
||||
}
|
||||
}
|
||||
|
||||
// MOD & MODULO (16.9.135, .136)
|
||||
template <bool IS_MODULO, typename T> inline T IntMod(T x, T p) {
|
||||
auto mod{x - (x / p) * p};
|
||||
if (IS_MODULO && (x > 0) != (p > 0)) {
|
||||
mod += p;
|
||||
}
|
||||
return mod;
|
||||
}
|
||||
template <bool IS_MODULO, typename T> inline T RealMod(T x, T p) {
|
||||
if constexpr (IS_MODULO) {
|
||||
return x - std::floor(x / p) * p;
|
||||
} else {
|
||||
return x - std::trunc(x / p) * p;
|
||||
}
|
||||
}
|
||||
|
||||
// RRSPACING (16.9.164)
|
||||
template <int PREC, typename T> inline T RRSpacing(T x) {
|
||||
if (std::isnan(x)) {
|
||||
return x; // NaN -> same NaN
|
||||
} else if (std::isinf(x)) {
|
||||
return std::numeric_limits<T>::quiet_NaN(); // +/-Inf -> NaN
|
||||
} else if (x == 0) {
|
||||
return 0; // 0 -> 0
|
||||
} else {
|
||||
return std::ldexp(std::abs(x), PREC - (std::ilogb(x) + 1));
|
||||
}
|
||||
}
|
||||
|
||||
// SCALE (16.9.166)
|
||||
template <typename T> inline T Scale(T x, std::int64_t p) {
|
||||
auto ip{static_cast<int>(p)};
|
||||
if (ip != p) {
|
||||
ip = p < 0 ? std::numeric_limits<int>::min()
|
||||
: std::numeric_limits<int>::max();
|
||||
}
|
||||
return std::ldexp(x, p); // x*2**p
|
||||
}
|
||||
|
||||
// SET_EXPONENT (16.9.171)
|
||||
template <typename T> inline T SetExponent(T x, std::int64_t p) {
|
||||
if (std::isnan(x)) {
|
||||
return x; // NaN -> same NaN
|
||||
} else if (std::isinf(x)) {
|
||||
return std::numeric_limits<T>::quiet_NaN(); // +/-Inf -> NaN
|
||||
} else if (x == 0) {
|
||||
return 0; // 0 -> 0
|
||||
} else {
|
||||
int expo{std::ilogb(x)};
|
||||
auto ip{static_cast<int>(p - expo)};
|
||||
if (ip != p - expo) {
|
||||
ip = p < 0 ? std::numeric_limits<int>::min()
|
||||
: std::numeric_limits<int>::max();
|
||||
}
|
||||
return std::ldexp(x, ip); // x*2**(p-e)
|
||||
}
|
||||
}
|
||||
|
||||
// SPACING (16.9.180)
|
||||
template <int PREC, typename T> inline T Spacing(T x) {
|
||||
if (std::isnan(x)) {
|
||||
return x; // NaN -> same NaN
|
||||
} else if (std::isinf(x)) {
|
||||
return std::numeric_limits<T>::quiet_NaN(); // +/-Inf -> NaN
|
||||
} else if (x == 0) {
|
||||
// The standard-mandated behavior seems broken, since TINY() can't be
|
||||
// subnormal.
|
||||
return std::numeric_limits<T>::min(); // 0 -> TINY(x)
|
||||
} else {
|
||||
return std::ldexp(
|
||||
static_cast<T>(1.0), std::ilogb(x) + 1 - PREC); // 2**(e-p)
|
||||
}
|
||||
}
|
||||
|
||||
// NEAREST (16.9.139)
|
||||
template <int PREC, typename T> inline T Nearest(T x, bool positive) {
|
||||
auto spacing{Spacing<PREC>(x)};
|
||||
if (x == 0) {
|
||||
auto least{std::numeric_limits<T>::denorm_min()};
|
||||
return positive ? least : -least;
|
||||
} else {
|
||||
return positive ? x + spacing : x - spacing;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint4_4)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Aint<CppTypeFor<TypeCategory::Real, 4>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint4_8)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Aint<CppTypeFor<TypeCategory::Real, 8>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint8_4)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Aint<CppTypeFor<TypeCategory::Real, 4>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint8_8)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Aint<CppTypeFor<TypeCategory::Real, 8>>(x);
|
||||
}
|
||||
#if LONG_DOUBLE == 80
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint4_10)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Aint<CppTypeFor<TypeCategory::Real, 10>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint8_10)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Aint<CppTypeFor<TypeCategory::Real, 10>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint10_4)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Aint<CppTypeFor<TypeCategory::Real, 4>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint10_8)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Aint<CppTypeFor<TypeCategory::Real, 8>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint10_10)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Aint<CppTypeFor<TypeCategory::Real, 10>>(x);
|
||||
}
|
||||
#elif LONG_DOUBLE == 128
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint4_16)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Aint<CppTypeFor<TypeCategory::Real, 16>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint8_16)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Aint<CppTypeFor<TypeCategory::Real, 16>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint16_4)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Aint<CppTypeFor<TypeCategory::Real, 4>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint16_8)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Aint<CppTypeFor<TypeCategory::Real, 8>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint16_16)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Aint<CppTypeFor<TypeCategory::Real, 16>>(x);
|
||||
}
|
||||
#endif
|
||||
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint4_4)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Real, 4>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint4_8)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Real, 8>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint8_4)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Real, 4>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint8_8)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Real, 8>>(x);
|
||||
}
|
||||
#if LONG_DOUBLE == 80
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint4_10)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Real, 10>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint8_10)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Real, 10>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint10_4)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Real, 4>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint10_8)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Real, 8>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint10_10)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Real, 10>>(x);
|
||||
}
|
||||
#elif LONG_DOUBLE == 128
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint4_16)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Real, 16>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint8_16)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Real, 16>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint16_4)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Real, 4>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint16_8)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Real, 8>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint16_16)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Real, 16>>(x);
|
||||
}
|
||||
#endif
|
||||
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling4_1)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Ceiling4_2)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Ceiling4_4)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling4_8)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling4_16)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling8_1)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Ceiling8_2)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Ceiling8_4)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling8_8)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling8_16)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x);
|
||||
}
|
||||
#if LONG_DOUBLE == 80
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling10_1)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Ceiling10_2)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Ceiling10_4)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling10_8)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling10_16)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x);
|
||||
}
|
||||
#else
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling16_1)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Ceiling16_2)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Ceiling16_4)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling16_8)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling16_16)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x);
|
||||
}
|
||||
#endif
|
||||
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent4_4)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent4_8)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent8_4)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent8_8)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x);
|
||||
}
|
||||
#if LONG_DOUBLE == 80
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent10_4)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent10_8)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x);
|
||||
}
|
||||
#elif LONG_DOUBLE == 128
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent16_4)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent16_8)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x);
|
||||
}
|
||||
#endif
|
||||
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor4_1)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Floor4_2)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Floor4_4)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor4_8)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor4_16)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor8_1)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Floor8_2)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Floor8_4)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor8_8)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor8_16)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x);
|
||||
}
|
||||
#if LONG_DOUBLE == 80
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor10_1)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Floor10_2)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Floor10_4)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor10_8)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor10_16)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x);
|
||||
}
|
||||
#else
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor16_1)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Floor16_2)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Floor16_4)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor16_8)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor16_16)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x);
|
||||
}
|
||||
#endif
|
||||
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(Fraction4)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Fraction(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(Fraction8)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Fraction(x);
|
||||
}
|
||||
#if LONG_DOUBLE == 80
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(Fraction10)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Fraction(x);
|
||||
}
|
||||
#elif LONG_DOUBLE == 128
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(Fraction16)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Fraction(x);
|
||||
}
|
||||
#endif
|
||||
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModInteger1)(
|
||||
CppTypeFor<TypeCategory::Integer, 1> x,
|
||||
CppTypeFor<TypeCategory::Integer, 1> p) {
|
||||
return IntMod<false>(x, p);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModInteger2)(
|
||||
CppTypeFor<TypeCategory::Integer, 2> x,
|
||||
CppTypeFor<TypeCategory::Integer, 2> p) {
|
||||
return IntMod<false>(x, p);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModInteger4)(
|
||||
CppTypeFor<TypeCategory::Integer, 4> x,
|
||||
CppTypeFor<TypeCategory::Integer, 4> p) {
|
||||
return IntMod<false>(x, p);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModInteger8)(
|
||||
CppTypeFor<TypeCategory::Integer, 8> x,
|
||||
CppTypeFor<TypeCategory::Integer, 8> p) {
|
||||
return IntMod<false>(x, p);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModInteger16)(
|
||||
CppTypeFor<TypeCategory::Integer, 16> x,
|
||||
CppTypeFor<TypeCategory::Integer, 16> p) {
|
||||
return IntMod<false>(x, p);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(ModReal4)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p) {
|
||||
return RealMod<false>(x, p);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(ModReal8)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p) {
|
||||
return RealMod<false>(x, p);
|
||||
}
|
||||
#if LONG_DOUBLE == 80
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(ModReal10)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x,
|
||||
CppTypeFor<TypeCategory::Real, 10> p) {
|
||||
return RealMod<false>(x, p);
|
||||
}
|
||||
#elif LONG_DOUBLE == 128
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(ModReal16)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x,
|
||||
CppTypeFor<TypeCategory::Real, 16> p) {
|
||||
return RealMod<false>(x, p);
|
||||
}
|
||||
#endif
|
||||
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModuloInteger1)(
|
||||
CppTypeFor<TypeCategory::Integer, 1> x,
|
||||
CppTypeFor<TypeCategory::Integer, 1> p) {
|
||||
return IntMod<true>(x, p);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModuloInteger2)(
|
||||
CppTypeFor<TypeCategory::Integer, 2> x,
|
||||
CppTypeFor<TypeCategory::Integer, 2> p) {
|
||||
return IntMod<true>(x, p);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModuloInteger4)(
|
||||
CppTypeFor<TypeCategory::Integer, 4> x,
|
||||
CppTypeFor<TypeCategory::Integer, 4> p) {
|
||||
return IntMod<true>(x, p);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModuloInteger8)(
|
||||
CppTypeFor<TypeCategory::Integer, 8> x,
|
||||
CppTypeFor<TypeCategory::Integer, 8> p) {
|
||||
return IntMod<true>(x, p);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModuloInteger16)(
|
||||
CppTypeFor<TypeCategory::Integer, 16> x,
|
||||
CppTypeFor<TypeCategory::Integer, 16> p) {
|
||||
return IntMod<true>(x, p);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(ModuloReal4)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p) {
|
||||
return RealMod<true>(x, p);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(ModuloReal8)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p) {
|
||||
return RealMod<true>(x, p);
|
||||
}
|
||||
#if LONG_DOUBLE == 80
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(ModuloReal10)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x,
|
||||
CppTypeFor<TypeCategory::Real, 10> p) {
|
||||
return RealMod<true>(x, p);
|
||||
}
|
||||
#elif LONG_DOUBLE == 128
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(ModuloReal16)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x,
|
||||
CppTypeFor<TypeCategory::Real, 16> p) {
|
||||
return RealMod<true>(x, p);
|
||||
}
|
||||
#endif
|
||||
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(Nearest4)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x, bool positive) {
|
||||
return Nearest<24>(x, positive);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(Nearest8)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x, bool positive) {
|
||||
return Nearest<53>(x, positive);
|
||||
}
|
||||
#if LONG_DOUBLE == 80
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(Nearest10)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x, bool positive) {
|
||||
return Nearest<64>(x, positive);
|
||||
}
|
||||
#elif LONG_DOUBLE == 128
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(Nearest16)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x, bool positive) {
|
||||
return Nearest<113>(x, positive);
|
||||
}
|
||||
#endif
|
||||
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint4_1)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint4_2)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Integer, 2>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint4_4)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Integer, 4>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint4_8)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Integer, 8>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint4_16)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint8_1)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint8_2)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Integer, 2>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint8_4)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Integer, 4>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint8_8)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Integer, 8>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint8_16)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x);
|
||||
}
|
||||
#if LONG_DOUBLE == 80
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint10_1)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint10_2)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Integer, 2>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint10_4)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Integer, 4>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint10_8)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Integer, 8>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint10_16)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x);
|
||||
}
|
||||
#else
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint16_1)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint16_2)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Integer, 2>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint16_4)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Integer, 4>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint16_8)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Integer, 8>>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint16_16)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x);
|
||||
}
|
||||
#endif
|
||||
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(RRSpacing4)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return RRSpacing<24>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(RRSpacing8)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return RRSpacing<53>(x);
|
||||
}
|
||||
#if LONG_DOUBLE == 80
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(RRSpacing10)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return RRSpacing<64>(x);
|
||||
}
|
||||
#elif LONG_DOUBLE == 128
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(RRSpacing16)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return RRSpacing<113>(x);
|
||||
}
|
||||
#endif
|
||||
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(SetExponent4)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x, std::int64_t p) {
|
||||
return SetExponent(x, p);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(SetExponent8)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x, std::int64_t p) {
|
||||
return SetExponent(x, p);
|
||||
}
|
||||
#if LONG_DOUBLE == 80
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(SetExponent10)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x, std::int64_t p) {
|
||||
return SetExponent(x, p);
|
||||
}
|
||||
#elif LONG_DOUBLE == 128
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(SetExponent16)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x, std::int64_t p) {
|
||||
return SetExponent(x, p);
|
||||
}
|
||||
#endif
|
||||
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(Scale4)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x, std::int64_t p) {
|
||||
return Scale(x, p);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(Scale8)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x, std::int64_t p) {
|
||||
return Scale(x, p);
|
||||
}
|
||||
#if LONG_DOUBLE == 80
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(Scale10)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x, std::int64_t p) {
|
||||
return Scale(x, p);
|
||||
}
|
||||
#elif LONG_DOUBLE == 128
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(Scale16)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x, std::int64_t p) {
|
||||
return Scale(x, p);
|
||||
}
|
||||
#endif
|
||||
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(Spacing4)(
|
||||
CppTypeFor<TypeCategory::Real, 4> x) {
|
||||
return Spacing<24>(x);
|
||||
}
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(Spacing8)(
|
||||
CppTypeFor<TypeCategory::Real, 8> x) {
|
||||
return Spacing<53>(x);
|
||||
}
|
||||
#if LONG_DOUBLE == 80
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(Spacing10)(
|
||||
CppTypeFor<TypeCategory::Real, 10> x) {
|
||||
return Spacing<64>(x);
|
||||
}
|
||||
#elif LONG_DOUBLE == 128
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(Spacing16)(
|
||||
CppTypeFor<TypeCategory::Real, 16> x) {
|
||||
return Spacing<113>(x);
|
||||
}
|
||||
#endif
|
||||
} // extern "C"
|
||||
} // namespace Fortran::runtime
|
329
flang/runtime/numeric.h
Normal file
329
flang/runtime/numeric.h
Normal file
|
@ -0,0 +1,329 @@
|
|||
//===-- runtime/numeric.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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Defines API between compiled code and the implementations of various numeric
|
||||
// intrinsic functions in the runtime library.
|
||||
|
||||
#ifndef FORTRAN_RUNTIME_NUMERIC_H_
|
||||
#define FORTRAN_RUNTIME_NUMERIC_H_
|
||||
|
||||
#include "cpp-type.h"
|
||||
#include "entry-names.h"
|
||||
|
||||
namespace Fortran::runtime {
|
||||
extern "C" {
|
||||
|
||||
// AINT
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint4_4)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint4_8)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint4_10)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint4_16)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint8_4)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint8_8)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint8_10)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint8_16)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
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>);
|
||||
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>);
|
||||
|
||||
// ANINT
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint4_4)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint4_8)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint4_10)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint4_16)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint8_4)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint8_8)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint8_10)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint8_16)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
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>);
|
||||
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>);
|
||||
|
||||
// CEILING
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling4_1)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Ceiling4_2)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Ceiling4_4)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling4_8)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling4_16)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling8_1)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Ceiling8_2)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Ceiling8_4)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling8_8)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling8_16)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling10_1)(
|
||||
CppTypeFor<TypeCategory::Real, 10>);
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Ceiling10_2)(
|
||||
CppTypeFor<TypeCategory::Real, 10>);
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Ceiling10_4)(
|
||||
CppTypeFor<TypeCategory::Real, 10>);
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling10_8)(
|
||||
CppTypeFor<TypeCategory::Real, 10>);
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling10_16)(
|
||||
CppTypeFor<TypeCategory::Real, 10>);
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling16_1)(
|
||||
CppTypeFor<TypeCategory::Real, 16>);
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Ceiling16_2)(
|
||||
CppTypeFor<TypeCategory::Real, 16>);
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Ceiling16_4)(
|
||||
CppTypeFor<TypeCategory::Real, 16>);
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling16_8)(
|
||||
CppTypeFor<TypeCategory::Real, 16>);
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling16_16)(
|
||||
CppTypeFor<TypeCategory::Real, 16>);
|
||||
|
||||
// EXPONENT is defined to return default INTEGER; support INTEGER(4 & 8)
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent4_4)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent4_8)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent8_4)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent8_8)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent10_4)(
|
||||
CppTypeFor<TypeCategory::Real, 10>);
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent10_8)(
|
||||
CppTypeFor<TypeCategory::Real, 10>);
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent16_4)(
|
||||
CppTypeFor<TypeCategory::Real, 16>);
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent16_8)(
|
||||
CppTypeFor<TypeCategory::Real, 16>);
|
||||
|
||||
// FLOOR
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor4_1)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Floor4_2)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Floor4_4)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor4_8)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor4_16)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor8_1)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Floor8_2)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Floor8_4)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor8_8)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor8_16)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor10_1)(
|
||||
CppTypeFor<TypeCategory::Real, 10>);
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Floor10_2)(
|
||||
CppTypeFor<TypeCategory::Real, 10>);
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Floor10_4)(
|
||||
CppTypeFor<TypeCategory::Real, 10>);
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor10_8)(
|
||||
CppTypeFor<TypeCategory::Real, 10>);
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor10_16)(
|
||||
CppTypeFor<TypeCategory::Real, 10>);
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor16_1)(
|
||||
CppTypeFor<TypeCategory::Real, 16>);
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Floor16_2)(
|
||||
CppTypeFor<TypeCategory::Real, 16>);
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Floor16_4)(
|
||||
CppTypeFor<TypeCategory::Real, 16>);
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor16_8)(
|
||||
CppTypeFor<TypeCategory::Real, 16>);
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor16_16)(
|
||||
CppTypeFor<TypeCategory::Real, 16>);
|
||||
|
||||
// FRACTION
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(Fraction4)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(Fraction8)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(Fraction10)(
|
||||
CppTypeFor<TypeCategory::Real, 10>);
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(Fraction16)(
|
||||
CppTypeFor<TypeCategory::Real, 16>);
|
||||
|
||||
// MOD & MODULO
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModInteger1)(
|
||||
CppTypeFor<TypeCategory::Integer, 1>, CppTypeFor<TypeCategory::Integer, 1>);
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModInteger2)(
|
||||
CppTypeFor<TypeCategory::Integer, 2>, CppTypeFor<TypeCategory::Integer, 2>);
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModInteger4)(
|
||||
CppTypeFor<TypeCategory::Integer, 4>, CppTypeFor<TypeCategory::Integer, 4>);
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModInteger8)(
|
||||
CppTypeFor<TypeCategory::Integer, 8>, CppTypeFor<TypeCategory::Integer, 8>);
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModInteger16)(
|
||||
CppTypeFor<TypeCategory::Integer, 16>,
|
||||
CppTypeFor<TypeCategory::Integer, 16>);
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(ModReal4)(
|
||||
CppTypeFor<TypeCategory::Real, 4>, CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(ModReal8)(
|
||||
CppTypeFor<TypeCategory::Real, 8>, CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(ModReal10)(
|
||||
CppTypeFor<TypeCategory::Real, 10>, CppTypeFor<TypeCategory::Real, 10>);
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(ModReal16)(
|
||||
CppTypeFor<TypeCategory::Real, 16>, CppTypeFor<TypeCategory::Real, 16>);
|
||||
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModuloInteger1)(
|
||||
CppTypeFor<TypeCategory::Integer, 1>, CppTypeFor<TypeCategory::Integer, 1>);
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModuloInteger2)(
|
||||
CppTypeFor<TypeCategory::Integer, 2>, CppTypeFor<TypeCategory::Integer, 2>);
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModuloInteger4)(
|
||||
CppTypeFor<TypeCategory::Integer, 4>, CppTypeFor<TypeCategory::Integer, 4>);
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModuloInteger8)(
|
||||
CppTypeFor<TypeCategory::Integer, 8>, CppTypeFor<TypeCategory::Integer, 8>);
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModuloInteger16)(
|
||||
CppTypeFor<TypeCategory::Integer, 16>,
|
||||
CppTypeFor<TypeCategory::Integer, 16>);
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(ModuloReal4)(
|
||||
CppTypeFor<TypeCategory::Real, 4>, CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(ModuloReal8)(
|
||||
CppTypeFor<TypeCategory::Real, 8>, CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(ModuloReal10)(
|
||||
CppTypeFor<TypeCategory::Real, 10>, CppTypeFor<TypeCategory::Real, 10>);
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(ModuloReal16)(
|
||||
CppTypeFor<TypeCategory::Real, 16>, CppTypeFor<TypeCategory::Real, 16>);
|
||||
|
||||
// NINT
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint4_1)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint4_2)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint4_4)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint4_8)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint4_16)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint8_1)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint8_2)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint8_4)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint8_8)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint8_16)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint10_1)(
|
||||
CppTypeFor<TypeCategory::Real, 10>);
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint10_2)(
|
||||
CppTypeFor<TypeCategory::Real, 10>);
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint10_4)(
|
||||
CppTypeFor<TypeCategory::Real, 10>);
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint10_8)(
|
||||
CppTypeFor<TypeCategory::Real, 10>);
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint10_16)(
|
||||
CppTypeFor<TypeCategory::Real, 10>);
|
||||
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint16_1)(
|
||||
CppTypeFor<TypeCategory::Real, 16>);
|
||||
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint16_2)(
|
||||
CppTypeFor<TypeCategory::Real, 16>);
|
||||
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint16_4)(
|
||||
CppTypeFor<TypeCategory::Real, 16>);
|
||||
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint16_8)(
|
||||
CppTypeFor<TypeCategory::Real, 16>);
|
||||
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint16_16)(
|
||||
CppTypeFor<TypeCategory::Real, 16>);
|
||||
|
||||
// NEAREST
|
||||
// The second argument to NEAREST is the result of a comparison
|
||||
// to zero (i.e., S > 0)
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(Nearest4)(
|
||||
CppTypeFor<TypeCategory::Real, 4>, bool positive);
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(Nearest8)(
|
||||
CppTypeFor<TypeCategory::Real, 8>, bool positive);
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(Nearest10)(
|
||||
CppTypeFor<TypeCategory::Real, 10>, bool positive);
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(Nearest16)(
|
||||
CppTypeFor<TypeCategory::Real, 16>, bool positive);
|
||||
|
||||
// RRSPACING
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(RRSpacing4)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(RRSpacing8)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(RRSpacing10)(
|
||||
CppTypeFor<TypeCategory::Real, 10>);
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(RRSpacing16)(
|
||||
CppTypeFor<TypeCategory::Real, 16>);
|
||||
|
||||
// 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);
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(SetExponent10)(
|
||||
CppTypeFor<TypeCategory::Real, 10>, std::int64_t);
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(SetExponent16)(
|
||||
CppTypeFor<TypeCategory::Real, 16>, std::int64_t);
|
||||
|
||||
// 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);
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(Scale10)(
|
||||
CppTypeFor<TypeCategory::Real, 10>, std::int64_t);
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(Scale16)(
|
||||
CppTypeFor<TypeCategory::Real, 16>, std::int64_t);
|
||||
|
||||
// SPACING
|
||||
CppTypeFor<TypeCategory::Real, 4> RTNAME(Spacing4)(
|
||||
CppTypeFor<TypeCategory::Real, 4>);
|
||||
CppTypeFor<TypeCategory::Real, 8> RTNAME(Spacing8)(
|
||||
CppTypeFor<TypeCategory::Real, 8>);
|
||||
CppTypeFor<TypeCategory::Real, 10> RTNAME(Spacing10)(
|
||||
CppTypeFor<TypeCategory::Real, 10>);
|
||||
CppTypeFor<TypeCategory::Real, 16> RTNAME(Spacing16)(
|
||||
CppTypeFor<TypeCategory::Real, 16>);
|
||||
} // extern "C"
|
||||
} // namespace Fortran::runtime
|
||||
#endif // FORTRAN_RUNTIME_NUMERIC_H_
|
|
@ -1,6 +1,7 @@
|
|||
add_flang_unittest(FlangRuntimeTests
|
||||
CharacterTest.cpp
|
||||
CrashHandlerFixture.cpp
|
||||
Numeric.cpp
|
||||
NumericalFormatTest.cpp
|
||||
Reduction.cpp
|
||||
RuntimeCrashTest.cpp
|
||||
|
|
168
flang/unittests/RuntimeGTest/Numeric.cpp
Normal file
168
flang/unittests/RuntimeGTest/Numeric.cpp
Normal file
|
@ -0,0 +1,168 @@
|
|||
//===-- flang/unittests/RuntimeGTest/Numeric.cpp ----------------*- 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../../runtime/numeric.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
|
||||
using namespace Fortran::runtime;
|
||||
using Fortran::common::TypeCategory;
|
||||
template <int KIND> using Int = CppTypeFor<TypeCategory::Integer, KIND>;
|
||||
template <int KIND> using Real = CppTypeFor<TypeCategory::Real, KIND>;
|
||||
|
||||
// Simple tests of numeric intrinsic functions using examples from Fortran 2018
|
||||
|
||||
TEST(Numeric, Aint) {
|
||||
EXPECT_EQ(RTNAME(Aint4_4)(Real<4>{3.7}), 3.0);
|
||||
EXPECT_EQ(RTNAME(Aint8_4)(Real<8>{-3.7}), -3.0);
|
||||
EXPECT_EQ(RTNAME(Aint8_8)(Real<8>{0}), 0.0);
|
||||
EXPECT_EQ(RTNAME(Aint4_4)(std::numeric_limits<Real<4>>::infinity()),
|
||||
std::numeric_limits<Real<4>>::infinity());
|
||||
EXPECT_TRUE(
|
||||
std::isnan(RTNAME(Aint8_8)(std::numeric_limits<Real<8>>::quiet_NaN())));
|
||||
}
|
||||
|
||||
TEST(Numeric, Anint) {
|
||||
EXPECT_EQ(RTNAME(Anint4_4)(Real<4>{2.783}), 3.0);
|
||||
EXPECT_EQ(RTNAME(Anint8_4)(Real<8>{-2.783}), -3.0);
|
||||
EXPECT_EQ(RTNAME(Anint4_4)(Real<4>{2.5}), 3.0);
|
||||
EXPECT_EQ(RTNAME(Anint8_4)(Real<8>{-2.5}), -3.0);
|
||||
EXPECT_EQ(RTNAME(Anint8_8)(Real<8>{0}), 0.0);
|
||||
EXPECT_EQ(RTNAME(Anint4_4)(std::numeric_limits<Real<4>>::infinity()),
|
||||
std::numeric_limits<Real<4>>::infinity());
|
||||
EXPECT_TRUE(
|
||||
std::isnan(RTNAME(Aint8_8)(std::numeric_limits<Real<8>>::quiet_NaN())));
|
||||
}
|
||||
|
||||
TEST(Numeric, Ceiling) {
|
||||
EXPECT_EQ(RTNAME(Ceiling4_4)(Real<4>{3.7}), 4);
|
||||
EXPECT_EQ(RTNAME(Ceiling8_8)(Real<8>{-3.7}), -3);
|
||||
EXPECT_EQ(RTNAME(Ceiling4_1)(Real<4>{0}), 0);
|
||||
EXPECT_EQ(RTNAME(Ceiling4_4)(std::numeric_limits<Real<4>>::infinity()),
|
||||
std::numeric_limits<Int<4>>::min());
|
||||
EXPECT_EQ(RTNAME(Ceiling4_4)(std::numeric_limits<Real<4>>::quiet_NaN()),
|
||||
std::numeric_limits<Int<4>>::min());
|
||||
}
|
||||
|
||||
TEST(Numeric, Floor) {
|
||||
EXPECT_EQ(RTNAME(Floor4_4)(Real<4>{3.7}), 3);
|
||||
EXPECT_EQ(RTNAME(Floor8_8)(Real<8>{-3.7}), -4);
|
||||
EXPECT_EQ(RTNAME(Floor4_1)(Real<4>{0}), 0);
|
||||
EXPECT_EQ(RTNAME(Floor4_4)(std::numeric_limits<Real<4>>::infinity()),
|
||||
std::numeric_limits<Int<4>>::min());
|
||||
EXPECT_EQ(RTNAME(Floor4_4)(std::numeric_limits<Real<4>>::quiet_NaN()),
|
||||
std::numeric_limits<Int<4>>::min());
|
||||
}
|
||||
|
||||
TEST(Numeric, Exponent) {
|
||||
EXPECT_EQ(RTNAME(Exponent4_4)(Real<4>{0}), 0);
|
||||
EXPECT_EQ(RTNAME(Exponent4_8)(Real<4>{1.0}), 1);
|
||||
EXPECT_EQ(RTNAME(Exponent8_4)(Real<8>{4.1}), 3);
|
||||
EXPECT_EQ(RTNAME(Exponent8_8)(std::numeric_limits<Real<8>>::infinity()),
|
||||
std::numeric_limits<Int<8>>::max());
|
||||
EXPECT_EQ(RTNAME(Exponent8_8)(std::numeric_limits<Real<8>>::quiet_NaN()),
|
||||
std::numeric_limits<Int<8>>::max());
|
||||
}
|
||||
|
||||
TEST(Numeric, Fraction) {
|
||||
EXPECT_EQ(RTNAME(Fraction4)(Real<4>{0}), 0);
|
||||
EXPECT_EQ(RTNAME(Fraction8)(Real<8>{3.0}), 0.75);
|
||||
EXPECT_TRUE(
|
||||
std::isnan(RTNAME(Fraction4)(std::numeric_limits<Real<4>>::infinity())));
|
||||
EXPECT_TRUE(
|
||||
std::isnan(RTNAME(Fraction8)(std::numeric_limits<Real<8>>::quiet_NaN())));
|
||||
}
|
||||
|
||||
TEST(Numeric, Mod) {
|
||||
EXPECT_EQ(RTNAME(ModInteger1)(Int<1>{8}, Int<1>(5)), 3);
|
||||
EXPECT_EQ(RTNAME(ModInteger4)(Int<4>{-8}, Int<4>(5)), -3);
|
||||
EXPECT_EQ(RTNAME(ModInteger2)(Int<2>{8}, Int<2>(-5)), 3);
|
||||
EXPECT_EQ(RTNAME(ModInteger8)(Int<8>{-8}, Int<8>(-5)), -3);
|
||||
EXPECT_EQ(RTNAME(ModReal4)(Real<4>{8.0}, Real<4>(5.0)), 3.0);
|
||||
EXPECT_EQ(RTNAME(ModReal4)(Real<4>{-8.0}, Real<4>(5.0)), -3.0);
|
||||
EXPECT_EQ(RTNAME(ModReal8)(Real<8>{8.0}, Real<8>(-5.0)), 3.0);
|
||||
EXPECT_EQ(RTNAME(ModReal8)(Real<8>{-8.0}, Real<8>(-5.0)), -3.0);
|
||||
}
|
||||
|
||||
TEST(Numeric, Modulo) {
|
||||
EXPECT_EQ(RTNAME(ModuloInteger1)(Int<1>{8}, Int<1>(5)), 3);
|
||||
EXPECT_EQ(RTNAME(ModuloInteger4)(Int<4>{-8}, Int<4>(5)), 2);
|
||||
EXPECT_EQ(RTNAME(ModuloInteger2)(Int<2>{8}, Int<2>(-5)), -2);
|
||||
EXPECT_EQ(RTNAME(ModuloInteger8)(Int<8>{-8}, Int<8>(-5)), -3);
|
||||
EXPECT_EQ(RTNAME(ModuloReal4)(Real<4>{8.0}, Real<4>(5.0)), 3.0);
|
||||
EXPECT_EQ(RTNAME(ModuloReal4)(Real<4>{-8.0}, Real<4>(5.0)), 2.0);
|
||||
EXPECT_EQ(RTNAME(ModuloReal8)(Real<8>{8.0}, Real<8>(-5.0)), -2.0);
|
||||
EXPECT_EQ(RTNAME(ModuloReal8)(Real<8>{-8.0}, Real<8>(-5.0)), -3.0);
|
||||
}
|
||||
|
||||
TEST(Numeric, Nearest) {
|
||||
EXPECT_EQ(RTNAME(Nearest4)(Real<4>{0}, true),
|
||||
std::numeric_limits<Real<4>>::denorm_min());
|
||||
EXPECT_EQ(RTNAME(Nearest4)(Real<4>{3.0}, true),
|
||||
Real<4>{3.0} + std::ldexp(Real<4>{1.0}, -22));
|
||||
EXPECT_EQ(RTNAME(Nearest8)(Real<8>{1.0}, true),
|
||||
Real<8>{1.0} + std::ldexp(Real<8>{1.0}, -52));
|
||||
EXPECT_EQ(RTNAME(Nearest8)(Real<8>{1.0}, false),
|
||||
Real<8>{1.0} - std::ldexp(Real<8>{1.0}, -52));
|
||||
}
|
||||
|
||||
TEST(Numeric, Nint) {
|
||||
EXPECT_EQ(RTNAME(Nint4_4)(Real<4>{2.783}), 3);
|
||||
EXPECT_EQ(RTNAME(Nint8_4)(Real<8>{-2.783}), -3);
|
||||
EXPECT_EQ(RTNAME(Nint4_4)(Real<4>{2.5}), 3);
|
||||
EXPECT_EQ(RTNAME(Nint8_4)(Real<8>{-2.5}), -3);
|
||||
EXPECT_EQ(RTNAME(Nint8_8)(Real<8>{0}), 0);
|
||||
EXPECT_EQ(RTNAME(Nint4_4)(std::numeric_limits<Real<4>>::infinity()),
|
||||
std::numeric_limits<Int<4>>::min());
|
||||
EXPECT_EQ(RTNAME(Nint4_4)(std::numeric_limits<Real<4>>::quiet_NaN()),
|
||||
std::numeric_limits<Int<4>>::min());
|
||||
}
|
||||
|
||||
TEST(Numeric, RRSpacing) {
|
||||
EXPECT_EQ(RTNAME(RRSpacing8)(Real<8>{0}), 0);
|
||||
EXPECT_EQ(RTNAME(RRSpacing4)(Real<4>{-3.0}), 0.75 * (1 << 24));
|
||||
EXPECT_EQ(RTNAME(RRSpacing8)(Real<8>{-3.0}), 0.75 * (std::int64_t{1} << 53));
|
||||
EXPECT_TRUE(
|
||||
std::isnan(RTNAME(RRSpacing4)(std::numeric_limits<Real<4>>::infinity())));
|
||||
EXPECT_TRUE(std::isnan(
|
||||
RTNAME(RRSpacing8)(std::numeric_limits<Real<8>>::quiet_NaN())));
|
||||
}
|
||||
|
||||
TEST(Numeric, Scale) {
|
||||
EXPECT_EQ(RTNAME(Scale4)(Real<4>{0}, 0), 0);
|
||||
EXPECT_EQ(RTNAME(Scale4)(Real<4>{1.0}, 0), 1.0);
|
||||
EXPECT_EQ(RTNAME(Scale4)(Real<4>{1.0}, 1), 2.0);
|
||||
EXPECT_EQ(RTNAME(Scale4)(Real<4>{1.0}, -1), 0.5);
|
||||
EXPECT_TRUE(
|
||||
std::isinf(RTNAME(Scale4)(std::numeric_limits<Real<4>>::infinity(), 1)));
|
||||
EXPECT_TRUE(
|
||||
std::isnan(RTNAME(Scale8)(std::numeric_limits<Real<8>>::quiet_NaN(), 1)));
|
||||
}
|
||||
|
||||
TEST(Numeric, SetExponent) {
|
||||
EXPECT_EQ(RTNAME(SetExponent4)(Real<4>{0}, 0), 0);
|
||||
EXPECT_EQ(RTNAME(SetExponent8)(Real<8>{0}, 666), 0);
|
||||
EXPECT_EQ(RTNAME(SetExponent8)(Real<8>{3.0}, 0), 1.5);
|
||||
EXPECT_EQ(RTNAME(SetExponent4)(Real<4>{1.0}, 0), 1.0);
|
||||
EXPECT_EQ(RTNAME(SetExponent4)(Real<4>{1.0}, 1), 2.0);
|
||||
EXPECT_EQ(RTNAME(SetExponent4)(Real<4>{1.0}, -1), 0.5);
|
||||
EXPECT_TRUE(std::isnan(
|
||||
RTNAME(SetExponent4)(std::numeric_limits<Real<4>>::infinity(), 1)));
|
||||
EXPECT_TRUE(std::isnan(
|
||||
RTNAME(SetExponent8)(std::numeric_limits<Real<8>>::quiet_NaN(), 1)));
|
||||
}
|
||||
|
||||
TEST(Numeric, Spacing) {
|
||||
EXPECT_EQ(RTNAME(Spacing8)(Real<8>{0}), std::numeric_limits<Real<8>>::min());
|
||||
EXPECT_EQ(RTNAME(Spacing4)(Real<4>{3.0}), std::ldexp(Real<4>{1.0}, -22));
|
||||
EXPECT_TRUE(
|
||||
std::isnan(RTNAME(Spacing4)(std::numeric_limits<Real<4>>::infinity())));
|
||||
EXPECT_TRUE(
|
||||
std::isnan(RTNAME(Spacing8)(std::numeric_limits<Real<8>>::quiet_NaN())));
|
||||
}
|
Loading…
Reference in a new issue