CIRCT 20.0.0git
Loading...
Searching...
No Matches
FVInt.h
Go to the documentation of this file.
1//===- FVInt.h - Four-valued integer ----------------------------*- 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// This file implements a class to represent arbitrary precision integers where
10// each bit can be one of four values. This corresponds to SystemVerilog's
11// four-valued `logic` type (originally defined in IEEE 1364, later merged into
12// IEEE 1800).
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef CIRCT_SUPPORT_FVINT_H
17#define CIRCT_SUPPORT_FVINT_H
18
19#include "circt/Support/LLVM.h"
20#include "llvm/ADT/APInt.h"
21#include "llvm/ADT/SmallString.h"
22#include "llvm/ADT/StringRef.h"
23#include "llvm/Support/raw_ostream.h"
24
25namespace llvm {
26template <typename T, typename Enable>
28} // namespace llvm
29
30namespace circt {
31
32/// Four-valued arbitrary precision integers.
33///
34/// Each bit of the integer can be 0, 1, X, or Z. Internally the bits are stored
35/// in a pair of `APInt`s, one of which specifies the value of each bit (0/X or
36/// 1/Z), and the other whether the bit is unknown (X or Z).
37class FVInt {
38public:
39 /// Default constructor that creates an zero-bit zero value.
40 explicit FVInt() : FVInt(0, 0) {}
41
42 /// Construct an `FVInt` from a 64-bit value. The result has no X or Z bits.
43 FVInt(unsigned numBits, uint64_t value, bool isSigned = false)
44 : FVInt(APInt(numBits, value, isSigned)) {}
45
46 /// Construct an `FVInt` from an `APInt`. The result has no X or Z bits.
47 FVInt(const APInt &value)
48 : value(value), unknown(APInt::getZero(value.getBitWidth())) {}
49
50 /// Construct an `FVInt` from two `APInt`s used internally to store the bit
51 /// data. The first argument specifies whether each bit is 0/X or 1/Z. The
52 /// second argument specifies whether each bit is 0/1 or X/Z. Both `APInt`s
53 /// must have the same bitwidth. The two arguments correspond to the results
54 /// of `getRawValue()` and `getRawUnknown()`.
55 FVInt(APInt &&rawValue, APInt &&rawUnknown)
56 : value(rawValue), unknown(rawUnknown) {
57 assert(rawValue.getBitWidth() == rawUnknown.getBitWidth());
58 }
59
60 /// Construct an `FVInt` with all bits set to 0.
61 static FVInt getZero(unsigned numBits) {
62 return FVInt(APInt::getZero(numBits));
63 }
64
65 /// Construct an `FVInt` with all bits set to 1.
66 static FVInt getAllOnes(unsigned numBits) {
67 return FVInt(APInt::getAllOnes(numBits));
68 }
69
70 /// Construct an `FVInt` with all bits set to X.
71 static FVInt getAllX(unsigned numBits) {
72 return FVInt(APInt::getZero(numBits), APInt::getAllOnes(numBits));
73 }
74
75 /// Construct an `FVInt` with all bits set to Z.
76 static FVInt getAllZ(unsigned numBits) {
77 return FVInt(APInt::getAllOnes(numBits), APInt::getAllOnes(numBits));
78 }
79
80 /// Return the number of bits this integer has.
81 unsigned getBitWidth() const { return value.getBitWidth(); }
82
83 /// Compute the number of active bits in the value. This is the smallest bit
84 /// width to which the value can be truncated without losing information in
85 /// the most significant bits. Or put differently, the value truncated to its
86 /// active bits and zero-extended back to its original width produces the
87 /// original value.
88 unsigned getActiveBits() const {
89 return std::max(value.getActiveBits(), unknown.getActiveBits());
90 }
91
92 /// Compute the minimum bit width necessary to accurately represent this
93 /// integer's value and sign. This is the smallest bit width to which the
94 /// value can be truncated without losing information in the most significant
95 /// bits and without flipping from negative to positive or vice versa. Or put
96 /// differently, the value truncated to its significant bits and sign-extended
97 /// back to its original width produces the original value.
98 unsigned getSignificantBits() const {
99 return std::max(value.getSignificantBits(), unknown.getSignificantBits());
100 }
101
102 /// Return the underlying `APInt` used to store whether a bit is 0/X or 1/Z.
103 const APInt &getRawValue() const { return value; }
104
105 /// Return the underlying `APInt` used to store whether a bit is unknown (X or
106 /// Z).
107 const APInt &getRawUnknown() const { return unknown; }
108
109 /// Convert the four-valued `FVInt` to a two-valued `APInt` by mapping X and Z
110 /// bits to either 0 or 1.
111 APInt toAPInt(bool unknownBitMapping) const {
112 auto v = value;
113 if (unknownBitMapping)
114 v |= unknown; // set unknown bits to 1
115 else
116 v &= ~unknown; // set unknown bits to 0
117 return v;
118 }
119
120 //===--------------------------------------------------------------------===//
121 // Resizing
122 //===--------------------------------------------------------------------===//
123
124 /// Truncate the integer to a smaller bit width. This simply discards the
125 /// high-order bits. If the integer is truncated to a bit width less than its
126 /// "active bits", information will be lost and the resulting integer will
127 /// have a different value.
128 FVInt trunc(unsigned bitWidth) const {
129 assert(bitWidth <= getBitWidth());
130 return FVInt(value.trunc(bitWidth), unknown.trunc(bitWidth));
131 }
132
133 /// Zero-extend the integer to a new bit width. The additional high-order bits
134 /// are filled in with zero.
135 FVInt zext(unsigned bitWidth) const {
136 assert(bitWidth >= getBitWidth());
137 return FVInt(value.zext(bitWidth), unknown.zext(bitWidth));
138 }
139
140 /// Sign-extend the integer to a new bit width. The additional high-order bits
141 /// are filled in with the sign bit (top-most bit) of the original number,
142 /// also when that sign bit is X or Z. Zero-width integers are extended with
143 /// zeros.
144 FVInt sext(unsigned bitWidth) const {
145 assert(bitWidth >= getBitWidth());
146 return FVInt(value.sext(bitWidth), unknown.sext(bitWidth));
147 }
148
149 /// Truncate or zero-extend to a target bit width.
150 FVInt zextOrTrunc(unsigned bitWidth) const {
151 return bitWidth > getBitWidth() ? zext(bitWidth) : trunc(bitWidth);
152 }
153
154 /// Truncate or sign-extend to a target bit width.
155 FVInt sextOrTrunc(unsigned bitWidth) const {
156 return bitWidth > getBitWidth() ? sext(bitWidth) : trunc(bitWidth);
157 }
158
159 //===--------------------------------------------------------------------===//
160 // Value Tests
161 //===--------------------------------------------------------------------===//
162
163 /// Determine if any bits are X or Z.
164 bool hasUnknown() const { return !unknown.isZero(); }
165
166 /// Determine if all bits are 0. This is true for zero-width values.
167 bool isZero() const { return value.isZero() && unknown.isZero(); }
168
169 /// Determine if all bits are 1. This is true for zero-width values.
170 bool isAllOnes() const { return value.isAllOnes() && unknown.isZero(); }
171
172 /// Determine if all bits are X. This is true for zero-width values.
173 bool isAllX() const { return value.isZero() && unknown.isAllOnes(); }
174
175 /// Determine if all bits are Z. This is true for zero-width values.
176 bool isAllZ() const { return value.isAllOnes() && unknown.isAllOnes(); }
177
178 /// Determine whether the integer interpreted as a signed number would be
179 /// negative. Returns true if the sign bit is 1, and false if it is 0, X, or
180 /// Z.
181 bool isNegative() const {
182 auto idx = getBitWidth() - 1;
183 return value[idx] && !unknown[idx];
184 }
185
186 //===--------------------------------------------------------------------===//
187 // Bit Manipulation
188 //===--------------------------------------------------------------------===//
189
190 /// The value of an individual bit. Can be 0, 1, X, or Z.
191 enum Bit { V0 = 0b00, V1 = 0b01, X = 0b10, Z = 0b11 };
192
193 /// Get the value of an individual bit.
194 Bit getBit(unsigned index) const {
195 return static_cast<Bit>(value[index] | unknown[index] << 1);
196 }
197
198 /// Set the value of an individual bit.
199 void setBit(unsigned index, Bit bit) {
200 value.setBitVal(index, (bit >> 0) & 1);
201 unknown.setBitVal(index, (bit >> 1) & 1);
202 }
203
204 void setBit(unsigned index, bool val) {
205 setBit(index, static_cast<Bit>(val));
206 }
207
208 /// Compute a mask of all the 0 bits in this integer.
209 APInt getZeroBits() const { return ~value & ~unknown; }
210
211 /// Compute a mask of all the 1 bits in this integer.
212 APInt getOneBits() const { return value & ~unknown; }
213
214 /// Compute a mask of all the X bits in this integer.
215 APInt getXBits() const { return ~value & unknown; }
216
217 /// Compute a mask of all the Z bits in this integer.
218 APInt getZBits() const { return value & unknown; }
219
220 /// Compute a mask of all the X and Z bits in this integer.
221 APInt getUnknownBits() const { return unknown; }
222
223 /// Set the value of all bits in the mask to 0.
224 template <typename T>
225 void setZeroBits(const T &mask) {
226 value &= ~mask;
227 unknown &= ~mask;
228 }
229
230 /// Set the value of all bits in the mask to 1.
231 template <typename T>
232 void setOneBits(const T &mask) {
233 value |= mask;
234 unknown &= ~mask;
235 }
236
237 /// Set the value of all bits in the mask to X.
238 template <typename T>
239 void setXBits(const T &mask) {
240 value &= ~mask;
241 unknown |= mask;
242 }
243
244 /// Set the value of all bits in the mask to Z.
245 template <typename T>
246 void setZBits(const T &mask) {
247 value |= mask;
248 unknown |= mask;
249 }
250
251 /// Set all bits to 0.
252 void setAllZero() {
253 value.clearAllBits();
254 unknown.clearAllBits();
255 }
256
257 /// Set all bits to 1.
258 void setAllOne() {
259 value.setAllBits();
260 unknown.clearAllBits();
261 }
262
263 /// Set all bits to X.
264 void setAllX() {
265 value.clearAllBits();
266 unknown.setAllBits();
267 }
268
269 /// Set all bits to Z.
270 void setAllZ() {
271 value.setAllBits();
272 unknown.setAllBits();
273 }
274
275 /// Replace all Z bits with X. This is useful since most logic operations will
276 /// treat X and Z bits the same way and produce an X bit in the output. By
277 /// mapping Z bits to X, these operations can then just handle 0, 1, and X
278 /// bits.
280 // Z bits have value and unknown set to 1. X bits have value set to 0 and
281 // unknown set to 1. To convert between the two, make sure that value is 0
282 // wherever unknown is 1.
283 value &= ~unknown;
284 }
285
286 /// If any bits are X or Z, set the entire integer to X.
288 if (hasUnknown())
289 setAllX();
290 }
291
292 /// If any bits in this integer or another integer are X or Z, set the entire
293 /// integer to X. This is useful for binary operators which want to set their
294 /// result to X if either of the two inputs contained an X or Z bit.
295 void setAllXIfAnyUnknown(const FVInt &other) {
296 if (hasUnknown() || other.hasUnknown())
297 setAllX();
298 }
299
300 //===--------------------------------------------------------------------===//
301 // Shift Operators
302 //===--------------------------------------------------------------------===//
303
304 /// Perform a logical left-shift. If any bits in the shift amount are unknown,
305 /// the entire result is X.
306 FVInt &operator<<=(const FVInt &amount) {
307 if (amount.hasUnknown()) {
308 setAllX();
309 } else {
310 value <<= amount.value;
311 unknown <<= amount.value;
312 }
313 return *this;
314 }
315
316 /// Perform a logical left-shift by a two-valued amount.
317 template <typename T>
318 FVInt &operator<<=(const T &amount) {
319 value <<= amount;
320 unknown <<= amount;
321 return *this;
322 }
323
324 //===--------------------------------------------------------------------===//
325 // Logic Operators
326 //===--------------------------------------------------------------------===//
327
328 /// Compute the logical NOT of this integer. This implements the following
329 /// bit-wise truth table:
330 /// ```
331 /// 0 | 1
332 /// 1 | 0
333 /// X | X
334 /// Z | X
335 /// ```
336 void flipAllBits() {
337 value = ~value;
339 }
340
341 /// Compute the logical NOT.
342 FVInt operator~() const {
343 auto v = *this;
344 v.flipAllBits();
345 return v;
346 }
347
348 /// Compute the logical AND of this integer and another. This implements the
349 /// following bit-wise truth table:
350 /// ```
351 /// 0 1 X Z
352 /// +--------
353 /// 0 | 0 0 0 0
354 /// 1 | 0 1 X X
355 /// X | 0 X X X
356 /// Z | 0 X X X
357 /// ```
358 FVInt &operator&=(const FVInt &other) {
359 auto zeros = getZeroBits() | other.getZeroBits();
360 value &= other.value;
361 unknown |= other.unknown;
362 unknown &= ~zeros;
364 return *this;
365 }
366
367 /// Compute the logical AND of this integer and a two-valued integer.
368 template <typename T>
369 FVInt &operator&=(T other) {
370 value &= other;
371 unknown &= other; // make 0 bits known
373 return *this;
374 }
375
376 /// Compute the logical AND.
377 template <typename T>
378 FVInt operator&(const T &other) const {
379 auto v = *this;
380 v &= other;
381 return v;
382 }
383
384 /// Compute the logical OR of this integer and another. This implements the
385 /// following bit-wise truth table:
386 /// ```
387 /// 0 1 X Z
388 /// +--------
389 /// 0 | 0 1 X X
390 /// 1 | 1 1 1 1
391 /// X | X 1 X X
392 /// Z | X 1 X X
393 /// ```
394 FVInt &operator|=(const FVInt &other) {
395 auto ones = getOneBits() | other.getOneBits();
396 value |= other.value;
397 unknown |= other.unknown;
398 unknown &= ~ones;
400 return *this;
401 }
402
403 /// Compute the logical OR of this integer and a two-valued integer.
404 template <typename T>
405 FVInt &operator|=(T other) {
406 value |= other;
407 unknown &= ~other; // make 1 bits known
409 return *this;
410 }
411
412 /// Compute the logical OR.
413 template <typename T>
414 FVInt operator|(const T &other) const {
415 auto v = *this;
416 v |= other;
417 return v;
418 }
419
420 /// Compute the logical XOR of this integer and another. This implements the
421 /// following bit-wise truth table:
422 /// ```
423 /// 0 1 X Z
424 /// +--------
425 /// 0 | 0 1 X X
426 /// 1 | 1 0 X X
427 /// X | X X X X
428 /// Z | X X X X
429 /// ```
430 FVInt &operator^=(const FVInt &other) {
431 value ^= other.value;
432 unknown |= other.unknown;
434 return *this;
435 }
436
437 /// Compute the logical XOR of this integer and a two-valued integer.
438 template <typename T>
439 FVInt &operator^=(const T &other) {
440 value ^= other;
442 return *this;
443 }
444
445 /// Compute the logical XOR.
446 template <typename T>
447 FVInt operator^(const T &other) const {
448 auto v = *this;
449 v ^= other;
450 return v;
451 }
452
453 //===--------------------------------------------------------------------===//
454 // Arithmetic Operators
455 //===--------------------------------------------------------------------===//
456
457 /// Compute the negation of this integer. If any bits are unknown, the entire
458 /// result is X.
459 void negate() {
460 value.negate();
462 }
463
464 /// Compute the negation of this integer.
465 FVInt operator-() const {
466 auto v = *this;
467 v.negate();
468 return v;
469 }
470
471 /// Compute the addition of this integer and another. If any bits in either
472 /// integer are unknown, the entire result is X.
473 FVInt &operator+=(const FVInt &other) {
474 value += other.value;
475 setAllXIfAnyUnknown(other);
476 return *this;
477 }
478
479 /// Compute the addition of this integer and a two-valued integer. If any bit
480 /// in the integer is unknown, the entire result is X.
481 template <typename T>
482 FVInt &operator+=(const T &other) {
483 value += other;
485 return *this;
486 }
487
488 /// Compute an addition.
489 template <typename T>
490 FVInt operator+(const T &other) const {
491 auto v = *this;
492 v += other;
493 return v;
494 }
495
496 /// Compute the subtraction of this integer and another. If any bits in either
497 /// integer are unknown, the entire result is X.
498 FVInt &operator-=(const FVInt &other) {
499 value -= other.value;
500 setAllXIfAnyUnknown(other);
501 return *this;
502 }
503
504 /// Compute the subtraction of this integer and a two-valued integer. If any
505 /// bit in the integer is unknown, the entire result is X.
506 template <typename T>
507 FVInt &operator-=(const T &other) {
508 value -= other;
510 return *this;
511 }
512
513 /// Compute an subtraction.
514 template <typename T>
515 FVInt operator-(const T &other) const {
516 auto v = *this;
517 v -= other;
518 return v;
519 }
520
521 /// Compute the multiplication of this integer and another. If any bits in
522 /// either integer are unknown, the entire result is X.
523 FVInt &operator*=(const FVInt &other) {
524 value *= other.value;
525 setAllXIfAnyUnknown(other);
526 return *this;
527 }
528
529 /// Compute the multiplication of this integer and a two-valued integer. If
530 /// any bit in the integer is unknown, the entire result is X.
531 template <typename T>
532 FVInt &operator*=(const T &other) {
533 value *= other;
535 return *this;
536 }
537
538 /// Compute a multiplication.
539 template <typename T>
540 FVInt operator*(const T &other) const {
541 auto v = *this;
542 v *= other;
543 return v;
544 }
545
546 //===--------------------------------------------------------------------===//
547 // Comparison
548 //===--------------------------------------------------------------------===//
549
550 /// Determine whether this integer is equal to another. Note that this
551 /// corresponds to SystemVerilog's `===` operator. Returns false if the two
552 /// integers have different bit width.
553 bool operator==(const FVInt &other) const {
554 if (getBitWidth() != other.getBitWidth())
555 return false;
556 return value == other.value && unknown == other.unknown;
557 }
558
559 /// Determine whether this integer is equal to a two-valued integer. Note that
560 /// this corresponds to SystemVerilog's `===` operator.
561 template <typename T>
562 bool operator==(const T &other) const {
563 return value == other && !hasUnknown();
564 }
565
566 /// Determine whether this integer is not equal to another. Returns true if
567 /// the two integers have different bit width.
568 bool operator!=(const FVInt &other) const { return !((*this) == other); }
569
570 /// Determine whether this integer is not equal to a two-valued integer.
571 template <typename T>
572 bool operator!=(const T &other) const {
573 return !((*this) == other);
574 }
575
576 //===--------------------------------------------------------------------===//
577 // String Conversion
578 //===--------------------------------------------------------------------===//
579
580 /// Convert a string into an `FVInt`.
581 ///
582 /// The radix can be 2, 8, 10, or 16. For radix 2, the input string may
583 /// contain the characters `x` or `X` to indicate an unknown X bit, and `z` or
584 /// `Z` to indicate an unknown Z bit. For radix 8, each X or Z counts as 3
585 /// bits. For radix 16, each X and Z counts as 4 bits. When radix is 10 the
586 /// input cannot contain any X or Z.
587 ///
588 /// Returns the parsed integer if the string is non-empty and a well-formed
589 /// number, otherwise returns none.
590 static std::optional<FVInt> tryFromString(StringRef str, unsigned radix = 10);
591
592 /// Convert a string into an `FVInt`. Same as `tryFromString`, but aborts if
593 /// the string is malformed.
594 static FVInt fromString(StringRef str, unsigned radix = 10) {
595 auto v = tryFromString(str, radix);
596 assert(v.has_value() && "string is not a well-formed FVInt");
597 return *v;
598 }
599
600 /// Convert an `FVInt` to a string.
601 ///
602 /// The radix can be 2, 8, 10, or 16. For radix 8 or 16, the integer can only
603 /// contain unknown bits in groups of 3 or 4, respectively, such that a `X` or
604 /// `Z` can be printed for the entire group of bits. For radix 10, the integer
605 /// cannot contain any unknown bits. In case the output contains letters,
606 /// `uppercase` specifies whether they are printed as uppercase letters.
607 ///
608 /// Appends the output characters to `str` and returns true if the integer
609 /// could be printed with the given configuration. Otherwise returns false and
610 /// leaves `str` in its original state. Always succeeds for radix 2.
611 bool tryToString(SmallVectorImpl<char> &str, unsigned radix = 10,
612 bool uppercase = true) const;
613
614 /// Convert an `FVInt` to a string. Same as `tryToString`, but directly
615 /// returns the string and aborts if the conversion is unsuccessful.
616 SmallString<16> toString(unsigned radix = 10, bool uppercase = true) const {
617 SmallString<16> str;
618 bool success = tryToString(str, radix, uppercase);
619 (void)success;
620 assert(success && "radix cannot represent FVInt");
621 return str;
622 }
623
624 /// Print an `FVInt` to an output stream.
625 void print(raw_ostream &os) const;
626
627private:
628 APInt value;
629 APInt unknown;
630};
631
632inline FVInt operator&(uint64_t a, const FVInt &b) { return b & a; }
633inline FVInt operator|(uint64_t a, const FVInt &b) { return b | a; }
634inline FVInt operator^(uint64_t a, const FVInt &b) { return b ^ a; }
635inline FVInt operator+(uint64_t a, const FVInt &b) { return b + a; }
636inline FVInt operator*(uint64_t a, const FVInt &b) { return b * a; }
637
638inline FVInt operator&(const APInt &a, const FVInt &b) { return b & a; }
639inline FVInt operator|(const APInt &a, const FVInt &b) { return b | a; }
640inline FVInt operator^(const APInt &a, const FVInt &b) { return b ^ a; }
641inline FVInt operator+(const APInt &a, const FVInt &b) { return b + a; }
642inline FVInt operator*(const APInt &a, const FVInt &b) { return b * a; }
643
644inline FVInt operator-(uint64_t a, const FVInt &b) {
645 return FVInt(b.getBitWidth(), a) - b;
646}
647
648inline FVInt operator-(const APInt &a, const FVInt &b) { return FVInt(a) - b; }
649
650inline bool operator==(uint64_t a, const FVInt &b) { return b == a; }
651inline bool operator!=(uint64_t a, const FVInt &b) { return b != a; }
652
653inline raw_ostream &operator<<(raw_ostream &os, const FVInt &value) {
654 value.print(os);
655 return os;
656}
657
658llvm::hash_code hash_value(const FVInt &a);
659
660/// Print a four-valued integer usign an `AsmPrinter`. This produces the
661/// following output formats:
662///
663/// - Decimal notation if the integer has no unknown bits. The sign bit is used
664/// to determine whether the value is printed as negative number or not.
665/// - Hexadecimal notation with a leading `h` if the integer the bits in each
666/// hex digit are either all known, all X, or all Z.
667/// - Binary notation with a leading `b` in all other cases.
668void printFVInt(AsmPrinter &p, const FVInt &value);
669
670/// Parse a four-valued integer using an `AsmParser`. This accepts the following
671/// formats:
672///
673/// - `42`/`-42`: positive or negative integer in decimal notation. The sign bit
674/// of the result indicates whether the value was negative. Cannot contain
675/// unknown X or Z digits.
676/// - `h123456789ABCDEF0XZ`: signless integer in hexadecimal notation. Can
677/// contain unknown X or Z digits.
678/// - `b10XZ`: signless integer in binary notation. Can contain unknown X or Z
679/// digits.
680///
681/// The result has enough bits to fully represent the parsed integer, and to
682/// have the sign bit encode whether the integer was written as a negative
683/// number in the input. The result's bit width may be larger than the minimum
684/// number of bits required to represent its value.
685ParseResult parseFVInt(AsmParser &p, FVInt &result);
686
687} // namespace circt
688
689namespace llvm {
690/// Provide DenseMapInfo for FVInt.
691template <>
692struct DenseMapInfo<circt::FVInt, void> {
696
700
701 static unsigned getHashValue(const circt::FVInt &Key);
702
703 static bool isEqual(const circt::FVInt &LHS, const circt::FVInt &RHS) {
704 return LHS == RHS;
705 }
706};
707} // namespace llvm
708
709#endif // CIRCT_SUPPORT_FVINT_H
assert(baseType &&"element must be base type")
Four-valued arbitrary precision integers.
Definition FVInt.h:37
void setAllXIfAnyUnknown()
If any bits are X or Z, set the entire integer to X.
Definition FVInt.h:287
void setAllOne()
Set all bits to 1.
Definition FVInt.h:258
FVInt & operator*=(const T &other)
Compute the multiplication of this integer and a two-valued integer.
Definition FVInt.h:532
FVInt(APInt &&rawValue, APInt &&rawUnknown)
Construct an FVInt from two APInts used internally to store the bit data.
Definition FVInt.h:55
static FVInt getZero(unsigned numBits)
Construct an FVInt with all bits set to 0.
Definition FVInt.h:61
FVInt & operator|=(T other)
Compute the logical OR of this integer and a two-valued integer.
Definition FVInt.h:405
FVInt & operator&=(T other)
Compute the logical AND of this integer and a two-valued integer.
Definition FVInt.h:369
void setBit(unsigned index, bool val)
Definition FVInt.h:204
FVInt & operator*=(const FVInt &other)
Compute the multiplication of this integer and another.
Definition FVInt.h:523
FVInt operator&(const T &other) const
Compute the logical AND.
Definition FVInt.h:378
void negate()
Compute the negation of this integer.
Definition FVInt.h:459
Bit
The value of an individual bit. Can be 0, 1, X, or Z.
Definition FVInt.h:191
void setAllZ()
Set all bits to Z.
Definition FVInt.h:270
FVInt & operator+=(const FVInt &other)
Compute the addition of this integer and another.
Definition FVInt.h:473
FVInt(const APInt &value)
Construct an FVInt from an APInt. The result has no X or Z bits.
Definition FVInt.h:47
SmallString< 16 > toString(unsigned radix=10, bool uppercase=true) const
Convert an FVInt to a string.
Definition FVInt.h:616
APInt value
Definition FVInt.h:628
bool operator==(const T &other) const
Determine whether this integer is equal to a two-valued integer.
Definition FVInt.h:562
APInt getOneBits() const
Compute a mask of all the 1 bits in this integer.
Definition FVInt.h:212
Bit getBit(unsigned index) const
Get the value of an individual bit.
Definition FVInt.h:194
FVInt & operator^=(const T &other)
Compute the logical XOR of this integer and a two-valued integer.
Definition FVInt.h:439
FVInt()
Default constructor that creates an zero-bit zero value.
Definition FVInt.h:40
FVInt & operator<<=(const T &amount)
Perform a logical left-shift by a two-valued amount.
Definition FVInt.h:318
APInt getXBits() const
Compute a mask of all the X bits in this integer.
Definition FVInt.h:215
FVInt & operator-=(const FVInt &other)
Compute the subtraction of this integer and another.
Definition FVInt.h:498
static FVInt getAllZ(unsigned numBits)
Construct an FVInt with all bits set to Z.
Definition FVInt.h:76
FVInt sextOrTrunc(unsigned bitWidth) const
Truncate or sign-extend to a target bit width.
Definition FVInt.h:155
void setAllXIfAnyUnknown(const FVInt &other)
If any bits in this integer or another integer are X or Z, set the entire integer to X.
Definition FVInt.h:295
bool operator==(const FVInt &other) const
Determine whether this integer is equal to another.
Definition FVInt.h:553
void setAllZero()
Set all bits to 0.
Definition FVInt.h:252
FVInt zextOrTrunc(unsigned bitWidth) const
Truncate or zero-extend to a target bit width.
Definition FVInt.h:150
FVInt & operator^=(const FVInt &other)
Compute the logical XOR of this integer and another.
Definition FVInt.h:430
APInt getZeroBits() const
Compute a mask of all the 0 bits in this integer.
Definition FVInt.h:209
FVInt operator|(const T &other) const
Compute the logical OR.
Definition FVInt.h:414
bool isNegative() const
Determine whether the integer interpreted as a signed number would be negative.
Definition FVInt.h:181
FVInt operator*(const T &other) const
Compute a multiplication.
Definition FVInt.h:540
FVInt operator-() const
Compute the negation of this integer.
Definition FVInt.h:465
FVInt operator^(const T &other) const
Compute the logical XOR.
Definition FVInt.h:447
void setZeroBits(const T &mask)
Set the value of all bits in the mask to 0.
Definition FVInt.h:225
bool isAllZ() const
Determine if all bits are Z. This is true for zero-width values.
Definition FVInt.h:176
void setAllX()
Set all bits to X.
Definition FVInt.h:264
void replaceZWithX()
Replace all Z bits with X.
Definition FVInt.h:279
void setOneBits(const T &mask)
Set the value of all bits in the mask to 1.
Definition FVInt.h:232
APInt unknown
Definition FVInt.h:629
static std::optional< FVInt > tryFromString(StringRef str, unsigned radix=10)
Convert a string into an FVInt.
Definition FVInt.cpp:17
FVInt & operator|=(const FVInt &other)
Compute the logical OR of this integer and another.
Definition FVInt.h:394
const APInt & getRawValue() const
Return the underlying APInt used to store whether a bit is 0/X or 1/Z.
Definition FVInt.h:103
bool isAllX() const
Determine if all bits are X. This is true for zero-width values.
Definition FVInt.h:173
FVInt operator-(const T &other) const
Compute an subtraction.
Definition FVInt.h:515
APInt getZBits() const
Compute a mask of all the Z bits in this integer.
Definition FVInt.h:218
static FVInt fromString(StringRef str, unsigned radix=10)
Convert a string into an FVInt.
Definition FVInt.h:594
FVInt & operator<<=(const FVInt &amount)
Perform a logical left-shift.
Definition FVInt.h:306
static FVInt getAllOnes(unsigned numBits)
Construct an FVInt with all bits set to 1.
Definition FVInt.h:66
FVInt operator+(const T &other) const
Compute an addition.
Definition FVInt.h:490
const APInt & getRawUnknown() const
Return the underlying APInt used to store whether a bit is unknown (X or Z).
Definition FVInt.h:107
bool operator!=(const T &other) const
Determine whether this integer is not equal to a two-valued integer.
Definition FVInt.h:572
FVInt & operator&=(const FVInt &other)
Compute the logical AND of this integer and another.
Definition FVInt.h:358
FVInt sext(unsigned bitWidth) const
Sign-extend the integer to a new bit width.
Definition FVInt.h:144
unsigned getSignificantBits() const
Compute the minimum bit width necessary to accurately represent this integer's value and sign.
Definition FVInt.h:98
void flipAllBits()
Compute the logical NOT of this integer.
Definition FVInt.h:336
void setXBits(const T &mask)
Set the value of all bits in the mask to X.
Definition FVInt.h:239
static FVInt getAllX(unsigned numBits)
Construct an FVInt with all bits set to X.
Definition FVInt.h:71
void print(raw_ostream &os) const
Print an FVInt to an output stream.
Definition FVInt.cpp:135
void setBit(unsigned index, Bit bit)
Set the value of an individual bit.
Definition FVInt.h:199
bool hasUnknown() const
Determine if any bits are X or Z.
Definition FVInt.h:164
APInt toAPInt(bool unknownBitMapping) const
Convert the four-valued FVInt to a two-valued APInt by mapping X and Z bits to either 0 or 1.
Definition FVInt.h:111
unsigned getActiveBits() const
Compute the number of active bits in the value.
Definition FVInt.h:88
bool isAllOnes() const
Determine if all bits are 1. This is true for zero-width values.
Definition FVInt.h:170
FVInt operator~() const
Compute the logical NOT.
Definition FVInt.h:342
FVInt zext(unsigned bitWidth) const
Zero-extend the integer to a new bit width.
Definition FVInt.h:135
APInt getUnknownBits() const
Compute a mask of all the X and Z bits in this integer.
Definition FVInt.h:221
unsigned getBitWidth() const
Return the number of bits this integer has.
Definition FVInt.h:81
FVInt & operator+=(const T &other)
Compute the addition of this integer and a two-valued integer.
Definition FVInt.h:482
bool isZero() const
Determine if all bits are 0. This is true for zero-width values.
Definition FVInt.h:167
FVInt(unsigned numBits, uint64_t value, bool isSigned=false)
Construct an FVInt from a 64-bit value. The result has no X or Z bits.
Definition FVInt.h:43
FVInt & operator-=(const T &other)
Compute the subtraction of this integer and a two-valued integer.
Definition FVInt.h:507
void setZBits(const T &mask)
Set the value of all bits in the mask to Z.
Definition FVInt.h:246
bool tryToString(SmallVectorImpl< char > &str, unsigned radix=10, bool uppercase=true) const
Convert an FVInt to a string.
Definition FVInt.cpp:68
bool operator!=(const FVInt &other) const
Determine whether this integer is not equal to another.
Definition FVInt.h:568
FVInt trunc(unsigned bitWidth) const
Truncate the integer to a smaller bit width.
Definition FVInt.h:128
OS & operator<<(OS &os, const InnerSymTarget &target)
Printing InnerSymTarget's.
static bool operator==(const ModulePort &a, const ModulePort &b)
Definition HWTypes.h:35
static llvm::hash_code hash_value(const ModulePort &port)
Definition HWTypes.h:38
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
FVInt operator^(uint64_t a, const FVInt &b)
Definition FVInt.h:634
FVInt operator|(uint64_t a, const FVInt &b)
Definition FVInt.h:633
FVInt operator*(uint64_t a, const FVInt &b)
Definition FVInt.h:636
void printFVInt(AsmPrinter &p, const FVInt &value)
Print a four-valued integer usign an AsmPrinter.
Definition FVInt.cpp:147
ParseResult parseFVInt(AsmParser &p, FVInt &result)
Parse a four-valued integer using an AsmParser.
Definition FVInt.cpp:162
FVInt operator&(uint64_t a, const FVInt &b)
Definition FVInt.h:632
FVInt operator-(uint64_t a, const FVInt &b)
Definition FVInt.h:644
bool operator!=(uint64_t a, const FVInt &b)
Definition FVInt.h:651
FVInt operator+(uint64_t a, const FVInt &b)
Definition FVInt.h:635
static circt::FVInt getEmptyKey()
Definition FVInt.h:693
static unsigned getHashValue(const circt::FVInt &Key)
static bool isEqual(const circt::FVInt &LHS, const circt::FVInt &RHS)
Definition FVInt.h:703
static circt::FVInt getTombstoneKey()
Definition FVInt.h:697