[Support] Remove unused includes (NFC) (#116752)
[llvm-project.git] / flang / runtime / numeric.cpp
blob4797ecf58fa7112976c22c12220a49c605909674
1 //===-- runtime/numeric.cpp -----------------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
9 #include "flang/Runtime/numeric.h"
10 #include "numeric-templates.h"
11 #include "terminator.h"
12 #include "tools.h"
13 #include "flang/Common/float128.h"
14 #include <cfloat>
15 #include <climits>
16 #include <cmath>
17 #include <limits>
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) {
24 RES res;
25 if (!arg) {
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) {
41 if (resKind != 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));
46 #endif
47 } else {
48 Terminator{source, line}.Crash("Unexpected integer kind in runtime");
50 return res;
53 // NINT (16.9.141)
54 template <typename RESULT, typename ARG>
55 inline RT_API_ATTRS RESULT Nint(ARG x) {
56 if (x >= 0) {
57 return std::trunc(x + ARG{0.5});
58 } else {
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) {
66 return std::ceil(x);
68 template <typename RESULT, typename ARG>
69 inline RT_API_ATTRS RESULT Floor(ARG x) {
70 return std::floor(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) {
76 if (p == 0) {
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)) {
82 mod += p;
84 return mod;
87 // SCALE (16.9.166)
88 template <typename T> inline RT_API_ATTRS T Scale(T x, std::int64_t p) {
89 auto ip{static_cast<int>(p)};
90 if (ip != 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(
100 X x, M mask) {
101 #if !defined __SIZEOF_INT128__ || defined FLANG_RUNTIME_NO_INTEGER_16
102 mask &= ~(1 << 16);
103 #endif
104 if (x <= 2 && (mask & (1 << 1))) {
105 return 1;
106 } else if (x <= 4 && (mask & (1 << 2))) {
107 return 2;
108 } else if (x <= 9 && (mask & (1 << 4))) {
109 return 4;
110 } else if (x <= 18 && (mask & (1 << 8))) {
111 return 8;
112 } else if (x <= 38 && (mask & (1 << 16))) {
113 return 16;
115 return -1;
118 // SELECTED_LOGICAL_KIND (F'2023 16.9.182)
119 template <typename T>
120 inline RT_API_ATTRS CppTypeFor<TypeCategory::Integer, 4> SelectedLogicalKind(
121 T x) {
122 if (x <= 8) {
123 return 1;
124 } else if (x <= 16) {
125 return 2;
126 } else if (x <= 32) {
127 return 4;
128 } else if (x <= 64) {
129 return 8;
131 return -1;
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) {
138 if (d != 2) {
139 return -5;
141 #ifdef FLANG_RUNTIME_NO_REAL_2
142 mask &= ~(1 << 2);
143 #endif
144 #ifdef FLANG_RUNTIME_NO_REAL_3
145 mask &= ~(1 << 3);
146 #endif
147 #if !HAS_FLOAT80 || defined FLANG_RUNTIME_NO_REAL_10
148 mask &= ~(1 << 10);
149 #endif
150 #if LDBL_MANT_DIG < 64 || defined FLANG_RUNTIME_NO_REAL_16
151 mask &= ~(1 << 16);
152 #endif
154 int error{0};
155 int kind{0};
156 if (p <= 3 && (mask & (1 << 2))) {
157 kind = 2;
158 } else if (p <= 6 && (mask & (1 << 4))) {
159 kind = 4;
160 } else if (p <= 15 && (mask & (1 << 8))) {
161 kind = 8;
162 } else if (p <= 18 && (mask & (1 << 10))) {
163 kind = 10;
164 } else if (p <= 33 && (mask & (1 << 16))) {
165 kind = 16;
166 } else {
167 error -= 1;
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;
182 } else {
183 error -= 2;
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) {
192 if (positive) {
193 return std::nextafter(x, std::numeric_limits<T>::infinity());
194 } else {
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) {
202 if (exp == ETy{0})
203 return BTy{1};
204 bool isNegativePower{exp < ETy{0}};
205 bool isMinPower{exp == std::numeric_limits<ETy>::min()};
206 if (isMinPower) {
207 exp = std::numeric_limits<ETy>::max();
208 } else if (isNegativePower) {
209 exp = -exp;
211 BTy result{1};
212 BTy origBase{base};
213 while (true) {
214 if (exp & ETy{1}) {
215 result *= base;
217 exp >>= 1;
218 if (exp == ETy{0}) {
219 break;
221 base *= base;
223 if (isMinPower) {
224 result *= origBase;
226 if (isNegativePower) {
227 result = BTy{1} / result;
229 return result;
232 extern "C" {
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);
256 #endif
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);
278 #endif
279 #if HAS_FLOAT80
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);
301 #endif
302 #elif HAS_LDBL128
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);
324 #endif
325 #endif
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);
335 #if HAS_FLOAT80
336 CppTypeFor<TypeCategory::Real, 10> RTDEF(ErfcScaled10)(
337 CppTypeFor<TypeCategory::Real, 10> x) {
338 return ErfcScaled(x);
340 #endif
341 #if HAS_LDBL128
342 CppTypeFor<TypeCategory::Real, 16> RTDEF(ErfcScaled16)(
343 CppTypeFor<TypeCategory::Real, 16> x) {
344 return ErfcScaled(x);
346 #endif
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);
364 #if HAS_FLOAT80
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);
373 #endif
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);
396 #endif
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);
418 #endif
419 #if HAS_FLOAT80
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);
441 #endif
442 #elif HAS_LDBL128
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);
464 #endif
465 #endif
467 CppTypeFor<TypeCategory::Real, 4> RTDEF(Fraction4)(
468 CppTypeFor<TypeCategory::Real, 4> x) {
469 return Fraction(x);
471 CppTypeFor<TypeCategory::Real, 8> RTDEF(Fraction8)(
472 CppTypeFor<TypeCategory::Real, 8> x) {
473 return Fraction(x);
475 #if HAS_FLOAT80
476 CppTypeFor<TypeCategory::Real, 10> RTDEF(Fraction10)(
477 CppTypeFor<TypeCategory::Real, 10> x) {
478 return Fraction(x);
480 #endif
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);
488 #if HAS_FLOAT80
489 bool RTDEF(IsFinite10)(CppTypeFor<TypeCategory::Real, 10> x) {
490 return std::isfinite(x);
492 #elif HAS_LDBL128
493 bool RTDEF(IsFinite16)(CppTypeFor<TypeCategory::Real, 16> x) {
494 return std::isfinite(x);
496 #endif
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);
504 #if HAS_FLOAT80
505 bool RTDEF(IsNaN10)(CppTypeFor<TypeCategory::Real, 10> x) {
506 return std::isnan(x);
508 #elif HAS_LDBL128
509 bool RTDEF(IsNaN16)(CppTypeFor<TypeCategory::Real, 16> x) {
510 return std::isnan(x);
512 #endif
514 CppTypeFor<TypeCategory::Integer, 1> RTDEF(ModInteger1)(
515 CppTypeFor<TypeCategory::Integer, 1> x,
516 CppTypeFor<TypeCategory::Integer, 1> p, const char *sourceFile,
517 int sourceLine) {
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,
523 int sourceLine) {
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,
529 int sourceLine) {
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,
535 int sourceLine) {
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,
542 int sourceLine) {
543 return IntMod<false>(x, p, sourceFile, sourceLine);
545 #endif
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);
556 #if HAS_FLOAT80
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);
562 #endif
564 CppTypeFor<TypeCategory::Integer, 1> RTDEF(ModuloInteger1)(
565 CppTypeFor<TypeCategory::Integer, 1> x,
566 CppTypeFor<TypeCategory::Integer, 1> p, const char *sourceFile,
567 int sourceLine) {
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,
573 int sourceLine) {
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,
579 int sourceLine) {
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,
585 int sourceLine) {
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,
592 int sourceLine) {
593 return IntMod<true>(x, p, sourceFile, sourceLine);
595 #endif
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);
606 #if HAS_FLOAT80
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);
612 #endif
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);
622 #if HAS_FLOAT80
623 CppTypeFor<TypeCategory::Real, 10> RTDEF(Nearest10)(
624 CppTypeFor<TypeCategory::Real, 10> x, bool positive) {
625 return Nearest<64>(x, positive);
627 #endif
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);
650 #endif
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);
672 #endif
673 #if HAS_FLOAT80
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);
695 #endif
696 #elif HAS_LDBL128
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);
718 #endif
719 #endif
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);
729 #if HAS_FLOAT80
730 CppTypeFor<TypeCategory::Real, 10> RTDEF(RRSpacing10)(
731 CppTypeFor<TypeCategory::Real, 10> x) {
732 return RRSpacing<64>(x);
734 #endif
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);
744 #if HAS_FLOAT80
745 CppTypeFor<TypeCategory::Real, 10> RTDEF(SetExponent10)(
746 CppTypeFor<TypeCategory::Real, 10> x, std::int64_t p) {
747 return SetExponent(x, p);
749 #endif
751 CppTypeFor<TypeCategory::Real, 4> RTDEF(Scale4)(
752 CppTypeFor<TypeCategory::Real, 4> x, std::int64_t p) {
753 return Scale(x, p);
755 CppTypeFor<TypeCategory::Real, 8> RTDEF(Scale8)(
756 CppTypeFor<TypeCategory::Real, 8> x, std::int64_t p) {
757 return Scale(x, p);
759 #if HAS_FLOAT80
760 CppTypeFor<TypeCategory::Real, 10> RTDEF(Scale10)(
761 CppTypeFor<TypeCategory::Real, 10> x, std::int64_t p) {
762 return Scale(x, p);
764 #endif
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)) {
772 case 0: // ASCII
773 case 1: // DEFAULT
774 return 1;
775 case 2: // UCS-2
776 return 2;
777 case 3: // ISO_10646
778 case 4: // UCS-4
779 return 4;
780 default:
781 return -1;
784 // SELECTED_INT_KIND
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);
797 #else
798 std::int64_t r = GetIntArgValue<std::int64_t>(
799 source, line, x, xKind, /*defaultValue*/ 0, /*resKind*/ 8);
800 #endif
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);
811 #else
812 std::int64_t r = GetIntArgValue<std::int64_t>(
813 source, line, x, xKind, /*defaultValue*/ 0, /*resKind*/ 8);
814 #endif
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,
821 int dKind) {
822 return RTNAME(SelectedRealKindMasked)(source, line, precision, pKind, range,
823 rKind, radix, dKind,
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);
840 #else
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);
847 #endif
848 return SelectedRealKind(p, r, d, mask);
851 #if HAS_FP16
852 CppTypeFor<TypeCategory::Real, 2> RTDEF(Spacing2)(
853 CppTypeFor<TypeCategory::Real, 2> x) {
854 return Spacing<11>(x);
856 #endif
857 CppTypeFor<TypeCategory::Real, 4> RTDEF(Spacing2By4)(
858 CppTypeFor<TypeCategory::Real, 4> x) {
859 return Spacing<11>(x);
861 #if HAS_BF16
862 CppTypeFor<TypeCategory::Real, 3> RTDEF(Spacing3)(
863 CppTypeFor<TypeCategory::Real, 3> x) {
864 return Spacing<8>(x);
866 #endif
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);
879 #if HAS_FLOAT80
880 CppTypeFor<TypeCategory::Real, 10> RTDEF(Spacing10)(
881 CppTypeFor<TypeCategory::Real, 10> x) {
882 return Spacing<64>(x);
884 #endif
886 CppTypeFor<TypeCategory::Real, 4> RTDEF(FPow4i)(
887 CppTypeFor<TypeCategory::Real, 4> b,
888 CppTypeFor<TypeCategory::Integer, 4> e) {
889 return FPowI(b, e);
891 CppTypeFor<TypeCategory::Real, 8> RTDEF(FPow8i)(
892 CppTypeFor<TypeCategory::Real, 8> b,
893 CppTypeFor<TypeCategory::Integer, 4> e) {
894 return FPowI(b, e);
896 #if HAS_FLOAT80
897 CppTypeFor<TypeCategory::Real, 10> RTDEF(FPow10i)(
898 CppTypeFor<TypeCategory::Real, 10> b,
899 CppTypeFor<TypeCategory::Integer, 4> e) {
900 return FPowI(b, e);
902 #endif
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) {
907 return FPowI(b, e);
909 #endif
911 CppTypeFor<TypeCategory::Real, 4> RTDEF(FPow4k)(
912 CppTypeFor<TypeCategory::Real, 4> b,
913 CppTypeFor<TypeCategory::Integer, 8> e) {
914 return FPowI(b, e);
916 CppTypeFor<TypeCategory::Real, 8> RTDEF(FPow8k)(
917 CppTypeFor<TypeCategory::Real, 8> b,
918 CppTypeFor<TypeCategory::Integer, 8> e) {
919 return FPowI(b, e);
921 #if HAS_FLOAT80
922 CppTypeFor<TypeCategory::Real, 10> RTDEF(FPow10k)(
923 CppTypeFor<TypeCategory::Real, 10> b,
924 CppTypeFor<TypeCategory::Integer, 8> e) {
925 return FPowI(b, e);
927 #endif
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) {
932 return FPowI(b, e);
934 #endif
936 RT_EXT_API_GROUP_END
937 } // extern "C"
938 } // namespace Fortran::runtime