@@ -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.
@@ -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