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"
24namespace Fortran::evaluate::value {
35 friend class RealValueImpl;
46 IntegerValue(
const IntegerValue &);
47 IntegerValue(IntegerValue &&);
48 IntegerValue &operator=(
const IntegerValue &);
49 IntegerValue &operator=(IntegerValue &&);
51 IntegerValue(
int kind,
const IntegerValue &x) : IntegerValue(x) {
54 IntegerValue(
int kind, IntegerValue &&x) : IntegerValue(std::move(x)) {
65 template <
typename INT,
66 typename = std::enable_if_t<common::numeric_limits<INT>::is_integer>>
67 IntegerValue(
int kind, INT v) {
68 if constexpr (
sizeof(INT) > 8) {
69 static_assert(
sizeof(INT) == 16);
70 ConstructFromIntegral(
kind,
static_cast<common::uint128_t
>(v));
71 }
else if constexpr (std::is_signed_v<INT>) {
72 ConstructFromIntegral(
73 kind,
static_cast<uint64_t
>(
static_cast<int64_t
>(v)),
true);
75 ConstructFromIntegral(
kind,
static_cast<uint64_t
>(v),
false);
84 void print(llvm::raw_ostream &os)
const;
86#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
87 LLVM_DUMP_METHOD
void dump()
const;
97 int bits()
const {
return bits(
kind()); }
118 bool operator<(
const IntegerValue &y)
const {
119 return CompareSigned(y) == Ordering::Less;
121 bool operator<=(
const IntegerValue &y)
const {
122 return CompareSigned(y) != Ordering::Greater;
124 bool operator==(
const IntegerValue &y)
const {
125 return CompareSigned(y) == Ordering::Equal;
127 bool operator!=(
const IntegerValue &y)
const {
128 return CompareSigned(y) != Ordering::Equal;
130 bool operator>=(
const IntegerValue &y)
const {
131 return CompareSigned(y) != Ordering::Less;
133 bool operator>(
const IntegerValue &y)
const {
134 return CompareSigned(y) == Ordering::Greater;
138 static IntegerValue
MASKL(
int kind,
int places);
141 static IntegerValue
MASKR(
int kind,
int places);
144 int kind,
const char *&pp,
int base,
bool isSigned);
148 int toKind,
const IntegerValue &from);
153 std::string UnsignedDecimal()
const;
155 std::string SignedDecimal()
const;
160 static constexpr int DIGITS(
int kind) {
162 return bits(
kind) - 1;
165 static IntegerValue HUGE(
int kind);
167 static IntegerValue Least(
int kind);
169 static int RANGE(
int kind);
171 static int UnsignedRANGE(
int kind);
175 bool IsNegative()
const;
177 Ordering CompareToZeroSigned()
const;
191 bool BTEST(
int pos)
const;
193 Ordering CompareUnsigned(
const IntegerValue &y)
const;
195 Ordering CompareSigned(
const IntegerValue &y)
const;
197 bool BGE(
const IntegerValue &y)
const {
198 return CompareUnsigned(y) != Ordering::Less;
200 bool BGT(
const IntegerValue &y)
const {
201 return CompareUnsigned(y) == Ordering::Greater;
203 bool BLE(
const IntegerValue &y)
const {
return !BGT(y); }
204 bool BLT(
const IntegerValue &y)
const {
return !BGE(y); }
206 std::uint64_t ToUInt64()
const;
208 std::int64_t ToInt64()
const;
210 Fortran::common::uint128_t ToUInt128()
const;
212 Fortran::common::int128_t ToInt128()
const;
214 template <
typename INT,
215 typename = std::enable_if_t<std::is_signed_v<INT> ||
216 std::is_same_v<INT, Fortran::common::int128_t>>>
218 if constexpr (std::is_same_v<INT, Fortran::common::int128_t>) {
225 template <
typename INT,
226 typename = std::enable_if_t<std::is_unsigned_v<INT> ||
227 std::is_same_v<INT, Fortran::common::uint128_t>>>
229 if constexpr (std::is_same_v<INT, Fortran::common::uint128_t>) {
237 IntegerValue
NOT()
const;
248 IntegerValue
ISHFT(
int count)
const {
294 return CompareSigned(y) == Ordering::Less ? y : *
this;
297 IntegerValue MIN(
const IntegerValue &y)
const {
298 return CompareSigned(y) == Ordering::Less ? *this : y;
301 ValueWithCarry AddUnsigned(
const IntegerValue &y,
bool carryIn =
false)
const;
303 ValueWithOverflow AddSigned(
const IntegerValue &y)
const;
305 ValueWithOverflow SubtractSigned(
const IntegerValue &y)
const;
308 ValueWithOverflow
DIM(
const IntegerValue &y)
const;
310 ValueWithOverflow SIGN(
const IntegerValue &sign)
const;
312 Product MultiplyUnsigned(
const IntegerValue &y)
const;
314 Product MultiplySigned(
const IntegerValue &y)
const;
316 QuotientWithRemainder DivideUnsigned(
const IntegerValue &y)
const;
321 QuotientWithRemainder
DivideSigned(
const IntegerValue &y)
const;
325 ValueWithOverflow
MODULO(
const IntegerValue &y)
const;
327 PowerWithErrors Power(
const IntegerValue &e)
const;
329 static IntegerValue FromRawBytes(
330 int kind,
const void *raw, std::size_t expectedSize);
331 void StoreRawBytes(
void *dst,
size_t size,
bool *changed =
nullptr)
const;
334 void ConstructFromIntegral(
int kind, std::uint64_t n,
bool isSigned);
335 void ConstructFromIntegral(
int kind, Fortran::common::uint128_t n);
337 static IntegerValue FromImpl(
const IntegerValueImpl &x);
338 static IntegerValue FromImpl(IntegerValueImpl &&x);
340 IntegerValueImpl &impl() {
341 return *
reinterpret_cast<IntegerValueImpl *
>(
this);
343 const IntegerValueImpl &impl()
const {
344 return *
reinterpret_cast<const IntegerValueImpl *
>(
this);
347 [[maybe_unused]]
alignas(
348 detail::kIntegerObjectAlign)
char opaque_[detail::kIntegerObjectSize];
353 bool overflow{
false};
362 IntegerValue upper, lower;
363 bool SignedMultiplicationOverflowed()
const {
return overflow; }
364 bool overflow{
false};
368 IntegerValue quotient, remainder;
369 bool divisionByZero{
false}, overflow{
false};
374 bool divisionByZero{
false}, overflow{
false}, zeroToZero{
false};
381inline raw_ostream &operator<<(
Definition integer-value-impl.h:26
Definition integer-value.h:34
static IntegerValue Zero(int kind)
Definition integer-value.cpp:41
static ValueWithOverflow ConvertSigned(int toKind, const IntegerValue &from)
SExt or Trunc.
Definition integer-value.cpp:75
IntegerValue ISHFTC(int count, int size) const
Definition integer-value.cpp:156
IntegerValue SHIFTA(int count) const
Definition integer-value.cpp:176
QuotientWithRemainder DivideSigned(const IntegerValue &y) const
Definition integer-value.cpp:260
ValueWithOverflow DIM(const IntegerValue &y) const
DIM(X,Y)=MAX(X-Y, 0)
Definition integer-value.cpp:227
IntegerValue IBSET(int pos) const
Sets a single bit.
Definition integer-value.cpp:184
int LEADZ() const
Definition integer-value.cpp:107
ValueWithOverflow Negate() const
Definition integer-value.cpp:143
IntegerValue NOT() const
Ones'-complement (i.e., C's ~)
Definition integer-value.cpp:141
bool IsNull() const
Definition integer-value.cpp:45
std::string Hexadecimal() const
Omits a leading "0x".
Definition integer-value.cpp:89
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:164
IntegerValue IBCLR(int pos) const
Clears a single bit.
Definition integer-value.cpp:180
static ValueWithOverflow ConvertUnsigned(int toKind, const IntegerValue &from)
ZExt or Trunc.
Definition integer-value.cpp:69
IntegerValue SHIFTL(int count) const
Left shift with zero fill.
Definition integer-value.cpp:152
IntegerValue IBITS(int pos, int size) const
Extracts a field.
Definition integer-value.cpp:188
ValueWithOverflow MODULO(const IntegerValue &y) const
Definition integer-value.cpp:267
static IntegerValue MASKL(int kind, int places)
Left-justified mask (e.g., MASKL(1) has only its sign bit set)
Definition integer-value.cpp:55
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:168
IntegerValue SHIFTR(int count) const
Vacated upper bits are filled with zeroes.
Definition integer-value.cpp:172
static IntegerValue MASKR(int kind, int places)
Right-justified mask (e.g., MASKR(1) == 1, MASKR(2) == 3, &c.)
Definition integer-value.cpp:59
bool POPPAR() const
True when POPCNT is odd.
Definition integer-value.cpp:111
IntegerValue ISHFT(int count) const
Definition integer-value.h:248
int POPCNT() const
Count the number of bit positions that are set.
Definition integer-value.cpp:109
std::size_t bytesStored() const
Number of bytes accessed by FromRawBytes/StoreRawBytes.
Definition integer-value.h:101
int kind() const
The kind of the value currently stored.
Definition integer-value.cpp:47
Definition integer-value.h:372
Definition integer-value.h:361
Definition integer-value.h:367
Definition integer-value.h:356
Definition integer-value.h:351