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 "terminator.h"
11 #include "flang/Runtime/float128.h"
17 namespace Fortran::runtime
{
19 template <typename RES
>
20 inline RES
getIntArgValue(const char *source
, int line
, void *arg
, int kind
,
21 std::int64_t defaultValue
, int resKind
) {
24 res
= static_cast<RES
>(defaultValue
);
25 } else if (kind
== 1) {
26 res
= static_cast<RES
>(
27 *static_cast<CppTypeFor
<TypeCategory::Integer
, 1> *>(arg
));
28 } else if (kind
== 2) {
29 res
= static_cast<RES
>(
30 *static_cast<CppTypeFor
<TypeCategory::Integer
, 2> *>(arg
));
31 } else if (kind
== 4) {
32 res
= static_cast<RES
>(
33 *static_cast<CppTypeFor
<TypeCategory::Integer
, 4> *>(arg
));
34 } else if (kind
== 8) {
35 res
= static_cast<RES
>(
36 *static_cast<CppTypeFor
<TypeCategory::Integer
, 8> *>(arg
));
37 #ifdef __SIZEOF_INT128__
38 } else if (kind
== 16) {
40 Terminator
{source
, line
}.Crash("Unexpected integer kind in runtime");
42 res
= static_cast<RES
>(
43 *static_cast<CppTypeFor
<TypeCategory::Integer
, 16> *>(arg
));
46 Terminator
{source
, line
}.Crash("Unexpected integer kind in runtime");
52 template <typename RESULT
, typename ARG
> inline RESULT
Nint(ARG x
) {
54 return std::trunc(x
+ ARG
{0.5});
56 return std::trunc(x
- ARG
{0.5});
60 // CEILING & FLOOR (16.9.43, .79)
61 template <typename RESULT
, typename ARG
> inline RESULT
Ceiling(ARG x
) {
64 template <typename RESULT
, typename ARG
> inline RESULT
Floor(ARG x
) {
69 template <typename RESULT
, typename ARG
> inline RESULT
Exponent(ARG x
) {
70 if (std::isinf(x
) || std::isnan(x
)) {
71 return std::numeric_limits
<RESULT
>::max(); // +/-Inf, NaN -> HUGE(0)
75 return std::ilogb(x
) + 1;
80 template <typename T
> inline T
Fraction(T x
) {
82 return x
; // NaN -> same NaN
83 } else if (std::isinf(x
)) {
84 return std::numeric_limits
<T
>::quiet_NaN(); // +/-Inf -> NaN
89 return std::frexp(x
, &ignoredExp
);
93 // MOD & MODULO (16.9.135, .136)
94 template <bool IS_MODULO
, typename T
>
95 inline T
IntMod(T x
, T p
, const char *sourceFile
, int sourceLine
) {
97 Terminator
{sourceFile
, sourceLine
}.Crash(
98 IS_MODULO
? "MODULO with P==0" : "MOD with P==0");
100 auto mod
{x
- (x
/ p
) * p
};
101 if (IS_MODULO
&& (x
> 0) != (p
> 0)) {
106 template <bool IS_MODULO
, typename T
>
107 inline T
RealMod(T a
, T p
, const char *sourceFile
, int sourceLine
) {
109 Terminator
{sourceFile
, sourceLine
}.Crash(
110 IS_MODULO
? "MODULO with P==0" : "MOD with P==0");
113 if (std::isinf(quotient
) && std::isfinite(a
) && std::isfinite(p
)) {
114 // a/p overflowed -- so it must be an integer, and the result
115 // must be a zero of the same sign as one of the operands.
116 return std::copysign(T
{}, IS_MODULO
? p
: a
);
118 T toInt
{IS_MODULO
? std::floor(quotient
) : std::trunc(quotient
)};
119 return a
- toInt
* p
;
122 // RRSPACING (16.9.164)
123 template <int PREC
, typename T
> inline T
RRSpacing(T x
) {
125 return x
; // NaN -> same NaN
126 } else if (std::isinf(x
)) {
127 return std::numeric_limits
<T
>::quiet_NaN(); // +/-Inf -> NaN
131 return std::ldexp(std::abs(x
), PREC
- (std::ilogb(x
) + 1));
136 template <typename T
> inline T
Scale(T x
, std::int64_t p
) {
137 auto ip
{static_cast<int>(p
)};
139 ip
= p
< 0 ? std::numeric_limits
<int>::min()
140 : std::numeric_limits
<int>::max();
142 return std::ldexp(x
, p
); // x*2**p
145 // SELECTED_INT_KIND (16.9.169)
146 template <typename T
>
147 inline CppTypeFor
<TypeCategory::Integer
, 4> SelectedIntKind(T x
) {
154 } else if (x
<= 18) {
156 #ifdef __SIZEOF_INT128__
157 } else if (x
<= 38) {
164 // SELECTED_REAL_KIND (16.9.170)
165 template <typename P
, typename R
, typename D
>
166 inline CppTypeFor
<TypeCategory::Integer
, 4> SelectedRealKind(P p
, R r
, D d
) {
177 } else if (p
<= 15) {
179 #if LDBL_MANT_DIG == 64
180 } else if (p
<= 18) {
182 } else if (p
<= 33) {
184 #elif LDBL_MANT_DIG == 113
185 } else if (p
<= 33) {
193 kind
= kind
< 2 ? 2 : kind
;
194 } else if (r
<= 37) {
195 kind
= kind
< 3 ? (p
== 3 ? 4 : 3) : kind
;
196 } else if (r
<= 307) {
197 kind
= kind
< 8 ? 8 : kind
;
198 #if LDBL_MANT_DIG == 64
199 } else if (r
<= 4931) {
200 kind
= kind
< 10 ? 10 : kind
;
201 #elif LDBL_MANT_DIG == 113
202 } else if (r
<= 4931) {
203 kind
= kind
< 16 ? 16 : kind
;
209 return error
? error
: kind
;
212 // SET_EXPONENT (16.9.171)
213 template <typename T
> inline T
SetExponent(T x
, std::int64_t p
) {
215 return x
; // NaN -> same NaN
216 } else if (std::isinf(x
)) {
217 return std::numeric_limits
<T
>::quiet_NaN(); // +/-Inf -> NaN
219 return x
; // return negative zero if x is negative zero
221 int expo
{std::ilogb(x
) + 1};
222 auto ip
{static_cast<int>(p
- expo
)};
223 if (ip
!= p
- expo
) {
224 ip
= p
< 0 ? std::numeric_limits
<int>::min()
225 : std::numeric_limits
<int>::max();
227 return std::ldexp(x
, ip
); // x*2**(p-e)
231 // SPACING (16.9.180)
232 template <int PREC
, typename T
> inline T
Spacing(T x
) {
234 return x
; // NaN -> same NaN
235 } else if (std::isinf(x
)) {
236 return std::numeric_limits
<T
>::quiet_NaN(); // +/-Inf -> NaN
238 // The standard-mandated behavior seems broken, since TINY() can't be
240 return std::numeric_limits
<T
>::min(); // 0 -> TINY(x)
243 static_cast<T
>(1.0), std::ilogb(x
) + 1 - PREC
); // 2**(e-p)
247 // NEAREST (16.9.139)
248 template <int PREC
, typename T
> inline T
Nearest(T x
, bool positive
) {
249 auto spacing
{Spacing
<PREC
>(x
)};
251 auto least
{std::numeric_limits
<T
>::denorm_min()};
252 return positive
? least
: -least
;
254 return positive
? x
+ spacing
: x
- spacing
;
258 // Exponentiation operator for (Real ** Integer) cases (10.1.5.2.1).
259 template <typename BTy
, typename ETy
> BTy
FPowI(BTy base
, ETy exp
) {
262 bool isNegativePower
{exp
< ETy
{0}};
263 bool isMinPower
{exp
== std::numeric_limits
<ETy
>::min()};
265 exp
= std::numeric_limits
<ETy
>::max();
266 } else if (isNegativePower
) {
284 if (isNegativePower
) {
285 result
= BTy
{1} / result
;
292 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(Ceiling4_1
)(
293 CppTypeFor
<TypeCategory::Real
, 4> x
) {
294 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
296 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(Ceiling4_2
)(
297 CppTypeFor
<TypeCategory::Real
, 4> x
) {
298 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
300 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Ceiling4_4
)(
301 CppTypeFor
<TypeCategory::Real
, 4> x
) {
302 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
304 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Ceiling4_8
)(
305 CppTypeFor
<TypeCategory::Real
, 4> x
) {
306 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
308 #ifdef __SIZEOF_INT128__
309 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(Ceiling4_16
)(
310 CppTypeFor
<TypeCategory::Real
, 4> x
) {
311 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
314 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(Ceiling8_1
)(
315 CppTypeFor
<TypeCategory::Real
, 8> x
) {
316 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
318 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(Ceiling8_2
)(
319 CppTypeFor
<TypeCategory::Real
, 8> x
) {
320 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
322 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Ceiling8_4
)(
323 CppTypeFor
<TypeCategory::Real
, 8> x
) {
324 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
326 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Ceiling8_8
)(
327 CppTypeFor
<TypeCategory::Real
, 8> x
) {
328 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
330 #ifdef __SIZEOF_INT128__
331 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(Ceiling8_16
)(
332 CppTypeFor
<TypeCategory::Real
, 8> x
) {
333 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
336 #if LDBL_MANT_DIG == 64
337 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(Ceiling10_1
)(
338 CppTypeFor
<TypeCategory::Real
, 10> x
) {
339 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
341 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(Ceiling10_2
)(
342 CppTypeFor
<TypeCategory::Real
, 10> x
) {
343 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
345 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Ceiling10_4
)(
346 CppTypeFor
<TypeCategory::Real
, 10> x
) {
347 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
349 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Ceiling10_8
)(
350 CppTypeFor
<TypeCategory::Real
, 10> x
) {
351 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
353 #ifdef __SIZEOF_INT128__
354 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(Ceiling10_16
)(
355 CppTypeFor
<TypeCategory::Real
, 10> x
) {
356 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
359 #elif LDBL_MANT_DIG == 113
360 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(Ceiling16_1
)(
361 CppTypeFor
<TypeCategory::Real
, 16> x
) {
362 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
364 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(Ceiling16_2
)(
365 CppTypeFor
<TypeCategory::Real
, 16> x
) {
366 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
368 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Ceiling16_4
)(
369 CppTypeFor
<TypeCategory::Real
, 16> x
) {
370 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
372 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Ceiling16_8
)(
373 CppTypeFor
<TypeCategory::Real
, 16> x
) {
374 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
376 #ifdef __SIZEOF_INT128__
377 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(Ceiling16_16
)(
378 CppTypeFor
<TypeCategory::Real
, 16> x
) {
379 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
384 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Exponent4_4
)(
385 CppTypeFor
<TypeCategory::Real
, 4> x
) {
386 return Exponent
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
388 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Exponent4_8
)(
389 CppTypeFor
<TypeCategory::Real
, 4> x
) {
390 return Exponent
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
392 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Exponent8_4
)(
393 CppTypeFor
<TypeCategory::Real
, 8> x
) {
394 return Exponent
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
396 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Exponent8_8
)(
397 CppTypeFor
<TypeCategory::Real
, 8> x
) {
398 return Exponent
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
400 #if LDBL_MANT_DIG == 64
401 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Exponent10_4
)(
402 CppTypeFor
<TypeCategory::Real
, 10> x
) {
403 return Exponent
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
405 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Exponent10_8
)(
406 CppTypeFor
<TypeCategory::Real
, 10> x
) {
407 return Exponent
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
409 #elif LDBL_MANT_DIG == 113
410 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Exponent16_4
)(
411 CppTypeFor
<TypeCategory::Real
, 16> x
) {
412 return Exponent
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
414 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Exponent16_8
)(
415 CppTypeFor
<TypeCategory::Real
, 16> x
) {
416 return Exponent
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
420 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(Floor4_1
)(
421 CppTypeFor
<TypeCategory::Real
, 4> x
) {
422 return Floor
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
424 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(Floor4_2
)(
425 CppTypeFor
<TypeCategory::Real
, 4> x
) {
426 return Floor
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
428 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Floor4_4
)(
429 CppTypeFor
<TypeCategory::Real
, 4> x
) {
430 return Floor
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
432 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Floor4_8
)(
433 CppTypeFor
<TypeCategory::Real
, 4> x
) {
434 return Floor
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
436 #ifdef __SIZEOF_INT128__
437 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(Floor4_16
)(
438 CppTypeFor
<TypeCategory::Real
, 4> x
) {
439 return Floor
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
442 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(Floor8_1
)(
443 CppTypeFor
<TypeCategory::Real
, 8> x
) {
444 return Floor
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
446 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(Floor8_2
)(
447 CppTypeFor
<TypeCategory::Real
, 8> x
) {
448 return Floor
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
450 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Floor8_4
)(
451 CppTypeFor
<TypeCategory::Real
, 8> x
) {
452 return Floor
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
454 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Floor8_8
)(
455 CppTypeFor
<TypeCategory::Real
, 8> x
) {
456 return Floor
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
458 #ifdef __SIZEOF_INT128__
459 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(Floor8_16
)(
460 CppTypeFor
<TypeCategory::Real
, 8> x
) {
461 return Floor
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
464 #if LDBL_MANT_DIG == 64
465 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(Floor10_1
)(
466 CppTypeFor
<TypeCategory::Real
, 10> x
) {
467 return Floor
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
469 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(Floor10_2
)(
470 CppTypeFor
<TypeCategory::Real
, 10> x
) {
471 return Floor
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
473 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Floor10_4
)(
474 CppTypeFor
<TypeCategory::Real
, 10> x
) {
475 return Floor
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
477 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Floor10_8
)(
478 CppTypeFor
<TypeCategory::Real
, 10> x
) {
479 return Floor
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
481 #ifdef __SIZEOF_INT128__
482 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(Floor10_16
)(
483 CppTypeFor
<TypeCategory::Real
, 10> x
) {
484 return Floor
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
487 #elif LDBL_MANT_DIG == 113
488 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(Floor16_1
)(
489 CppTypeFor
<TypeCategory::Real
, 16> x
) {
490 return Floor
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
492 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(Floor16_2
)(
493 CppTypeFor
<TypeCategory::Real
, 16> x
) {
494 return Floor
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
496 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Floor16_4
)(
497 CppTypeFor
<TypeCategory::Real
, 16> x
) {
498 return Floor
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
500 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Floor16_8
)(
501 CppTypeFor
<TypeCategory::Real
, 16> x
) {
502 return Floor
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
504 #ifdef __SIZEOF_INT128__
505 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(Floor16_16
)(
506 CppTypeFor
<TypeCategory::Real
, 16> x
) {
507 return Floor
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
512 CppTypeFor
<TypeCategory::Real
, 4> RTNAME(Fraction4
)(
513 CppTypeFor
<TypeCategory::Real
, 4> x
) {
516 CppTypeFor
<TypeCategory::Real
, 8> RTNAME(Fraction8
)(
517 CppTypeFor
<TypeCategory::Real
, 8> x
) {
520 #if LDBL_MANT_DIG == 64
521 CppTypeFor
<TypeCategory::Real
, 10> RTNAME(Fraction10
)(
522 CppTypeFor
<TypeCategory::Real
, 10> x
) {
525 #elif LDBL_MANT_DIG == 113
526 CppTypeFor
<TypeCategory::Real
, 16> RTNAME(Fraction16
)(
527 CppTypeFor
<TypeCategory::Real
, 16> x
) {
532 bool RTNAME(IsFinite4
)(CppTypeFor
<TypeCategory::Real
, 4> x
) {
533 return std::isfinite(x
);
535 bool RTNAME(IsFinite8
)(CppTypeFor
<TypeCategory::Real
, 8> x
) {
536 return std::isfinite(x
);
538 #if LDBL_MANT_DIG == 64
539 bool RTNAME(IsFinite10
)(CppTypeFor
<TypeCategory::Real
, 10> x
) {
540 return std::isfinite(x
);
542 #elif LDBL_MANT_DIG == 113
543 bool RTNAME(IsFinite16
)(CppTypeFor
<TypeCategory::Real
, 16> x
) {
544 return std::isfinite(x
);
548 bool RTNAME(IsNaN4
)(CppTypeFor
<TypeCategory::Real
, 4> x
) {
549 return std::isnan(x
);
551 bool RTNAME(IsNaN8
)(CppTypeFor
<TypeCategory::Real
, 8> x
) {
552 return std::isnan(x
);
554 #if LDBL_MANT_DIG == 64
555 bool RTNAME(IsNaN10
)(CppTypeFor
<TypeCategory::Real
, 10> x
) {
556 return std::isnan(x
);
558 #elif LDBL_MANT_DIG == 113
559 bool RTNAME(IsNaN16
)(CppTypeFor
<TypeCategory::Real
, 16> x
) {
560 return std::isnan(x
);
564 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(ModInteger1
)(
565 CppTypeFor
<TypeCategory::Integer
, 1> x
,
566 CppTypeFor
<TypeCategory::Integer
, 1> p
, const char *sourceFile
,
568 return IntMod
<false>(x
, p
, sourceFile
, sourceLine
);
570 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(ModInteger2
)(
571 CppTypeFor
<TypeCategory::Integer
, 2> x
,
572 CppTypeFor
<TypeCategory::Integer
, 2> p
, const char *sourceFile
,
574 return IntMod
<false>(x
, p
, sourceFile
, sourceLine
);
576 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(ModInteger4
)(
577 CppTypeFor
<TypeCategory::Integer
, 4> x
,
578 CppTypeFor
<TypeCategory::Integer
, 4> p
, const char *sourceFile
,
580 return IntMod
<false>(x
, p
, sourceFile
, sourceLine
);
582 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(ModInteger8
)(
583 CppTypeFor
<TypeCategory::Integer
, 8> x
,
584 CppTypeFor
<TypeCategory::Integer
, 8> p
, const char *sourceFile
,
586 return IntMod
<false>(x
, p
, sourceFile
, sourceLine
);
588 #ifdef __SIZEOF_INT128__
589 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(ModInteger16
)(
590 CppTypeFor
<TypeCategory::Integer
, 16> x
,
591 CppTypeFor
<TypeCategory::Integer
, 16> p
, const char *sourceFile
,
593 return IntMod
<false>(x
, p
, sourceFile
, sourceLine
);
596 CppTypeFor
<TypeCategory::Real
, 4> RTNAME(ModReal4
)(
597 CppTypeFor
<TypeCategory::Real
, 4> x
, CppTypeFor
<TypeCategory::Real
, 4> p
,
598 const char *sourceFile
, int sourceLine
) {
599 return RealMod
<false>(x
, p
, sourceFile
, sourceLine
);
601 CppTypeFor
<TypeCategory::Real
, 8> RTNAME(ModReal8
)(
602 CppTypeFor
<TypeCategory::Real
, 8> x
, CppTypeFor
<TypeCategory::Real
, 8> p
,
603 const char *sourceFile
, int sourceLine
) {
604 return RealMod
<false>(x
, p
, sourceFile
, sourceLine
);
606 #if LDBL_MANT_DIG == 64
607 CppTypeFor
<TypeCategory::Real
, 10> RTNAME(ModReal10
)(
608 CppTypeFor
<TypeCategory::Real
, 10> x
, CppTypeFor
<TypeCategory::Real
, 10> p
,
609 const char *sourceFile
, int sourceLine
) {
610 return RealMod
<false>(x
, p
, sourceFile
, sourceLine
);
612 #elif LDBL_MANT_DIG == 113
613 CppTypeFor
<TypeCategory::Real
, 16> RTNAME(ModReal16
)(
614 CppTypeFor
<TypeCategory::Real
, 16> x
, CppTypeFor
<TypeCategory::Real
, 16> p
,
615 const char *sourceFile
, int sourceLine
) {
616 return RealMod
<false>(x
, p
, sourceFile
, sourceLine
);
620 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(ModuloInteger1
)(
621 CppTypeFor
<TypeCategory::Integer
, 1> x
,
622 CppTypeFor
<TypeCategory::Integer
, 1> p
, const char *sourceFile
,
624 return IntMod
<true>(x
, p
, sourceFile
, sourceLine
);
626 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(ModuloInteger2
)(
627 CppTypeFor
<TypeCategory::Integer
, 2> x
,
628 CppTypeFor
<TypeCategory::Integer
, 2> p
, const char *sourceFile
,
630 return IntMod
<true>(x
, p
, sourceFile
, sourceLine
);
632 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(ModuloInteger4
)(
633 CppTypeFor
<TypeCategory::Integer
, 4> x
,
634 CppTypeFor
<TypeCategory::Integer
, 4> p
, const char *sourceFile
,
636 return IntMod
<true>(x
, p
, sourceFile
, sourceLine
);
638 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(ModuloInteger8
)(
639 CppTypeFor
<TypeCategory::Integer
, 8> x
,
640 CppTypeFor
<TypeCategory::Integer
, 8> p
, const char *sourceFile
,
642 return IntMod
<true>(x
, p
, sourceFile
, sourceLine
);
644 #ifdef __SIZEOF_INT128__
645 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(ModuloInteger16
)(
646 CppTypeFor
<TypeCategory::Integer
, 16> x
,
647 CppTypeFor
<TypeCategory::Integer
, 16> p
, const char *sourceFile
,
649 return IntMod
<true>(x
, p
, sourceFile
, sourceLine
);
652 CppTypeFor
<TypeCategory::Real
, 4> RTNAME(ModuloReal4
)(
653 CppTypeFor
<TypeCategory::Real
, 4> x
, CppTypeFor
<TypeCategory::Real
, 4> p
,
654 const char *sourceFile
, int sourceLine
) {
655 return RealMod
<true>(x
, p
, sourceFile
, sourceLine
);
657 CppTypeFor
<TypeCategory::Real
, 8> RTNAME(ModuloReal8
)(
658 CppTypeFor
<TypeCategory::Real
, 8> x
, CppTypeFor
<TypeCategory::Real
, 8> p
,
659 const char *sourceFile
, int sourceLine
) {
660 return RealMod
<true>(x
, p
, sourceFile
, sourceLine
);
662 #if LDBL_MANT_DIG == 64
663 CppTypeFor
<TypeCategory::Real
, 10> RTNAME(ModuloReal10
)(
664 CppTypeFor
<TypeCategory::Real
, 10> x
, CppTypeFor
<TypeCategory::Real
, 10> p
,
665 const char *sourceFile
, int sourceLine
) {
666 return RealMod
<true>(x
, p
, sourceFile
, sourceLine
);
668 #elif LDBL_MANT_DIG == 113
669 CppTypeFor
<TypeCategory::Real
, 16> RTNAME(ModuloReal16
)(
670 CppTypeFor
<TypeCategory::Real
, 16> x
, CppTypeFor
<TypeCategory::Real
, 16> p
,
671 const char *sourceFile
, int sourceLine
) {
672 return RealMod
<true>(x
, p
, sourceFile
, sourceLine
);
676 CppTypeFor
<TypeCategory::Real
, 4> RTNAME(Nearest4
)(
677 CppTypeFor
<TypeCategory::Real
, 4> x
, bool positive
) {
678 return Nearest
<24>(x
, positive
);
680 CppTypeFor
<TypeCategory::Real
, 8> RTNAME(Nearest8
)(
681 CppTypeFor
<TypeCategory::Real
, 8> x
, bool positive
) {
682 return Nearest
<53>(x
, positive
);
684 #if LDBL_MANT_DIG == 64
685 CppTypeFor
<TypeCategory::Real
, 10> RTNAME(Nearest10
)(
686 CppTypeFor
<TypeCategory::Real
, 10> x
, bool positive
) {
687 return Nearest
<64>(x
, positive
);
689 #elif LDBL_MANT_DIG == 113
690 CppTypeFor
<TypeCategory::Real
, 16> RTNAME(Nearest16
)(
691 CppTypeFor
<TypeCategory::Real
, 16> x
, bool positive
) {
692 return Nearest
<113>(x
, positive
);
696 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(Nint4_1
)(
697 CppTypeFor
<TypeCategory::Real
, 4> x
) {
698 return Nint
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
700 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(Nint4_2
)(
701 CppTypeFor
<TypeCategory::Real
, 4> x
) {
702 return Nint
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
704 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Nint4_4
)(
705 CppTypeFor
<TypeCategory::Real
, 4> x
) {
706 return Nint
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
708 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Nint4_8
)(
709 CppTypeFor
<TypeCategory::Real
, 4> x
) {
710 return Nint
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
712 #ifdef __SIZEOF_INT128__
713 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(Nint4_16
)(
714 CppTypeFor
<TypeCategory::Real
, 4> x
) {
715 return Nint
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
718 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(Nint8_1
)(
719 CppTypeFor
<TypeCategory::Real
, 8> x
) {
720 return Nint
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
722 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(Nint8_2
)(
723 CppTypeFor
<TypeCategory::Real
, 8> x
) {
724 return Nint
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
726 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Nint8_4
)(
727 CppTypeFor
<TypeCategory::Real
, 8> x
) {
728 return Nint
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
730 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Nint8_8
)(
731 CppTypeFor
<TypeCategory::Real
, 8> x
) {
732 return Nint
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
734 #ifdef __SIZEOF_INT128__
735 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(Nint8_16
)(
736 CppTypeFor
<TypeCategory::Real
, 8> x
) {
737 return Nint
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
740 #if LDBL_MANT_DIG == 64
741 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(Nint10_1
)(
742 CppTypeFor
<TypeCategory::Real
, 10> x
) {
743 return Nint
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
745 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(Nint10_2
)(
746 CppTypeFor
<TypeCategory::Real
, 10> x
) {
747 return Nint
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
749 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Nint10_4
)(
750 CppTypeFor
<TypeCategory::Real
, 10> x
) {
751 return Nint
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
753 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Nint10_8
)(
754 CppTypeFor
<TypeCategory::Real
, 10> x
) {
755 return Nint
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
757 #ifdef __SIZEOF_INT128__
758 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(Nint10_16
)(
759 CppTypeFor
<TypeCategory::Real
, 10> x
) {
760 return Nint
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
763 #elif LDBL_MANT_DIG == 113
764 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(Nint16_1
)(
765 CppTypeFor
<TypeCategory::Real
, 16> x
) {
766 return Nint
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
768 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(Nint16_2
)(
769 CppTypeFor
<TypeCategory::Real
, 16> x
) {
770 return Nint
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
772 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Nint16_4
)(
773 CppTypeFor
<TypeCategory::Real
, 16> x
) {
774 return Nint
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
776 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Nint16_8
)(
777 CppTypeFor
<TypeCategory::Real
, 16> x
) {
778 return Nint
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
780 #ifdef __SIZEOF_INT128__
781 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(Nint16_16
)(
782 CppTypeFor
<TypeCategory::Real
, 16> x
) {
783 return Nint
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
788 CppTypeFor
<TypeCategory::Real
, 4> RTNAME(RRSpacing4
)(
789 CppTypeFor
<TypeCategory::Real
, 4> x
) {
790 return RRSpacing
<24>(x
);
792 CppTypeFor
<TypeCategory::Real
, 8> RTNAME(RRSpacing8
)(
793 CppTypeFor
<TypeCategory::Real
, 8> x
) {
794 return RRSpacing
<53>(x
);
796 #if LDBL_MANT_DIG == 64
797 CppTypeFor
<TypeCategory::Real
, 10> RTNAME(RRSpacing10
)(
798 CppTypeFor
<TypeCategory::Real
, 10> x
) {
799 return RRSpacing
<64>(x
);
801 #elif LDBL_MANT_DIG == 113
802 CppTypeFor
<TypeCategory::Real
, 16> RTNAME(RRSpacing16
)(
803 CppTypeFor
<TypeCategory::Real
, 16> x
) {
804 return RRSpacing
<113>(x
);
808 CppTypeFor
<TypeCategory::Real
, 4> RTNAME(SetExponent4
)(
809 CppTypeFor
<TypeCategory::Real
, 4> x
, std::int64_t p
) {
810 return SetExponent(x
, p
);
812 CppTypeFor
<TypeCategory::Real
, 8> RTNAME(SetExponent8
)(
813 CppTypeFor
<TypeCategory::Real
, 8> x
, std::int64_t p
) {
814 return SetExponent(x
, p
);
816 #if LDBL_MANT_DIG == 64
817 CppTypeFor
<TypeCategory::Real
, 10> RTNAME(SetExponent10
)(
818 CppTypeFor
<TypeCategory::Real
, 10> x
, std::int64_t p
) {
819 return SetExponent(x
, p
);
821 #elif LDBL_MANT_DIG == 113
822 CppTypeFor
<TypeCategory::Real
, 16> RTNAME(SetExponent16
)(
823 CppTypeFor
<TypeCategory::Real
, 16> x
, std::int64_t p
) {
824 return SetExponent(x
, p
);
828 CppTypeFor
<TypeCategory::Real
, 4> RTNAME(Scale4
)(
829 CppTypeFor
<TypeCategory::Real
, 4> x
, std::int64_t p
) {
832 CppTypeFor
<TypeCategory::Real
, 8> RTNAME(Scale8
)(
833 CppTypeFor
<TypeCategory::Real
, 8> x
, std::int64_t p
) {
836 #if LDBL_MANT_DIG == 64
837 CppTypeFor
<TypeCategory::Real
, 10> RTNAME(Scale10
)(
838 CppTypeFor
<TypeCategory::Real
, 10> x
, std::int64_t p
) {
841 #elif LDBL_MANT_DIG == 113
842 CppTypeFor
<TypeCategory::Real
, 16> RTNAME(Scale16
)(
843 CppTypeFor
<TypeCategory::Real
, 16> x
, std::int64_t p
) {
849 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(SelectedIntKind
)(
850 const char *source
, int line
, void *x
, int xKind
) {
851 #ifdef __SIZEOF_INT128__
852 CppTypeFor
<TypeCategory::Integer
, 16> r
=
853 getIntArgValue
<CppTypeFor
<TypeCategory::Integer
, 16>>(
854 source
, line
, x
, xKind
, /*defaultValue*/ 0, /*resKind*/ 16);
856 std::int64_t r
= getIntArgValue
<std::int64_t>(
857 source
, line
, x
, xKind
, /*defaultValue*/ 0, /*resKind*/ 8);
859 return SelectedIntKind(r
);
862 // SELECTED_REAL_KIND
863 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(SelectedRealKind
)(
864 const char *source
, int line
, void *precision
, int pKind
, void *range
,
865 int rKind
, void *radix
, int dKind
) {
866 #ifdef __SIZEOF_INT128__
867 CppTypeFor
<TypeCategory::Integer
, 16> p
=
868 getIntArgValue
<CppTypeFor
<TypeCategory::Integer
, 16>>(
869 source
, line
, precision
, pKind
, /*defaultValue*/ 0, /*resKind*/ 16);
870 CppTypeFor
<TypeCategory::Integer
, 16> r
=
871 getIntArgValue
<CppTypeFor
<TypeCategory::Integer
, 16>>(
872 source
, line
, range
, rKind
, /*defaultValue*/ 0, /*resKind*/ 16);
873 CppTypeFor
<TypeCategory::Integer
, 16> d
=
874 getIntArgValue
<CppTypeFor
<TypeCategory::Integer
, 16>>(
875 source
, line
, radix
, dKind
, /*defaultValue*/ 2, /*resKind*/ 16);
877 std::int64_t p
= getIntArgValue
<std::int64_t>(
878 source
, line
, precision
, pKind
, /*defaultValue*/ 0, /*resKind*/ 8);
879 std::int64_t r
= getIntArgValue
<std::int64_t>(
880 source
, line
, range
, rKind
, /*defaultValue*/ 0, /*resKind*/ 8);
881 std::int64_t d
= getIntArgValue
<std::int64_t>(
882 source
, line
, radix
, dKind
, /*defaultValue*/ 2, /*resKind*/ 8);
884 return SelectedRealKind(p
, r
, d
);
887 CppTypeFor
<TypeCategory::Real
, 4> RTNAME(Spacing4
)(
888 CppTypeFor
<TypeCategory::Real
, 4> x
) {
889 return Spacing
<24>(x
);
891 CppTypeFor
<TypeCategory::Real
, 8> RTNAME(Spacing8
)(
892 CppTypeFor
<TypeCategory::Real
, 8> x
) {
893 return Spacing
<53>(x
);
895 #if LDBL_MANT_DIG == 64
896 CppTypeFor
<TypeCategory::Real
, 10> RTNAME(Spacing10
)(
897 CppTypeFor
<TypeCategory::Real
, 10> x
) {
898 return Spacing
<64>(x
);
900 #elif LDBL_MANT_DIG == 113
901 CppTypeFor
<TypeCategory::Real
, 16> RTNAME(Spacing16
)(
902 CppTypeFor
<TypeCategory::Real
, 16> x
) {
903 return Spacing
<113>(x
);
907 CppTypeFor
<TypeCategory::Real
, 4> RTNAME(FPow4i
)(
908 CppTypeFor
<TypeCategory::Real
, 4> b
,
909 CppTypeFor
<TypeCategory::Integer
, 4> e
) {
912 CppTypeFor
<TypeCategory::Real
, 8> RTNAME(FPow8i
)(
913 CppTypeFor
<TypeCategory::Real
, 8> b
,
914 CppTypeFor
<TypeCategory::Integer
, 4> e
) {
917 #if LDBL_MANT_DIG == 64
918 CppTypeFor
<TypeCategory::Real
, 10> RTNAME(FPow10i
)(
919 CppTypeFor
<TypeCategory::Real
, 10> b
,
920 CppTypeFor
<TypeCategory::Integer
, 4> e
) {
924 #if LDBL_MANT_DIG == 113 || HAS_FLOAT128
925 CppTypeFor
<TypeCategory::Real
, 16> RTNAME(FPow16i
)(
926 CppTypeFor
<TypeCategory::Real
, 16> b
,
927 CppTypeFor
<TypeCategory::Integer
, 4> e
) {
932 CppTypeFor
<TypeCategory::Real
, 4> RTNAME(FPow4k
)(
933 CppTypeFor
<TypeCategory::Real
, 4> b
,
934 CppTypeFor
<TypeCategory::Integer
, 8> e
) {
937 CppTypeFor
<TypeCategory::Real
, 8> RTNAME(FPow8k
)(
938 CppTypeFor
<TypeCategory::Real
, 8> b
,
939 CppTypeFor
<TypeCategory::Integer
, 8> e
) {
942 #if LDBL_MANT_DIG == 64
943 CppTypeFor
<TypeCategory::Real
, 10> RTNAME(FPow10k
)(
944 CppTypeFor
<TypeCategory::Real
, 10> b
,
945 CppTypeFor
<TypeCategory::Integer
, 8> e
) {
949 #if LDBL_MANT_DIG == 113 || HAS_FLOAT128
950 CppTypeFor
<TypeCategory::Real
, 16> RTNAME(FPow16k
)(
951 CppTypeFor
<TypeCategory::Real
, 16> b
,
952 CppTypeFor
<TypeCategory::Integer
, 8> e
) {
957 } // namespace Fortran::runtime