Skip to content

Commit abc9cf7

Browse files
committed
Use KnownBits for encodings as well
1 parent 72b4e1e commit abc9cf7

File tree

1 file changed

+49
-113
lines changed

1 file changed

+49
-113
lines changed

llvm/utils/TableGen/DecoderEmitter.cpp

Lines changed: 49 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -329,60 +329,8 @@ class DecoderEmitter {
329329
StringRef PredicateNamespace;
330330
};
331331

332-
// The set (BIT_TRUE, BIT_FALSE, BIT_UNSET) represents a ternary logic system
333-
// for a bit value.
334-
struct BitValue {
335-
enum bit_value_t : uint8_t {
336-
BIT_FALSE, // '0'
337-
BIT_TRUE, // '1'
338-
BIT_UNSET, // '?', printed as '_'
339-
};
340-
341-
BitValue(bit_value_t V) : V(V) {}
342-
explicit BitValue(const Init *Init) {
343-
if (const auto *Bit = dyn_cast<BitInit>(Init))
344-
V = Bit->getValue() ? BIT_TRUE : BIT_FALSE;
345-
else
346-
V = BIT_UNSET;
347-
}
348-
BitValue(const BitsInit &Bits, unsigned Idx) : BitValue(Bits.getBit(Idx)) {}
349-
350-
bool isSet() const { return V == BIT_TRUE || V == BIT_FALSE; }
351-
bool isUnset() const { return V == BIT_UNSET; }
352-
std::optional<uint64_t> getValue() const {
353-
if (isSet())
354-
return static_cast<uint64_t>(V);
355-
return std::nullopt;
356-
}
357-
358-
// For printing a bit value.
359-
operator StringRef() const {
360-
switch (V) {
361-
case BIT_FALSE:
362-
return "0";
363-
case BIT_TRUE:
364-
return "1";
365-
case BIT_UNSET:
366-
return "_";
367-
}
368-
llvm_unreachable("Unknow bit value");
369-
}
370-
371-
bool operator==(bit_value_t Other) const { return Other == V; }
372-
bool operator!=(bit_value_t Other) const { return Other != V; }
373-
374-
private:
375-
bit_value_t V;
376-
};
377-
378332
} // end anonymous namespace
379333

