1 //===-- runtime/numeric.cpp -----------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "flang/Runtime/numeric.h"
10 #include "numeric-templates.h"
11 #include "terminator.h"
13 #include "flang/Common/float128.h"
19 namespace Fortran::runtime
{
21 template <typename RES
>
22 inline RT_API_ATTRS RES
GetIntArgValue(const char *source
, int line
,
23 const void *arg
, int kind
, std::int64_t defaultValue
, int resKind
) {
26 res
= static_cast<RES
>(defaultValue
);
27 } else if (kind
== 1) {
28 res
= static_cast<RES
>(
29 *static_cast<const CppTypeFor
<TypeCategory::Integer
, 1> *>(arg
));
30 } else if (kind
== 2) {
31 res
= static_cast<RES
>(
32 *static_cast<const CppTypeFor
<TypeCategory::Integer
, 2> *>(arg
));
33 } else if (kind
== 4) {
34 res
= static_cast<RES
>(
35 *static_cast<const CppTypeFor
<TypeCategory::Integer
, 4> *>(arg
));
36 } else if (kind
== 8) {
37 res
= static_cast<RES
>(
38 *static_cast<const CppTypeFor
<TypeCategory::Integer
, 8> *>(arg
));
39 #ifdef __SIZEOF_INT128__
40 } else if (kind
== 16) {
42 Terminator
{source
, line
}.Crash("Unexpected integer kind in runtime");
44 res
= static_cast<RES
>(
45 *static_cast<const CppTypeFor
<TypeCategory::Integer
, 16> *>(arg
));
48 Terminator
{source
, line
}.Crash("Unexpected integer kind in runtime");
54 template <typename RESULT
, typename ARG
>
55 inline RT_API_ATTRS RESULT
Nint(ARG x
) {
57 return std::trunc(x
+ ARG
{0.5});
59 return std::trunc(x
- ARG
{0.5});
63 // CEILING & FLOOR (16.9.43, .79)
64 template <typename RESULT
, typename ARG
>
65 inline RT_API_ATTRS RESULT
Ceiling(ARG x
) {
68 template <typename RESULT
, typename ARG
>
69 inline RT_API_ATTRS RESULT
Floor(ARG x
) {
73 // MOD & MODULO (16.9.135, .136)
74 template <bool IS_MODULO
, typename T
>
75 inline RT_API_ATTRS T
IntMod(T x
, T p
, const char *sourceFile
, int sourceLine
) {
77 Terminator
{sourceFile
, sourceLine
}.Crash(
78 IS_MODULO
? "MODULO with P==0" : "MOD with P==0");
80 auto mod
{x
- (x
/ p
) * p
};
81 if (IS_MODULO
&& (x
> 0) != (p
> 0)) {
88 template <typename T
> inline RT_API_ATTRS T
Scale(T x
, std::int64_t p
) {
89 auto ip
{static_cast<int>(p
)};
91 ip
= p
< 0 ? std::numeric_limits
<int>::min()
92 : std::numeric_limits
<int>::max();
94 return std::ldexp(x
, ip
); // x*2**p
97 // SELECTED_INT_KIND (16.9.169)
98 template <typename X
, typename M
>
99 inline RT_API_ATTRS CppTypeFor
<TypeCategory::Integer
, 4> SelectedIntKind(
101 #if !defined __SIZEOF_INT128__ || defined FLANG_RUNTIME_NO_INTEGER_16
104 if (x
<= 2 && (mask
& (1 << 1))) {
106 } else if (x
<= 4 && (mask
& (1 << 2))) {
108 } else if (x
<= 9 && (mask
& (1 << 4))) {
110 } else if (x
<= 18 && (mask
& (1 << 8))) {
112 } else if (x
<= 38 && (mask
& (1 << 16))) {
118 // SELECTED_LOGICAL_KIND (F'2023 16.9.182)
119 template <typename T
>
120 inline RT_API_ATTRS CppTypeFor
<TypeCategory::Integer
, 4> SelectedLogicalKind(
124 } else if (x
<= 16) {
126 } else if (x
<= 32) {
128 } else if (x
<= 64) {
134 // SELECTED_REAL_KIND (16.9.170)
135 template <typename P
, typename R
, typename D
, typename M
>
136 inline RT_API_ATTRS CppTypeFor
<TypeCategory::Integer
, 4> SelectedRealKind(
137 P p
, R r
, D d
, M mask
) {
141 #ifdef FLANG_RUNTIME_NO_REAL_2
144 #ifdef FLANG_RUNTIME_NO_REAL_3
147 #if !HAS_FLOAT80 || defined FLANG_RUNTIME_NO_REAL_10
150 #if LDBL_MANT_DIG < 64 || defined FLANG_RUNTIME_NO_REAL_16
156 if (p
<= 3 && (mask
& (1 << 2))) {
158 } else if (p
<= 6 && (mask
& (1 << 4))) {
160 } else if (p
<= 15 && (mask
& (1 << 8))) {
162 } else if (p
<= 18 && (mask
& (1 << 10))) {
164 } else if (p
<= 33 && (mask
& (1 << 16))) {
170 if (r
<= 4 && (mask
& (1 << 2))) {
171 kind
= kind
< 2 ? 2 : kind
;
172 } else if (r
<= 37 && p
!= 3 && (mask
& (1 << 3))) {
173 kind
= kind
< 3 ? 3 : kind
;
174 } else if (r
<= 37 && (mask
& (1 << 4))) {
175 kind
= kind
< 4 ? 4 : kind
;
176 } else if (r
<= 307 && (mask
& (1 << 8))) {
177 kind
= kind
< 8 ? 8 : kind
;
178 } else if (r
<= 4931 && (mask
& (1 << 10))) {
179 kind
= kind
< 10 ? 10 : kind
;
180 } else if (r
<= 4931 && (mask
& (1 << 16))) {
181 kind
= kind
< 16 ? 16 : kind
;
186 return error
? error
: kind
;
189 // NEAREST (16.9.139)
190 template <int PREC
, typename T
>
191 inline RT_API_ATTRS T
Nearest(T x
, bool positive
) {
193 return std::nextafter(x
, std::numeric_limits
<T
>::infinity());
195 return std::nextafter(x
, -std::numeric_limits
<T
>::infinity());
199 // Exponentiation operator for (Real ** Integer) cases (10.1.5.2.1).
200 template <typename BTy
, typename ETy
>
201 RT_API_ATTRS BTy
FPowI(BTy base
, ETy exp
) {
204 bool isNegativePower
{exp
< ETy
{0}};
205 bool isMinPower
{exp
== std::numeric_limits
<ETy
>::min()};
207 exp
= std::numeric_limits
<ETy
>::max();
208 } else if (isNegativePower
) {
226 if (isNegativePower
) {
227 result
= BTy
{1} / result
;
233 RT_EXT_API_GROUP_BEGIN
235 CppTypeFor
<TypeCategory::Integer
, 1> RTDEF(Ceiling4_1
)(
236 CppTypeFor
<TypeCategory::Real
, 4> x
) {
237 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
239 CppTypeFor
<TypeCategory::Integer
, 2> RTDEF(Ceiling4_2
)(
240 CppTypeFor
<TypeCategory::Real
, 4> x
) {
241 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
243 CppTypeFor
<TypeCategory::Integer
, 4> RTDEF(Ceiling4_4
)(
244 CppTypeFor
<TypeCategory::Real
, 4> x
) {
245 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
247 CppTypeFor
<TypeCategory::Integer
, 8> RTDEF(Ceiling4_8
)(
248 CppTypeFor
<TypeCategory::Real
, 4> x
) {
249 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
251 #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
252 CppTypeFor
<TypeCategory::Integer
, 16> RTDEF(Ceiling4_16
)(
253 CppTypeFor
<TypeCategory::Real
, 4> x
) {
254 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
257 CppTypeFor
<TypeCategory::Integer
, 1> RTDEF(Ceiling8_1
)(
258 CppTypeFor
<TypeCategory::Real
, 8> x
) {
259 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
261 CppTypeFor
<TypeCategory::Integer
, 2> RTDEF(Ceiling8_2
)(
262 CppTypeFor
<TypeCategory::Real
, 8> x
) {
263 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
265 CppTypeFor
<TypeCategory::Integer
, 4> RTDEF(Ceiling8_4
)(
266 CppTypeFor
<TypeCategory::Real
, 8> x
) {
267 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
269 CppTypeFor
<TypeCategory::Integer
, 8> RTDEF(Ceiling8_8
)(
270 CppTypeFor
<TypeCategory::Real
, 8> x
) {
271 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
273 #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
274 CppTypeFor
<TypeCategory::Integer
, 16> RTDEF(Ceiling8_16
)(
275 CppTypeFor
<TypeCategory::Real
, 8> x
) {
276 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
280 CppTypeFor
<TypeCategory::Integer
, 1> RTDEF(Ceiling10_1
)(
281 CppTypeFor
<TypeCategory::Real
, 10> x
) {
282 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
284 CppTypeFor
<TypeCategory::Integer
, 2> RTDEF(Ceiling10_2
)(
285 CppTypeFor
<TypeCategory::Real
, 10> x
) {
286 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
288 CppTypeFor
<TypeCategory::Integer
, 4> RTDEF(Ceiling10_4
)(
289 CppTypeFor
<TypeCategory::Real
, 10> x
) {
290 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
292 CppTypeFor
<TypeCategory::Integer
, 8> RTDEF(Ceiling10_8
)(
293 CppTypeFor
<TypeCategory::Real
, 10> x
) {
294 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
296 #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
297 CppTypeFor
<TypeCategory::Integer
, 16> RTDEF(Ceiling10_16
)(
298 CppTypeFor
<TypeCategory::Real
, 10> x
) {
299 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
303 CppTypeFor
<TypeCategory::Integer
, 1> RTDEF(Ceiling16_1
)(
304 CppTypeFor
<TypeCategory::Real
, 16> x
) {
305 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
307 CppTypeFor
<TypeCategory::Integer
, 2> RTDEF(Ceiling16_2
)(
308 CppTypeFor
<TypeCategory::Real
, 16> x
) {
309 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
311 CppTypeFor
<TypeCategory::Integer
, 4> RTDEF(Ceiling16_4
)(
312 CppTypeFor
<TypeCategory::Real
, 16> x
) {
313 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
315 CppTypeFor
<TypeCategory::Integer
, 8> RTDEF(Ceiling16_8
)(
316 CppTypeFor
<TypeCategory::Real
, 16> x
) {
317 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
319 #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
320 CppTypeFor
<TypeCategory::Integer
, 16> RTDEF(Ceiling16_16
)(
321 CppTypeFor
<TypeCategory::Real
, 16> x
) {
322 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
327 CppTypeFor
<TypeCategory::Real
, 4> RTDEF(ErfcScaled4
)(
328 CppTypeFor
<TypeCategory::Real
, 4> x
) {
329 return ErfcScaled(x
);
331 CppTypeFor
<TypeCategory::Real
, 8> RTDEF(ErfcScaled8
)(
332 CppTypeFor
<TypeCategory::Real
, 8> x
) {
333 return ErfcScaled(x
);
336 CppTypeFor
<TypeCategory::Real
, 10> RTDEF(ErfcScaled10
)(
337 CppTypeFor
<TypeCategory::Real
, 10> x
) {
338 return ErfcScaled(x
);
342 CppTypeFor
<TypeCategory::Real
, 16> RTDEF(ErfcScaled16
)(
343 CppTypeFor
<TypeCategory::Real
, 16> x
) {
344 return ErfcScaled(x
);
348 CppTypeFor
<TypeCategory::Integer
, 4> RTDEF(Exponent4_4
)(
349 CppTypeFor
<TypeCategory::Real
, 4> x
) {
350 return Exponent
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
352 CppTypeFor
<TypeCategory::Integer
, 8> RTDEF(Exponent4_8
)(
353 CppTypeFor
<TypeCategory::Real
, 4> x
) {
354 return Exponent
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
356 CppTypeFor
<TypeCategory::Integer
, 4> RTDEF(Exponent8_4
)(
357 CppTypeFor
<TypeCategory::Real
, 8> x
) {
358 return Exponent
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
360 CppTypeFor
<TypeCategory::Integer
, 8> RTDEF(Exponent8_8
)(
361 CppTypeFor
<TypeCategory::Real
, 8> x
) {
362 return Exponent
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
365 CppTypeFor
<TypeCategory::Integer
, 4> RTDEF(Exponent10_4
)(
366 CppTypeFor
<TypeCategory::Real
, 10> x
) {
367 return Exponent
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
369 CppTypeFor
<TypeCategory::Integer
, 8> RTDEF(Exponent10_8
)(
370 CppTypeFor
<TypeCategory::Real
, 10> x
) {
371 return Exponent
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
375 CppTypeFor
<TypeCategory::Integer
, 1> RTDEF(Floor4_1
)(
376 CppTypeFor
<TypeCategory::Real
, 4> x
) {
377 return Floor
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
379 CppTypeFor
<TypeCategory::Integer
, 2> RTDEF(Floor4_2
)(
380 CppTypeFor
<TypeCategory::Real
, 4> x
) {
381 return Floor
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
383 CppTypeFor
<TypeCategory::Integer
, 4> RTDEF(Floor4_4
)(
384 CppTypeFor
<TypeCategory::Real
, 4> x
) {
385 return Floor
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
387 CppTypeFor
<TypeCategory::Integer
, 8> RTDEF(Floor4_8
)(
388 CppTypeFor
<TypeCategory::Real
, 4> x
) {
389 return Floor
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
391 #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
392 CppTypeFor
<TypeCategory::Integer
, 16> RTDEF(Floor4_16
)(
393 CppTypeFor
<TypeCategory::Real
, 4> x
) {
394 return Floor
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
397 CppTypeFor
<TypeCategory::Integer
, 1> RTDEF(Floor8_1
)(
398 CppTypeFor
<TypeCategory::Real
, 8> x
) {
399 return Floor
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
401 CppTypeFor
<TypeCategory::Integer
, 2> RTDEF(Floor8_2
)(
402 CppTypeFor
<TypeCategory::Real
, 8> x
) {
403 return Floor
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
405 CppTypeFor
<TypeCategory::Integer
, 4> RTDEF(Floor8_4
)(
406 CppTypeFor
<TypeCategory::Real
, 8> x
) {
407 return Floor
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
409 CppTypeFor
<TypeCategory::Integer
, 8> RTDEF(Floor8_8
)(
410 CppTypeFor
<TypeCategory::Real
, 8> x
) {
411 return Floor
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
413 #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
414 CppTypeFor
<TypeCategory::Integer
, 16> RTDEF(Floor8_16
)(
415 CppTypeFor
<TypeCategory::Real
, 8> x
) {
416 return Floor
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
420 CppTypeFor
<TypeCategory::Integer
, 1> RTDEF(Floor10_1
)(
421 CppTypeFor
<TypeCategory::Real
, 10> x
) {
422 return Floor
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
424 CppTypeFor
<TypeCategory::Integer
, 2> RTDEF(Floor10_2
)(
425 CppTypeFor
<TypeCategory::Real
, 10> x
) {
426 return Floor
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
428 CppTypeFor
<TypeCategory::Integer
, 4> RTDEF(Floor10_4
)(
429 CppTypeFor
<TypeCategory::Real
, 10> x
) {
430 return Floor
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
432 CppTypeFor
<TypeCategory::Integer
, 8> RTDEF(Floor10_8
)(
433 CppTypeFor
<TypeCategory::Real
, 10> x
) {
434 return Floor
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
436 #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
437 CppTypeFor
<TypeCategory::Integer
, 16> RTDEF(Floor10_16
)(
438 CppTypeFor
<TypeCategory::Real
, 10> x
) {
439 return Floor
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
443 CppTypeFor
<TypeCategory::Integer
, 1> RTDEF(Floor16_1
)(
444 CppTypeFor
<TypeCategory::Real
, 16> x
) {
445 return Floor
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
447 CppTypeFor
<TypeCategory::Integer
, 2> RTDEF(Floor16_2
)(
448 CppTypeFor
<TypeCategory::Real
, 16> x
) {
449 return Floor
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
451 CppTypeFor
<TypeCategory::Integer
, 4> RTDEF(Floor16_4
)(
452 CppTypeFor
<TypeCategory::Real
, 16> x
) {
453 return Floor
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
455 CppTypeFor
<TypeCategory::Integer
, 8> RTDEF(Floor16_8
)(
456 CppTypeFor
<TypeCategory::Real
, 16> x
) {
457 return Floor
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
459 #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
460 CppTypeFor
<TypeCategory::Integer
, 16> RTDEF(Floor16_16
)(
461 CppTypeFor
<TypeCategory::Real
, 16> x
) {
462 return Floor
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
467 CppTypeFor
<TypeCategory::Real
, 4> RTDEF(Fraction4
)(
468 CppTypeFor
<TypeCategory::Real
, 4> x
) {
471 CppTypeFor
<TypeCategory::Real
, 8> RTDEF(Fraction8
)(
472 CppTypeFor
<TypeCategory::Real
, 8> x
) {
476 CppTypeFor
<TypeCategory::Real
, 10> RTDEF(Fraction10
)(
477 CppTypeFor
<TypeCategory::Real
, 10> x
) {
482 bool RTDEF(IsFinite4
)(CppTypeFor
<TypeCategory::Real
, 4> x
) {
483 return std::isfinite(x
);
485 bool RTDEF(IsFinite8
)(CppTypeFor
<TypeCategory::Real
, 8> x
) {
486 return std::isfinite(x
);
489 bool RTDEF(IsFinite10
)(CppTypeFor
<TypeCategory::Real
, 10> x
) {
490 return std::isfinite(x
);
493 bool RTDEF(IsFinite16
)(CppTypeFor
<TypeCategory::Real
, 16> x
) {
494 return std::isfinite(x
);
498 bool RTDEF(IsNaN4
)(CppTypeFor
<TypeCategory::Real
, 4> x
) {
499 return std::isnan(x
);
501 bool RTDEF(IsNaN8
)(CppTypeFor
<TypeCategory::Real
, 8> x
) {
502 return std::isnan(x
);
505 bool RTDEF(IsNaN10
)(CppTypeFor
<TypeCategory::Real
, 10> x
) {
506 return std::isnan(x
);
509 bool RTDEF(IsNaN16
)(CppTypeFor
<TypeCategory::Real
, 16> x
) {
510 return std::isnan(x
);
514 CppTypeFor
<TypeCategory::Integer
, 1> RTDEF(ModInteger1
)(
515 CppTypeFor
<TypeCategory::Integer
, 1> x
,
516 CppTypeFor
<TypeCategory::Integer
, 1> p
, const char *sourceFile
,
518 return IntMod
<false>(x
, p
, sourceFile
, sourceLine
);
520 CppTypeFor
<TypeCategory::Integer
, 2> RTDEF(ModInteger2
)(
521 CppTypeFor
<TypeCategory::Integer
, 2> x
,
522 CppTypeFor
<TypeCategory::Integer
, 2> p
, const char *sourceFile
,
524 return IntMod
<false>(x
, p
, sourceFile
, sourceLine
);
526 CppTypeFor
<TypeCategory::Integer
, 4> RTDEF(ModInteger4
)(
527 CppTypeFor
<TypeCategory::Integer
, 4> x
,
528 CppTypeFor
<TypeCategory::Integer
, 4> p
, const char *sourceFile
,
530 return IntMod
<false>(x
, p
, sourceFile
, sourceLine
);
532 CppTypeFor
<TypeCategory::Integer
, 8> RTDEF(ModInteger8
)(
533 CppTypeFor
<TypeCategory::Integer
, 8> x
,
534 CppTypeFor
<TypeCategory::Integer
, 8> p
, const char *sourceFile
,
536 return IntMod
<false>(x
, p
, sourceFile
, sourceLine
);
538 #ifdef __SIZEOF_INT128__
539 CppTypeFor
<TypeCategory::Integer
, 16> RTDEF(ModInteger16
)(
540 CppTypeFor
<TypeCategory::Integer
, 16> x
,
541 CppTypeFor
<TypeCategory::Integer
, 16> p
, const char *sourceFile
,
543 return IntMod
<false>(x
, p
, sourceFile
, sourceLine
);
546 CppTypeFor
<TypeCategory::Real
, 4> RTDEF(ModReal4
)(
547 CppTypeFor
<TypeCategory::Real
, 4> x
, CppTypeFor
<TypeCategory::Real
, 4> p
,
548 const char *sourceFile
, int sourceLine
) {
549 return RealMod
<false>(x
, p
, sourceFile
, sourceLine
);
551 CppTypeFor
<TypeCategory::Real
, 8> RTDEF(ModReal8
)(
552 CppTypeFor
<TypeCategory::Real
, 8> x
, CppTypeFor
<TypeCategory::Real
, 8> p
,
553 const char *sourceFile
, int sourceLine
) {
554 return RealMod
<false>(x
, p
, sourceFile
, sourceLine
);
557 CppTypeFor
<TypeCategory::Real
, 10> RTDEF(ModReal10
)(
558 CppTypeFor
<TypeCategory::Real
, 10> x
, CppTypeFor
<TypeCategory::Real
, 10> p
,
559 const char *sourceFile
, int sourceLine
) {
560 return RealMod
<false>(x
, p
, sourceFile
, sourceLine
);
564 CppTypeFor
<TypeCategory::Integer
, 1> RTDEF(ModuloInteger1
)(
565 CppTypeFor
<TypeCategory::Integer
, 1> x
,
566 CppTypeFor
<TypeCategory::Integer
, 1> p
, const char *sourceFile
,
568 return IntMod
<true>(x
, p
, sourceFile
, sourceLine
);
570 CppTypeFor
<TypeCategory::Integer
, 2> RTDEF(ModuloInteger2
)(
571 CppTypeFor
<TypeCategory::Integer
, 2> x
,
572 CppTypeFor
<TypeCategory::Integer
, 2> p
, const char *sourceFile
,
574 return IntMod
<true>(x
, p
, sourceFile
, sourceLine
);
576 CppTypeFor
<TypeCategory::Integer
, 4> RTDEF(ModuloInteger4
)(
577 CppTypeFor
<TypeCategory::Integer
, 4> x
,
578 CppTypeFor
<TypeCategory::Integer
, 4> p
, const char *sourceFile
,
580 return IntMod
<true>(x
, p
, sourceFile
, sourceLine
);
582 CppTypeFor
<TypeCategory::Integer
, 8> RTDEF(ModuloInteger8
)(
583 CppTypeFor
<TypeCategory::Integer
, 8> x
,
584 CppTypeFor
<TypeCategory::Integer
, 8> p
, const char *sourceFile
,
586 return IntMod
<true>(x
, p
, sourceFile
, sourceLine
);
588 #ifdef __SIZEOF_INT128__
589 CppTypeFor
<TypeCategory::Integer
, 16> RTDEF(ModuloInteger16
)(
590 CppTypeFor
<TypeCategory::Integer
, 16> x
,
591 CppTypeFor
<TypeCategory::Integer
, 16> p
, const char *sourceFile
,
593 return IntMod
<true>(x
, p
, sourceFile
, sourceLine
);
596 CppTypeFor
<TypeCategory::Real
, 4> RTDEF(ModuloReal4
)(
597 CppTypeFor
<TypeCategory::Real
, 4> x
, CppTypeFor
<TypeCategory::Real
, 4> p
,
598 const char *sourceFile
, int sourceLine
) {
599 return RealMod
<true>(x
, p
, sourceFile
, sourceLine
);
601 CppTypeFor
<TypeCategory::Real
, 8> RTDEF(ModuloReal8
)(
602 CppTypeFor
<TypeCategory::Real
, 8> x
, CppTypeFor
<TypeCategory::Real
, 8> p
,
603 const char *sourceFile
, int sourceLine
) {
604 return RealMod
<true>(x
, p
, sourceFile
, sourceLine
);
607 CppTypeFor
<TypeCategory::Real
, 10> RTDEF(ModuloReal10
)(
608 CppTypeFor
<TypeCategory::Real
, 10> x
, CppTypeFor
<TypeCategory::Real
, 10> p
,
609 const char *sourceFile
, int sourceLine
) {
610 return RealMod
<true>(x
, p
, sourceFile
, sourceLine
);
614 CppTypeFor
<TypeCategory::Real
, 4> RTDEF(Nearest4
)(
615 CppTypeFor
<TypeCategory::Real
, 4> x
, bool positive
) {
616 return Nearest
<24>(x
, positive
);
618 CppTypeFor
<TypeCategory::Real
, 8> RTDEF(Nearest8
)(
619 CppTypeFor
<TypeCategory::Real
, 8> x
, bool positive
) {
620 return Nearest
<53>(x
, positive
);
623 CppTypeFor
<TypeCategory::Real
, 10> RTDEF(Nearest10
)(
624 CppTypeFor
<TypeCategory::Real
, 10> x
, bool positive
) {
625 return Nearest
<64>(x
, positive
);
629 CppTypeFor
<TypeCategory::Integer
, 1> RTDEF(Nint4_1
)(
630 CppTypeFor
<TypeCategory::Real
, 4> x
) {
631 return Nint
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
633 CppTypeFor
<TypeCategory::Integer
, 2> RTDEF(Nint4_2
)(
634 CppTypeFor
<TypeCategory::Real
, 4> x
) {
635 return Nint
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
637 CppTypeFor
<TypeCategory::Integer
, 4> RTDEF(Nint4_4
)(
638 CppTypeFor
<TypeCategory::Real
, 4> x
) {
639 return Nint
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
641 CppTypeFor
<TypeCategory::Integer
, 8> RTDEF(Nint4_8
)(
642 CppTypeFor
<TypeCategory::Real
, 4> x
) {
643 return Nint
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
645 #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
646 CppTypeFor
<TypeCategory::Integer
, 16> RTDEF(Nint4_16
)(
647 CppTypeFor
<TypeCategory::Real
, 4> x
) {
648 return Nint
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
651 CppTypeFor
<TypeCategory::Integer
, 1> RTDEF(Nint8_1
)(
652 CppTypeFor
<TypeCategory::Real
, 8> x
) {
653 return Nint
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
655 CppTypeFor
<TypeCategory::Integer
, 2> RTDEF(Nint8_2
)(
656 CppTypeFor
<TypeCategory::Real
, 8> x
) {
657 return Nint
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
659 CppTypeFor
<TypeCategory::Integer
, 4> RTDEF(Nint8_4
)(
660 CppTypeFor
<TypeCategory::Real
, 8> x
) {
661 return Nint
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
663 CppTypeFor
<TypeCategory::Integer
, 8> RTDEF(Nint8_8
)(
664 CppTypeFor
<TypeCategory::Real
, 8> x
) {
665 return Nint
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
667 #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
668 CppTypeFor
<TypeCategory::Integer
, 16> RTDEF(Nint8_16
)(
669 CppTypeFor
<TypeCategory::Real
, 8> x
) {
670 return Nint
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
674 CppTypeFor
<TypeCategory::Integer
, 1> RTDEF(Nint10_1
)(
675 CppTypeFor
<TypeCategory::Real
, 10> x
) {
676 return Nint
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
678 CppTypeFor
<TypeCategory::Integer
, 2> RTDEF(Nint10_2
)(
679 CppTypeFor
<TypeCategory::Real
, 10> x
) {
680 return Nint
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
682 CppTypeFor
<TypeCategory::Integer
, 4> RTDEF(Nint10_4
)(
683 CppTypeFor
<TypeCategory::Real
, 10> x
) {
684 return Nint
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
686 CppTypeFor
<TypeCategory::Integer
, 8> RTDEF(Nint10_8
)(
687 CppTypeFor
<TypeCategory::Real
, 10> x
) {
688 return Nint
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
690 #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
691 CppTypeFor
<TypeCategory::Integer
, 16> RTDEF(Nint10_16
)(
692 CppTypeFor
<TypeCategory::Real
, 10> x
) {
693 return Nint
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
697 CppTypeFor
<TypeCategory::Integer
, 1> RTDEF(Nint16_1
)(
698 CppTypeFor
<TypeCategory::Real
, 16> x
) {
699 return Nint
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
701 CppTypeFor
<TypeCategory::Integer
, 2> RTDEF(Nint16_2
)(
702 CppTypeFor
<TypeCategory::Real
, 16> x
) {
703 return Nint
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
705 CppTypeFor
<TypeCategory::Integer
, 4> RTDEF(Nint16_4
)(
706 CppTypeFor
<TypeCategory::Real
, 16> x
) {
707 return Nint
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
709 CppTypeFor
<TypeCategory::Integer
, 8> RTDEF(Nint16_8
)(
710 CppTypeFor
<TypeCategory::Real
, 16> x
) {
711 return Nint
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
713 #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
714 CppTypeFor
<TypeCategory::Integer
, 16> RTDEF(Nint16_16
)(
715 CppTypeFor
<TypeCategory::Real
, 16> x
) {
716 return Nint
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
721 CppTypeFor
<TypeCategory::Real
, 4> RTDEF(RRSpacing4
)(
722 CppTypeFor
<TypeCategory::Real
, 4> x
) {
723 return RRSpacing
<24>(x
);
725 CppTypeFor
<TypeCategory::Real
, 8> RTDEF(RRSpacing8
)(
726 CppTypeFor
<TypeCategory::Real
, 8> x
) {
727 return RRSpacing
<53>(x
);
730 CppTypeFor
<TypeCategory::Real
, 10> RTDEF(RRSpacing10
)(
731 CppTypeFor
<TypeCategory::Real
, 10> x
) {
732 return RRSpacing
<64>(x
);
736 CppTypeFor
<TypeCategory::Real
, 4> RTDEF(SetExponent4
)(
737 CppTypeFor
<TypeCategory::Real
, 4> x
, std::int64_t p
) {
738 return SetExponent(x
, p
);
740 CppTypeFor
<TypeCategory::Real
, 8> RTDEF(SetExponent8
)(
741 CppTypeFor
<TypeCategory::Real
, 8> x
, std::int64_t p
) {
742 return SetExponent(x
, p
);
745 CppTypeFor
<TypeCategory::Real
, 10> RTDEF(SetExponent10
)(
746 CppTypeFor
<TypeCategory::Real
, 10> x
, std::int64_t p
) {
747 return SetExponent(x
, p
);
751 CppTypeFor
<TypeCategory::Real
, 4> RTDEF(Scale4
)(
752 CppTypeFor
<TypeCategory::Real
, 4> x
, std::int64_t p
) {
755 CppTypeFor
<TypeCategory::Real
, 8> RTDEF(Scale8
)(
756 CppTypeFor
<TypeCategory::Real
, 8> x
, std::int64_t p
) {
760 CppTypeFor
<TypeCategory::Real
, 10> RTDEF(Scale10
)(
761 CppTypeFor
<TypeCategory::Real
, 10> x
, std::int64_t p
) {
766 // SELECTED_CHAR_KIND
767 CppTypeFor
<TypeCategory::Integer
, 4> RTDEF(SelectedCharKind
)(
768 const char *source
, int line
, const char *x
, std::size_t length
) {
769 static const char *keywords
[]{
770 "ASCII", "DEFAULT", "UCS-2", "ISO_10646", "UCS-4", nullptr};
771 switch (IdentifyValue(x
, length
, keywords
)) {
785 CppTypeFor
<TypeCategory::Integer
, 4> RTDEF(SelectedIntKind
)(
786 const char *source
, int line
, void *x
, int xKind
) {
787 return RTNAME(SelectedIntKindMasked
)(source
, line
, x
, xKind
,
788 (1 << 1) | (1 << 2) | (1 << 4) | (1 << 8) | (1 << 16));
791 CppTypeFor
<TypeCategory::Integer
, 4> RTDEF(SelectedIntKindMasked
)(
792 const char *source
, int line
, void *x
, int xKind
, int mask
) {
793 #ifdef __SIZEOF_INT128__
794 CppTypeFor
<TypeCategory::Integer
, 16> r
=
795 GetIntArgValue
<CppTypeFor
<TypeCategory::Integer
, 16>>(
796 source
, line
, x
, xKind
, /*defaultValue*/ 0, /*resKind*/ 16);
798 std::int64_t r
= GetIntArgValue
<std::int64_t>(
799 source
, line
, x
, xKind
, /*defaultValue*/ 0, /*resKind*/ 8);
801 return SelectedIntKind(r
, mask
);
804 // SELECTED_LOGICAL_KIND
805 CppTypeFor
<TypeCategory::Integer
, 4> RTDEF(SelectedLogicalKind
)(
806 const char *source
, int line
, void *x
, int xKind
) {
807 #ifdef __SIZEOF_INT128__
808 CppTypeFor
<TypeCategory::Integer
, 16> r
=
809 GetIntArgValue
<CppTypeFor
<TypeCategory::Integer
, 16>>(
810 source
, line
, x
, xKind
, /*defaultValue*/ 0, /*resKind*/ 16);
812 std::int64_t r
= GetIntArgValue
<std::int64_t>(
813 source
, line
, x
, xKind
, /*defaultValue*/ 0, /*resKind*/ 8);
815 return SelectedLogicalKind(r
);
818 // SELECTED_REAL_KIND
819 CppTypeFor
<TypeCategory::Integer
, 4> RTDEF(SelectedRealKind
)(const char *source
,
820 int line
, void *precision
, int pKind
, void *range
, int rKind
, void *radix
,
822 return RTNAME(SelectedRealKindMasked
)(source
, line
, precision
, pKind
, range
,
824 (1 << 2) | (1 << 3) | (1 << 4) | (1 << 8) | (1 << 10) | (1 << 16));
827 CppTypeFor
<TypeCategory::Integer
, 4> RTDEF(SelectedRealKindMasked
)(
828 const char *source
, int line
, void *precision
, int pKind
, void *range
,
829 int rKind
, void *radix
, int dKind
, int mask
) {
830 #ifdef __SIZEOF_INT128__
831 CppTypeFor
<TypeCategory::Integer
, 16> p
=
832 GetIntArgValue
<CppTypeFor
<TypeCategory::Integer
, 16>>(
833 source
, line
, precision
, pKind
, /*defaultValue*/ 0, /*resKind*/ 16);
834 CppTypeFor
<TypeCategory::Integer
, 16> r
=
835 GetIntArgValue
<CppTypeFor
<TypeCategory::Integer
, 16>>(
836 source
, line
, range
, rKind
, /*defaultValue*/ 0, /*resKind*/ 16);
837 CppTypeFor
<TypeCategory::Integer
, 16> d
=
838 GetIntArgValue
<CppTypeFor
<TypeCategory::Integer
, 16>>(
839 source
, line
, radix
, dKind
, /*defaultValue*/ 2, /*resKind*/ 16);
841 std::int64_t p
= GetIntArgValue
<std::int64_t>(
842 source
, line
, precision
, pKind
, /*defaultValue*/ 0, /*resKind*/ 8);
843 std::int64_t r
= GetIntArgValue
<std::int64_t>(
844 source
, line
, range
, rKind
, /*defaultValue*/ 0, /*resKind*/ 8);
845 std::int64_t d
= GetIntArgValue
<std::int64_t>(
846 source
, line
, radix
, dKind
, /*defaultValue*/ 2, /*resKind*/ 8);
848 return SelectedRealKind(p
, r
, d
, mask
);
852 CppTypeFor
<TypeCategory::Real
, 2> RTDEF(Spacing2
)(
853 CppTypeFor
<TypeCategory::Real
, 2> x
) {
854 return Spacing
<11>(x
);
857 CppTypeFor
<TypeCategory::Real
, 4> RTDEF(Spacing2By4
)(
858 CppTypeFor
<TypeCategory::Real
, 4> x
) {
859 return Spacing
<11>(x
);
862 CppTypeFor
<TypeCategory::Real
, 3> RTDEF(Spacing3
)(
863 CppTypeFor
<TypeCategory::Real
, 3> x
) {
864 return Spacing
<8>(x
);
867 CppTypeFor
<TypeCategory::Real
, 4> RTDEF(Spacing3By4
)(
868 CppTypeFor
<TypeCategory::Real
, 4> x
) {
869 return Spacing
<8>(x
);
871 CppTypeFor
<TypeCategory::Real
, 4> RTDEF(Spacing4
)(
872 CppTypeFor
<TypeCategory::Real
, 4> x
) {
873 return Spacing
<24>(x
);
875 CppTypeFor
<TypeCategory::Real
, 8> RTDEF(Spacing8
)(
876 CppTypeFor
<TypeCategory::Real
, 8> x
) {
877 return Spacing
<53>(x
);
880 CppTypeFor
<TypeCategory::Real
, 10> RTDEF(Spacing10
)(
881 CppTypeFor
<TypeCategory::Real
, 10> x
) {
882 return Spacing
<64>(x
);
886 CppTypeFor
<TypeCategory::Real
, 4> RTDEF(FPow4i
)(
887 CppTypeFor
<TypeCategory::Real
, 4> b
,
888 CppTypeFor
<TypeCategory::Integer
, 4> e
) {
891 CppTypeFor
<TypeCategory::Real
, 8> RTDEF(FPow8i
)(
892 CppTypeFor
<TypeCategory::Real
, 8> b
,
893 CppTypeFor
<TypeCategory::Integer
, 4> e
) {
897 CppTypeFor
<TypeCategory::Real
, 10> RTDEF(FPow10i
)(
898 CppTypeFor
<TypeCategory::Real
, 10> b
,
899 CppTypeFor
<TypeCategory::Integer
, 4> e
) {
903 #if HAS_LDBL128 || HAS_FLOAT128
904 CppTypeFor
<TypeCategory::Real
, 16> RTDEF(FPow16i
)(
905 CppTypeFor
<TypeCategory::Real
, 16> b
,
906 CppTypeFor
<TypeCategory::Integer
, 4> e
) {
911 CppTypeFor
<TypeCategory::Real
, 4> RTDEF(FPow4k
)(
912 CppTypeFor
<TypeCategory::Real
, 4> b
,
913 CppTypeFor
<TypeCategory::Integer
, 8> e
) {
916 CppTypeFor
<TypeCategory::Real
, 8> RTDEF(FPow8k
)(
917 CppTypeFor
<TypeCategory::Real
, 8> b
,
918 CppTypeFor
<TypeCategory::Integer
, 8> e
) {
922 CppTypeFor
<TypeCategory::Real
, 10> RTDEF(FPow10k
)(
923 CppTypeFor
<TypeCategory::Real
, 10> b
,
924 CppTypeFor
<TypeCategory::Integer
, 8> e
) {
928 #if HAS_LDBL128 || HAS_FLOAT128
929 CppTypeFor
<TypeCategory::Real
, 16> RTDEF(FPow16k
)(
930 CppTypeFor
<TypeCategory::Real
, 16> b
,
931 CppTypeFor
<TypeCategory::Integer
, 8> e
) {
938 } // namespace Fortran::runtime