26class IntegerValueImpl {
36 using I80 = X87IntegerContainer;
38 using Storage = std::variant<std::monostate, I8, I16, I32, I64, I80, I128>;
47 ~IntegerValueImpl() =
default;
48 IntegerValueImpl(
const IntegerValueImpl &) =
default;
49 IntegerValueImpl(IntegerValueImpl &&) =
default;
50 IntegerValueImpl &operator=(
const IntegerValueImpl &) =
default;
51 IntegerValueImpl &operator=(IntegerValueImpl &&) =
default;
53 IntegerValueImpl() =
default;
54 IntegerValueImpl(
int kind,
const IntegerValueImpl &x) : IntegerValueImpl(x) {
55 CHECK(x.kind() == kind);
58 static IntegerValueImpl Zero(
int kind);
60 IntegerValueImpl(
int kind, uint64_t v,
bool isSigned) {
61 WithWordProto(kind, [=](
auto wordProto) {
62 using T =
decltype(wordProto);
63 storage_ = isSigned ? T{
static_cast<int64_t
>(v)} : T{v};
67 IntegerValueImpl(
int kind, Fortran::common::uint128_t v) {
68 WithWordProto(kind, [=](
auto wordProto) {
69 using T =
decltype(wordProto);
70 std::uint64_t lo{
static_cast<std::uint64_t
>(v)};
71 std::uint64_t hi{
static_cast<std::uint64_t
>(v >> 64)};
72 storage_ = T{lo}.IOR(T{hi}.SHIFTL(64));
76 template <
typename T>
static IntegerValueImpl FromWord(
const T &n) {
82 static IntegerValueImpl FromRawBytes(
83 int kind,
const void *raw, std::size_t expectedSize);
85 void print(llvm::raw_ostream &os)
const;
87#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
88 LLVM_DUMP_METHOD
void dump()
const;
91 bool IsNull()
const {
return storage_.index() == 0; }
96 std::size_t bytesStored()
const {
return bytesStored(kind()); }
97 static constexpr std::size_t bytesStored(
int kind) {
111 static IntegerValueImpl
MASKL(
int kind,
int places);
113 static IntegerValueImpl
MASKR(
int kind,
int places);
114 static IntegerValueImpl HUGE(
int kind);
115 static IntegerValueImpl Least(
int kind);
117 bool IsNegative()
const;
119 std::uint64_t ToUInt64()
const;
120 std::int64_t ToInt64()
const;
122 Fortran::common::uint128_t ToUInt128()
const;
123 Fortran::common::int128_t ToInt128()
const;
126 Ordering CompareSigned(
const IntegerValueImpl &y)
const;
127 Ordering CompareUnsigned(
const IntegerValueImpl &y)
const;
128 Ordering CompareToZeroSigned()
const;
135 const IntegerValueImpl &y,
bool carryIn =
false)
const;
141 Product MultiplySigned(
const IntegerValueImpl &y)
const;
142 Product MultiplyUnsigned(
const IntegerValueImpl &y)
const;
149 IntegerValueImpl NOT()
const;
150 IntegerValueImpl IAND(
const IntegerValueImpl &y)
const;
151 IntegerValueImpl IOR(
const IntegerValueImpl &y)
const;
152 IntegerValueImpl IEOR(
const IntegerValueImpl &y)
const;
153 IntegerValueImpl MERGE_BITS(
154 const IntegerValueImpl &y,
const IntegerValueImpl &mask)
const;
155 IntegerValueImpl MAX(
const IntegerValueImpl &y)
const {
156 return CompareSigned(y) == Ordering::Less ? y : *
this;
158 IntegerValueImpl MIN(
const IntegerValueImpl &y)
const {
159 return CompareSigned(y) == Ordering::Less ? *this : y;
163 IntegerValueImpl ISHFT(
int count)
const {
164 return count < 0 ? SHIFTR(-count) : SHIFTL(count);
166 IntegerValueImpl SHIFTL(
int count)
const;
167 IntegerValueImpl SHIFTR(
int count)
const;
168 IntegerValueImpl SHIFTA(
int count)
const;
169 IntegerValueImpl ISHFTC(
int count,
int size)
const;
170 IntegerValueImpl ISHFTC(
int count)
const {
return ISHFTC(count, bits()); }
171 IntegerValueImpl IBITS(
int pos,
int size)
const;
172 IntegerValueImpl IBSET(
int pos)
const;
173 IntegerValueImpl IBCLR(
int pos)
const;
174 IntegerValueImpl DSHIFTL(
const IntegerValueImpl &fill,
int count)
const;
175 IntegerValueImpl DSHIFTR(
const IntegerValueImpl &v2,
int count)
const;
176 bool BTEST(
int pos)
const;
183 int toKind,
const IntegerValueImpl &from);
185 int toKind,
const IntegerValueImpl &from);
188 int kind,
const char *&pp,
int base,
bool isSigned);
191 std::string SignedDecimal()
const;
192 std::string UnsignedDecimal()
const;
193 std::string Hexadecimal()
const;
195 void StoreRawBytes(
void *dst,
size_t size,
bool *changed)
const;
201 template <
typename T>
const T &
GetWord()
const {
211 if (!std::holds_alternative<T>(storage_)) {
212 DIE(
"value does not store the requested kind");
215 return std::get<T>(storage_);
218 template <
typename F>
219 auto WithWordProto(F &&f)
const
220 ->
decltype(std::declval<F>()(std::declval<I64>())) {
221 return WithWordProto(kind(), std::forward<F>(f));
224 template <
typename F>
225 static auto WithWordProto(
int kind, F &&f)
226 ->
decltype(std::declval<F>()(std::declval<I64>())) {
242 DIE(
"unsupported integer width");
246 template <
typename F>
247 auto WithWord(F &&f)
const ->
decltype(f(std::declval<const I64 &>())) {
248 return common::visit(
250 [](std::monostate) ->
decltype(f(std::declval<const I64 &>())) {
251 DIE(
"operation on uninitialized IntegerValueImpl");
static IntegerValueImpl MASKL(int kind, int places)
Left-justified mask (e.g., MASKL(1) has only its sign bit set)
Definition integer-value-impl.cpp:70
static IntegerValueImpl MASKR(int kind, int places)
Right-justified mask (e.g., MASKR(1) == 1, MASKR(2) == 3, &c.)
Definition integer-value-impl.cpp:77
Definition integer-value-impl.h:278