[llvm] [TableGen][Decoder] Decode operands with zero width or all bits known (PR #156358)
Rahul Joshi via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 3 09:29:43 PDT 2025
================
@@ -1922,15 +1946,48 @@ static void debugDumpRecord(const Record &Rec) {
/// insert from the decoded instruction.
static void addOneOperandFields(const Record *EncodingDef, const BitsInit &Bits,
std::map<StringRef, StringRef> &TiedNames,
- StringRef OpName, OperandInfo &OpInfo) {
- // Some bits of the operand may be required to be 1 depending on the
- // instruction's encoding. Collect those bits.
- if (const RecordVal *EncodedValue = EncodingDef->getValue(OpName))
- if (const BitsInit *OpBits = dyn_cast<BitsInit>(EncodedValue->getValue()))
- for (unsigned I = 0; I < OpBits->getNumBits(); ++I)
- if (const BitInit *OpBit = dyn_cast<BitInit>(OpBits->getBit(I)))
- if (OpBit->getValue())
- OpInfo.InitValue |= 1ULL << I;
+ const Record *OpRec, StringRef OpName,
+ OperandInfo &OpInfo) {
+ // Find a field with the operand's name.
+ const RecordVal *OpEncodingField = EncodingDef->getValue(OpName);
+
+ // If there is no such field, try tied operand's name.
+ if (!OpEncodingField) {
+ if (auto I = TiedNames.find(OpName); I != TiedNames.end())
+ OpEncodingField = EncodingDef->getValue(I->second);
+
+ // If still no luck, the old behavior is to not decode this operand
+ // automatically and let the target do it. This is error-prone, so
+ // the new behavior is to report an error.
+ if (!OpEncodingField) {
+ if (!IgnoreNonDecodableOperands)
+ PrintError(EncodingDef->getLoc(),
+ "could not find field for operand '" + OpName + "'");
+ return;
+ }
+ }
+
+ // Some or all bits of the operand may be required to be 0 or 1 depending
+ // on the instruction's encoding. Collect those bits.
+ if (const auto *OpBit = dyn_cast<BitInit>(OpEncodingField->getValue())) {
+ OpInfo.InitValue = OpBit->getValue();
+ return;
+ }
+ if (const auto *OpBits = dyn_cast<BitsInit>(OpEncodingField->getValue())) {
+ if (OpBits->getNumBits() == 0) {
+ if (OpInfo.Decoder.empty()) {
+ PrintError(EncodingDef->getLoc(), "operand '" + OpName + "' of type '" +
+ OpRec->getName() +
+ "' must have a decoder method");
+ }
+ return;
+ }
+ for (unsigned I = 0; I < OpBits->getNumBits(); ++I) {
+ if (const auto *OpBit = dyn_cast<BitInit>(OpBits->getBit(I)))
+ OpInfo.InitValue = OpInfo.InitValue.value_or(0) |
+ static_cast<uint64_t>(OpBit->getValue()) << I;
+ }
+ }
for (unsigned I = 0, J = 0; I != Bits.getNumBits(); I = J) {
----------------
jurahul wrote:
not related to this PR directly, but this loop to collect spans of initializations based on the same variable can use some comments to make it easy to understand.
https://github.com/llvm/llvm-project/pull/156358
More information about the llvm-commits
mailing list