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//===----------------------------------------------------------------------===//
8
9#include "flang/Runtime/numeric.h"
10#include "numeric-templates.h"
11#include "terminator.h"
12#include "flang/Common/float128.h"
13#include <cfloat>
14#include <climits>
15#include <cmath>
16#include <limits>
17
18namespace Fortran::runtime {
19
20template <typename RES>
21inline RT_API_ATTRS RES getIntArgValue(const char *source, int line, void *arg,
22 int kind, std::int64_t defaultValue, int resKind) {
23 RES res;
24 if (!arg) {
25 res = static_cast<RES>(defaultValue);
26 } else if (kind == 1) {
27 res = static_cast<RES>(
28 *static_cast<CppTypeFor<TypeCategory::Integer, 1> *>(arg));
29 } else if (kind == 2) {
30 res = static_cast<RES>(
31 *static_cast<CppTypeFor<TypeCategory::Integer, 2> *>(arg));
32 } else if (kind == 4) {
33 res = static_cast<RES>(
34 *static_cast<CppTypeFor<TypeCategory::Integer, 4> *>(arg));
35 } else if (kind == 8) {
36 res = static_cast<RES>(
37 *static_cast<CppTypeFor<TypeCategory::Integer, 8> *>(arg));
38#ifdef __SIZEOF_INT128__
39 } else if (kind == 16) {
40 if (resKind != 16) {
41 Terminator{source, line}.Crash("Unexpected integer kind in runtime");
42 }
43 res = static_cast<RES>(
44 *static_cast<CppTypeFor<TypeCategory::Integer, 16> *>(arg));
45#endif
46 } else {
47 Terminator{source, line}.Crash("Unexpected integer kind in runtime");
48 }
49 return res;
50}
51
52// NINT (16.9.141)
53template <typename RESULT, typename ARG>
54inline RT_API_ATTRS RESULT Nint(ARG x) {
55 if (x >= 0) {
56 return std::trunc(x + ARG{0.5});
57 } else {
58 return std::trunc(x - ARG{0.5});
59 }
60}
61
62// CEILING & FLOOR (16.9.43, .79)
63template <typename RESULT, typename ARG>
64inline RT_API_ATTRS RESULT Ceiling(ARG x) {
65 return std::ceil(x);
66}
67template <typename RESULT, typename ARG>
68inline RT_API_ATTRS RESULT Floor(ARG x) {
69 return std::floor(x);
70}
71
72// MOD & MODULO (16.9.135, .136)
73template <bool IS_MODULO, typename T>
74inline RT_API_ATTRS T IntMod(T x, T p, const char *sourceFile, int sourceLine) {
75 if (p == 0) {
76 Terminator{sourceFile, sourceLine}.Crash(
77 IS_MODULO ? "MODULO with P==0" : "MOD with P==0");
78 }
79 auto mod{x - (x / p) * p};
80 if (IS_MODULO && (x > 0) != (p > 0)) {
81 mod += p;
82 }
83 return mod;
84}
85
86// SCALE (16.9.166)
87template <typename T> inline RT_API_ATTRS T Scale(T x, std::int64_t p) {
88 auto ip{static_cast<int>(p)};
89 if (ip != p) {
90 ip = p < 0 ? std::numeric_limits<int>::min()
91 : std::numeric_limits<int>::max();
92 }
93 return std::ldexp(x, ip); // x*2**p
94}
95
96// SELECTED_INT_KIND (16.9.169)
97template <typename T>
98inline RT_API_ATTRS CppTypeFor<TypeCategory::Integer, 4> SelectedIntKind(T x) {
99 if (x <= 2) {
100 return 1;
101 } else if (x <= 4) {
102 return 2;
103 } else if (x <= 9) {
104 return 4;
105 } else if (x <= 18) {
106 return 8;
107#ifdef __SIZEOF_INT128__
108 } else if (x <= 38) {
109 return 16;
110#endif
111 }
112 return -1;
113}
114
115// SELECTED_REAL_KIND (16.9.170)
116template <typename P, typename R, typename D>
117inline RT_API_ATTRS CppTypeFor<TypeCategory::Integer, 4> SelectedRealKind(
118 P p, R r, D d) {
119 if (d != 2) {
120 return -5;
121 }
122
123 int error{0};
124 int kind{0};
125 if (p <= 3) {
126 kind = 2;
127 } else if (p <= 6) {
128 kind = 4;
129 } else if (p <= 15) {
130 kind = 8;
131#if LDBL_MANT_DIG == 64
132 } else if (p <= 18) {
133 kind = 10;
134 } else if (p <= 33) {
135 kind = 16;
136#elif LDBL_MANT_DIG == 113
137 } else if (p <= 33) {
138 kind = 16;
139#endif
140 } else {
141 error -= 1;
142 }
143
144 if (r <= 4) {
145 kind = kind < 2 ? 2 : kind;
146 } else if (r <= 37) {
147 kind = kind < 3 ? (p == 3 ? 4 : 3) : kind;
148 } else if (r <= 307) {
149 kind = kind < 8 ? 8 : kind;
150#if LDBL_MANT_DIG == 64
151 } else if (r <= 4931) {
152 kind = kind < 10 ? 10 : kind;
153#elif LDBL_MANT_DIG == 113
154 } else if (r <= 4931) {
155 kind = kind < 16 ? 16 : kind;
156#endif
157 } else {
158 error -= 2;
159 }
160
161 return error ? error : kind;
162}
163
164// NEAREST (16.9.139)
165template <int PREC, typename T>
166inline RT_API_ATTRS T Nearest(T x, bool positive) {
167 if (positive) {
168 return std::nextafter(x, std::numeric_limits<T>::infinity());
169 } else {
170 return std::nextafter(x, -std::numeric_limits<T>::infinity());
171 }
172}
173
174// Exponentiation operator for (Real ** Integer) cases (10.1.5.2.1).
175template <typename BTy, typename ETy>
176RT_API_ATTRS BTy FPowI(BTy base, ETy exp) {
177 if (exp == ETy{0})
178 return BTy{1};
179 bool isNegativePower{exp < ETy{0}};
180 bool isMinPower{exp == std::numeric_limits<ETy>::min()};
181 if (isMinPower) {
182 exp = std::numeric_limits<ETy>::max();
183 } else if (isNegativePower) {
184 exp = -exp;
185 }
186 BTy result{1};
187 BTy origBase{base};
188 while (true) {
189 if (exp & ETy{1}) {
190 result *= base;
191 }
192 exp >>= 1;
193 if (exp == ETy{0}) {
194 break;
195 }
196 base *= base;
197 }
198 if (isMinPower) {
199 result *= origBase;
200 }
201 if (isNegativePower) {
202 result = BTy{1} / result;
203 }
204 return result;
205}
206
207extern "C" {
208RT_EXT_API_GROUP_BEGIN
209
210CppTypeFor<TypeCategory::Integer, 1> RTDEF(Ceiling4_1)(
211 CppTypeFor<TypeCategory::Real, 4> x) {
212 return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x);
213}
214CppTypeFor<TypeCategory::Integer, 2> RTDEF(Ceiling4_2)(
215 CppTypeFor<TypeCategory::Real, 4> x) {
216 return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x);
217}
218CppTypeFor<TypeCategory::Integer, 4> RTDEF(Ceiling4_4)(
219 CppTypeFor<TypeCategory::Real, 4> x) {
220 return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x);
221}
222CppTypeFor<TypeCategory::Integer, 8> RTDEF(Ceiling4_8)(
223 CppTypeFor<TypeCategory::Real, 4> x) {
224 return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x);
225}
226#if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
227CppTypeFor<TypeCategory::Integer, 16> RTDEF(Ceiling4_16)(
228 CppTypeFor<TypeCategory::Real, 4> x) {
229 return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x);
230}
231#endif
232CppTypeFor<TypeCategory::Integer, 1> RTDEF(Ceiling8_1)(
233 CppTypeFor<TypeCategory::Real, 8> x) {
234 return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x);
235}
236CppTypeFor<TypeCategory::Integer, 2> RTDEF(Ceiling8_2)(
237 CppTypeFor<TypeCategory::Real, 8> x) {
238 return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x);
239}
240CppTypeFor<TypeCategory::Integer, 4> RTDEF(Ceiling8_4)(
241 CppTypeFor<TypeCategory::Real, 8> x) {
242 return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x);
243}
244CppTypeFor<TypeCategory::Integer, 8> RTDEF(Ceiling8_8)(
245 CppTypeFor<TypeCategory::Real, 8> x) {
246 return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x);
247}
248#if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
249CppTypeFor<TypeCategory::Integer, 16> RTDEF(Ceiling8_16)(
250 CppTypeFor<TypeCategory::Real, 8> x) {
251 return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x);
252}
253#endif
254#if LDBL_MANT_DIG == 64
255CppTypeFor<TypeCategory::Integer, 1> RTDEF(Ceiling10_1)(
256 CppTypeFor<TypeCategory::Real, 10> x) {
257 return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x);
258}
259CppTypeFor<TypeCategory::Integer, 2> RTDEF(Ceiling10_2)(
260 CppTypeFor<TypeCategory::Real, 10> x) {
261 return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x);
262}
263CppTypeFor<TypeCategory::Integer, 4> RTDEF(Ceiling10_4)(
264 CppTypeFor<TypeCategory::Real, 10> x) {
265 return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x);
266}
267CppTypeFor<TypeCategory::Integer, 8> RTDEF(Ceiling10_8)(
268 CppTypeFor<TypeCategory::Real, 10> x) {
269 return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x);
270}
271#if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
272CppTypeFor<TypeCategory::Integer, 16> RTDEF(Ceiling10_16)(
273 CppTypeFor<TypeCategory::Real, 10> x) {
274 return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x);
275}
276#endif
277#elif LDBL_MANT_DIG == 113
278CppTypeFor<TypeCategory::Integer, 1> RTDEF(Ceiling16_1)(
279 CppTypeFor<TypeCategory::Real, 16> x) {
280 return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x);
281}
282CppTypeFor<TypeCategory::Integer, 2> RTDEF(Ceiling16_2)(
283 CppTypeFor<TypeCategory::Real, 16> x) {
284 return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x);
285}
286CppTypeFor<TypeCategory::Integer, 4> RTDEF(Ceiling16_4)(
287 CppTypeFor<TypeCategory::Real, 16> x) {
288 return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x);
289}
290CppTypeFor<TypeCategory::Integer, 8> RTDEF(Ceiling16_8)(
291 CppTypeFor<TypeCategory::Real, 16> x) {
292 return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x);
293}
294#if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
295CppTypeFor<TypeCategory::Integer, 16> RTDEF(Ceiling16_16)(
296 CppTypeFor<TypeCategory::Real, 16> x) {
297 return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x);
298}
299#endif
300#endif
301
302CppTypeFor<TypeCategory::Integer, 4> RTDEF(Exponent4_4)(
303 CppTypeFor<TypeCategory::Real, 4> x) {
304 return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x);
305}
306CppTypeFor<TypeCategory::Integer, 8> RTDEF(Exponent4_8)(
307 CppTypeFor<TypeCategory::Real, 4> x) {
308 return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x);
309}
310CppTypeFor<TypeCategory::Integer, 4> RTDEF(Exponent8_4)(
311 CppTypeFor<TypeCategory::Real, 8> x) {
312 return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x);
313}
314CppTypeFor<TypeCategory::Integer, 8> RTDEF(Exponent8_8)(
315 CppTypeFor<TypeCategory::Real, 8> x) {
316 return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x);
317}
318#if LDBL_MANT_DIG == 64
319CppTypeFor<TypeCategory::Integer, 4> RTDEF(Exponent10_4)(
320 CppTypeFor<TypeCategory::Real, 10> x) {
321 return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x);
322}
323CppTypeFor<TypeCategory::Integer, 8> RTDEF(Exponent10_8)(
324 CppTypeFor<TypeCategory::Real, 10> x) {
325 return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x);
326}
327#endif
328
329CppTypeFor<TypeCategory::Integer, 1> RTDEF(Floor4_1)(
330 CppTypeFor<TypeCategory::Real, 4> x) {
331 return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x);
332}
333CppTypeFor<TypeCategory::Integer, 2> RTDEF(Floor4_2)(
334 CppTypeFor<TypeCategory::Real, 4> x) {
335 return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x);
336}
337CppTypeFor<TypeCategory::Integer, 4> RTDEF(Floor4_4)(
338 CppTypeFor<TypeCategory::Real, 4> x) {
339 return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x);
340}
341CppTypeFor<TypeCategory::Integer, 8> RTDEF(Floor4_8)(
342 CppTypeFor<TypeCategory::Real, 4> x) {
343 return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x);
344}
345#if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
346CppTypeFor<TypeCategory::Integer, 16> RTDEF(Floor4_16)(
347 CppTypeFor<TypeCategory::Real, 4> x) {
348 return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x);
349}
350#endif
351CppTypeFor<TypeCategory::Integer, 1> RTDEF(Floor8_1)(
352 CppTypeFor<TypeCategory::Real, 8> x) {
353 return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x);
354}
355CppTypeFor<TypeCategory::Integer, 2> RTDEF(Floor8_2)(
356 CppTypeFor<TypeCategory::Real, 8> x) {
357 return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x);
358}
359CppTypeFor<TypeCategory::Integer, 4> RTDEF(Floor8_4)(
360 CppTypeFor<TypeCategory::Real, 8> x) {
361 return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x);
362}
363CppTypeFor<TypeCategory::Integer, 8> RTDEF(Floor8_8)(
364 CppTypeFor<TypeCategory::Real, 8> x) {
365 return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x);
366}
367#if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
368CppTypeFor<TypeCategory::Integer, 16> RTDEF(Floor8_16)(
369 CppTypeFor<TypeCategory::Real, 8> x) {
370 return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x);
371}
372#endif
373#if LDBL_MANT_DIG == 64
374CppTypeFor<TypeCategory::Integer, 1> RTDEF(Floor10_1)(
375 CppTypeFor<TypeCategory::Real, 10> x) {
376 return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x);
377}
378CppTypeFor<TypeCategory::Integer, 2> RTDEF(Floor10_2)(
379 CppTypeFor<TypeCategory::Real, 10> x) {
380 return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x);
381}
382CppTypeFor<TypeCategory::Integer, 4> RTDEF(Floor10_4)(
383 CppTypeFor<TypeCategory::Real, 10> x) {
384 return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x);
385}
386CppTypeFor<TypeCategory::Integer, 8> RTDEF(Floor10_8)(
387 CppTypeFor<TypeCategory::Real, 10> x) {
388 return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x);
389}
390#if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
391CppTypeFor<TypeCategory::Integer, 16> RTDEF(Floor10_16)(
392 CppTypeFor<TypeCategory::Real, 10> x) {
393 return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x);
394}
395#endif
396#elif LDBL_MANT_DIG == 113
397CppTypeFor<TypeCategory::Integer, 1> RTDEF(Floor16_1)(
398 CppTypeFor<TypeCategory::Real, 16> x) {
399 return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x);
400}
401CppTypeFor<TypeCategory::Integer, 2> RTDEF(Floor16_2)(
402 CppTypeFor<TypeCategory::Real, 16> x) {
403 return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x);
404}
405CppTypeFor<TypeCategory::Integer, 4> RTDEF(Floor16_4)(
406 CppTypeFor<TypeCategory::Real, 16> x) {
407 return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x);
408}
409CppTypeFor<TypeCategory::Integer, 8> RTDEF(Floor16_8)(
410 CppTypeFor<TypeCategory::Real, 16> x) {
411 return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x);
412}
413#if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
414CppTypeFor<TypeCategory::Integer, 16> RTDEF(Floor16_16)(
415 CppTypeFor<TypeCategory::Real, 16> x) {
416 return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x);
417}
418#endif
419#endif
420
421CppTypeFor<TypeCategory::Real, 4> RTDEF(Fraction4)(
422 CppTypeFor<TypeCategory::Real, 4> x) {
423 return Fraction(x);
424}
425CppTypeFor<TypeCategory::Real, 8> RTDEF(Fraction8)(
426 CppTypeFor<TypeCategory::Real, 8> x) {
427 return Fraction(x);
428}
429#if LDBL_MANT_DIG == 64
430CppTypeFor<TypeCategory::Real, 10> RTDEF(Fraction10)(
431 CppTypeFor<TypeCategory::Real, 10> x) {
432 return Fraction(x);
433}
434#endif
435
436bool RTDEF(IsFinite4)(CppTypeFor<TypeCategory::Real, 4> x) {
437 return std::isfinite(x);
438}
439bool RTDEF(IsFinite8)(CppTypeFor<TypeCategory::Real, 8> x) {
440 return std::isfinite(x);
441}
442#if LDBL_MANT_DIG == 64
443bool RTDEF(IsFinite10)(CppTypeFor<TypeCategory::Real, 10> x) {
444 return std::isfinite(x);
445}
446#elif LDBL_MANT_DIG == 113
447bool RTDEF(IsFinite16)(CppTypeFor<TypeCategory::Real, 16> x) {
448 return std::isfinite(x);
449}
450#endif
451
452bool RTDEF(IsNaN4)(CppTypeFor<TypeCategory::Real, 4> x) {
453 return std::isnan(x);
454}
455bool RTDEF(IsNaN8)(CppTypeFor<TypeCategory::Real, 8> x) {
456 return std::isnan(x);
457}
458#if LDBL_MANT_DIG == 64
459bool RTDEF(IsNaN10)(CppTypeFor<TypeCategory::Real, 10> x) {
460 return std::isnan(x);
461}
462#elif LDBL_MANT_DIG == 113
463bool RTDEF(IsNaN16)(CppTypeFor<TypeCategory::Real, 16> x) {
464 return std::isnan(x);
465}
466#endif
467
468CppTypeFor<TypeCategory::Integer, 1> RTDEF(ModInteger1)(
469 CppTypeFor<TypeCategory::Integer, 1> x,
470 CppTypeFor<TypeCategory::Integer, 1> p, const char *sourceFile,
471 int sourceLine) {
472 return IntMod<false>(x, p, sourceFile, sourceLine);
473}
474CppTypeFor<TypeCategory::Integer, 2> RTDEF(ModInteger2)(
475 CppTypeFor<TypeCategory::Integer, 2> x,
476 CppTypeFor<TypeCategory::Integer, 2> p, const char *sourceFile,
477 int sourceLine) {
478 return IntMod<false>(x, p, sourceFile, sourceLine);
479}
480CppTypeFor<TypeCategory::Integer, 4> RTDEF(ModInteger4)(
481 CppTypeFor<TypeCategory::Integer, 4> x,
482 CppTypeFor<TypeCategory::Integer, 4> p, const char *sourceFile,
483 int sourceLine) {
484 return IntMod<false>(x, p, sourceFile, sourceLine);
485}
486CppTypeFor<TypeCategory::Integer, 8> RTDEF(ModInteger8)(
487 CppTypeFor<TypeCategory::Integer, 8> x,
488 CppTypeFor<TypeCategory::Integer, 8> p, const char *sourceFile,
489 int sourceLine) {
490 return IntMod<false>(x, p, sourceFile, sourceLine);
491}
492#ifdef __SIZEOF_INT128__
493CppTypeFor<TypeCategory::Integer, 16> RTDEF(ModInteger16)(
494 CppTypeFor<TypeCategory::Integer, 16> x,
495 CppTypeFor<TypeCategory::Integer, 16> p, const char *sourceFile,
496 int sourceLine) {
497 return IntMod<false>(x, p, sourceFile, sourceLine);
498}
499#endif
500CppTypeFor<TypeCategory::Real, 4> RTDEF(ModReal4)(
501 CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p,
502 const char *sourceFile, int sourceLine) {
503 return RealMod<false>(x, p, sourceFile, sourceLine);
504}
505CppTypeFor<TypeCategory::Real, 8> RTDEF(ModReal8)(
506 CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p,
507 const char *sourceFile, int sourceLine) {
508 return RealMod<false>(x, p, sourceFile, sourceLine);
509}
510#if LDBL_MANT_DIG == 64
511CppTypeFor<TypeCategory::Real, 10> RTDEF(ModReal10)(
512 CppTypeFor<TypeCategory::Real, 10> x, CppTypeFor<TypeCategory::Real, 10> p,
513 const char *sourceFile, int sourceLine) {
514 return RealMod<false>(x, p, sourceFile, sourceLine);
515}
516#endif
517
518CppTypeFor<TypeCategory::Integer, 1> RTDEF(ModuloInteger1)(
519 CppTypeFor<TypeCategory::Integer, 1> x,
520 CppTypeFor<TypeCategory::Integer, 1> p, const char *sourceFile,
521 int sourceLine) {
522 return IntMod<true>(x, p, sourceFile, sourceLine);
523}
524CppTypeFor<TypeCategory::Integer, 2> RTDEF(ModuloInteger2)(
525 CppTypeFor<TypeCategory::Integer, 2> x,
526 CppTypeFor<TypeCategory::Integer, 2> p, const char *sourceFile,
527 int sourceLine) {
528 return IntMod<true>(x, p, sourceFile, sourceLine);
529}
530CppTypeFor<TypeCategory::Integer, 4> RTDEF(ModuloInteger4)(
531 CppTypeFor<TypeCategory::Integer, 4> x,
532 CppTypeFor<TypeCategory::Integer, 4> p, const char *sourceFile,
533 int sourceLine) {
534 return IntMod<true>(x, p, sourceFile, sourceLine);
535}
536CppTypeFor<TypeCategory::Integer, 8> RTDEF(ModuloInteger8)(
537 CppTypeFor<TypeCategory::Integer, 8> x,
538 CppTypeFor<TypeCategory::Integer, 8> p, const char *sourceFile,
539 int sourceLine) {
540 return IntMod<true>(x, p, sourceFile, sourceLine);
541}
542#ifdef __SIZEOF_INT128__
543CppTypeFor<TypeCategory::Integer, 16> RTDEF(ModuloInteger16)(
544 CppTypeFor<TypeCategory::Integer, 16> x,
545 CppTypeFor<TypeCategory::Integer, 16> p, const char *sourceFile,
546 int sourceLine) {
547 return IntMod<true>(x, p, sourceFile, sourceLine);
548}
549#endif
550CppTypeFor<TypeCategory::Real, 4> RTDEF(ModuloReal4)(
551 CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p,
552 const char *sourceFile, int sourceLine) {
553 return RealMod<true>(x, p, sourceFile, sourceLine);
554}
555CppTypeFor<TypeCategory::Real, 8> RTDEF(ModuloReal8)(
556 CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p,
557 const char *sourceFile, int sourceLine) {
558 return RealMod<true>(x, p, sourceFile, sourceLine);
559}
560#if LDBL_MANT_DIG == 64
561CppTypeFor<TypeCategory::Real, 10> RTDEF(ModuloReal10)(
562 CppTypeFor<TypeCategory::Real, 10> x, CppTypeFor<TypeCategory::Real, 10> p,
563 const char *sourceFile, int sourceLine) {
564 return RealMod<true>(x, p, sourceFile, sourceLine);
565}
566#endif
567
568CppTypeFor<TypeCategory::Real, 4> RTDEF(Nearest4)(
569 CppTypeFor<TypeCategory::Real, 4> x, bool positive) {
570 return Nearest<24>(x, positive);
571}
572CppTypeFor<TypeCategory::Real, 8> RTDEF(Nearest8)(
573 CppTypeFor<TypeCategory::Real, 8> x, bool positive) {
574 return Nearest<53>(x, positive);
575}
576#if LDBL_MANT_DIG == 64
577CppTypeFor<TypeCategory::Real, 10> RTDEF(Nearest10)(
578 CppTypeFor<TypeCategory::Real, 10> x, bool positive) {
579 return Nearest<64>(x, positive);
580}
581#endif
582
583CppTypeFor<TypeCategory::Integer, 1> RTDEF(Nint4_1)(
584 CppTypeFor<TypeCategory::Real, 4> x) {
585 return Nint<CppTypeFor<TypeCategory::Integer, 1>>(x);
586}
587CppTypeFor<TypeCategory::Integer, 2> RTDEF(Nint4_2)(
588 CppTypeFor<TypeCategory::Real, 4> x) {
589 return Nint<CppTypeFor<TypeCategory::Integer, 2>>(x);
590}
591CppTypeFor<TypeCategory::Integer, 4> RTDEF(Nint4_4)(
592 CppTypeFor<TypeCategory::Real, 4> x) {
593 return Nint<CppTypeFor<TypeCategory::Integer, 4>>(x);
594}
595CppTypeFor<TypeCategory::Integer, 8> RTDEF(Nint4_8)(
596 CppTypeFor<TypeCategory::Real, 4> x) {
597 return Nint<CppTypeFor<TypeCategory::Integer, 8>>(x);
598}
599#if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
600CppTypeFor<TypeCategory::Integer, 16> RTDEF(Nint4_16)(
601 CppTypeFor<TypeCategory::Real, 4> x) {
602 return Nint<CppTypeFor<TypeCategory::Integer, 16>>(x);
603}
604#endif
605CppTypeFor<TypeCategory::Integer, 1> RTDEF(Nint8_1)(
606 CppTypeFor<TypeCategory::Real, 8> x) {
607 return Nint<CppTypeFor<TypeCategory::Integer, 1>>(x);
608}
609CppTypeFor<TypeCategory::Integer, 2> RTDEF(Nint8_2)(
610 CppTypeFor<TypeCategory::Real, 8> x) {
611 return Nint<CppTypeFor<TypeCategory::Integer, 2>>(x);
612}
613CppTypeFor<TypeCategory::Integer, 4> RTDEF(Nint8_4)(
614 CppTypeFor<TypeCategory::Real, 8> x) {
615 return Nint<CppTypeFor<TypeCategory::Integer, 4>>(x);
616}
617CppTypeFor<TypeCategory::Integer, 8> RTDEF(Nint8_8)(
618 CppTypeFor<TypeCategory::Real, 8> x) {
619 return Nint<CppTypeFor<TypeCategory::Integer, 8>>(x);
620}
621#if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
622CppTypeFor<TypeCategory::Integer, 16> RTDEF(Nint8_16)(
623 CppTypeFor<TypeCategory::Real, 8> x) {
624 return Nint<CppTypeFor<TypeCategory::Integer, 16>>(x);
625}
626#endif
627#if LDBL_MANT_DIG == 64
628CppTypeFor<TypeCategory::Integer, 1> RTDEF(Nint10_1)(
629 CppTypeFor<TypeCategory::Real, 10> x) {
630 return Nint<CppTypeFor<TypeCategory::Integer, 1>>(x);
631}
632CppTypeFor<TypeCategory::Integer, 2> RTDEF(Nint10_2)(
633 CppTypeFor<TypeCategory::Real, 10> x) {
634 return Nint<CppTypeFor<TypeCategory::Integer, 2>>(x);
635}
636CppTypeFor<TypeCategory::Integer, 4> RTDEF(Nint10_4)(
637 CppTypeFor<TypeCategory::Real, 10> x) {
638 return Nint<CppTypeFor<TypeCategory::Integer, 4>>(x);
639}
640CppTypeFor<TypeCategory::Integer, 8> RTDEF(Nint10_8)(
641 CppTypeFor<TypeCategory::Real, 10> x) {
642 return Nint<CppTypeFor<TypeCategory::Integer, 8>>(x);
643}
644#if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
645CppTypeFor<TypeCategory::Integer, 16> RTDEF(Nint10_16)(
646 CppTypeFor<TypeCategory::Real, 10> x) {
647 return Nint<CppTypeFor<TypeCategory::Integer, 16>>(x);
648}
649#endif
650#elif LDBL_MANT_DIG == 113
651CppTypeFor<TypeCategory::Integer, 1> RTDEF(Nint16_1)(
652 CppTypeFor<TypeCategory::Real, 16> x) {
653 return Nint<CppTypeFor<TypeCategory::Integer, 1>>(x);
654}
655CppTypeFor<TypeCategory::Integer, 2> RTDEF(Nint16_2)(
656 CppTypeFor<TypeCategory::Real, 16> x) {
657 return Nint<CppTypeFor<TypeCategory::Integer, 2>>(x);
658}
659CppTypeFor<TypeCategory::Integer, 4> RTDEF(Nint16_4)(
660 CppTypeFor<TypeCategory::Real, 16> x) {
661 return Nint<CppTypeFor<TypeCategory::Integer, 4>>(x);
662}
663CppTypeFor<TypeCategory::Integer, 8> RTDEF(Nint16_8)(
664 CppTypeFor<TypeCategory::Real, 16> x) {
665 return Nint<CppTypeFor<TypeCategory::Integer, 8>>(x);
666}
667#if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
668CppTypeFor<TypeCategory::Integer, 16> RTDEF(Nint16_16)(
669 CppTypeFor<TypeCategory::Real, 16> x) {
670 return Nint<CppTypeFor<TypeCategory::Integer, 16>>(x);
671}
672#endif
673#endif
674
675CppTypeFor<TypeCategory::Real, 4> RTDEF(RRSpacing4)(
676 CppTypeFor<TypeCategory::Real, 4> x) {
677 return RRSpacing<24>(x);
678}
679CppTypeFor<TypeCategory::Real, 8> RTDEF(RRSpacing8)(
680 CppTypeFor<TypeCategory::Real, 8> x) {
681 return RRSpacing<53>(x);
682}
683#if LDBL_MANT_DIG == 64
684CppTypeFor<TypeCategory::Real, 10> RTDEF(RRSpacing10)(
685 CppTypeFor<TypeCategory::Real, 10> x) {
686 return RRSpacing<64>(x);
687}
688#endif
689
690CppTypeFor<TypeCategory::Real, 4> RTDEF(SetExponent4)(
691 CppTypeFor<TypeCategory::Real, 4> x, std::int64_t p) {
692 return SetExponent(x, p);
693}
694CppTypeFor<TypeCategory::Real, 8> RTDEF(SetExponent8)(
695 CppTypeFor<TypeCategory::Real, 8> x, std::int64_t p) {
696 return SetExponent(x, p);
697}
698#if LDBL_MANT_DIG == 64
699CppTypeFor<TypeCategory::Real, 10> RTDEF(SetExponent10)(
700 CppTypeFor<TypeCategory::Real, 10> x, std::int64_t p) {
701 return SetExponent(x, p);
702}
703#endif
704
705CppTypeFor<TypeCategory::Real, 4> RTDEF(Scale4)(
706 CppTypeFor<TypeCategory::Real, 4> x, std::int64_t p) {
707 return Scale(x, p);
708}
709CppTypeFor<TypeCategory::Real, 8> RTDEF(Scale8)(
710 CppTypeFor<TypeCategory::Real, 8> x, std::int64_t p) {
711 return Scale(x, p);
712}
713#if LDBL_MANT_DIG == 64
714CppTypeFor<TypeCategory::Real, 10> RTDEF(Scale10)(
715 CppTypeFor<TypeCategory::Real, 10> x, std::int64_t p) {
716 return Scale(x, p);
717}
718#endif
719
720// SELECTED_INT_KIND
721CppTypeFor<TypeCategory::Integer, 4> RTDEF(SelectedIntKind)(
722 const char *source, int line, void *x, int xKind) {
723#ifdef __SIZEOF_INT128__
724 CppTypeFor<TypeCategory::Integer, 16> r =
725 getIntArgValue<CppTypeFor<TypeCategory::Integer, 16>>(
726 source, line, x, xKind, /*defaultValue*/ 0, /*resKind*/ 16);
727#else
728 std::int64_t r = getIntArgValue<std::int64_t>(
729 source, line, x, xKind, /*defaultValue*/ 0, /*resKind*/ 8);
730#endif
731 return SelectedIntKind(r);
732}
733
734// SELECTED_REAL_KIND
735CppTypeFor<TypeCategory::Integer, 4> RTDEF(SelectedRealKind)(const char *source,
736 int line, void *precision, int pKind, void *range, int rKind, void *radix,
737 int dKind) {
738#ifdef __SIZEOF_INT128__
739 CppTypeFor<TypeCategory::Integer, 16> p =
740 getIntArgValue<CppTypeFor<TypeCategory::Integer, 16>>(
741 source, line, precision, pKind, /*defaultValue*/ 0, /*resKind*/ 16);
742 CppTypeFor<TypeCategory::Integer, 16> r =
743 getIntArgValue<CppTypeFor<TypeCategory::Integer, 16>>(
744 source, line, range, rKind, /*defaultValue*/ 0, /*resKind*/ 16);
745 CppTypeFor<TypeCategory::Integer, 16> d =
746 getIntArgValue<CppTypeFor<TypeCategory::Integer, 16>>(
747 source, line, radix, dKind, /*defaultValue*/ 2, /*resKind*/ 16);
748#else
749 std::int64_t p = getIntArgValue<std::int64_t>(
750 source, line, precision, pKind, /*defaultValue*/ 0, /*resKind*/ 8);
751 std::int64_t r = getIntArgValue<std::int64_t>(
752 source, line, range, rKind, /*defaultValue*/ 0, /*resKind*/ 8);
753 std::int64_t d = getIntArgValue<std::int64_t>(
754 source, line, radix, dKind, /*defaultValue*/ 2, /*resKind*/ 8);
755#endif
756 return SelectedRealKind(p, r, d);
757}
758
759CppTypeFor<TypeCategory::Real, 4> RTDEF(Spacing4)(
760 CppTypeFor<TypeCategory::Real, 4> x) {
761 return Spacing<24>(x);
762}
763CppTypeFor<TypeCategory::Real, 8> RTDEF(Spacing8)(
764 CppTypeFor<TypeCategory::Real, 8> x) {
765 return Spacing<53>(x);
766}
767#if LDBL_MANT_DIG == 64
768CppTypeFor<TypeCategory::Real, 10> RTDEF(Spacing10)(
769 CppTypeFor<TypeCategory::Real, 10> x) {
770 return Spacing<64>(x);
771}
772#endif
773
774CppTypeFor<TypeCategory::Real, 4> RTDEF(FPow4i)(
775 CppTypeFor<TypeCategory::Real, 4> b,
776 CppTypeFor<TypeCategory::Integer, 4> e) {
777 return FPowI(b, e);
778}
779CppTypeFor<TypeCategory::Real, 8> RTDEF(FPow8i)(
780 CppTypeFor<TypeCategory::Real, 8> b,
781 CppTypeFor<TypeCategory::Integer, 4> e) {
782 return FPowI(b, e);
783}
784#if LDBL_MANT_DIG == 64
785CppTypeFor<TypeCategory::Real, 10> RTDEF(FPow10i)(
786 CppTypeFor<TypeCategory::Real, 10> b,
787 CppTypeFor<TypeCategory::Integer, 4> e) {
788 return FPowI(b, e);
789}
790#endif
791#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
792CppTypeFor<TypeCategory::Real, 16> RTDEF(FPow16i)(
793 CppTypeFor<TypeCategory::Real, 16> b,
794 CppTypeFor<TypeCategory::Integer, 4> e) {
795 return FPowI(b, e);
796}
797#endif
798
799CppTypeFor<TypeCategory::Real, 4> RTDEF(FPow4k)(
800 CppTypeFor<TypeCategory::Real, 4> b,
801 CppTypeFor<TypeCategory::Integer, 8> e) {
802 return FPowI(b, e);
803}
804CppTypeFor<TypeCategory::Real, 8> RTDEF(FPow8k)(
805 CppTypeFor<TypeCategory::Real, 8> b,
806 CppTypeFor<TypeCategory::Integer, 8> e) {
807 return FPowI(b, e);
808}
809#if LDBL_MANT_DIG == 64
810CppTypeFor<TypeCategory::Real, 10> RTDEF(FPow10k)(
811 CppTypeFor<TypeCategory::Real, 10> b,
812 CppTypeFor<TypeCategory::Integer, 8> e) {
813 return FPowI(b, e);
814}
815#endif
816#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
817CppTypeFor<TypeCategory::Real, 16> RTDEF(FPow16k)(
818 CppTypeFor<TypeCategory::Real, 16> b,
819 CppTypeFor<TypeCategory::Integer, 8> e) {
820 return FPowI(b, e);
821}
822#endif
823
824RT_EXT_API_GROUP_END
825} // extern "C"
826} // namespace Fortran::runtime
827

source code of flang/runtime/numeric.cpp