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/Common/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
86 return x
; // 0 -> same 0
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 std::ldexp(static_cast<T
>(1.0), std::ilogb(x
) + 1 - PREC
)}; // 2**(e-p)
244 return result
== 0 ? /*TINY(x)*/ std::numeric_limits
<T
>::min() : result
;
248 // NEAREST (16.9.139)
249 template <int PREC
, typename T
> inline T
Nearest(T x
, bool positive
) {
250 auto spacing
{Spacing
<PREC
>(x
)};
252 auto least
{std::numeric_limits
<T
>::denorm_min()};
253 return positive
? least
: -least
;
255 return positive
? x
+ spacing
: x
- spacing
;
259 // Exponentiation operator for (Real ** Integer) cases (10.1.5.2.1).
260 template <typename BTy
, typename ETy
> BTy
FPowI(BTy base
, ETy exp
) {
263 bool isNegativePower
{exp
< ETy
{0}};
264 bool isMinPower
{exp
== std::numeric_limits
<ETy
>::min()};
266 exp
= std::numeric_limits
<ETy
>::max();
267 } else if (isNegativePower
) {
285 if (isNegativePower
) {
286 result
= BTy
{1} / result
;
293 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(Ceiling4_1
)(
294 CppTypeFor
<TypeCategory::Real
, 4> x
) {
295 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
297 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(Ceiling4_2
)(
298 CppTypeFor
<TypeCategory::Real
, 4> x
) {
299 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
301 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Ceiling4_4
)(
302 CppTypeFor
<TypeCategory::Real
, 4> x
) {
303 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
305 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Ceiling4_8
)(
306 CppTypeFor
<TypeCategory::Real
, 4> x
) {
307 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
309 #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
310 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(Ceiling4_16
)(
311 CppTypeFor
<TypeCategory::Real
, 4> x
) {
312 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
315 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(Ceiling8_1
)(
316 CppTypeFor
<TypeCategory::Real
, 8> x
) {
317 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
319 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(Ceiling8_2
)(
320 CppTypeFor
<TypeCategory::Real
, 8> x
) {
321 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
323 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Ceiling8_4
)(
324 CppTypeFor
<TypeCategory::Real
, 8> x
) {
325 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
327 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Ceiling8_8
)(
328 CppTypeFor
<TypeCategory::Real
, 8> x
) {
329 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
331 #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
332 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(Ceiling8_16
)(
333 CppTypeFor
<TypeCategory::Real
, 8> x
) {
334 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
337 #if LDBL_MANT_DIG == 64
338 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(Ceiling10_1
)(
339 CppTypeFor
<TypeCategory::Real
, 10> x
) {
340 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
342 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(Ceiling10_2
)(
343 CppTypeFor
<TypeCategory::Real
, 10> x
) {
344 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
346 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Ceiling10_4
)(
347 CppTypeFor
<TypeCategory::Real
, 10> x
) {
348 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
350 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Ceiling10_8
)(
351 CppTypeFor
<TypeCategory::Real
, 10> x
) {
352 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
354 #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
355 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(Ceiling10_16
)(
356 CppTypeFor
<TypeCategory::Real
, 10> x
) {
357 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
360 #elif LDBL_MANT_DIG == 113
361 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(Ceiling16_1
)(
362 CppTypeFor
<TypeCategory::Real
, 16> x
) {
363 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
365 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(Ceiling16_2
)(
366 CppTypeFor
<TypeCategory::Real
, 16> x
) {
367 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
369 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Ceiling16_4
)(
370 CppTypeFor
<TypeCategory::Real
, 16> x
) {
371 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
373 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Ceiling16_8
)(
374 CppTypeFor
<TypeCategory::Real
, 16> x
) {
375 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
377 #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
378 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(Ceiling16_16
)(
379 CppTypeFor
<TypeCategory::Real
, 16> x
) {
380 return Ceiling
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
385 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Exponent4_4
)(
386 CppTypeFor
<TypeCategory::Real
, 4> x
) {
387 return Exponent
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
389 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Exponent4_8
)(
390 CppTypeFor
<TypeCategory::Real
, 4> x
) {
391 return Exponent
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
393 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Exponent8_4
)(
394 CppTypeFor
<TypeCategory::Real
, 8> x
) {
395 return Exponent
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
397 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Exponent8_8
)(
398 CppTypeFor
<TypeCategory::Real
, 8> x
) {
399 return Exponent
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
401 #if LDBL_MANT_DIG == 64
402 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Exponent10_4
)(
403 CppTypeFor
<TypeCategory::Real
, 10> x
) {
404 return Exponent
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
406 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Exponent10_8
)(
407 CppTypeFor
<TypeCategory::Real
, 10> x
) {
408 return Exponent
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
410 #elif LDBL_MANT_DIG == 113
411 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Exponent16_4
)(
412 CppTypeFor
<TypeCategory::Real
, 16> x
) {
413 return Exponent
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
415 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Exponent16_8
)(
416 CppTypeFor
<TypeCategory::Real
, 16> x
) {
417 return Exponent
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
421 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(Floor4_1
)(
422 CppTypeFor
<TypeCategory::Real
, 4> x
) {
423 return Floor
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
425 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(Floor4_2
)(
426 CppTypeFor
<TypeCategory::Real
, 4> x
) {
427 return Floor
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
429 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Floor4_4
)(
430 CppTypeFor
<TypeCategory::Real
, 4> x
) {
431 return Floor
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
433 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Floor4_8
)(
434 CppTypeFor
<TypeCategory::Real
, 4> x
) {
435 return Floor
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
437 #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
438 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(Floor4_16
)(
439 CppTypeFor
<TypeCategory::Real
, 4> x
) {
440 return Floor
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
443 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(Floor8_1
)(
444 CppTypeFor
<TypeCategory::Real
, 8> x
) {
445 return Floor
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
447 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(Floor8_2
)(
448 CppTypeFor
<TypeCategory::Real
, 8> x
) {
449 return Floor
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
451 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Floor8_4
)(
452 CppTypeFor
<TypeCategory::Real
, 8> x
) {
453 return Floor
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
455 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Floor8_8
)(
456 CppTypeFor
<TypeCategory::Real
, 8> x
) {
457 return Floor
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
459 #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
460 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(Floor8_16
)(
461 CppTypeFor
<TypeCategory::Real
, 8> x
) {
462 return Floor
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
465 #if LDBL_MANT_DIG == 64
466 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(Floor10_1
)(
467 CppTypeFor
<TypeCategory::Real
, 10> x
) {
468 return Floor
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
470 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(Floor10_2
)(
471 CppTypeFor
<TypeCategory::Real
, 10> x
) {
472 return Floor
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
474 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Floor10_4
)(
475 CppTypeFor
<TypeCategory::Real
, 10> x
) {
476 return Floor
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
478 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Floor10_8
)(
479 CppTypeFor
<TypeCategory::Real
, 10> x
) {
480 return Floor
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
482 #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
483 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(Floor10_16
)(
484 CppTypeFor
<TypeCategory::Real
, 10> x
) {
485 return Floor
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
488 #elif LDBL_MANT_DIG == 113
489 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(Floor16_1
)(
490 CppTypeFor
<TypeCategory::Real
, 16> x
) {
491 return Floor
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
493 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(Floor16_2
)(
494 CppTypeFor
<TypeCategory::Real
, 16> x
) {
495 return Floor
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
497 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Floor16_4
)(
498 CppTypeFor
<TypeCategory::Real
, 16> x
) {
499 return Floor
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
501 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Floor16_8
)(
502 CppTypeFor
<TypeCategory::Real
, 16> x
) {
503 return Floor
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
505 #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
506 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(Floor16_16
)(
507 CppTypeFor
<TypeCategory::Real
, 16> x
) {
508 return Floor
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
513 CppTypeFor
<TypeCategory::Real
, 4> RTNAME(Fraction4
)(
514 CppTypeFor
<TypeCategory::Real
, 4> x
) {
517 CppTypeFor
<TypeCategory::Real
, 8> RTNAME(Fraction8
)(
518 CppTypeFor
<TypeCategory::Real
, 8> x
) {
521 #if LDBL_MANT_DIG == 64
522 CppTypeFor
<TypeCategory::Real
, 10> RTNAME(Fraction10
)(
523 CppTypeFor
<TypeCategory::Real
, 10> x
) {
526 #elif LDBL_MANT_DIG == 113
527 CppTypeFor
<TypeCategory::Real
, 16> RTNAME(Fraction16
)(
528 CppTypeFor
<TypeCategory::Real
, 16> x
) {
533 bool RTNAME(IsFinite4
)(CppTypeFor
<TypeCategory::Real
, 4> x
) {
534 return std::isfinite(x
);
536 bool RTNAME(IsFinite8
)(CppTypeFor
<TypeCategory::Real
, 8> x
) {
537 return std::isfinite(x
);
539 #if LDBL_MANT_DIG == 64
540 bool RTNAME(IsFinite10
)(CppTypeFor
<TypeCategory::Real
, 10> x
) {
541 return std::isfinite(x
);
543 #elif LDBL_MANT_DIG == 113
544 bool RTNAME(IsFinite16
)(CppTypeFor
<TypeCategory::Real
, 16> x
) {
545 return std::isfinite(x
);
549 bool RTNAME(IsNaN4
)(CppTypeFor
<TypeCategory::Real
, 4> x
) {
550 return std::isnan(x
);
552 bool RTNAME(IsNaN8
)(CppTypeFor
<TypeCategory::Real
, 8> x
) {
553 return std::isnan(x
);
555 #if LDBL_MANT_DIG == 64
556 bool RTNAME(IsNaN10
)(CppTypeFor
<TypeCategory::Real
, 10> x
) {
557 return std::isnan(x
);
559 #elif LDBL_MANT_DIG == 113
560 bool RTNAME(IsNaN16
)(CppTypeFor
<TypeCategory::Real
, 16> x
) {
561 return std::isnan(x
);
565 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(ModInteger1
)(
566 CppTypeFor
<TypeCategory::Integer
, 1> x
,
567 CppTypeFor
<TypeCategory::Integer
, 1> p
, const char *sourceFile
,
569 return IntMod
<false>(x
, p
, sourceFile
, sourceLine
);
571 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(ModInteger2
)(
572 CppTypeFor
<TypeCategory::Integer
, 2> x
,
573 CppTypeFor
<TypeCategory::Integer
, 2> p
, const char *sourceFile
,
575 return IntMod
<false>(x
, p
, sourceFile
, sourceLine
);
577 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(ModInteger4
)(
578 CppTypeFor
<TypeCategory::Integer
, 4> x
,
579 CppTypeFor
<TypeCategory::Integer
, 4> p
, const char *sourceFile
,
581 return IntMod
<false>(x
, p
, sourceFile
, sourceLine
);
583 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(ModInteger8
)(
584 CppTypeFor
<TypeCategory::Integer
, 8> x
,
585 CppTypeFor
<TypeCategory::Integer
, 8> p
, const char *sourceFile
,
587 return IntMod
<false>(x
, p
, sourceFile
, sourceLine
);
589 #ifdef __SIZEOF_INT128__
590 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(ModInteger16
)(
591 CppTypeFor
<TypeCategory::Integer
, 16> x
,
592 CppTypeFor
<TypeCategory::Integer
, 16> p
, const char *sourceFile
,
594 return IntMod
<false>(x
, p
, sourceFile
, sourceLine
);
597 CppTypeFor
<TypeCategory::Real
, 4> RTNAME(ModReal4
)(
598 CppTypeFor
<TypeCategory::Real
, 4> x
, CppTypeFor
<TypeCategory::Real
, 4> p
,
599 const char *sourceFile
, int sourceLine
) {
600 return RealMod
<false>(x
, p
, sourceFile
, sourceLine
);
602 CppTypeFor
<TypeCategory::Real
, 8> RTNAME(ModReal8
)(
603 CppTypeFor
<TypeCategory::Real
, 8> x
, CppTypeFor
<TypeCategory::Real
, 8> p
,
604 const char *sourceFile
, int sourceLine
) {
605 return RealMod
<false>(x
, p
, sourceFile
, sourceLine
);
607 #if LDBL_MANT_DIG == 64
608 CppTypeFor
<TypeCategory::Real
, 10> RTNAME(ModReal10
)(
609 CppTypeFor
<TypeCategory::Real
, 10> x
, CppTypeFor
<TypeCategory::Real
, 10> p
,
610 const char *sourceFile
, int sourceLine
) {
611 return RealMod
<false>(x
, p
, sourceFile
, sourceLine
);
613 #elif LDBL_MANT_DIG == 113
614 CppTypeFor
<TypeCategory::Real
, 16> RTNAME(ModReal16
)(
615 CppTypeFor
<TypeCategory::Real
, 16> x
, CppTypeFor
<TypeCategory::Real
, 16> p
,
616 const char *sourceFile
, int sourceLine
) {
617 return RealMod
<false>(x
, p
, sourceFile
, sourceLine
);
621 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(ModuloInteger1
)(
622 CppTypeFor
<TypeCategory::Integer
, 1> x
,
623 CppTypeFor
<TypeCategory::Integer
, 1> p
, const char *sourceFile
,
625 return IntMod
<true>(x
, p
, sourceFile
, sourceLine
);
627 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(ModuloInteger2
)(
628 CppTypeFor
<TypeCategory::Integer
, 2> x
,
629 CppTypeFor
<TypeCategory::Integer
, 2> p
, const char *sourceFile
,
631 return IntMod
<true>(x
, p
, sourceFile
, sourceLine
);
633 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(ModuloInteger4
)(
634 CppTypeFor
<TypeCategory::Integer
, 4> x
,
635 CppTypeFor
<TypeCategory::Integer
, 4> p
, const char *sourceFile
,
637 return IntMod
<true>(x
, p
, sourceFile
, sourceLine
);
639 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(ModuloInteger8
)(
640 CppTypeFor
<TypeCategory::Integer
, 8> x
,
641 CppTypeFor
<TypeCategory::Integer
, 8> p
, const char *sourceFile
,
643 return IntMod
<true>(x
, p
, sourceFile
, sourceLine
);
645 #ifdef __SIZEOF_INT128__
646 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(ModuloInteger16
)(
647 CppTypeFor
<TypeCategory::Integer
, 16> x
,
648 CppTypeFor
<TypeCategory::Integer
, 16> p
, const char *sourceFile
,
650 return IntMod
<true>(x
, p
, sourceFile
, sourceLine
);
653 CppTypeFor
<TypeCategory::Real
, 4> RTNAME(ModuloReal4
)(
654 CppTypeFor
<TypeCategory::Real
, 4> x
, CppTypeFor
<TypeCategory::Real
, 4> p
,
655 const char *sourceFile
, int sourceLine
) {
656 return RealMod
<true>(x
, p
, sourceFile
, sourceLine
);
658 CppTypeFor
<TypeCategory::Real
, 8> RTNAME(ModuloReal8
)(
659 CppTypeFor
<TypeCategory::Real
, 8> x
, CppTypeFor
<TypeCategory::Real
, 8> p
,
660 const char *sourceFile
, int sourceLine
) {
661 return RealMod
<true>(x
, p
, sourceFile
, sourceLine
);
663 #if LDBL_MANT_DIG == 64
664 CppTypeFor
<TypeCategory::Real
, 10> RTNAME(ModuloReal10
)(
665 CppTypeFor
<TypeCategory::Real
, 10> x
, CppTypeFor
<TypeCategory::Real
, 10> p
,
666 const char *sourceFile
, int sourceLine
) {
667 return RealMod
<true>(x
, p
, sourceFile
, sourceLine
);
669 #elif LDBL_MANT_DIG == 113
670 CppTypeFor
<TypeCategory::Real
, 16> RTNAME(ModuloReal16
)(
671 CppTypeFor
<TypeCategory::Real
, 16> x
, CppTypeFor
<TypeCategory::Real
, 16> p
,
672 const char *sourceFile
, int sourceLine
) {
673 return RealMod
<true>(x
, p
, sourceFile
, sourceLine
);
677 CppTypeFor
<TypeCategory::Real
, 4> RTNAME(Nearest4
)(
678 CppTypeFor
<TypeCategory::Real
, 4> x
, bool positive
) {
679 return Nearest
<24>(x
, positive
);
681 CppTypeFor
<TypeCategory::Real
, 8> RTNAME(Nearest8
)(
682 CppTypeFor
<TypeCategory::Real
, 8> x
, bool positive
) {
683 return Nearest
<53>(x
, positive
);
685 #if LDBL_MANT_DIG == 64
686 CppTypeFor
<TypeCategory::Real
, 10> RTNAME(Nearest10
)(
687 CppTypeFor
<TypeCategory::Real
, 10> x
, bool positive
) {
688 return Nearest
<64>(x
, positive
);
690 #elif LDBL_MANT_DIG == 113
691 CppTypeFor
<TypeCategory::Real
, 16> RTNAME(Nearest16
)(
692 CppTypeFor
<TypeCategory::Real
, 16> x
, bool positive
) {
693 return Nearest
<113>(x
, positive
);
697 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(Nint4_1
)(
698 CppTypeFor
<TypeCategory::Real
, 4> x
) {
699 return Nint
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
701 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(Nint4_2
)(
702 CppTypeFor
<TypeCategory::Real
, 4> x
) {
703 return Nint
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
705 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Nint4_4
)(
706 CppTypeFor
<TypeCategory::Real
, 4> x
) {
707 return Nint
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
709 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Nint4_8
)(
710 CppTypeFor
<TypeCategory::Real
, 4> x
) {
711 return Nint
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
713 #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
714 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(Nint4_16
)(
715 CppTypeFor
<TypeCategory::Real
, 4> x
) {
716 return Nint
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
719 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(Nint8_1
)(
720 CppTypeFor
<TypeCategory::Real
, 8> x
) {
721 return Nint
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
723 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(Nint8_2
)(
724 CppTypeFor
<TypeCategory::Real
, 8> x
) {
725 return Nint
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
727 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Nint8_4
)(
728 CppTypeFor
<TypeCategory::Real
, 8> x
) {
729 return Nint
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
731 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Nint8_8
)(
732 CppTypeFor
<TypeCategory::Real
, 8> x
) {
733 return Nint
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
735 #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
736 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(Nint8_16
)(
737 CppTypeFor
<TypeCategory::Real
, 8> x
) {
738 return Nint
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
741 #if LDBL_MANT_DIG == 64
742 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(Nint10_1
)(
743 CppTypeFor
<TypeCategory::Real
, 10> x
) {
744 return Nint
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
746 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(Nint10_2
)(
747 CppTypeFor
<TypeCategory::Real
, 10> x
) {
748 return Nint
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
750 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Nint10_4
)(
751 CppTypeFor
<TypeCategory::Real
, 10> x
) {
752 return Nint
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
754 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Nint10_8
)(
755 CppTypeFor
<TypeCategory::Real
, 10> x
) {
756 return Nint
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
758 #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
759 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(Nint10_16
)(
760 CppTypeFor
<TypeCategory::Real
, 10> x
) {
761 return Nint
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
764 #elif LDBL_MANT_DIG == 113
765 CppTypeFor
<TypeCategory::Integer
, 1> RTNAME(Nint16_1
)(
766 CppTypeFor
<TypeCategory::Real
, 16> x
) {
767 return Nint
<CppTypeFor
<TypeCategory::Integer
, 1>>(x
);
769 CppTypeFor
<TypeCategory::Integer
, 2> RTNAME(Nint16_2
)(
770 CppTypeFor
<TypeCategory::Real
, 16> x
) {
771 return Nint
<CppTypeFor
<TypeCategory::Integer
, 2>>(x
);
773 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(Nint16_4
)(
774 CppTypeFor
<TypeCategory::Real
, 16> x
) {
775 return Nint
<CppTypeFor
<TypeCategory::Integer
, 4>>(x
);
777 CppTypeFor
<TypeCategory::Integer
, 8> RTNAME(Nint16_8
)(
778 CppTypeFor
<TypeCategory::Real
, 16> x
) {
779 return Nint
<CppTypeFor
<TypeCategory::Integer
, 8>>(x
);
781 #if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
782 CppTypeFor
<TypeCategory::Integer
, 16> RTNAME(Nint16_16
)(
783 CppTypeFor
<TypeCategory::Real
, 16> x
) {
784 return Nint
<CppTypeFor
<TypeCategory::Integer
, 16>>(x
);
789 CppTypeFor
<TypeCategory::Real
, 4> RTNAME(RRSpacing4
)(
790 CppTypeFor
<TypeCategory::Real
, 4> x
) {
791 return RRSpacing
<24>(x
);
793 CppTypeFor
<TypeCategory::Real
, 8> RTNAME(RRSpacing8
)(
794 CppTypeFor
<TypeCategory::Real
, 8> x
) {
795 return RRSpacing
<53>(x
);
797 #if LDBL_MANT_DIG == 64
798 CppTypeFor
<TypeCategory::Real
, 10> RTNAME(RRSpacing10
)(
799 CppTypeFor
<TypeCategory::Real
, 10> x
) {
800 return RRSpacing
<64>(x
);
802 #elif LDBL_MANT_DIG == 113
803 CppTypeFor
<TypeCategory::Real
, 16> RTNAME(RRSpacing16
)(
804 CppTypeFor
<TypeCategory::Real
, 16> x
) {
805 return RRSpacing
<113>(x
);
809 CppTypeFor
<TypeCategory::Real
, 4> RTNAME(SetExponent4
)(
810 CppTypeFor
<TypeCategory::Real
, 4> x
, std::int64_t p
) {
811 return SetExponent(x
, p
);
813 CppTypeFor
<TypeCategory::Real
, 8> RTNAME(SetExponent8
)(
814 CppTypeFor
<TypeCategory::Real
, 8> x
, std::int64_t p
) {
815 return SetExponent(x
, p
);
817 #if LDBL_MANT_DIG == 64
818 CppTypeFor
<TypeCategory::Real
, 10> RTNAME(SetExponent10
)(
819 CppTypeFor
<TypeCategory::Real
, 10> x
, std::int64_t p
) {
820 return SetExponent(x
, p
);
822 #elif LDBL_MANT_DIG == 113
823 CppTypeFor
<TypeCategory::Real
, 16> RTNAME(SetExponent16
)(
824 CppTypeFor
<TypeCategory::Real
, 16> x
, std::int64_t p
) {
825 return SetExponent(x
, p
);
829 CppTypeFor
<TypeCategory::Real
, 4> RTNAME(Scale4
)(
830 CppTypeFor
<TypeCategory::Real
, 4> x
, std::int64_t p
) {
833 CppTypeFor
<TypeCategory::Real
, 8> RTNAME(Scale8
)(
834 CppTypeFor
<TypeCategory::Real
, 8> x
, std::int64_t p
) {
837 #if LDBL_MANT_DIG == 64
838 CppTypeFor
<TypeCategory::Real
, 10> RTNAME(Scale10
)(
839 CppTypeFor
<TypeCategory::Real
, 10> x
, std::int64_t p
) {
842 #elif LDBL_MANT_DIG == 113
843 CppTypeFor
<TypeCategory::Real
, 16> RTNAME(Scale16
)(
844 CppTypeFor
<TypeCategory::Real
, 16> x
, std::int64_t p
) {
850 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(SelectedIntKind
)(
851 const char *source
, int line
, void *x
, int xKind
) {
852 #ifdef __SIZEOF_INT128__
853 CppTypeFor
<TypeCategory::Integer
, 16> r
=
854 getIntArgValue
<CppTypeFor
<TypeCategory::Integer
, 16>>(
855 source
, line
, x
, xKind
, /*defaultValue*/ 0, /*resKind*/ 16);
857 std::int64_t r
= getIntArgValue
<std::int64_t>(
858 source
, line
, x
, xKind
, /*defaultValue*/ 0, /*resKind*/ 8);
860 return SelectedIntKind(r
);
863 // SELECTED_REAL_KIND
864 CppTypeFor
<TypeCategory::Integer
, 4> RTNAME(SelectedRealKind
)(
865 const char *source
, int line
, void *precision
, int pKind
, void *range
,
866 int rKind
, void *radix
, int dKind
) {
867 #ifdef __SIZEOF_INT128__
868 CppTypeFor
<TypeCategory::Integer
, 16> p
=
869 getIntArgValue
<CppTypeFor
<TypeCategory::Integer
, 16>>(
870 source
, line
, precision
, pKind
, /*defaultValue*/ 0, /*resKind*/ 16);
871 CppTypeFor
<TypeCategory::Integer
, 16> r
=
872 getIntArgValue
<CppTypeFor
<TypeCategory::Integer
, 16>>(
873 source
, line
, range
, rKind
, /*defaultValue*/ 0, /*resKind*/ 16);
874 CppTypeFor
<TypeCategory::Integer
, 16> d
=
875 getIntArgValue
<CppTypeFor
<TypeCategory::Integer
, 16>>(
876 source
, line
, radix
, dKind
, /*defaultValue*/ 2, /*resKind*/ 16);
878 std::int64_t p
= getIntArgValue
<std::int64_t>(
879 source
, line
, precision
, pKind
, /*defaultValue*/ 0, /*resKind*/ 8);
880 std::int64_t r
= getIntArgValue
<std::int64_t>(
881 source
, line
, range
, rKind
, /*defaultValue*/ 0, /*resKind*/ 8);
882 std::int64_t d
= getIntArgValue
<std::int64_t>(
883 source
, line
, radix
, dKind
, /*defaultValue*/ 2, /*resKind*/ 8);
885 return SelectedRealKind(p
, r
, d
);
888 CppTypeFor
<TypeCategory::Real
, 4> RTNAME(Spacing4
)(
889 CppTypeFor
<TypeCategory::Real
, 4> x
) {
890 return Spacing
<24>(x
);
892 CppTypeFor
<TypeCategory::Real
, 8> RTNAME(Spacing8
)(
893 CppTypeFor
<TypeCategory::Real
, 8> x
) {
894 return Spacing
<53>(x
);
896 #if LDBL_MANT_DIG == 64
897 CppTypeFor
<TypeCategory::Real
, 10> RTNAME(Spacing10
)(
898 CppTypeFor
<TypeCategory::Real
, 10> x
) {
899 return Spacing
<64>(x
);
901 #elif LDBL_MANT_DIG == 113
902 CppTypeFor
<TypeCategory::Real
, 16> RTNAME(Spacing16
)(
903 CppTypeFor
<TypeCategory::Real
, 16> x
) {
904 return Spacing
<113>(x
);
908 CppTypeFor
<TypeCategory::Real
, 4> RTNAME(FPow4i
)(
909 CppTypeFor
<TypeCategory::Real
, 4> b
,
910 CppTypeFor
<TypeCategory::Integer
, 4> e
) {
913 CppTypeFor
<TypeCategory::Real
, 8> RTNAME(FPow8i
)(
914 CppTypeFor
<TypeCategory::Real
, 8> b
,
915 CppTypeFor
<TypeCategory::Integer
, 4> e
) {
918 #if LDBL_MANT_DIG == 64
919 CppTypeFor
<TypeCategory::Real
, 10> RTNAME(FPow10i
)(
920 CppTypeFor
<TypeCategory::Real
, 10> b
,
921 CppTypeFor
<TypeCategory::Integer
, 4> e
) {
925 #if LDBL_MANT_DIG == 113 || HAS_FLOAT128
926 CppTypeFor
<TypeCategory::Real
, 16> RTNAME(FPow16i
)(
927 CppTypeFor
<TypeCategory::Real
, 16> b
,
928 CppTypeFor
<TypeCategory::Integer
, 4> e
) {
933 CppTypeFor
<TypeCategory::Real
, 4> RTNAME(FPow4k
)(
934 CppTypeFor
<TypeCategory::Real
, 4> b
,
935 CppTypeFor
<TypeCategory::Integer
, 8> e
) {
938 CppTypeFor
<TypeCategory::Real
, 8> RTNAME(FPow8k
)(
939 CppTypeFor
<TypeCategory::Real
, 8> b
,
940 CppTypeFor
<TypeCategory::Integer
, 8> e
) {
943 #if LDBL_MANT_DIG == 64
944 CppTypeFor
<TypeCategory::Real
, 10> RTNAME(FPow10k
)(
945 CppTypeFor
<TypeCategory::Real
, 10> b
,
946 CppTypeFor
<TypeCategory::Integer
, 8> e
) {
950 #if LDBL_MANT_DIG == 113 || HAS_FLOAT128
951 CppTypeFor
<TypeCategory::Real
, 16> RTNAME(FPow16k
)(
952 CppTypeFor
<TypeCategory::Real
, 16> b
,
953 CppTypeFor
<TypeCategory::Integer
, 8> e
) {
958 } // namespace Fortran::runtime