@@ -131,6 +131,14 @@ static void printKnownBits(raw_ostream &OS, const KnownBits &Bits,
131131
132132namespace {
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.
134142struct 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