1 | //===-- lib/runtime/numeric.cpp ---------------------------------*- C++ -*-===// |
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 "flang-rt/runtime/numeric-templates.h" |
11 | #include "flang-rt/runtime/terminator.h" |
12 | #include "flang-rt/runtime/tools.h" |
13 | #include "flang/Common/float128.h" |
14 | #include <cfloat> |
15 | #include <climits> |
16 | #include <cmath> |
17 | #include <limits> |
18 | |
19 | namespace Fortran::runtime { |
20 | |
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" ); |
43 | } |
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" ); |
49 | } |
50 | return res; |
51 | } |
52 | |
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}); |
60 | } |
61 | } |
62 | |
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); |
67 | } |
68 | template <typename RESULT, typename ARG> |
69 | inline RT_API_ATTRS RESULT Floor(ARG x) { |
70 | return std::floor(x); |
71 | } |
72 | |
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" ); |
79 | } |
80 | auto mod{x - (x / p) * p}; |
81 | if (IS_MODULO && (x > 0) != (p > 0)) { |
82 | mod += p; |
83 | } |
84 | return mod; |
85 | } |
86 | |
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(); |
93 | } |
94 | return std::ldexp(x, ip); // x*2**p |
95 | } |
96 | |
97 | // SELECTED_INT_KIND (16.9.169) and SELECTED_UNSIGNED_KIND extension |
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; |
114 | } |
115 | return -1; |
116 | } |
117 | |
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; |
130 | } |
131 | return -1; |
132 | } |
133 | |
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; |
140 | } |
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 |
153 | |
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; |
168 | } |
169 | |
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; |
184 | } |
185 | |
186 | return error ? error : kind; |
187 | } |
188 | |
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()); |
196 | } |
197 | } |
198 | |
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; |
210 | } |
211 | BTy result{1}; |
212 | BTy origBase{base}; |
213 | while (true) { |
214 | if (exp & ETy{1}) { |
215 | result *= base; |
216 | } |
217 | exp >>= 1; |
218 | if (exp == ETy{0}) { |
219 | break; |
220 | } |
221 | base *= base; |
222 | } |
223 | if (isMinPower) { |
224 | result *= origBase; |
225 | } |
226 | if (isNegativePower) { |
227 | result = BTy{1} / result; |
228 | } |
229 | return result; |
230 | } |
231 | |
232 | extern "C" { |
233 | RT_EXT_API_GROUP_BEGIN |
234 | |
235 | CppTypeFor<TypeCategory::Integer, 1> RTDEF(Ceiling4_1)( |
236 | CppTypeFor<TypeCategory::Real, 4> x) { |
237 | return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x); |
238 | } |
239 | CppTypeFor<TypeCategory::Integer, 2> RTDEF(Ceiling4_2)( |
240 | CppTypeFor<TypeCategory::Real, 4> x) { |
241 | return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x); |
242 | } |
243 | CppTypeFor<TypeCategory::Integer, 4> RTDEF(Ceiling4_4)( |
244 | CppTypeFor<TypeCategory::Real, 4> x) { |
245 | return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x); |
246 | } |
247 | CppTypeFor<TypeCategory::Integer, 8> RTDEF(Ceiling4_8)( |
248 | CppTypeFor<TypeCategory::Real, 4> x) { |
249 | return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x); |
250 | } |
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); |
255 | } |
256 | #endif |
257 | CppTypeFor<TypeCategory::Integer, 1> RTDEF(Ceiling8_1)( |
258 | CppTypeFor<TypeCategory::Real, 8> x) { |
259 | return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x); |
260 | } |
261 | CppTypeFor<TypeCategory::Integer, 2> RTDEF(Ceiling8_2)( |
262 | CppTypeFor<TypeCategory::Real, 8> x) { |
263 | return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x); |
264 | } |
265 | CppTypeFor<TypeCategory::Integer, 4> RTDEF(Ceiling8_4)( |
266 | CppTypeFor<TypeCategory::Real, 8> x) { |
267 | return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x); |
268 | } |
269 | CppTypeFor<TypeCategory::Integer, 8> RTDEF(Ceiling8_8)( |
270 | CppTypeFor<TypeCategory::Real, 8> x) { |
271 | return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x); |
272 | } |
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); |
277 | } |
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); |
283 | } |
284 | CppTypeFor<TypeCategory::Integer, 2> RTDEF(Ceiling10_2)( |
285 | CppTypeFor<TypeCategory::Real, 10> x) { |
286 | return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x); |
287 | } |
288 | CppTypeFor<TypeCategory::Integer, 4> RTDEF(Ceiling10_4)( |
289 | CppTypeFor<TypeCategory::Real, 10> x) { |
290 | return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x); |
291 | } |
292 | CppTypeFor<TypeCategory::Integer, 8> RTDEF(Ceiling10_8)( |
293 | CppTypeFor<TypeCategory::Real, 10> x) { |
294 | return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x); |
295 | } |
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); |
300 | } |
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); |
306 | } |
307 | CppTypeFor<TypeCategory::Integer, 2> RTDEF(Ceiling16_2)( |
308 | CppTypeFor<TypeCategory::Real, 16> x) { |
309 | return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x); |
310 | } |
311 | CppTypeFor<TypeCategory::Integer, 4> RTDEF(Ceiling16_4)( |
312 | CppTypeFor<TypeCategory::Real, 16> x) { |
313 | return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x); |
314 | } |
315 | CppTypeFor<TypeCategory::Integer, 8> RTDEF(Ceiling16_8)( |
316 | CppTypeFor<TypeCategory::Real, 16> x) { |
317 | return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x); |
318 | } |
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); |
323 | } |
324 | #endif |
325 | #endif |
326 | |
327 | CppTypeFor<TypeCategory::Real, 4> RTDEF(ErfcScaled4)( |
328 | CppTypeFor<TypeCategory::Real, 4> x) { |
329 | return ErfcScaled(x); |
330 | } |
331 | CppTypeFor<TypeCategory::Real, 8> RTDEF(ErfcScaled8)( |
332 | CppTypeFor<TypeCategory::Real, 8> x) { |
333 | return ErfcScaled(x); |
334 | } |
335 | #if HAS_FLOAT80 |
336 | CppTypeFor<TypeCategory::Real, 10> RTDEF(ErfcScaled10)( |
337 | CppTypeFor<TypeCategory::Real, 10> x) { |
338 | return ErfcScaled(x); |
339 | } |
340 | #endif |
341 | #if HAS_LDBL128 |
342 | CppTypeFor<TypeCategory::Real, 16> RTDEF(ErfcScaled16)( |
343 | CppTypeFor<TypeCategory::Real, 16> x) { |
344 | return ErfcScaled(x); |
345 | } |
346 | #endif |
347 | |
348 | CppTypeFor<TypeCategory::Integer, 4> RTDEF(Exponent4_4)( |
349 | CppTypeFor<TypeCategory::Real, 4> x) { |
350 | return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x); |
351 | } |
352 | CppTypeFor<TypeCategory::Integer, 8> RTDEF(Exponent4_8)( |
353 | CppTypeFor<TypeCategory::Real, 4> x) { |
354 | return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x); |
355 | } |
356 | CppTypeFor<TypeCategory::Integer, 4> RTDEF(Exponent8_4)( |
357 | CppTypeFor<TypeCategory::Real, 8> x) { |
358 | return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x); |
359 | } |
360 | CppTypeFor<TypeCategory::Integer, 8> RTDEF(Exponent8_8)( |
361 | CppTypeFor<TypeCategory::Real, 8> x) { |
362 | return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x); |
363 | } |
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); |
368 | } |
369 | CppTypeFor<TypeCategory::Integer, 8> RTDEF(Exponent10_8)( |
370 | CppTypeFor<TypeCategory::Real, 10> x) { |
371 | return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x); |
372 | } |
373 | #endif |
374 | |
375 | CppTypeFor<TypeCategory::Integer, 1> RTDEF(Floor4_1)( |
376 | CppTypeFor<TypeCategory::Real, 4> x) { |
377 | return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x); |
378 | } |
379 | CppTypeFor<TypeCategory::Integer, 2> RTDEF(Floor4_2)( |
380 | CppTypeFor<TypeCategory::Real, 4> x) { |
381 | return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x); |
382 | } |
383 | CppTypeFor<TypeCategory::Integer, 4> RTDEF(Floor4_4)( |
384 | CppTypeFor<TypeCategory::Real, 4> x) { |
385 | return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x); |
386 | } |
387 | CppTypeFor<TypeCategory::Integer, 8> RTDEF(Floor4_8)( |
388 | CppTypeFor<TypeCategory::Real, 4> x) { |
389 | return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x); |
390 | } |
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); |
395 | } |
396 | #endif |
397 | CppTypeFor<TypeCategory::Integer, 1> RTDEF(Floor8_1)( |
398 | CppTypeFor<TypeCategory::Real, 8> x) { |
399 | return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x); |
400 | } |
401 | CppTypeFor<TypeCategory::Integer, 2> RTDEF(Floor8_2)( |
402 | CppTypeFor<TypeCategory::Real, 8> x) { |
403 | return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x); |
404 | } |
405 | CppTypeFor<TypeCategory::Integer, 4> RTDEF(Floor8_4)( |
406 | CppTypeFor<TypeCategory::Real, 8> x) { |
407 | return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x); |
408 | } |
409 | CppTypeFor<TypeCategory::Integer, 8> RTDEF(Floor8_8)( |
410 | CppTypeFor<TypeCategory::Real, 8> x) { |
411 | return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x); |
412 | } |
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); |
417 | } |
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); |
423 | } |
424 | CppTypeFor<TypeCategory::Integer, 2> RTDEF(Floor10_2)( |
425 | CppTypeFor<TypeCategory::Real, 10> x) { |
426 | return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x); |
427 | } |
428 | CppTypeFor<TypeCategory::Integer, 4> RTDEF(Floor10_4)( |
429 | CppTypeFor<TypeCategory::Real, 10> x) { |
430 | return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x); |
431 | } |
432 | CppTypeFor<TypeCategory::Integer, 8> RTDEF(Floor10_8)( |
433 | CppTypeFor<TypeCategory::Real, 10> x) { |
434 | return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x); |
435 | } |
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); |
440 | } |
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); |
446 | } |
447 | CppTypeFor<TypeCategory::Integer, 2> RTDEF(Floor16_2)( |
448 | CppTypeFor<TypeCategory::Real, 16> x) { |
449 | return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x); |
450 | } |
451 | CppTypeFor<TypeCategory::Integer, 4> RTDEF(Floor16_4)( |
452 | CppTypeFor<TypeCategory::Real, 16> x) { |
453 | return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x); |
454 | } |
455 | CppTypeFor<TypeCategory::Integer, 8> RTDEF(Floor16_8)( |
456 | CppTypeFor<TypeCategory::Real, 16> x) { |
457 | return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x); |
458 | } |
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); |
463 | } |
464 | #endif |
465 | #endif |
466 | |
467 | CppTypeFor<TypeCategory::Real, 4> RTDEF(Fraction4)( |
468 | CppTypeFor<TypeCategory::Real, 4> x) { |
469 | return Fraction(x); |
470 | } |
471 | CppTypeFor<TypeCategory::Real, 8> RTDEF(Fraction8)( |
472 | CppTypeFor<TypeCategory::Real, 8> x) { |
473 | return Fraction(x); |
474 | } |
475 | #if HAS_FLOAT80 |
476 | CppTypeFor<TypeCategory::Real, 10> RTDEF(Fraction10)( |
477 | CppTypeFor<TypeCategory::Real, 10> x) { |
478 | return Fraction(x); |
479 | } |
480 | #endif |
481 | |
482 | bool RTDEF(IsFinite4)(CppTypeFor<TypeCategory::Real, 4> x) { |
483 | return std::isfinite(x); |
484 | } |
485 | bool RTDEF(IsFinite8)(CppTypeFor<TypeCategory::Real, 8> x) { |
486 | return std::isfinite(x); |
487 | } |
488 | #if HAS_FLOAT80 |
489 | bool RTDEF(IsFinite10)(CppTypeFor<TypeCategory::Real, 10> x) { |
490 | return std::isfinite(x); |
491 | } |
492 | #elif HAS_LDBL128 |
493 | bool RTDEF(IsFinite16)(CppTypeFor<TypeCategory::Real, 16> x) { |
494 | return std::isfinite(x); |
495 | } |
496 | #endif |
497 | |
498 | bool RTDEF(IsNaN4)(CppTypeFor<TypeCategory::Real, 4> x) { |
499 | return std::isnan(x); |
500 | } |
501 | bool RTDEF(IsNaN8)(CppTypeFor<TypeCategory::Real, 8> x) { |
502 | return std::isnan(x); |
503 | } |
504 | #if HAS_FLOAT80 |
505 | bool RTDEF(IsNaN10)(CppTypeFor<TypeCategory::Real, 10> x) { |
506 | return std::isnan(x); |
507 | } |
508 | #elif HAS_LDBL128 |
509 | bool RTDEF(IsNaN16)(CppTypeFor<TypeCategory::Real, 16> x) { |
510 | return std::isnan(x); |
511 | } |
512 | #endif |
513 | |
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); |
519 | } |
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); |
525 | } |
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); |
531 | } |
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); |
537 | } |
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); |
544 | } |
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); |
550 | } |
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); |
555 | } |
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); |
561 | } |
562 | #endif |
563 | |
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); |
569 | } |
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); |
575 | } |
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); |
581 | } |
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); |
587 | } |
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); |
594 | } |
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); |
600 | } |
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); |
605 | } |
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); |
611 | } |
612 | #endif |
613 | |
614 | CppTypeFor<TypeCategory::Real, 4> RTDEF(Nearest4)( |
615 | CppTypeFor<TypeCategory::Real, 4> x, bool positive) { |
616 | return Nearest<24>(x, positive); |
617 | } |
618 | CppTypeFor<TypeCategory::Real, 8> RTDEF(Nearest8)( |
619 | CppTypeFor<TypeCategory::Real, 8> x, bool positive) { |
620 | return Nearest<53>(x, positive); |
621 | } |
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); |
626 | } |
627 | #endif |
628 | |
629 | CppTypeFor<TypeCategory::Integer, 1> RTDEF(Nint4_1)( |
630 | CppTypeFor<TypeCategory::Real, 4> x) { |
631 | return Nint<CppTypeFor<TypeCategory::Integer, 1>>(x); |
632 | } |
633 | CppTypeFor<TypeCategory::Integer, 2> RTDEF(Nint4_2)( |
634 | CppTypeFor<TypeCategory::Real, 4> x) { |
635 | return Nint<CppTypeFor<TypeCategory::Integer, 2>>(x); |
636 | } |
637 | CppTypeFor<TypeCategory::Integer, 4> RTDEF(Nint4_4)( |
638 | CppTypeFor<TypeCategory::Real, 4> x) { |
639 | return Nint<CppTypeFor<TypeCategory::Integer, 4>>(x); |
640 | } |
641 | CppTypeFor<TypeCategory::Integer, 8> RTDEF(Nint4_8)( |
642 | CppTypeFor<TypeCategory::Real, 4> x) { |
643 | return Nint<CppTypeFor<TypeCategory::Integer, 8>>(x); |
644 | } |
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); |
649 | } |
650 | #endif |
651 | CppTypeFor<TypeCategory::Integer, 1> RTDEF(Nint8_1)( |
652 | CppTypeFor<TypeCategory::Real, 8> x) { |
653 | return Nint<CppTypeFor<TypeCategory::Integer, 1>>(x); |
654 | } |
655 | CppTypeFor<TypeCategory::Integer, 2> RTDEF(Nint8_2)( |
656 | CppTypeFor<TypeCategory::Real, 8> x) { |
657 | return Nint<CppTypeFor<TypeCategory::Integer, 2>>(x); |
658 | } |
659 | CppTypeFor<TypeCategory::Integer, 4> RTDEF(Nint8_4)( |
660 | CppTypeFor<TypeCategory::Real, 8> x) { |
661 | return Nint<CppTypeFor<TypeCategory::Integer, 4>>(x); |
662 | } |
663 | CppTypeFor<TypeCategory::Integer, 8> RTDEF(Nint8_8)( |
664 | CppTypeFor<TypeCategory::Real, 8> x) { |
665 | return Nint<CppTypeFor<TypeCategory::Integer, 8>>(x); |
666 | } |
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); |
671 | } |
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); |
677 | } |
678 | CppTypeFor<TypeCategory::Integer, 2> RTDEF(Nint10_2)( |
679 | CppTypeFor<TypeCategory::Real, 10> x) { |
680 | return Nint<CppTypeFor<TypeCategory::Integer, 2>>(x); |
681 | } |
682 | CppTypeFor<TypeCategory::Integer, 4> RTDEF(Nint10_4)( |
683 | CppTypeFor<TypeCategory::Real, 10> x) { |
684 | return Nint<CppTypeFor<TypeCategory::Integer, 4>>(x); |
685 | } |
686 | CppTypeFor<TypeCategory::Integer, 8> RTDEF(Nint10_8)( |
687 | CppTypeFor<TypeCategory::Real, 10> x) { |
688 | return Nint<CppTypeFor<TypeCategory::Integer, 8>>(x); |
689 | } |
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); |
694 | } |
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); |
700 | } |
701 | CppTypeFor<TypeCategory::Integer, 2> RTDEF(Nint16_2)( |
702 | CppTypeFor<TypeCategory::Real, 16> x) { |
703 | return Nint<CppTypeFor<TypeCategory::Integer, 2>>(x); |
704 | } |
705 | CppTypeFor<TypeCategory::Integer, 4> RTDEF(Nint16_4)( |
706 | CppTypeFor<TypeCategory::Real, 16> x) { |
707 | return Nint<CppTypeFor<TypeCategory::Integer, 4>>(x); |
708 | } |
709 | CppTypeFor<TypeCategory::Integer, 8> RTDEF(Nint16_8)( |
710 | CppTypeFor<TypeCategory::Real, 16> x) { |
711 | return Nint<CppTypeFor<TypeCategory::Integer, 8>>(x); |
712 | } |
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); |
717 | } |
718 | #endif |
719 | #endif |
720 | |
721 | CppTypeFor<TypeCategory::Real, 4> RTDEF(RRSpacing4)( |
722 | CppTypeFor<TypeCategory::Real, 4> x) { |
723 | return RRSpacing<24>(x); |
724 | } |
725 | CppTypeFor<TypeCategory::Real, 8> RTDEF(RRSpacing8)( |
726 | CppTypeFor<TypeCategory::Real, 8> x) { |
727 | return RRSpacing<53>(x); |
728 | } |
729 | #if HAS_FLOAT80 |
730 | CppTypeFor<TypeCategory::Real, 10> RTDEF(RRSpacing10)( |
731 | CppTypeFor<TypeCategory::Real, 10> x) { |
732 | return RRSpacing<64>(x); |
733 | } |
734 | #endif |
735 | |
736 | CppTypeFor<TypeCategory::Real, 4> RTDEF(SetExponent4)( |
737 | CppTypeFor<TypeCategory::Real, 4> x, std::int64_t p) { |
738 | return SetExponent(x, p); |
739 | } |
740 | CppTypeFor<TypeCategory::Real, 8> RTDEF(SetExponent8)( |
741 | CppTypeFor<TypeCategory::Real, 8> x, std::int64_t p) { |
742 | return SetExponent(x, p); |
743 | } |
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); |
748 | } |
749 | #endif |
750 | |
751 | CppTypeFor<TypeCategory::Real, 4> RTDEF(Scale4)( |
752 | CppTypeFor<TypeCategory::Real, 4> x, std::int64_t p) { |
753 | return Scale(x, p); |
754 | } |
755 | CppTypeFor<TypeCategory::Real, 8> RTDEF(Scale8)( |
756 | CppTypeFor<TypeCategory::Real, 8> x, std::int64_t p) { |
757 | return Scale(x, p); |
758 | } |
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); |
763 | } |
764 | #endif |
765 | |
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; |
782 | } |
783 | } |
784 | // SELECTED_INT_KIND and SELECTED_UNSIGNED_KIND extension |
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)); |
789 | } |
790 | |
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); |
802 | } |
803 | |
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); |
816 | } |
817 | |
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)); |
825 | } |
826 | |
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); |
849 | } |
850 | |
851 | #if HAS_FP16 |
852 | CppTypeFor<TypeCategory::Real, 2> RTDEF(Spacing2)( |
853 | CppTypeFor<TypeCategory::Real, 2> x) { |
854 | return Spacing<11>(x); |
855 | } |
856 | #endif |
857 | CppTypeFor<TypeCategory::Real, 4> RTDEF(Spacing2By4)( |
858 | CppTypeFor<TypeCategory::Real, 4> x) { |
859 | return Spacing<11>(x); |
860 | } |
861 | #if HAS_BF16 |
862 | CppTypeFor<TypeCategory::Real, 3> RTDEF(Spacing3)( |
863 | CppTypeFor<TypeCategory::Real, 3> x) { |
864 | return Spacing<8>(x); |
865 | } |
866 | #endif |
867 | CppTypeFor<TypeCategory::Real, 4> RTDEF(Spacing3By4)( |
868 | CppTypeFor<TypeCategory::Real, 4> x) { |
869 | return Spacing<8>(x); |
870 | } |
871 | CppTypeFor<TypeCategory::Real, 4> RTDEF(Spacing4)( |
872 | CppTypeFor<TypeCategory::Real, 4> x) { |
873 | return Spacing<24>(x); |
874 | } |
875 | CppTypeFor<TypeCategory::Real, 8> RTDEF(Spacing8)( |
876 | CppTypeFor<TypeCategory::Real, 8> x) { |
877 | return Spacing<53>(x); |
878 | } |
879 | #if HAS_FLOAT80 |
880 | CppTypeFor<TypeCategory::Real, 10> RTDEF(Spacing10)( |
881 | CppTypeFor<TypeCategory::Real, 10> x) { |
882 | return Spacing<64>(x); |
883 | } |
884 | #endif |
885 | |
886 | CppTypeFor<TypeCategory::Real, 4> RTDEF(FPow4i)( |
887 | CppTypeFor<TypeCategory::Real, 4> b, |
888 | CppTypeFor<TypeCategory::Integer, 4> e) { |
889 | return FPowI(b, e); |
890 | } |
891 | CppTypeFor<TypeCategory::Real, 8> RTDEF(FPow8i)( |
892 | CppTypeFor<TypeCategory::Real, 8> b, |
893 | CppTypeFor<TypeCategory::Integer, 4> e) { |
894 | return FPowI(b, e); |
895 | } |
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); |
901 | } |
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); |
908 | } |
909 | #endif |
910 | |
911 | CppTypeFor<TypeCategory::Real, 4> RTDEF(FPow4k)( |
912 | CppTypeFor<TypeCategory::Real, 4> b, |
913 | CppTypeFor<TypeCategory::Integer, 8> e) { |
914 | return FPowI(b, e); |
915 | } |
916 | CppTypeFor<TypeCategory::Real, 8> RTDEF(FPow8k)( |
917 | CppTypeFor<TypeCategory::Real, 8> b, |
918 | CppTypeFor<TypeCategory::Integer, 8> e) { |
919 | return FPowI(b, e); |
920 | } |
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); |
926 | } |
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); |
933 | } |
934 | #endif |
935 | |
936 | RT_EXT_API_GROUP_END |
937 | } // extern "C" |
938 | } // namespace Fortran::runtime |
939 | |