Skip to content

Commit 21532f0

Browse files
authored
[NFC][MC][DecoderEmitter] Refactor code related to EncodingField (#156759)
1 parent c8e760e commit 21532f0

File tree

1 file changed

+39
-19
lines changed

1 file changed

+39
-19
lines changed

llvm/utils/TableGen/DecoderEmitter.cpp

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,14 @@ static void printKnownBits(raw_ostream &OS, const KnownBits &Bits,
131131

132132
namespace {
133133

134+
// Represents a span of bits in the instruction encoding that's based on a span
135+
// of bits in an operand's encoding.
136+
//
137+
// Width is the width of the span.
138+
// Base is the starting position of that span in the instruction encoding.
139+
// Offset if the starting position of that span in the operand's encoding.
140+
// That is, bits {Base + Width - 1, Base} in the instruction encoding form
141+
// bits {Offset + Width - 1, Offset} in the operands encoding.
134142
struct EncodingField {
135143
unsigned Base, Width, Offset;
136144
EncodingField(unsigned B, unsigned W, unsigned O)
@@ -146,15 +154,12 @@ struct OperandInfo {
146154
OperandInfo(std::string D, bool HCD) : Decoder(D), HasCompleteDecoder(HCD) {}
147155

148156
void addField(unsigned Base, unsigned Width, unsigned Offset) {
149-
Fields.push_back(EncodingField(Base, Width, Offset));
157+
Fields.emplace_back(Base, Width, Offset);
150158
}
151159

152160
unsigned numFields() const { return Fields.size(); }
153161

154-
typedef std::vector<EncodingField>::const_iterator const_iterator;
155-
156-
const_iterator begin() const { return Fields.begin(); }
157-
const_iterator end() const { return Fields.end(); }
162+
ArrayRef<EncodingField> fields() const { return Fields; }
158163
};
159164

160165
/// Represents a parsed InstructionEncoding record or a record derived from it.
@@ -1113,17 +1118,17 @@ void DecoderTableBuilder::emitBinaryParser(raw_ostream &OS, indent Indent,
11131118
OS << ";\n";
11141119
}
11151120

1116-
for (const EncodingField &EF : OpInfo) {
1121+
for (const auto &[Base, Width, Offset] : OpInfo.fields()) {
11171122
OS << Indent;
11181123
if (UseInsertBits)
11191124
OS << "insertBits(tmp, ";
11201125
else
11211126
OS << "tmp = ";
1122-
OS << "fieldFromInstruction(insn, " << EF.Base << ", " << EF.Width << ')';
1127+
OS << "fieldFromInstruction(insn, " << Base << ", " << Width << ')';
11231128
if (UseInsertBits)
1124-
OS << ", " << EF.Offset << ", " << EF.Width << ')';
1125-
else if (EF.Offset != 0)
1126-
OS << " << " << EF.Offset;
1129+
OS << ", " << Offset << ", " << Width << ')';
1130+
else if (Offset != 0)
1131+
OS << " << " << Offset;
11271132
OS << ";\n";
11281133
}
11291134

@@ -1933,7 +1938,8 @@ static void debugDumpRecord(const Record &Rec) {
19331938
/// For an operand field named OpName: populate OpInfo.InitValue with the
19341939
/// constant-valued bit values, and OpInfo.Fields with the ranges of bits to
19351940
/// insert from the decoded instruction.
1936-
static void addOneOperandFields(const Record *EncodingDef, const BitsInit &Bits,
1941+
static void addOneOperandFields(const Record *EncodingDef,
1942+
const BitsInit &InstBits,
19371943
std::map<StringRef, StringRef> &TiedNames,
19381944
StringRef OpName, OperandInfo &OpInfo) {
19391945
// 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,
19451951
if (OpBit->getValue())
19461952
OpInfo.InitValue |= 1ULL << I;
19471953

1948-
for (unsigned I = 0, J = 0; I != Bits.getNumBits(); I = J) {
1954+
// Find out where the variable bits of the operand are encoded. The bits don't
1955+
// have to be consecutive or in ascending order. For example, an operand could
1956+
// be encoded as follows:
1957+
//
1958+
// 7 6 5 4 3 2 1 0
1959+
// {1, op{5}, op{2}, op{1}, 0, op{4}, op{3}, ?}
1960+
//
1961+
// In this example the operand is encoded in three segments:
1962+
//
1963+
// Base Width Offset
1964+
// op{2...1} 4 2 1
1965+
// op{4...3} 1 2 3
1966+
// op{5} 6 1 5
1967+
//
1968+
for (unsigned I = 0, J = 0; I != InstBits.getNumBits(); I = J) {
19491969
const VarInit *Var;
19501970
unsigned Offset = 0;
1951-
for (; J != Bits.getNumBits(); ++J) {
1952-
const VarBitInit *BJ = dyn_cast<VarBitInit>(Bits.getBit(J));
1953-
if (BJ) {
1954-
Var = dyn_cast<VarInit>(BJ->getBitVar());
1971+
for (; J != InstBits.getNumBits(); ++J) {
1972+
const Init *BitJ = InstBits.getBit(J);
1973+
if (const auto *VBI = dyn_cast<VarBitInit>(BitJ)) {
1974+
Var = dyn_cast<VarInit>(VBI->getBitVar());
19551975
if (I == J)
1956-
Offset = BJ->getBitNum();
1957-
else if (BJ->getBitNum() != Offset + J - I)
1976+
Offset = VBI->getBitNum();
1977+
else if (VBI->getBitNum() != Offset + J - I)
19581978
break;
19591979
} else {
1960-
Var = dyn_cast<VarInit>(Bits.getBit(J));
1980+
Var = dyn_cast<VarInit>(BitJ);
19611981
}
19621982
if (!Var ||
19631983
(Var->getName() != OpName && Var->getName() != TiedNames[OpName]))

0 commit comments

Comments
 (0)