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