[llvm] 21532f0 - [NFC][MC][DecoderEmitter] Refactor code related to EncodingField (#156759)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 4 05:59:42 PDT 2025
Author: Rahul Joshi
Date: 2025-09-04T05:59:38-07:00
New Revision: 21532f008461c65438475c53444f33f185f9574f
URL: https://github.com/llvm/llvm-project/commit/21532f008461c65438475c53444f33f185f9574f
DIFF: https://github.com/llvm/llvm-project/commit/21532f008461c65438475c53444f33f185f9574f.diff
LOG: [NFC][MC][DecoderEmitter] Refactor code related to EncodingField (#156759)
Added:
Modified:
llvm/utils/TableGen/DecoderEmitter.cpp
Removed:
################################################################################
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index 2b06cfc7c3138..339063dd112a6 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -131,6 +131,14 @@ static void printKnownBits(raw_ostream &OS, const KnownBits &Bits,
namespace {
+// Represents a span of bits in the instruction encoding that's based on a span
+// of bits in an operand's encoding.
+//
+// Width is the width of the span.
+// Base is the starting position of that span in the instruction encoding.
+// Offset if the starting position of that span in the operand's encoding.
+// That is, bits {Base + Width - 1, Base} in the instruction encoding form
+// bits {Offset + Width - 1, Offset} in the operands encoding.
struct EncodingField {
unsigned Base, Width, Offset;
EncodingField(unsigned B, unsigned W, unsigned O)
@@ -146,15 +154,12 @@ struct OperandInfo {
OperandInfo(std::string D, bool HCD) : Decoder(D), HasCompleteDecoder(HCD) {}
void addField(unsigned Base, unsigned Width, unsigned Offset) {
- Fields.push_back(EncodingField(Base, Width, Offset));
+ Fields.emplace_back(Base, Width, Offset);
}
unsigned numFields() const { return Fields.size(); }
- typedef std::vector<EncodingField>::const_iterator const_iterator;
-
- const_iterator begin() const { return Fields.begin(); }
- const_iterator end() const { return Fields.end(); }
+ ArrayRef<EncodingField> fields() const { return Fields; }
};
/// Represents a parsed InstructionEncoding record or a record derived from it.
@@ -1113,17 +1118,17 @@ void DecoderTableBuilder::emitBinaryParser(raw_ostream &OS, indent Indent,
OS << ";\n";
}
- for (const EncodingField &EF : OpInfo) {
+ for (const auto &[Base, Width, Offset] : OpInfo.fields()) {
OS << Indent;
if (UseInsertBits)
OS << "insertBits(tmp, ";
else
OS << "tmp = ";
- OS << "fieldFromInstruction(insn, " << EF.Base << ", " << EF.Width << ')';
+ OS << "fieldFromInstruction(insn, " << Base << ", " << Width << ')';
if (UseInsertBits)
- OS << ", " << EF.Offset << ", " << EF.Width << ')';
- else if (EF.Offset != 0)
- OS << " << " << EF.Offset;
+ OS << ", " << Offset << ", " << Width << ')';
+ else if (Offset != 0)
+ OS << " << " << Offset;
OS << ";\n";
}
@@ -1933,7 +1938,8 @@ static void debugDumpRecord(const Record &Rec) {
/// For an operand field named OpName: populate OpInfo.InitValue with the
/// constant-valued bit values, and OpInfo.Fields with the ranges of bits to
/// insert from the decoded instruction.
-static void addOneOperandFields(const Record *EncodingDef, const BitsInit &Bits,
+static void addOneOperandFields(const Record *EncodingDef,
+ const BitsInit &InstBits,
std::map<StringRef, StringRef> &TiedNames,
StringRef OpName, OperandInfo &OpInfo) {
// Some bits of the operand may be required to be 1 depending on the
@@ -1945,19 +1951,33 @@ static void addOneOperandFields(const Record *EncodingDef, const BitsInit &Bits,
if (OpBit->getValue())
OpInfo.InitValue |= 1ULL << I;
- for (unsigned I = 0, J = 0; I != Bits.getNumBits(); I = J) {
+ // Find out where the variable bits of the operand are encoded. The bits don't
+ // have to be consecutive or in ascending order. For example, an operand could
+ // be encoded as follows:
+ //
+ // 7 6 5 4 3 2 1 0
+ // {1, op{5}, op{2}, op{1}, 0, op{4}, op{3}, ?}
+ //
+ // In this example the operand is encoded in three segments:
+ //
+ // Base Width Offset
+ // op{2...1} 4 2 1
+ // op{4...3} 1 2 3
+ // op{5} 6 1 5
+ //
+ for (unsigned I = 0, J = 0; I != InstBits.getNumBits(); I = J) {
const VarInit *Var;
unsigned Offset = 0;
- for (; J != Bits.getNumBits(); ++J) {
- const VarBitInit *BJ = dyn_cast<VarBitInit>(Bits.getBit(J));
- if (BJ) {
- Var = dyn_cast<VarInit>(BJ->getBitVar());
+ for (; J != InstBits.getNumBits(); ++J) {
+ const Init *BitJ = InstBits.getBit(J);
+ if (const auto *VBI = dyn_cast<VarBitInit>(BitJ)) {
+ Var = dyn_cast<VarInit>(VBI->getBitVar());
if (I == J)
- Offset = BJ->getBitNum();
- else if (BJ->getBitNum() != Offset + J - I)
+ Offset = VBI->getBitNum();
+ else if (VBI->getBitNum() != Offset + J - I)
break;
} else {
- Var = dyn_cast<VarInit>(Bits.getBit(J));
+ Var = dyn_cast<VarInit>(BitJ);
}
if (!Var ||
(Var->getName() != OpName && Var->getName() != TiedNames[OpName]))
More information about the llvm-commits
mailing list