Skip to content

Commit a734a4b

Browse files
committed
[NFC][MC][DecoderEmitter] Refactor code related to EncodingField
- Add comment to document various EncodingField members. - Add comment in `addOneOperandFields` to give an example of the generated encoding fields. - Rename `Bits` argument for `addOneOperandFields` to `InstBits` to clarify that it represents the instruction bits as opposed to operand bits - Rewrite the loop to form encoding fields in ``addOneOperandFields` a little bit. - Change `OperandInfo` to vend out an `ArrayRef<EncodingField>` via a new `fields` member instead of start/end. - Use structured binding in the loop over fields in `emitBinaryParser`.
1 parent c93e2de commit a734a4b

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.
@@ -1100,17 +1105,17 @@ void DecoderTableBuilder::emitBinaryParser(raw_ostream &OS, indent Indent,
11001105
OS << ";\n";
11011106
}
11021107

1103-
for (const EncodingField &EF : OpInfo) {
1108+
for (const auto &[Base, Width, Offset] : OpInfo.fields()) {
11041109
OS << Indent;
11051110
if (UseInsertBits)
11061111
OS << "insertBits(tmp, ";
11071112
else
11081113
OS << "tmp = ";
1109-
OS << "fieldFromInstruction(insn, " << EF.Base << ", " << EF.Width << ')';
1114+
OS << "fieldFromInstruction(insn, " << Base << ", " << Width << ')';
11101115
if (UseInsertBits)
1111-
OS << ", " << EF.Offset << ", " << EF.Width << ')';
1112-
else if (EF.Offset != 0)
1113-
OS << " << " << EF.Offset;
1116+
OS << ", " << Offset << ", " << Width << ')';
1117+
else if (Offset != 0)
1118+
OS << " << " << Offset;
11141119
OS << ";\n";
11151120
}
11161121

@@ -1920,7 +1925,8 @@ static void debugDumpRecord(const Record &Rec) {
19201925
/// For an operand field named OpName: populate OpInfo.InitValue with the
19211926
/// constant-valued bit values, and OpInfo.Fields with the ranges of bits to
19221927
/// insert from the decoded instruction.
1923-
static void addOneOperandFields(const Record *EncodingDef, const BitsInit &Bits,
1928+
static void addOneOperandFields(const Record *EncodingDef,
1929+
const BitsInit &InstBits,
19241930
std::map<StringRef, StringRef> &TiedNames,
19251931
StringRef OpName, OperandInfo &OpInfo) {
19261932
// Some bits of the operand may be required to be 1 depending on the
@@ -1932,19 +1938,33 @@ static void addOneOperandFields(const Record *EncodingDef, const BitsInit &Bits,
19321938
if (OpBit->getValue())
19331939
OpInfo.InitValue |= 1ULL << I;
19341940

1935-
for (unsigned I = 0, J = 0; I != Bits.getNumBits(); I = J) {
1941+
// Find out where the variable bits of the operand are encoded. The bits don't
1942+
// have to be consecutive or in ascending order. For example, an operand could
1943+
// be encoded as follows:
1944+
//
1945+
// 7 6 5 4 3 2 1 0
1946+
// {1, op{5}, op{2}, op{1}, 0, op{4}, op{3}, ?}
1947+
//
1948+
// In this example the operand is encoded in three segments:
1949+
//
1950+
// Base Width Offset
1951+
// op{2...1} 4 2 1
1952+
// op{4...3} 1 2 3
1953+
// op{5} 6 1 5
1954+
//
1955+
for (unsigned I = 0, J = 0; I != InstBits.getNumBits(); I = J) {
19361956
const VarInit *Var;
19371957
unsigned Offset = 0;
1938-
for (; J != Bits.getNumBits(); ++J) {
1939-
const VarBitInit *BJ = dyn_cast<VarBitInit>(Bits.getBit(J));
1940-
if (BJ) {
1941-
Var = dyn_cast<VarInit>(BJ->getBitVar());
1958+
for (; J != InstBits.getNumBits(); ++J) {
1959+
const Init *BitJ = InstBits.getBit(J);
1960+
if (const auto *VBI = dyn_cast<VarBitInit>(BitJ)) {
1961+
Var = dyn_cast<VarInit>(VBI->getBitVar());
19421962
if (I == J)
1943-
Offset = BJ->getBitNum();
1944-
else if (BJ->getBitNum() != Offset + J - I)
1963+
Offset = VBI->getBitNum();
1964+
else if (VBI->getBitNum() != Offset + J - I)
19451965
break;
19461966
} else {
1947-
Var = dyn_cast<VarInit>(Bits.getBit(J));
1967+
Var = dyn_cast<VarInit>(BitJ);
19481968
}
19491969
if (!Var ||
19501970
(Var->getName() != OpName && Var->getName() != TiedNames[OpName]))

0 commit comments

Comments
 (0)