1 //===-- include/flang/Evaluate/integer.h ------------------------*- 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 #ifndef FORTRAN_EVALUATE_INTEGER_H_ 10 #define FORTRAN_EVALUATE_INTEGER_H_ 11 12 // Emulates binary integers of an arbitrary (but fixed) bit size for use 13 // when the host C++ environment does not support that size or when the 14 // full suite of Fortran's integer intrinsic scalar functions are needed. 15 // The data model is typeless, so signed* and unsigned operations 16 // are distinguished from each other with distinct member function interfaces. 17 // (*"Signed" here means two's-complement, just to be clear. Ones'-complement 18 // and signed-magnitude encodings appear to be extinct in 2018.) 19 20 #include "flang/Common/bit-population-count.h" 21 #include "flang/Common/leading-zero-bit-count.h" 22 #include "flang/Evaluate/common.h" 23 #include <cinttypes> 24 #include <climits> 25 #include <cstddef> 26 #include <cstdint> 27 #include <string> 28 #include <type_traits> 29 30 // Some environments, viz. glibc 2.17 and *BSD, allow the macro HUGE 31 // to leak out of <math.h>. 32 #undef HUGE 33 34 namespace Fortran::evaluate::value { 35 36 // Computes decimal range in the sense of SELECTED_INT_KIND 37 static constexpr int DecimalRange(int bits) { 38 // This magic value is LOG10(2.)*1E12. 39 return static_cast<int>((bits * 301029995664) / 1000000000000); 40 } 41 42 // Implements an integer as an assembly of smaller host integer parts 43 // that constitute the digits of a large-radix fixed-point number. 44 // For best performance, the type of these parts should be half of the 45 // size of the largest efficient integer supported by the host processor. 46 // These parts are stored in either little- or big-endian order, which can 47 // match that of the host's endianness or not; but if the ordering matches 48 // that of the host, raw host data can be overlaid with a properly configured 49 // instance of this class and used in situ. 50 // To facilitate exhaustive testing of what would otherwise be more rare 51 // edge cases, this class template may be configured to use other part 52 // types &/or partial fields in the parts. The radix (i.e., the number 53 // of possible values in a part), however, must be a power of two; this 54 // template class is not generalized to enable, say, decimal arithmetic. 55 // Member functions that correspond to Fortran intrinsic functions are 56 // named accordingly in ALL CAPS so that they can be referenced easily in 57 // the language standard. 58 template <int BITS, bool IS_LITTLE_ENDIAN = isHostLittleEndian, 59 int PARTBITS = BITS <= 32 ? BITS 60 : BITS % 32 == 0 ? 32 61 : BITS % 16 == 0 ? 16 62 : 8, 63 typename PART = HostUnsignedInt<PARTBITS>, 64 typename BIGPART = HostUnsignedInt<PARTBITS * 2>, int ALIGNMENT = BITS> 65 class Integer { 66 public: 67 static constexpr int bits{BITS}; 68 static constexpr int partBits{PARTBITS}; 69 using Part = PART; 70 using BigPart = BIGPART; 71 static_assert(std::is_integral_v<Part>); 72 static_assert(std::is_unsigned_v<Part>); 73 static_assert(std::is_integral_v<BigPart>); 74 static_assert(std::is_unsigned_v<BigPart>); 75 static_assert(CHAR_BIT * sizeof(BigPart) >= 2 * partBits); 76 static constexpr bool littleEndian{IS_LITTLE_ENDIAN}; 77 78 private: 79 static constexpr int maxPartBits{CHAR_BIT * sizeof(Part)}; 80 static_assert(partBits > 0 && partBits <= maxPartBits); 81 static constexpr int extraPartBits{maxPartBits - partBits}; 82 static constexpr int parts{(bits + partBits - 1) / partBits}; 83 static_assert(parts >= 1); 84 static constexpr int extraTopPartBits{ 85 extraPartBits + (parts * partBits) - bits}; 86 static constexpr int topPartBits{maxPartBits - extraTopPartBits}; 87 static_assert(topPartBits > 0 && topPartBits <= partBits); 88 static_assert((parts - 1) * partBits + topPartBits == bits); 89 static constexpr Part partMask{static_cast<Part>(~0) >> extraPartBits}; 90 static constexpr Part topPartMask{static_cast<Part>(~0) >> extraTopPartBits}; 91 static constexpr int partsWithAlignment{ 92 (ALIGNMENT + partBits - 1) / partBits}; 93 94 public: 95 // Some types used for member function results 96 struct ValueWithOverflow { 97 Integer value; 98 bool overflow; 99 }; 100 101 struct ValueWithCarry { 102 Integer value; 103 bool carry; 104 }; 105 106 struct Product { 107 bool SignedMultiplicationOverflowed() const { 108 return lower.IsNegative() ? (upper.POPCNT() != bits) : !upper.IsZero(); 109 } 110 Integer upper, lower; 111 }; 112 113 struct QuotientWithRemainder { 114 Integer quotient, remainder; 115 bool divisionByZero, overflow; 116 }; 117 118 struct PowerWithErrors { 119 Integer power; 120 bool divisionByZero{false}, overflow{false}, zeroToZero{false}; 121 }; 122 123 // Constructors and value-generating static functions 124 constexpr Integer() { Clear(); } // default constructor: zero 125 constexpr Integer(const Integer &) = default; 126 constexpr Integer(Integer &&) = default; 127 128 // C++'s integral types can all be converted to Integer 129 // with silent truncation. 130 template <typename INT, typename = std::enable_if_t<std::is_integral_v<INT>>> 131 constexpr Integer(INT n) { 132 constexpr int nBits = CHAR_BIT * sizeof n; 133 if constexpr (nBits < partBits) { 134 if constexpr (std::is_unsigned_v<INT>) { 135 // Zero-extend an unsigned smaller value. 136 SetLEPart(0, n); 137 for (int j{1}; j < parts; ++j) { 138 SetLEPart(j, 0); 139 } 140 } else { 141 // n has a signed type smaller than the usable 142 // bits in a Part. 143 // Avoid conversions that change both size and sign. 144 using SignedPart = std::make_signed_t<Part>; 145 Part p = static_cast<SignedPart>(n); 146 SetLEPart(0, p); 147 if constexpr (parts > 1) { 148 Part signExtension = static_cast<SignedPart>(-(n < 0)); 149 for (int j{1}; j < parts; ++j) { 150 SetLEPart(j, signExtension); 151 } 152 } 153 } 154 } else { 155 // n has some integral type no smaller than the usable 156 // bits in a Part. 157 // Ensure that all shifts are smaller than a whole word. 158 if constexpr (std::is_unsigned_v<INT>) { 159 for (int j{0}; j < parts; ++j) { 160 SetLEPart(j, static_cast<Part>(n)); 161 if constexpr (nBits > partBits) { 162 n >>= partBits; 163 } else { 164 n = 0; 165 } 166 } 167 } else { 168 // Avoid left shifts of negative signed values (that's an undefined 169 // behavior in C++). 170 auto signExtension{std::make_unsigned_t<INT>(n < 0)}; 171 signExtension = ~signExtension + 1; 172 static_assert(nBits >= partBits); 173 if constexpr (nBits > partBits) { 174 signExtension <<= nBits - partBits; 175 for (int j{0}; j < parts; ++j) { 176 SetLEPart(j, static_cast<Part>(n)); 177 n >>= partBits; 178 n |= signExtension; 179 } 180 } else { 181 SetLEPart(0, static_cast<Part>(n)); 182 for (int j{1}; j < parts; ++j) { 183 SetLEPart(j, static_cast<Part>(signExtension)); 184 } 185 } 186 } 187 } 188 } 189 190 constexpr Integer &operator=(const Integer &) = default; 191 192 constexpr bool operator<(const Integer &that) const { 193 return CompareSigned(that) == Ordering::Less; 194 } 195 constexpr bool operator<=(const Integer &that) const { 196 return CompareSigned(that) != Ordering::Greater; 197 } 198 constexpr bool operator==(const Integer &that) const { 199 return CompareSigned(that) == Ordering::Equal; 200 } 201 constexpr bool operator!=(const Integer &that) const { 202 return !(*this == that); 203 } 204 constexpr bool operator>=(const Integer &that) const { 205 return CompareSigned(that) != Ordering::Less; 206 } 207 constexpr bool operator>(const Integer &that) const { 208 return CompareSigned(that) == Ordering::Greater; 209 } 210 211 // Left-justified mask (e.g., MASKL(1) has only its sign bit set) 212 static constexpr Integer MASKL(int places) { 213 if (places <= 0) { 214 return {}; 215 } else if (places >= bits) { 216 return MASKR(bits); 217 } else { 218 return MASKR(bits - places).NOT(); 219 } 220 } 221 222 // Right-justified mask (e.g., MASKR(1) == 1, MASKR(2) == 3, &c.) 223 static constexpr Integer MASKR(int places) { 224 Integer result{nullptr}; 225 int j{0}; 226 for (; j + 1 < parts && places >= partBits; ++j, places -= partBits) { 227 result.LEPart(j) = partMask; 228 } 229 if (places > 0) { 230 if (j + 1 < parts) { 231 result.LEPart(j++) = partMask >> (partBits - places); 232 } else if (j + 1 == parts) { 233 if (places >= topPartBits) { 234 result.LEPart(j++) = topPartMask; 235 } else { 236 result.LEPart(j++) = topPartMask >> (topPartBits - places); 237 } 238 } 239 } 240 for (; j < parts; ++j) { 241 result.LEPart(j) = 0; 242 } 243 return result; 244 } 245 246 static constexpr ValueWithOverflow Read( 247 const char *&pp, std::uint64_t base = 10, bool isSigned = false) { 248 Integer result; 249 bool overflow{false}; 250 const char *p{pp}; 251 while (*p == ' ' || *p == '\t') { 252 ++p; 253 } 254 bool negate{*p == '-'}; 255 if (negate || *p == '+') { 256 while (*++p == ' ' || *p == '\t') { 257 } 258 } 259 Integer radix{base}; 260 // This code makes assumptions about local contiguity in regions of the 261 // character set and only works up to base 36. These assumptions hold 262 // for all current combinations of surviving character sets (ASCII, UTF-8, 263 // EBCDIC) and the bases used in Fortran source and formatted I/O 264 // (viz., 2, 8, 10, & 16). But: management thought that a disclaimer 265 // might be needed here to warn future users of this code about these 266 // assumptions, so here you go, future programmer in some postapocalyptic 267 // hellscape, and best of luck with the inexorable killer robots. 268 for (; std::uint64_t digit = *p; ++p) { 269 if (digit >= '0' && digit <= '9' && digit < '0' + base) { 270 digit -= '0'; 271 } else if (base > 10 && digit >= 'A' && digit < 'A' + base - 10) { 272 digit -= 'A' - 10; 273 } else if (base > 10 && digit >= 'a' && digit < 'a' + base - 10) { 274 digit -= 'a' - 10; 275 } else { 276 break; 277 } 278 Product shifted{result.MultiplyUnsigned(radix)}; 279 overflow |= !shifted.upper.IsZero(); 280 ValueWithCarry next{shifted.lower.AddUnsigned(Integer{digit})}; 281 overflow |= next.carry; 282 result = next.value; 283 } 284 pp = p; 285 if (negate) { 286 result = result.Negate().value; 287 overflow |= isSigned && !result.IsNegative() && !result.IsZero(); 288 } else { 289 overflow |= isSigned && result.IsNegative(); 290 } 291 return {result, overflow}; 292 } 293 294 template <typename FROM> 295 static constexpr ValueWithOverflow ConvertUnsigned(const FROM &that) { 296 std::uint64_t field{that.ToUInt64()}; 297 ValueWithOverflow result{field, false}; 298 if constexpr (bits < 64) { 299 result.overflow = (field >> bits) != 0; 300 } 301 for (int j{64}; j < that.bits && !result.overflow; j += 64) { 302 field = that.SHIFTR(j).ToUInt64(); 303 if (bits <= j) { 304 result.overflow = field != 0; 305 } else { 306 result.value = result.value.IOR(Integer{field}.SHIFTL(j)); 307 if (bits < j + 64) { 308 result.overflow = (field >> (bits - j)) != 0; 309 } 310 } 311 } 312 return result; 313 } 314 315 template <typename FROM> 316 static constexpr ValueWithOverflow ConvertSigned(const FROM &that) { 317 ValueWithOverflow result{ConvertUnsigned(that)}; 318 if constexpr (bits > FROM::bits) { 319 if (that.IsNegative()) { 320 result.value = result.value.IOR(MASKL(bits - FROM::bits)); 321 } 322 result.overflow = false; 323 } else if constexpr (bits < FROM::bits) { 324 auto back{FROM::template ConvertSigned<Integer>(result.value)}; 325 result.overflow = back.value.CompareUnsigned(that) != Ordering::Equal; 326 } 327 return result; 328 } 329 330 std::string UnsignedDecimal() const { 331 if constexpr (bits < 4) { 332 char digit = '0' + ToUInt64(); 333 return {digit}; 334 } else if (IsZero()) { 335 return {'0'}; 336 } else { 337 QuotientWithRemainder qr{DivideUnsigned(10)}; 338 char digit = '0' + qr.remainder.ToUInt64(); 339 if (qr.quotient.IsZero()) { 340 return {digit}; 341 } else { 342 return qr.quotient.UnsignedDecimal() + digit; 343 } 344 } 345 } 346 347 std::string SignedDecimal() const { 348 if (IsNegative()) { 349 return std::string{'-'} + Negate().value.UnsignedDecimal(); 350 } else { 351 return UnsignedDecimal(); 352 } 353 } 354 355 // Omits a leading "0x". 356 std::string Hexadecimal() const { 357 std::string result; 358 int digits{(bits + 3) >> 2}; 359 for (int j{0}; j < digits; ++j) { 360 int pos{(digits - 1 - j) * 4}; 361 char nybble = IBITS(pos, 4).ToUInt64(); 362 if (nybble != 0 || !result.empty() || j + 1 == digits) { 363 char digit = '0' + nybble; 364 if (digit > '9') { 365 digit += 'a' - ('9' + 1); 366 } 367 result += digit; 368 } 369 } 370 return result; 371 } 372 373 static constexpr int DIGITS{bits - 1}; // don't count the sign bit 374 static constexpr Integer HUGE() { return MASKR(bits - 1); } 375 static constexpr Integer Least() { return MASKL(1); } 376 static constexpr int RANGE{DecimalRange(bits - 1)}; 377 static constexpr int UnsignedRANGE{DecimalRange(bits)}; 378 379 constexpr bool IsZero() const { 380 for (int j{0}; j < parts; ++j) { 381 if (part_[j] != 0) { 382 return false; 383 } 384 } 385 return true; 386 } 387 388 constexpr bool IsNegative() const { 389 return (LEPart(parts - 1) >> (topPartBits - 1)) & 1; 390 } 391 392 constexpr Ordering CompareToZeroSigned() const { 393 if (IsNegative()) { 394 return Ordering::Less; 395 } else if (IsZero()) { 396 return Ordering::Equal; 397 } else { 398 return Ordering::Greater; 399 } 400 } 401 402 // Count the number of contiguous most-significant bit positions 403 // that are clear. 404 constexpr int LEADZ() const { 405 if (LEPart(parts - 1) != 0) { 406 int lzbc{common::LeadingZeroBitCount(LEPart(parts - 1))}; 407 return lzbc - extraTopPartBits; 408 } 409 int upperZeroes{topPartBits}; 410 for (int j{1}; j < parts; ++j) { 411 if (Part p{LEPart(parts - 1 - j)}) { 412 int lzbc{common::LeadingZeroBitCount(p)}; 413 return upperZeroes + lzbc - extraPartBits; 414 } 415 upperZeroes += partBits; 416 } 417 return bits; 418 } 419 420 // Count the number of bit positions that are set. 421 constexpr int POPCNT() const { 422 int count{0}; 423 for (int j{0}; j < parts; ++j) { 424 count += common::BitPopulationCount(part_[j]); 425 } 426 return count; 427 } 428 429 // True when POPCNT is odd. 430 constexpr bool POPPAR() const { return POPCNT() & 1; } 431 432 constexpr int TRAILZ() const { 433 auto minus1{AddUnsigned(MASKR(bits))}; // { x-1, carry = x > 0 } 434 if (!minus1.carry) { 435 return bits; // was zero 436 } else { 437 // x ^ (x-1) has all bits set at and below original least-order set bit. 438 return IEOR(minus1.value).POPCNT() - 1; 439 } 440 } 441 442 constexpr bool BTEST(int pos) const { 443 if (pos < 0 || pos >= bits) { 444 return false; 445 } else { 446 return (LEPart(pos / partBits) >> (pos % partBits)) & 1; 447 } 448 } 449 450 constexpr Ordering CompareUnsigned(const Integer &y) const { 451 for (int j{parts}; j-- > 0;) { 452 if (LEPart(j) > y.LEPart(j)) { 453 return Ordering::Greater; 454 } 455 if (LEPart(j) < y.LEPart(j)) { 456 return Ordering::Less; 457 } 458 } 459 return Ordering::Equal; 460 } 461 462 constexpr bool BGE(const Integer &y) const { 463 return CompareUnsigned(y) != Ordering::Less; 464 } 465 constexpr bool BGT(const Integer &y) const { 466 return CompareUnsigned(y) == Ordering::Greater; 467 } 468 constexpr bool BLE(const Integer &y) const { return !BGT(y); } 469 constexpr bool BLT(const Integer &y) const { return !BGE(y); } 470 471 constexpr Ordering CompareSigned(const Integer &y) const { 472 bool isNegative{IsNegative()}; 473 if (isNegative != y.IsNegative()) { 474 return isNegative ? Ordering::Less : Ordering::Greater; 475 } 476 return CompareUnsigned(y); 477 } 478 479 template <typename UINT = std::uint64_t> constexpr UINT ToUInt() const { 480 UINT n{LEPart(0)}; 481 std::size_t filled{partBits}; 482 constexpr std::size_t maxBits{CHAR_BIT * sizeof n}; 483 for (int j{1}; filled < maxBits && j < parts; ++j, filled += partBits) { 484 n |= UINT{LEPart(j)} << filled; 485 } 486 return n; 487 } 488 489 template <typename SINT = std::int64_t, typename UINT = std::uint64_t> 490 constexpr SINT ToSInt() const { 491 SINT n = ToUInt<UINT>(); 492 constexpr std::size_t maxBits{CHAR_BIT * sizeof n}; 493 if constexpr (bits < maxBits) { 494 // Avoid left shifts of negative signed values (that's an undefined 495 // behavior in C++). 496 auto u{std::make_unsigned_t<SINT>(ToUInt())}; 497 u = (u >> (bits - 1)) << (bits - 1); // Get the sign bit only. 498 u = ~u + 1; // Negate top bits if not 0. 499 n |= static_cast<SINT>(u); 500 } 501 return n; 502 } 503 504 constexpr std::uint64_t ToUInt64() const { return ToUInt<std::uint64_t>(); } 505 506 constexpr std::int64_t ToInt64() const { 507 return ToSInt<std::int64_t, std::uint64_t>(); 508 } 509 510 // Ones'-complement (i.e., C's ~) 511 constexpr Integer NOT() const { 512 Integer result{nullptr}; 513 for (int j{0}; j < parts; ++j) { 514 result.SetLEPart(j, ~LEPart(j)); 515 } 516 return result; 517 } 518 519 // Two's-complement negation (-x = ~x + 1). 520 // An overflow flag accompanies the result, and will be true when the 521 // operand is the most negative signed number (MASKL(1)). 522 constexpr ValueWithOverflow Negate() const { 523 Integer result{nullptr}; 524 Part carry{1}; 525 for (int j{0}; j + 1 < parts; ++j) { 526 Part newCarry{LEPart(j) == 0 && carry}; 527 result.SetLEPart(j, ~LEPart(j) + carry); 528 carry = newCarry; 529 } 530 Part top{LEPart(parts - 1)}; 531 result.SetLEPart(parts - 1, ~top + carry); 532 bool overflow{top != 0 && result.LEPart(parts - 1) == top}; 533 return {result, overflow}; 534 } 535 536 constexpr ValueWithOverflow ABS() const { 537 if (IsNegative()) { 538 return Negate(); 539 } else { 540 return {*this, false}; 541 } 542 } 543 544 // Shifts the operand left when the count is positive, right when negative. 545 // Vacated bit positions are filled with zeroes. 546 constexpr Integer ISHFT(int count) const { 547 if (count < 0) { 548 return SHIFTR(-count); 549 } else { 550 return SHIFTL(count); 551 } 552 } 553 554 // Left shift with zero fill. 555 constexpr Integer SHIFTL(int count) const { 556 if (count <= 0) { 557 return *this; 558 } else { 559 Integer result{nullptr}; 560 int shiftParts{count / partBits}; 561 int bitShift{count - partBits * shiftParts}; 562 int j{parts - 1}; 563 if (bitShift == 0) { 564 for (; j >= shiftParts; --j) { 565 result.SetLEPart(j, LEPart(j - shiftParts)); 566 } 567 for (; j >= 0; --j) { 568 result.LEPart(j) = 0; 569 } 570 } else { 571 for (; j > shiftParts; --j) { 572 result.SetLEPart(j, 573 ((LEPart(j - shiftParts) << bitShift) | 574 (LEPart(j - shiftParts - 1) >> (partBits - bitShift)))); 575 } 576 if (j == shiftParts) { 577 result.SetLEPart(j, LEPart(0) << bitShift); 578 --j; 579 } 580 for (; j >= 0; --j) { 581 result.LEPart(j) = 0; 582 } 583 } 584 return result; 585 } 586 } 587 588 // Circular shift of a field of least-significant bits. The least-order 589 // "size" bits are shifted circularly in place by "count" positions; 590 // the shift is leftward if count is nonnegative, rightward otherwise. 591 // Higher-order bits are unchanged. 592 constexpr Integer ISHFTC(int count, int size = bits) const { 593 if (count == 0 || size <= 0) { 594 return *this; 595 } 596 if (size > bits) { 597 size = bits; 598 } 599 count %= size; 600 if (count == 0) { 601 return *this; 602 } 603 int middleBits{size - count}, leastBits{count}; 604 if (count < 0) { 605 middleBits = -count; 606 leastBits = size + count; 607 } 608 if (size == bits) { 609 return SHIFTL(leastBits).IOR(SHIFTR(middleBits)); 610 } 611 Integer unchanged{IAND(MASKL(bits - size))}; 612 Integer middle{IAND(MASKR(middleBits)).SHIFTL(leastBits)}; 613 Integer least{SHIFTR(middleBits).IAND(MASKR(leastBits))}; 614 return unchanged.IOR(middle).IOR(least); 615 } 616 617 // Double shifts, aka shifts with specific fill. 618 constexpr Integer SHIFTLWithFill(const Integer &fill, int count) const { 619 if (count <= 0) { 620 return *this; 621 } else if (count >= 2 * bits) { 622 return {}; 623 } else if (count > bits) { 624 return fill.SHIFTL(count - bits); 625 } else if (count == bits) { 626 return fill; 627 } else { 628 return SHIFTL(count).IOR(fill.SHIFTR(bits - count)); 629 } 630 } 631 632 constexpr Integer SHIFTRWithFill(const Integer &fill, int count) const { 633 if (count <= 0) { 634 return *this; 635 } else if (count >= 2 * bits) { 636 return {}; 637 } else if (count > bits) { 638 return fill.SHIFTR(count - bits); 639 } else if (count == bits) { 640 return fill; 641 } else { 642 return SHIFTR(count).IOR(fill.SHIFTL(bits - count)); 643 } 644 } 645 646 constexpr Integer DSHIFTL(const Integer &fill, int count) const { 647 // DSHIFTL(I,J) shifts I:J left; the second argument is the right fill. 648 return SHIFTLWithFill(fill, count); 649 } 650 651 constexpr Integer DSHIFTR(const Integer &value, int count) const { 652 // DSHIFTR(I,J) shifts I:J right; the *first* argument is the left fill. 653 return value.SHIFTRWithFill(*this, count); 654 } 655 656 // Vacated upper bits are filled with zeroes. 657 constexpr Integer SHIFTR(int count) const { 658 if (count <= 0) { 659 return *this; 660 } else { 661 Integer result{nullptr}; 662 int shiftParts{count / partBits}; 663 int bitShift{count - partBits * shiftParts}; 664 int j{0}; 665 if (bitShift == 0) { 666 for (; j + shiftParts < parts; ++j) { 667 result.LEPart(j) = LEPart(j + shiftParts); 668 } 669 for (; j < parts; ++j) { 670 result.LEPart(j) = 0; 671 } 672 } else { 673 for (; j + shiftParts + 1 < parts; ++j) { 674 result.SetLEPart(j, 675 (LEPart(j + shiftParts) >> bitShift) | 676 (LEPart(j + shiftParts + 1) << (partBits - bitShift))); 677 } 678 if (j + shiftParts + 1 == parts) { 679 result.LEPart(j++) = LEPart(parts - 1) >> bitShift; 680 } 681 for (; j < parts; ++j) { 682 result.LEPart(j) = 0; 683 } 684 } 685 return result; 686 } 687 } 688 689 // Be advised, an arithmetic (sign-filling) right shift is not 690 // the same as a division by a power of two in all cases. 691 constexpr Integer SHIFTA(int count) const { 692 if (count <= 0) { 693 return *this; 694 } else if (IsNegative()) { 695 return SHIFTR(count).IOR(MASKL(count)); 696 } else { 697 return SHIFTR(count); 698 } 699 } 700 701 // Clears a single bit. 702 constexpr Integer IBCLR(int pos) const { 703 if (pos < 0 || pos >= bits) { 704 return *this; 705 } else { 706 Integer result{*this}; 707 result.LEPart(pos / partBits) &= ~(Part{1} << (pos % partBits)); 708 return result; 709 } 710 } 711 712 // Sets a single bit. 713 constexpr Integer IBSET(int pos) const { 714 if (pos < 0 || pos >= bits) { 715 return *this; 716 } else { 717 Integer result{*this}; 718 result.LEPart(pos / partBits) |= Part{1} << (pos % partBits); 719 return result; 720 } 721 } 722 723 // Extracts a field. 724 constexpr Integer IBITS(int pos, int size) const { 725 return SHIFTR(pos).IAND(MASKR(size)); 726 } 727 728 constexpr Integer IAND(const Integer &y) const { 729 Integer result{nullptr}; 730 for (int j{0}; j < parts; ++j) { 731 result.LEPart(j) = LEPart(j) & y.LEPart(j); 732 } 733 return result; 734 } 735 736 constexpr Integer IOR(const Integer &y) const { 737 Integer result{nullptr}; 738 for (int j{0}; j < parts; ++j) { 739 result.LEPart(j) = LEPart(j) | y.LEPart(j); 740 } 741 return result; 742 } 743 744 constexpr Integer IEOR(const Integer &y) const { 745 Integer result{nullptr}; 746 for (int j{0}; j < parts; ++j) { 747 result.LEPart(j) = LEPart(j) ^ y.LEPart(j); 748 } 749 return result; 750 } 751 752 constexpr Integer MERGE_BITS(const Integer &y, const Integer &mask) const { 753 return IAND(mask).IOR(y.IAND(mask.NOT())); 754 } 755 756 constexpr Integer MAX(const Integer &y) const { 757 if (CompareSigned(y) == Ordering::Less) { 758 return y; 759 } else { 760 return *this; 761 } 762 } 763 764 constexpr Integer MIN(const Integer &y) const { 765 if (CompareSigned(y) == Ordering::Less) { 766 return *this; 767 } else { 768 return y; 769 } 770 } 771 772 // Unsigned addition with carry. 773 constexpr ValueWithCarry AddUnsigned( 774 const Integer &y, bool carryIn = false) const { 775 Integer sum{nullptr}; 776 BigPart carry{carryIn}; 777 for (int j{0}; j + 1 < parts; ++j) { 778 carry += LEPart(j); 779 carry += y.LEPart(j); 780 sum.SetLEPart(j, carry); 781 carry >>= partBits; 782 } 783 carry += LEPart(parts - 1); 784 carry += y.LEPart(parts - 1); 785 sum.SetLEPart(parts - 1, carry); 786 return {sum, carry > topPartMask}; 787 } 788 789 constexpr ValueWithOverflow AddSigned(const Integer &y) const { 790 bool isNegative{IsNegative()}; 791 bool sameSign{isNegative == y.IsNegative()}; 792 ValueWithCarry sum{AddUnsigned(y)}; 793 bool overflow{sameSign && sum.value.IsNegative() != isNegative}; 794 return {sum.value, overflow}; 795 } 796 797 constexpr ValueWithOverflow SubtractSigned(const Integer &y) const { 798 bool isNegative{IsNegative()}; 799 bool sameSign{isNegative == y.IsNegative()}; 800 ValueWithCarry diff{AddUnsigned(y.Negate().value)}; 801 bool overflow{!sameSign && diff.value.IsNegative() != isNegative}; 802 return {diff.value, overflow}; 803 } 804 805 // DIM(X,Y)=MAX(X-Y, 0) 806 constexpr ValueWithOverflow DIM(const Integer &y) const { 807 if (CompareSigned(y) != Ordering::Greater) { 808 return {}; 809 } else { 810 return SubtractSigned(y); 811 } 812 } 813 814 constexpr ValueWithOverflow SIGN(bool toNegative) const { 815 if (toNegative == IsNegative()) { 816 return {*this, false}; 817 } else if (toNegative) { 818 return Negate(); 819 } else { 820 return ABS(); 821 } 822 } 823 824 constexpr ValueWithOverflow SIGN(const Integer &sign) const { 825 return SIGN(sign.IsNegative()); 826 } 827 828 constexpr Product MultiplyUnsigned(const Integer &y) const { 829 Part product[2 * parts]{}; // little-endian full product 830 for (int j{0}; j < parts; ++j) { 831 if (Part xpart{LEPart(j)}) { 832 for (int k{0}; k < parts; ++k) { 833 if (Part ypart{y.LEPart(k)}) { 834 BigPart xy{xpart}; 835 xy *= ypart; 836 #if defined __GNUC__ && __GNUC__ < 8 || __GNUC__ >= 12 837 // && to < (2 * parts) was added to avoid GCC build failure on 838 // -Werror=array-bounds. This can be removed if -Werror is disabled. 839 for (int to{j + k}; xy != 0 && to < (2 * parts); ++to) { 840 #else 841 for (int to{j + k}; xy != 0; ++to) { 842 #endif 843 xy += product[to]; 844 product[to] = xy & partMask; 845 xy >>= partBits; 846 } 847 } 848 } 849 } 850 } 851 Integer upper{nullptr}, lower{nullptr}; 852 for (int j{0}; j < parts; ++j) { 853 lower.LEPart(j) = product[j]; 854 upper.LEPart(j) = product[j + parts]; 855 } 856 if constexpr (topPartBits < partBits) { 857 upper = upper.SHIFTL(partBits - topPartBits); 858 upper.LEPart(0) |= lower.LEPart(parts - 1) >> topPartBits; 859 lower.LEPart(parts - 1) &= topPartMask; 860 } 861 return {upper, lower}; 862 } 863 864 constexpr Product MultiplySigned(const Integer &y) const { 865 bool yIsNegative{y.IsNegative()}; 866 Integer absy{y}; 867 if (yIsNegative) { 868 absy = y.Negate().value; 869 } 870 bool isNegative{IsNegative()}; 871 Integer absx{*this}; 872 if (isNegative) { 873 absx = Negate().value; 874 } 875 Product product{absx.MultiplyUnsigned(absy)}; 876 if (isNegative != yIsNegative) { 877 product.lower = product.lower.NOT(); 878 product.upper = product.upper.NOT(); 879 Integer one{1}; 880 auto incremented{product.lower.AddUnsigned(one)}; 881 product.lower = incremented.value; 882 if (incremented.carry) { 883 product.upper = product.upper.AddUnsigned(one).value; 884 } 885 } 886 return product; 887 } 888 889 constexpr QuotientWithRemainder DivideUnsigned(const Integer &divisor) const { 890 if (divisor.IsZero()) { 891 return {MASKR(bits), Integer{}, true, false}; // overflow to max value 892 } 893 int bitsDone{LEADZ()}; 894 Integer top{SHIFTL(bitsDone)}; 895 Integer quotient, remainder; 896 for (; bitsDone < bits; ++bitsDone) { 897 auto doubledTop{top.AddUnsigned(top)}; 898 top = doubledTop.value; 899 remainder = remainder.AddUnsigned(remainder, doubledTop.carry).value; 900 bool nextBit{remainder.CompareUnsigned(divisor) != Ordering::Less}; 901 quotient = quotient.AddUnsigned(quotient, nextBit).value; 902 if (nextBit) { 903 remainder = remainder.SubtractSigned(divisor).value; 904 } 905 } 906 return {quotient, remainder, false, false}; 907 } 908 909 // A nonzero remainder has the sign of the dividend, i.e., it computes 910 // the MOD intrinsic (X-INT(X/Y)*Y), not MODULO (which is below). 911 // 8/5 = 1r3; -8/5 = -1r-3; 8/-5 = -1r3; -8/-5 = 1r-3 912 constexpr QuotientWithRemainder DivideSigned(Integer divisor) const { 913 bool dividendIsNegative{IsNegative()}; 914 bool negateQuotient{dividendIsNegative}; 915 Ordering divisorOrdering{divisor.CompareToZeroSigned()}; 916 if (divisorOrdering == Ordering::Less) { 917 negateQuotient = !negateQuotient; 918 auto negated{divisor.Negate()}; 919 if (negated.overflow) { 920 // divisor was (and is) the most negative number 921 if (CompareUnsigned(divisor) == Ordering::Equal) { 922 return {MASKR(1), Integer{}, false, bits <= 1}; 923 } else { 924 return {Integer{}, *this, false, false}; 925 } 926 } 927 divisor = negated.value; 928 } else if (divisorOrdering == Ordering::Equal) { 929 // division by zero 930 if (dividendIsNegative) { 931 return {MASKL(1), Integer{}, true, false}; 932 } else { 933 return {MASKR(bits - 1), Integer{}, true, false}; 934 } 935 } 936 Integer dividend{*this}; 937 if (dividendIsNegative) { 938 auto negated{Negate()}; 939 if (negated.overflow) { 940 // Dividend was (and remains) the most negative number. 941 // See whether the original divisor was -1 (if so, it's 1 now). 942 if (divisorOrdering == Ordering::Less && 943 divisor.CompareUnsigned(Integer{1}) == Ordering::Equal) { 944 // most negative number / -1 is the sole overflow case 945 return {*this, Integer{}, false, true}; 946 } 947 } else { 948 dividend = negated.value; 949 } 950 } 951 // Overflow is not possible, and both the dividend and divisor 952 // are now positive. 953 QuotientWithRemainder result{dividend.DivideUnsigned(divisor)}; 954 if (negateQuotient) { 955 result.quotient = result.quotient.Negate().value; 956 } 957 if (dividendIsNegative) { 958 result.remainder = result.remainder.Negate().value; 959 } 960 return result; 961 } 962 963 // Result has the sign of the divisor argument. 964 // 8 mod 5 = 3; -8 mod 5 = 2; 8 mod -5 = -2; -8 mod -5 = -3 965 constexpr ValueWithOverflow MODULO(const Integer &divisor) const { 966 bool negativeDivisor{divisor.IsNegative()}; 967 bool distinctSigns{IsNegative() != negativeDivisor}; 968 QuotientWithRemainder divided{DivideSigned(divisor)}; 969 if (distinctSigns && !divided.remainder.IsZero()) { 970 return {divided.remainder.AddUnsigned(divisor).value, divided.overflow}; 971 } else { 972 return {divided.remainder, divided.overflow}; 973 } 974 } 975 976 constexpr PowerWithErrors Power(const Integer &exponent) const { 977 PowerWithErrors result{1, false, false, false}; 978 if (exponent.IsZero()) { 979 // x**0 -> 1, including the case 0**0, which is not defined specifically 980 // in F'18 afaict; however, other Fortrans tested all produce 1, not 0, 981 // apart from nagfor, which stops with an error at runtime. 982 // Ada, APL, C's pow(), Haskell, Julia, MATLAB, and R all produce 1 too. 983 // F'77 explicitly states that 0**0 is mathematically undefined and 984 // therefore prohibited. 985 result.zeroToZero = IsZero(); 986 } else if (exponent.IsNegative()) { 987 if (IsZero()) { 988 result.divisionByZero = true; 989 result.power = MASKR(bits - 1); 990 } else if (CompareSigned(Integer{1}) == Ordering::Equal) { 991 result.power = *this; // 1**x -> 1 992 } else if (CompareSigned(Integer{-1}) == Ordering::Equal) { 993 if (exponent.BTEST(0)) { 994 result.power = *this; // (-1)**x -> -1 if x is odd 995 } 996 } else { 997 result.power.Clear(); // j**k -> 0 if |j| > 1 and k < 0 998 } 999 } else { 1000 Integer shifted{*this}; 1001 Integer pow{exponent}; 1002 int nbits{bits - pow.LEADZ()}; 1003 for (int j{0}; j < nbits; ++j) { 1004 if (pow.BTEST(j)) { 1005 Product product{result.power.MultiplySigned(shifted)}; 1006 result.power = product.lower; 1007 result.overflow |= product.SignedMultiplicationOverflowed(); 1008 } 1009 if (j + 1 < nbits) { 1010 Product squared{shifted.MultiplySigned(shifted)}; 1011 result.overflow |= squared.SignedMultiplicationOverflowed(); 1012 shifted = squared.lower; 1013 } 1014 } 1015 } 1016 return result; 1017 } 1018 1019 private: 1020 // A private constructor, selected by the use of nullptr, 1021 // that is used by member functions when it would be a waste 1022 // of time to initialize parts_[]. 1023 constexpr Integer(std::nullptr_t) {} 1024 1025 // Accesses parts in little-endian order. 1026 constexpr const Part &LEPart(int part) const { 1027 if constexpr (littleEndian) { 1028 return part_[part]; 1029 } else { 1030 return part_[parts - 1 - part]; 1031 } 1032 } 1033 1034 constexpr Part &LEPart(int part) { 1035 if constexpr (littleEndian) { 1036 return part_[part]; 1037 } else { 1038 return part_[parts - 1 - part]; 1039 } 1040 } 1041 1042 constexpr void SetLEPart(int part, Part x) { 1043 LEPart(part) = x & PartMask(part); 1044 } 1045 1046 static constexpr Part PartMask(int part) { 1047 return part == parts - 1 ? topPartMask : partMask; 1048 } 1049 1050 constexpr void Clear() { 1051 for (int j{0}; j < parts; ++j) { 1052 part_[j] = 0; 1053 } 1054 } 1055 1056 Part part_[partsWithAlignment]{}; 1057 }; 1058 1059 extern template class Integer<8>; 1060 extern template class Integer<16>; 1061 extern template class Integer<32>; 1062 extern template class Integer<64>; 1063 using X87IntegerContainer = 1064 Integer<80, isHostLittleEndian, 16, std::uint16_t, std::uint32_t, 128>; 1065 extern template class Integer<80, isHostLittleEndian, 16, std::uint16_t, 1066 std::uint32_t, 128>; 1067 extern template class Integer<128>; 1068 } // namespace Fortran::evaluate::value 1069 #endif // FORTRAN_EVALUATE_INTEGER_H_ 1070