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