FLANG
integer.h
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
34namespace Fortran::evaluate::value {
35
36// Computes decimal range in the sense of SELECTED_INT_KIND
37static 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.
58template <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>
65class Integer {
66public:
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
78private:
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
94public:
95 // Some types used for member function results
97 Integer value;
98 bool overflow;
99 };
100
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
114 Integer quotient, remainder;
115 bool divisionByZero, overflow;
116 };
117
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
1019private:
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
1059extern template class Integer<8>;
1060extern template class Integer<16>;
1061extern template class Integer<32>;
1062extern template class Integer<64>;
1063using X87IntegerContainer =
1064 Integer<80, isHostLittleEndian, 16, std::uint16_t, std::uint32_t, 128>;
1065extern template class Integer<80, isHostLittleEndian, 16, std::uint16_t,
1066 std::uint32_t, 128>;
1067extern template class Integer<128>;
1068} // namespace Fortran::evaluate::value
1069#endif // FORTRAN_EVALUATE_INTEGER_H_
Definition: integer.h:106