380-
// Prints the bit value for each position.
381-
static void dumpBits(raw_ostream &OS, const BitsInit &Bits, unsigned BitWidth) {
382-
for (const Init *Bit : reverse(Bits.getBits().take_front(BitWidth)))
383-
OS << BitValue(Bit);
384-
}
385-
386334
static const BitsInit &getBitsField(const Record &Def, StringRef FieldName) {
387335
const RecordVal *RV = Def.getValue(FieldName);
388336
if (const BitsInit *Bits = dyn_cast<BitsInit>(RV->getValue()))
@@ -404,27 +352,6 @@ static const BitsInit &getBitsField(const Record &Def, StringRef FieldName) {
404352
return *BitsInit::get(Def.getRecords(), Bits);
405353
}
406354

407-
// Representation of the instruction to work on.
408-
typedef std::vector<BitValue> insn_t;
409-
410-
/// Extracts a NumBits long field from Insn, starting from StartBit.
411-
/// Returns the value of the field if all bits are well-known,
412-
/// otherwise std::nullopt.
413-
static std::optional<uint64_t>
414-
fieldFromInsn(const insn_t &Insn, unsigned StartBit, unsigned NumBits) {
415-
uint64_t Field = 0;
416-
417-
for (unsigned BitIndex = 0; BitIndex < NumBits; ++BitIndex) {
418-
if (Insn[StartBit + BitIndex] == BitValue::BIT_UNSET)
419-
return std::nullopt;
420-
421-
if (Insn[StartBit + BitIndex] == BitValue::BIT_TRUE)
422-
Field = Field | (1ULL << BitIndex);
423-
}
424-
425-
return Field;
426-
}
427-
428355
namespace {
429356

430357
class FilterChooser;
@@ -606,11 +533,10 @@ class FilterChooser {
606533
unsigned getBitWidth() const { return BitWidth; }
607534

608535
protected:
609-
// Populates the insn given the uid.
610-
insn_t insnWithID(unsigned EncodingID) const {
536+
KnownBits getMandatoryEncodingBits(unsigned EncodingID) const {
611537
const Record *EncodingDef = Encodings[EncodingID].getRecord();
612538
const BitsInit &Bits = getBitsField(*EncodingDef, "Inst");
613-
insn_t Insn(std::max(BitWidth, Bits.getNumBits()), BitValue::BIT_UNSET);
539+
KnownBits Insn(std::max(BitWidth, Bits.getNumBits()));
614540
// We may have a SoftFail bitmask, which specifies a mask where an encoding
615541
// may differ from the value in "Inst" and yet still be valid, but the
616542
// disassembler should return SoftFail instead of Success.
@@ -619,10 +545,17 @@ class FilterChooser {
619545
const RecordVal *RV = EncodingDef->getValue("SoftFail");
620546
const BitsInit *SFBits = RV ? dyn_cast<BitsInit>(RV->getValue()) : nullptr;
621547
for (unsigned i = 0; i < Bits.getNumBits(); ++i) {
622-
if (SFBits && BitValue(*SFBits, i) == BitValue::BIT_TRUE)
623-
Insn[i] = BitValue::BIT_UNSET;
624-
else
625-
Insn[i] = BitValue(Bits, i);
548+
if (SFBits) {
549+
const auto *B = dyn_cast<BitInit>(SFBits->getBit(i));
550+
if (B && B->getValue())
551+
continue;
552+
}
553+
if (const auto *B = dyn_cast<BitInit>(Bits.getBit(i))) {
554+
if (B->getValue())
555+
Insn.One.setBit(i);
556+
else
557+
Insn.Zero.setBit(i);
558+
}
626559
}
627560
return Insn;
628561
}
@@ -639,7 +572,7 @@ class FilterChooser {
639572
// This returns a list of undecoded bits of an instructions, for example,
640573
// Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be
641574
// decoded bits in order to verify that the instruction matches the Opcode.
642-
std::vector<Island> getIslands(const insn_t &Insn) const;
575+
std::vector<Island> getIslands(const KnownBits &EncodingBits) const;
643576

644577
// Emits code to check the Predicates member of an instruction are true.
645578
// Returns true if predicate matches were emitted, false otherwise.
@@ -717,15 +650,15 @@ Filter::Filter(const FilterChooser &owner, unsigned startBit, unsigned numBits)
717650

718651
for (unsigned EncodingID : Owner.EncodingIDs) {
719652
// Populates the insn given the uid.
720-
insn_t Insn = Owner.insnWithID(EncodingID);
653+
KnownBits EncodingBits = Owner.getMandatoryEncodingBits(EncodingID);
721654

722655
// Scans the segment for possibly well-specified encoding bits.
723-
std::optional<uint64_t> Field = fieldFromInsn(Insn, StartBit, NumBits);
656+
KnownBits FieldBits = EncodingBits.extractBits(NumBits, StartBit);
724657

725-
if (Field) {
658+
if (FieldBits.isConstant()) {
726659
// The encoding bits are well-known. Lets add the uid of the
727660
// instruction into the bucket keyed off the constant field value.
728-
FilteredIDs[*Field].push_back(EncodingID);
661+
FilteredIDs[FieldBits.getConstant().getZExtValue()].push_back(EncodingID);
729662
++NumFiltered;
730663
} else {
731664
// Some of the encoding bit(s) are unspecified. This contributes to
@@ -1160,7 +1093,7 @@ void FilterChooser::dumpStack(raw_ostream &OS, indent Indent) const {
11601093
// Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be
11611094
// decoded bits in order to verify that the instruction matches the Opcode.
11621095
std::vector<FilterChooser::Island>
1163-
FilterChooser::getIslands(const insn_t &Insn) const {
1096+
FilterChooser::getIslands(const KnownBits &EncodingBits) const {
11641097
std::vector<Island> Islands;
11651098
uint64_t FieldVal;
11661099
unsigned StartBit;
@@ -1171,28 +1104,29 @@ FilterChooser::getIslands(const insn_t &Insn) const {
11711104
unsigned State = 0;
11721105

11731106
for (unsigned i = 0; i < BitWidth; ++i) {
1174-
std::optional<uint64_t> Val = Insn[i].getValue();
1107+
bool IsKnown = EncodingBits.Zero[i] || EncodingBits.One[i];
11751108
bool Filtered = isPositionFiltered(i);
11761109
switch (State) {
11771110
default:
11781111
llvm_unreachable("Unreachable code!");
11791112
case 0:
11801113
case 1:
1181-
if (Filtered || !Val) {
1114+
if (Filtered || !IsKnown) {
11821115
State = 1; // Still in Water
11831116
} else {
11841117
State = 2; // Into the Island
11851118
StartBit = i;
1186-
FieldVal = *Val;
1119+
FieldVal = static_cast<uint64_t>(EncodingBits.One[i]);
11871120
}
11881121
break;
11891122
case 2:
1190-
if (Filtered || !Val) {
1123+
if (Filtered || !IsKnown) {
11911124
State = 1; // Into the Water
11921125
Islands.push_back({StartBit, i - StartBit, FieldVal});
11931126
} else {
11941127
State = 2; // Still in Island
1195-
FieldVal |= *Val << (i - StartBit);
1128+
FieldVal |= static_cast<uint64_t>(EncodingBits.One[i])
1129+
<< (i - StartBit);
11961130
}
11971131
break;
11981132
}
@@ -1421,19 +1355,11 @@ void FilterChooser::emitSoftFailTableEntry(DecoderTableInfo &TableInfo,
14211355
APInt PositiveMask(BitWidth, 0ULL);
14221356
APInt NegativeMask(BitWidth, 0ULL);
14231357
for (unsigned i = 0; i < BitWidth; ++i) {
1424-
BitValue B(*SFBits, i);
1425-
BitValue IB(*InstBits, i);
1426-
1427-
if (B != BitValue::BIT_TRUE)
1358+
if (!isa<BitInit>(SFBits->getBit(i)) ||
1359+
!cast<BitInit>(SFBits->getBit(i))->getValue())
14281360
continue;
14291361

1430-
if (IB == BitValue::BIT_FALSE) {
1431-
// The bit is meant to be false, so emit a check to see if it is true.
1432-
PositiveMask.setBit(i);
1433-
} else if (IB == BitValue::BIT_TRUE) {
1434-
// The bit is meant to be true, so emit a check to see if it is false.
1435-
NegativeMask.setBit(i);
1436-
} else {
1362+
if (!isa<BitInit>(InstBits->getBit(i))) {
14371363
// The bit is not set; this must be an error!
14381364
errs() << "SoftFail Conflict: bit SoftFail{" << i << "} in "
14391365
<< Encodings[EncodingID].getName() << " is set but Inst{" << i
@@ -1442,6 +1368,15 @@ void FilterChooser::emitSoftFailTableEntry(DecoderTableInfo &TableInfo,
14421368
<< " (1/0 - not '?') in Inst\n";
14431369
return;
14441370
}
1371+
1372+
bool IB = cast<BitInit>(InstBits->getBit(i))->getValue();
1373+
if (!IB) {
1374+
// The bit is meant to be false, so emit a check to see if it is true.
1375+
PositiveMask.setBit(i);
1376+
} else {
1377+
// The bit is meant to be true, so emit a check to see if it is false.
1378+
NegativeMask.setBit(i);
1379+
}
14451380
}
14461381

14471382
bool NeedPositiveMask = PositiveMask.getBoolValue();
@@ -1458,10 +1393,10 @@ void FilterChooser::emitSoftFailTableEntry(DecoderTableInfo &TableInfo,
14581393
// Emits table entries to decode the singleton.
14591394
void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
14601395
unsigned EncodingID) const {
1461-
insn_t Insn = insnWithID(EncodingID);
1396+
KnownBits EncodingBits = getMandatoryEncodingBits(EncodingID);
14621397

14631398
// Look for islands of undecoded bits of the singleton.
1464-
std::vector<Island> Islands = getIslands(Insn);
1399+
std::vector<Island> Islands = getIslands(EncodingBits);
14651400

14661401
// Emit the predicate table entry if one is needed.
14671402
emitPredicateTableEntry(TableInfo, EncodingID);
@@ -1561,10 +1496,10 @@ bool FilterChooser::filterProcessor(ArrayRef<bitAttr_t> BitAttrs,
15611496
assert(EncodingIDs.size() == 3);
15621497

15631498
for (unsigned EncodingID : EncodingIDs) {
1564-
insn_t Insn = insnWithID(EncodingID);
1499+
KnownBits EncodingBits = getMandatoryEncodingBits(EncodingID);
15651500

15661501
// Look for islands of undecoded bits of any instruction.
1567-
std::vector<Island> Islands = getIslands(Insn);
1502+
std::vector<Island> Islands = getIslands(EncodingBits);
15681503
if (!Islands.empty()) {
15691504
// Found an instruction with island(s). Now just assign a filter.
15701505
runSingleFilter(Islands[0].StartBit, Islands[0].NumBits);
@@ -1750,22 +1685,23 @@ void FilterChooser::doFilter() {
17501685
BitAttrs[BitIndex] = ATTR_FILTERED;
17511686

17521687
for (unsigned EncodingID : EncodingIDs) {
1753-
insn_t EncodingBits = insnWithID(EncodingID);
1688+
KnownBits EncodingBits = getMandatoryEncodingBits(EncodingID);
17541689

17551690
for (unsigned BitIndex = 0; BitIndex < BitWidth; ++BitIndex) {
1691+
bool IsKnown = EncodingBits.Zero[BitIndex] || EncodingBits.One[BitIndex];
17561692
switch (BitAttrs[BitIndex]) {
17571693
case ATTR_NONE:
1758-
if (EncodingBits[BitIndex] == BitValue::BIT_UNSET)
1759-
BitAttrs[BitIndex] = ATTR_ALL_UNSET;
1760-
else
1694+
if (IsKnown)
17611695
BitAttrs[BitIndex] = ATTR_ALL_SET;
1696+
else
1697+
BitAttrs[BitIndex] = ATTR_ALL_UNSET;
17621698
break;
17631699
case ATTR_ALL_SET:
1764-
if (EncodingBits[BitIndex] == BitValue::BIT_UNSET)
1700+
if (!IsKnown)
17651701
BitAttrs[BitIndex] = ATTR_MIXED;
17661702
break;
17671703
case ATTR_ALL_UNSET:
1768-
if (EncodingBits[BitIndex] != BitValue::BIT_UNSET)
1704+
if (IsKnown)
17691705
BitAttrs[BitIndex] = ATTR_MIXED;
17701706
break;
17711707
case ATTR_MIXED:
@@ -1806,7 +1742,7 @@ void FilterChooser::doFilter() {
18061742
for (unsigned EncodingID : EncodingIDs) {
18071743
const InstructionEncoding &Enc = Encodings[EncodingID];
18081744
errs() << Indent;
1809-
dumpBits(errs(), getBitsField(*Enc.getRecord(), "Inst"), BitWidth);
1745+
printKnownBits(errs(), getMandatoryEncodingBits(EncodingID), '_');
18101746
errs() << " " << Enc.getName() << '\n';
18111747
}
18121748
PrintFatalError("Decoding conflict encountered");

0 commit comments

Comments
 (0)