9#ifndef FORTRAN_EVALUATE_INTEGER_VALUE_H_
10#define FORTRAN_EVALUATE_INTEGER_VALUE_H_
12#include "flang/Common/uint128.h"
13#include "flang/Evaluate/common.h"
14#include "flang/Evaluate/object-sizes.h"
15#include "llvm/Support/Compiler.h"
16#include "llvm/Support/raw_ostream.h"
25namespace Fortran::evaluate::value {
36 friend class RealValueImpl;
46#if FLANG_TRIVIALLY_COPYABLE_VALUE_IMPL
47 ~IntegerValue() =
default;
48 IntegerValue(
const IntegerValue &) =
default;
49 IntegerValue(IntegerValue &&) =
default;
50 IntegerValue &operator=(
const IntegerValue &) =
default;
51 IntegerValue &operator=(IntegerValue &&) =
default;
54 IntegerValue(
const IntegerValue &);
55 IntegerValue(IntegerValue &&);
56 IntegerValue &operator=(
const IntegerValue &);
57 IntegerValue &operator=(IntegerValue &&);
60 IntegerValue(
int kind,
const IntegerValue &x) : IntegerValue(x) {
63 IntegerValue(
int kind, IntegerValue &&x) : IntegerValue(std::move(x)) {
74 template <
typename INT,
75 typename = std::enable_if_t<common::numeric_limits<INT>::is_integer>>
76 IntegerValue(
int kind, INT v) {
77 if constexpr (
sizeof(INT) > 8) {
78 static_assert(
sizeof(INT) == 16);
79 ConstructFromIntegral(
kind,
static_cast<common::uint128_t
>(v));
80 }
else if constexpr (std::is_signed_v<INT>) {
81 ConstructFromIntegral(
82 kind,
static_cast<uint64_t
>(
static_cast<int64_t
>(v)),
true);
84 ConstructFromIntegral(
kind,
static_cast<uint64_t
>(v),
false);
93 void print(llvm::raw_ostream &os)
const;
95#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
96 LLVM_DUMP_METHOD
void dump()
const;
106 int bits()
const {
return bits(
kind()); }
127 bool operator<(
const IntegerValue &y)
const {
128 return CompareSigned(y) == Ordering::Less;
130 bool operator<=(
const IntegerValue &y)
const {
131 return CompareSigned(y) != Ordering::Greater;
133 bool operator==(
const IntegerValue &y)
const {
134 return CompareSigned(y) == Ordering::Equal;
136 bool operator!=(
const IntegerValue &y)
const {
137 return CompareSigned(y) != Ordering::Equal;
139 bool operator>=(
const IntegerValue &y)
const {
140 return CompareSigned(y) != Ordering::Less;
142 bool operator>(
const IntegerValue &y)
const {
143 return CompareSigned(y) == Ordering::Greater;
147 static IntegerValue
MASKL(
int kind,
int places);
150 static IntegerValue
MASKR(
int kind,
int places);
153 int kind,
const char *&pp,
int base,
bool isSigned);
157 int toKind,
const IntegerValue &from);
162 std::string UnsignedDecimal()
const;
164 std::string SignedDecimal()
const;
169 static constexpr int DIGITS(
int kind) {
171 return bits(
kind) - 1;
174 static IntegerValue HUGE(
int kind);
176 static IntegerValue Least(
int kind);
178 static int RANGE(
int kind);
180 static int UnsignedRANGE(
int kind);
184 bool IsNegative()
const;
186 Ordering CompareToZeroSigned()
const;
200 bool BTEST(
int pos)
const;
202 Ordering CompareUnsigned(
const IntegerValue &y)
const;
204 Ordering CompareSigned(
const IntegerValue &y)
const;
206 bool BGE(
const IntegerValue &y)
const {
207 return CompareUnsigned(y) != Ordering::Less;
209 bool BGT(
const IntegerValue &y)
const {
210 return CompareUnsigned(y) == Ordering::Greater;
212 bool BLE(
const IntegerValue &y)
const {
return !BGT(y); }
213 bool BLT(
const IntegerValue &y)
const {
return !BGE(y); }
215 std::uint64_t ToUInt64()
const;
217 std::int64_t ToInt64()
const;
219 Fortran::common::uint128_t ToUInt128()
const;
221 Fortran::common::int128_t ToInt128()
const;
223 template <
typename INT,
224 typename = std::enable_if_t<std::is_signed_v<INT> ||
225 std::is_same_v<INT, Fortran::common::int128_t>>>
227 if constexpr (std::is_same_v<INT, Fortran::common::int128_t>) {
234 template <
typename INT,
235 typename = std::enable_if_t<std::is_unsigned_v<INT> ||
236 std::is_same_v<INT, Fortran::common::uint128_t>>>
238 if constexpr (std::is_same_v<INT, Fortran::common::uint128_t>) {
246 IntegerValue
NOT()
const;
257 IntegerValue
ISHFT(
int count)
const {
303 return CompareSigned(y) == Ordering::Less ? y : *
this;
306 IntegerValue MIN(
const IntegerValue &y)
const {
307 return CompareSigned(y) == Ordering::Less ? *this : y;
310 ValueWithCarry AddUnsigned(
const IntegerValue &y,
bool carryIn =
false)
const;
312 ValueWithOverflow AddSigned(
const IntegerValue &y)
const;
314 ValueWithOverflow SubtractSigned(
const IntegerValue &y)
const;
317 ValueWithOverflow
DIM(
const IntegerValue &y)
const;
319 ValueWithOverflow SIGN(
const IntegerValue &sign)
const;
321 Product MultiplyUnsigned(
const IntegerValue &y)
const;
323 Product MultiplySigned(
const IntegerValue &y)
const;
325 QuotientWithRemainder DivideUnsigned(
const IntegerValue &y)
const;
330 QuotientWithRemainder
DivideSigned(
const IntegerValue &y)
const;
334 ValueWithOverflow
MODULO(
const IntegerValue &y)
const;
336 PowerWithErrors Power(
const IntegerValue &e)
const;
338 static IntegerValue FromRawBytes(
339 int kind,
const void *raw, std::size_t expectedSize);
340 void StoreRawBytes(
void *dst,
size_t size,
bool *changed =
nullptr)
const;
343 void ConstructFromIntegral(
int kind, std::uint64_t n,
bool isSigned);
344 void ConstructFromIntegral(
int kind, Fortran::common::uint128_t n);
346 static IntegerValue FromImpl(
const IntegerValueImpl &x);
347 static IntegerValue FromImpl(IntegerValueImpl &&x);
349 IntegerValueImpl &impl();
350 const IntegerValueImpl &impl()
const;
352 alignas(detail::kIntegerObjectAlign)
353 std::byte opaque_[detail::kIntegerObjectSize];
358 bool overflow{
false};
367 IntegerValue upper, lower;
368 bool SignedMultiplicationOverflowed()
const {
return overflow; }
369 bool overflow{
false};
373 IntegerValue quotient, remainder;
374 bool divisionByZero{
false}, overflow{
false};
379 bool divisionByZero{
false}, overflow{
false}, zeroToZero{
false};
386inline raw_ostream &operator<<(
Definition integer-value-impl.h:26
Definition integer-value.h:35
static IntegerValue Zero(int kind)
Definition integer-value.cpp:55
static ValueWithOverflow ConvertSigned(int toKind, const IntegerValue &from)
SExt or Trunc.
Definition integer-value.cpp:89
IntegerValue ISHFTC(int count, int size) const
Definition integer-value.cpp:170
IntegerValue SHIFTA(int count) const
Definition integer-value.cpp:190
QuotientWithRemainder DivideSigned(const IntegerValue &y) const
Definition integer-value.cpp:274
ValueWithOverflow DIM(const IntegerValue &y) const
DIM(X,Y)=MAX(X-Y, 0)
Definition integer-value.cpp:241
IntegerValue IBSET(int pos) const
Sets a single bit.
Definition integer-value.cpp:198
int LEADZ() const
Definition integer-value.cpp:121
ValueWithOverflow Negate() const
Definition integer-value.cpp:157
IntegerValue NOT() const
Ones'-complement (i.e., C's ~)
Definition integer-value.cpp:155
bool IsNull() const
Definition integer-value.cpp:59
std::string Hexadecimal() const
Omits a leading "0x".
Definition integer-value.cpp:103
IntegerValue DSHIFTL(const IntegerValue &fill, int count) const
DSHIFTL(I,J) shifts I:J left; the second argument is the right fill.
Definition integer-value.cpp:178
IntegerValue IBCLR(int pos) const
Clears a single bit.
Definition integer-value.cpp:194
static ValueWithOverflow ConvertUnsigned(int toKind, const IntegerValue &from)
ZExt or Trunc.
Definition integer-value.cpp:83
IntegerValue SHIFTL(int count) const
Left shift with zero fill.
Definition integer-value.cpp:166
IntegerValue IBITS(int pos, int size) const
Extracts a field.
Definition integer-value.cpp:202
ValueWithOverflow MODULO(const IntegerValue &y) const
Definition integer-value.cpp:281
static IntegerValue MASKL(int kind, int places)
Left-justified mask (e.g., MASKL(1) has only its sign bit set)
Definition integer-value.cpp:69
IntegerValue DSHIFTR(const IntegerValue &v2, int count) const
DSHIFTR(I,J) shifts I:J right; the first argument is the left fill.
Definition integer-value.cpp:182
IntegerValue SHIFTR(int count) const
Vacated upper bits are filled with zeroes.
Definition integer-value.cpp:186
static IntegerValue MASKR(int kind, int places)
Right-justified mask (e.g., MASKR(1) == 1, MASKR(2) == 3, &c.)
Definition integer-value.cpp:73
bool POPPAR() const
True when POPCNT is odd.
Definition integer-value.cpp:125
IntegerValue ISHFT(int count) const
Definition integer-value.h:257
int POPCNT() const
Count the number of bit positions that are set.
Definition integer-value.cpp:123
std::size_t bytesStored() const
Number of bytes accessed by FromRawBytes/StoreRawBytes.
Definition integer-value.h:110
int kind() const
The kind of the value currently stored.
Definition integer-value.cpp:61
Definition integer-value.h:377
Definition integer-value.h:366
Definition integer-value.h:372
Definition integer-value.h:361
Definition integer-value.h:356