LCOV - code coverage report
Current view: top level - build-llvm/lib/Target/BPF - BPFGenAsmMatcher.inc (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 104 202 51.5 %
Date: 2018-10-20 13:21:21 Functions: 5 12 41.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
       2             : |*                                                                            *|
       3             : |* Assembly Matcher Source Fragment                                           *|
       4             : |*                                                                            *|
       5             : |* Automatically generated file, do not edit!                                 *|
       6             : |*                                                                            *|
       7             : \*===----------------------------------------------------------------------===*/
       8             : 
       9             : 
      10             : #ifdef GET_ASSEMBLER_HEADER
      11             : #undef GET_ASSEMBLER_HEADER
      12             :   // This should be included into the middle of the declaration of
      13             :   // your subclasses implementation of MCTargetAsmParser.
      14             :   uint64_t ComputeAvailableFeatures(const FeatureBitset& FB) const;
      15             :   void convertToMCInst(unsigned Kind, MCInst &Inst, unsigned Opcode,
      16             :                        const OperandVector &Operands);
      17             :   void convertToMapAndConstraints(unsigned Kind,
      18             :                            const OperandVector &Operands) override;
      19             :   unsigned MatchInstructionImpl(const OperandVector &Operands,
      20             :                                 MCInst &Inst,
      21             :                                 uint64_t &ErrorInfo,
      22             :                                 bool matchingInlineAsm,
      23             :                                 unsigned VariantID = 0);
      24             : #endif // GET_ASSEMBLER_HEADER_INFO
      25             : 
      26             : 
      27             : #ifdef GET_OPERAND_DIAGNOSTIC_TYPES
      28             : #undef GET_OPERAND_DIAGNOSTIC_TYPES
      29             : 
      30             : #endif // GET_OPERAND_DIAGNOSTIC_TYPES
      31             : 
      32             : 
      33             : #ifdef GET_REGISTER_MATCHER
      34             : #undef GET_REGISTER_MATCHER
      35             : 
      36             : // Flags for subtarget features that participate in instruction matching.
      37             : enum SubtargetFeatureFlag : uint8_t {
      38             :   Feature_None = 0
      39             : };
      40             : 
      41         207 : static unsigned MatchRegisterName(StringRef Name) {
      42         207 :   switch (Name.size()) {
      43             :   default: break;
      44         164 :   case 2:        // 20 strings to match.
      45             :     switch (Name[0]) {
      46             :     default: break;
      47         105 :     case 'r':    // 10 strings to match.
      48             :       switch (Name[1]) {
      49             :       default: break;
      50             :       case '0':  // 1 string to match.
      51             :         return 1;        // "r0"
      52             :       case '1':  // 1 string to match.
      53             :         return 2;        // "r1"
      54             :       case '2':  // 1 string to match.
      55             :         return 3;        // "r2"
      56             :       case '3':  // 1 string to match.
      57             :         return 4;        // "r3"
      58             :       case '4':  // 1 string to match.
      59             :         return 5;        // "r4"
      60             :       case '5':  // 1 string to match.
      61             :         return 6;        // "r5"
      62             :       case '6':  // 1 string to match.
      63             :         return 7;        // "r6"
      64             :       case '7':  // 1 string to match.
      65             :         return 8;        // "r7"
      66             :       case '8':  // 1 string to match.
      67             :         return 9;        // "r8"
      68             :       case '9':  // 1 string to match.
      69             :         return 10;       // "r9"
      70             :       }
      71             :       break;
      72          39 :     case 'w':    // 10 strings to match.
      73             :       switch (Name[1]) {
      74             :       default: break;
      75             :       case '0':  // 1 string to match.
      76             :         return 13;       // "w0"
      77             :       case '1':  // 1 string to match.
      78             :         return 14;       // "w1"
      79             :       case '2':  // 1 string to match.
      80             :         return 15;       // "w2"
      81             :       case '3':  // 1 string to match.
      82             :         return 16;       // "w3"
      83             :       case '4':  // 1 string to match.
      84             :         return 17;       // "w4"
      85             :       case '5':  // 1 string to match.
      86             :         return 18;       // "w5"
      87             :       case '6':  // 1 string to match.
      88             :         return 19;       // "w6"
      89             :       case '7':  // 1 string to match.
      90             :         return 20;       // "w7"
      91             :       case '8':  // 1 string to match.
      92             :         return 21;       // "w8"
      93             :       case '9':  // 1 string to match.
      94             :         return 22;       // "w9"
      95             :       }
      96             :       break;
      97             :     }
      98             :     break;
      99           9 :   case 3:        // 4 strings to match.
     100             :     switch (Name[0]) {
     101             :     default: break;
     102           6 :     case 'r':    // 2 strings to match.
     103           6 :       if (Name[1] != '1')
     104             :         break;
     105             :       switch (Name[2]) {
     106             :       default: break;
     107             :       case '0':  // 1 string to match.
     108             :         return 11;       // "r10"
     109           0 :       case '1':  // 1 string to match.
     110           0 :         return 12;       // "r11"
     111             :       }
     112             :       break;
     113           3 :     case 'w':    // 2 strings to match.
     114           3 :       if (Name[1] != '1')
     115             :         break;
     116             :       switch (Name[2]) {
     117             :       default: break;
     118             :       case '0':  // 1 string to match.
     119             :         return 23;       // "w10"
     120           0 :       case '1':  // 1 string to match.
     121           0 :         return 24;       // "w11"
     122             :       }
     123             :       break;
     124             :     }
     125             :     break;
     126             :   }
     127             :   return 0;
     128             : }
     129             : 
     130             : #endif // GET_REGISTER_MATCHER
     131             : 
     132             : 
     133             : #ifdef GET_SUBTARGET_FEATURE_NAME
     134             : #undef GET_SUBTARGET_FEATURE_NAME
     135             : 
     136             : // User-level names for subtarget features that participate in
     137             : // instruction matching.
     138             : static const char *getSubtargetFeatureName(uint64_t Val) {
     139             :   return "(unknown)";
     140             : }
     141             : 
     142             : #endif // GET_SUBTARGET_FEATURE_NAME
     143             : 
     144             : 
     145             : #ifdef GET_MATCHER_IMPLEMENTATION
     146             : #undef GET_MATCHER_IMPLEMENTATION
     147             : 
     148             : enum {
     149             :   Tie0_0_0,
     150             :   Tie0_0_3,
     151             :   Tie0_12_12,
     152             : };
     153             : 
     154             : static const uint8_t TiedAsmOperandTable[][3] = {
     155             :   /* Tie0_0_0 */ { 0, 0, 0 },
     156             :   /* Tie0_0_3 */ { 0, 0, 3 },
     157             :   /* Tie0_12_12 */ { 0, 12, 12 },
     158             : };
     159             : 
     160             : namespace {
     161             : enum OperatorConversionKind {
     162             :   CVT_Done,
     163             :   CVT_Reg,
     164             :   CVT_Tied,
     165             :   CVT_95_Reg,
     166             :   CVT_95_addImmOperands,
     167             :   CVT_imm_95_0,
     168             :   CVT_NUM_CONVERTERS
     169             : };
     170             : 
     171             : enum InstructionConversionKind {
     172             :   Convert__Reg1_0__Reg1_2,
     173             :   Convert__Reg1_0__Imm1_2,
     174             :   Convert__Reg1_0__Tie0_0_0__Reg1_3,
     175             :   Convert__Reg1_0__Tie0_0_0__Imm1_3,
     176             :   Convert__Reg1_0__Tie0_0_3,
     177             :   Convert__Reg1_0__Tie0_0_0__Reg1_4,
     178             :   Convert__Reg1_0__Tie0_0_0__Imm1_4,
     179             :   Convert__Reg1_0__Tie0_0_0__Reg1_5,
     180             :   Convert__Reg1_0__Tie0_0_0__Imm1_5,
     181             :   Convert__Reg1_0__Reg1_8__Imm1_9,
     182             :   Convert__Reg1_10__Reg1_6__Imm1_7,
     183             :   Convert__Imm1_1,
     184             :   Convert_NoOperands,
     185             :   Convert__Reg1_1__Reg1_3__Imm1_5,
     186             :   Convert__Reg1_1__Imm1_3__Imm1_5,
     187             :   Convert__Reg1_1__Reg1_4__Imm1_6,
     188             :   Convert__Reg1_1__Imm1_4__Imm1_6,
     189             :   Convert__Reg1_1__Reg1_5__Imm1_7,
     190             :   Convert__Reg1_1__Imm1_5__Imm1_7,
     191             :   Convert__Reg1_1__Imm1_2__Imm1_3,
     192             :   Convert__Reg1_1__Reg1_2__Imm1_3,
     193             :   Convert__Reg1_12__Reg1_7__Imm1_8__Tie0_12_12,
     194             :   Convert__imm_95_0__Reg1_9,
     195             :   Convert__imm_95_0__Imm1_9,
     196             :   CVT_NUM_SIGNATURES
     197             : };
     198             : 
     199             : } // end anonymous namespace
     200             : 
     201             : static const uint8_t ConversionTable[CVT_NUM_SIGNATURES][9] = {
     202             :   // Convert__Reg1_0__Reg1_2
     203             :   { CVT_95_Reg, 0, CVT_95_Reg, 2, CVT_Done },
     204             :   // Convert__Reg1_0__Imm1_2
     205             :   { CVT_95_Reg, 0, CVT_95_addImmOperands, 2, CVT_Done },
     206             :   // Convert__Reg1_0__Tie0_0_0__Reg1_3
     207             :   { CVT_95_Reg, 0, CVT_Tied, Tie0_0_0, CVT_95_Reg, 3, CVT_Done },
     208             :   // Convert__Reg1_0__Tie0_0_0__Imm1_3
     209             :   { CVT_95_Reg, 0, CVT_Tied, Tie0_0_0, CVT_95_addImmOperands, 3, CVT_Done },
     210             :   // Convert__Reg1_0__Tie0_0_3
     211             :   { CVT_95_Reg, 0, CVT_Tied, Tie0_0_3, CVT_Done },
     212             :   // Convert__Reg1_0__Tie0_0_0__Reg1_4
     213             :   { CVT_95_Reg, 0, CVT_Tied, Tie0_0_0, CVT_95_Reg, 4, CVT_Done },
     214             :   // Convert__Reg1_0__Tie0_0_0__Imm1_4
     215             :   { CVT_95_Reg, 0, CVT_Tied, Tie0_0_0, CVT_95_addImmOperands, 4, CVT_Done },
     216             :   // Convert__Reg1_0__Tie0_0_0__Reg1_5
     217             :   { CVT_95_Reg, 0, CVT_Tied, Tie0_0_0, CVT_95_Reg, 5, CVT_Done },
     218             :   // Convert__Reg1_0__Tie0_0_0__Imm1_5
     219             :   { CVT_95_Reg, 0, CVT_Tied, Tie0_0_0, CVT_95_addImmOperands, 5, CVT_Done },
     220             :   // Convert__Reg1_0__Reg1_8__Imm1_9
     221             :   { CVT_95_Reg, 0, CVT_95_Reg, 8, CVT_95_addImmOperands, 9, CVT_Done },
     222             :   // Convert__Reg1_10__Reg1_6__Imm1_7
     223             :   { CVT_95_Reg, 10, CVT_95_Reg, 6, CVT_95_addImmOperands, 7, CVT_Done },
     224             :   // Convert__Imm1_1
     225             :   { CVT_95_addImmOperands, 1, CVT_Done },
     226             :   // Convert_NoOperands
     227             :   { CVT_Done },
     228             :   // Convert__Reg1_1__Reg1_3__Imm1_5
     229             :   { CVT_95_Reg, 1, CVT_95_Reg, 3, CVT_95_addImmOperands, 5, CVT_Done },
     230             :   // Convert__Reg1_1__Imm1_3__Imm1_5
     231             :   { CVT_95_Reg, 1, CVT_95_addImmOperands, 3, CVT_95_addImmOperands, 5, CVT_Done },
     232             :   // Convert__Reg1_1__Reg1_4__Imm1_6
     233             :   { CVT_95_Reg, 1, CVT_95_Reg, 4, CVT_95_addImmOperands, 6, CVT_Done },
     234             :   // Convert__Reg1_1__Imm1_4__Imm1_6
     235             :   { CVT_95_Reg, 1, CVT_95_addImmOperands, 4, CVT_95_addImmOperands, 6, CVT_Done },
     236             :   // Convert__Reg1_1__Reg1_5__Imm1_7
     237             :   { CVT_95_Reg, 1, CVT_95_Reg, 5, CVT_95_addImmOperands, 7, CVT_Done },
     238             :   // Convert__Reg1_1__Imm1_5__Imm1_7
     239             :   { CVT_95_Reg, 1, CVT_95_addImmOperands, 5, CVT_95_addImmOperands, 7, CVT_Done },
     240             :   // Convert__Reg1_1__Imm1_2__Imm1_3
     241             :   { CVT_95_Reg, 1, CVT_95_addImmOperands, 2, CVT_95_addImmOperands, 3, CVT_Done },
     242             :   // Convert__Reg1_1__Reg1_2__Imm1_3
     243             :   { CVT_95_Reg, 1, CVT_95_Reg, 2, CVT_95_addImmOperands, 3, CVT_Done },
     244             :   // Convert__Reg1_12__Reg1_7__Imm1_8__Tie0_12_12
     245             :   { CVT_95_Reg, 12, CVT_95_Reg, 7, CVT_95_addImmOperands, 8, CVT_Tied, Tie0_12_12, CVT_Done },
     246             :   // Convert__imm_95_0__Reg1_9
     247             :   { CVT_imm_95_0, 0, CVT_95_Reg, 9, CVT_Done },
     248             :   // Convert__imm_95_0__Imm1_9
     249             :   { CVT_imm_95_0, 0, CVT_95_addImmOperands, 9, CVT_Done },
     250             : };
     251             : 
     252           0 : void BPFAsmParser::
     253             : convertToMCInst(unsigned Kind, MCInst &Inst, unsigned Opcode,
     254             :                 const OperandVector &Operands) {
     255             :   assert(Kind < CVT_NUM_SIGNATURES && "Invalid signature!");
     256           0 :   const uint8_t *Converter = ConversionTable[Kind];
     257             :   unsigned OpIdx;
     258             :   Inst.setOpcode(Opcode);
     259           0 :   for (const uint8_t *p = Converter; *p; p+= 2) {
     260           0 :     OpIdx = *(p + 1);
     261           0 :     switch (*p) {
     262           0 :     default: llvm_unreachable("invalid conversion entry!");
     263           0 :     case CVT_Reg:
     264           0 :       static_cast<BPFOperand&>(*Operands[OpIdx]).addRegOperands(Inst, 1);
     265             :       break;
     266           0 :     case CVT_Tied: {
     267             :       assert(OpIdx < (size_t)(std::end(TiedAsmOperandTable) -
     268             :                           std::begin(TiedAsmOperandTable)) &&
     269             :              "Tied operand not found");
     270           0 :       unsigned TiedResOpnd = TiedAsmOperandTable[OpIdx][0];
     271           0 :       if (TiedResOpnd != (uint8_t) -1)
     272             :         Inst.addOperand(Inst.getOperand(TiedResOpnd));
     273             :       break;
     274             :     }
     275           0 :     case CVT_95_Reg:
     276           0 :       static_cast<BPFOperand&>(*Operands[OpIdx]).addRegOperands(Inst, 1);
     277             :       break;
     278           0 :     case CVT_95_addImmOperands:
     279           0 :       static_cast<BPFOperand&>(*Operands[OpIdx]).addImmOperands(Inst, 1);
     280             :       break;
     281             :     case CVT_imm_95_0:
     282           0 :       Inst.addOperand(MCOperand::createImm(0));
     283           0 :       break;
     284             :     }
     285             :   }
     286           0 : }
     287             : 
     288           0 : void BPFAsmParser::
     289             : convertToMapAndConstraints(unsigned Kind,
     290             :                            const OperandVector &Operands) {
     291             :   assert(Kind < CVT_NUM_SIGNATURES && "Invalid signature!");
     292             :   unsigned NumMCOperands = 0;
     293           0 :   const uint8_t *Converter = ConversionTable[Kind];
     294           0 :   for (const uint8_t *p = Converter; *p; p+= 2) {
     295           0 :     switch (*p) {
     296           0 :     default: llvm_unreachable("invalid conversion entry!");
     297           0 :     case CVT_Reg:
     298           0 :       Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
     299           0 :       Operands[*(p + 1)]->setConstraint("r");
     300           0 :       ++NumMCOperands;
     301           0 :       break;
     302           0 :     case CVT_Tied:
     303           0 :       ++NumMCOperands;
     304           0 :       break;
     305           0 :     case CVT_95_Reg:
     306           0 :       Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
     307           0 :       Operands[*(p + 1)]->setConstraint("r");
     308           0 :       NumMCOperands += 1;
     309           0 :       break;
     310           0 :     case CVT_95_addImmOperands:
     311           0 :       Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
     312           0 :       Operands[*(p + 1)]->setConstraint("m");
     313           0 :       NumMCOperands += 1;
     314           0 :       break;
     315           0 :     case CVT_imm_95_0:
     316           0 :       Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
     317           0 :       Operands[*(p + 1)]->setConstraint("");
     318           0 :       ++NumMCOperands;
     319           0 :       break;
     320             :     }
     321             :   }
     322           0 : }
     323             : 
     324             : namespace {
     325             : 
     326             : /// MatchClassKind - The kinds of classes which participate in
     327             : /// instruction matching.
     328             : enum MatchClassKind {
     329             :   InvalidMatchClass = 0,
     330             :   OptionalMatchClass = 1,
     331             :   MCK__EXCLAIM_, // '!'
     332             :   MCK__38_, // '&'
     333             :   MCK__40_, // '('
     334             :   MCK__41_, // ')'
     335             :   MCK__STAR_, // '*'
     336             :   MCK__43_, // '+'
     337             :   MCK__MINUS_, // '-'
     338             :   MCK__47_, // '/'
     339             :   MCK__LT_, // '<'
     340             :   MCK__61_, // '='
     341             :   MCK__GT_, // '>'
     342             :   MCK__91_, // '['
     343             :   MCK__93_, // ']'
     344             :   MCK__94_, // '^'
     345             :   MCK_be16, // 'be16'
     346             :   MCK_be32, // 'be32'
     347             :   MCK_be64, // 'be64'
     348             :   MCK_call, // 'call'
     349             :   MCK_callx, // 'callx'
     350             :   MCK_exit, // 'exit'
     351             :   MCK_goto, // 'goto'
     352             :   MCK_if, // 'if'
     353             :   MCK_ld_95_pseudo, // 'ld_pseudo'
     354             :   MCK_le16, // 'le16'
     355             :   MCK_le32, // 'le32'
     356             :   MCK_le64, // 'le64'
     357             :   MCK_lea, // 'lea'
     358             :   MCK_ll, // 'll'
     359             :   MCK_lock, // 'lock'
     360             :   MCK_nop, // 'nop'
     361             :   MCK_s, // 's'
     362             :   MCK_skb, // 'skb'
     363             :   MCK_u16, // 'u16'
     364             :   MCK_u32, // 'u32'
     365             :   MCK_u64, // 'u64'
     366             :   MCK_u8, // 'u8'
     367             :   MCK__124_, // '|'
     368             :   MCK_LAST_TOKEN = MCK__124_,
     369             :   MCK_R0, // register class 'R0'
     370             :   MCK_GPR, // register class 'GPR'
     371             :   MCK_GPR32, // register class 'GPR32'
     372             :   MCK_LAST_REGISTER = MCK_GPR32,
     373             :   MCK_Imm, // user defined class 'ImmAsmOperand'
     374             :   NumMatchClassKinds
     375             : };
     376             : 
     377             : }
     378             : 
     379           0 : static unsigned getDiagKindFromRegisterClass(MatchClassKind RegisterClass) {
     380           0 :   return MCTargetAsmParser::Match_InvalidOperand;
     381             : }
     382             : 
     383        2035 : static MatchClassKind matchTokenString(StringRef Name) {
     384        2035 :   switch (Name.size()) {
     385             :   default: break;
     386        1895 :   case 1:        // 16 strings to match.
     387             :     switch (Name[0]) {
     388             :     default: break;
     389             :     case '!':    // 1 string to match.
     390             :       return MCK__EXCLAIM_;      // "!"
     391             :     case '&':        // 1 string to match.
     392             :       return MCK__38_;   // "&"
     393             :     case '(':    // 1 string to match.
     394             :       return MCK__40_;   // "("
     395             :     case ')':    // 1 string to match.
     396             :       return MCK__41_;   // ")"
     397             :     case '*':    // 1 string to match.
     398             :       return MCK__STAR_;         // "*"
     399             :     case '+':    // 1 string to match.
     400             :       return MCK__43_;   // "+"
     401             :     case '-':    // 1 string to match.
     402             :       return MCK__MINUS_;        // "-"
     403             :     case '/':    // 1 string to match.
     404             :       return MCK__47_;   // "/"
     405             :     case '<':         // 1 string to match.
     406             :       return MCK__LT_;   // "<"
     407             :     case '=':    // 1 string to match.
     408             :       return MCK__61_;   // "="
     409             :     case '>':         // 1 string to match.
     410             :       return MCK__GT_;   // ">"
     411             :     case '[':    // 1 string to match.
     412             :       return MCK__91_;   // "["
     413             :     case ']':    // 1 string to match.
     414             :       return MCK__93_;   // "]"
     415             :     case '^':    // 1 string to match.
     416             :       return MCK__94_;   // "^"
     417             :     case 's':    // 1 string to match.
     418             :       return MCK_s;      // "s"
     419             :     case '|':    // 1 string to match.
     420             :       return MCK__124_;  // "|"
     421             :     }
     422             :     break;
     423          43 :   case 2:        // 3 strings to match.
     424             :     switch (Name[0]) {
     425             :     default: break;
     426           0 :     case 'i':    // 1 string to match.
     427           0 :       if (Name[1] != 'f')
     428             :         break;
     429             :       return MCK_if;     // "if"
     430           4 :     case 'l':    // 1 string to match.
     431           4 :       if (Name[1] != 'l')
     432             :         break;
     433             :       return MCK_ll;     // "ll"
     434          39 :     case 'u':    // 1 string to match.
     435          39 :       if (Name[1] != '8')
     436             :         break;
     437             :       return MCK_u8;     // "u8"
     438             :     }
     439             :     break;
     440          68 :   case 3:        // 6 strings to match.
     441             :     switch (Name[0]) {
     442             :     default: break;
     443             :     case 'l':    // 1 string to match.
     444           0 :       if (memcmp(Name.data()+1, "ea", 2) != 0)
     445             :         break;
     446             :       return MCK_lea;    // "lea"
     447             :     case 'n':    // 1 string to match.
     448           0 :       if (memcmp(Name.data()+1, "op", 2) != 0)
     449             :         break;
     450             :       return MCK_nop;    // "nop"
     451             :     case 's':    // 1 string to match.
     452          15 :       if (memcmp(Name.data()+1, "kb", 2) != 0)
     453             :         break;
     454             :       return MCK_skb;    // "skb"
     455          53 :     case 'u':    // 3 strings to match.
     456             :       switch (Name[1]) {
     457             :       default: break;
     458          16 :       case '1':  // 1 string to match.
     459          16 :         if (Name[2] != '6')
     460             :           break;
     461             :         return MCK_u16;  // "u16"
     462          27 :       case '3':  // 1 string to match.
     463          27 :         if (Name[2] != '2')
     464             :           break;
     465             :         return MCK_u32;  // "u32"
     466          10 :       case '6':  // 1 string to match.
     467          10 :         if (Name[2] != '4')
     468             :           break;
     469             :         return MCK_u64;  // "u64"
     470             :       }
     471             :       break;
     472             :     }
     473             :     break;
     474          29 :   case 4:        // 10 strings to match.
     475             :     switch (Name[0]) {
     476             :     default: break;
     477           9 :     case 'b':    // 3 strings to match.
     478           9 :       if (Name[1] != 'e')
     479             :         break;
     480             :       switch (Name[2]) {
     481             :       default: break;
     482           2 :       case '1':  // 1 string to match.
     483           2 :         if (Name[3] != '6')
     484             :           break;
     485             :         return MCK_be16;         // "be16"
     486           3 :       case '3':  // 1 string to match.
     487           3 :         if (Name[3] != '2')
     488             :           break;
     489             :         return MCK_be32;         // "be32"
     490           4 :       case '6':  // 1 string to match.
     491           4 :         if (Name[3] != '4')
     492             :           break;
     493             :         return MCK_be64;         // "be64"
     494             :       }
     495             :       break;
     496             :     case 'c':    // 1 string to match.
     497           0 :       if (memcmp(Name.data()+1, "all", 3) != 0)
     498             :         break;
     499             :       return MCK_call;   // "call"
     500             :     case 'e':    // 1 string to match.
     501           0 :       if (memcmp(Name.data()+1, "xit", 3) != 0)
     502             :         break;
     503             :       return MCK_exit;   // "exit"
     504             :     case 'g':    // 1 string to match.
     505          20 :       if (memcmp(Name.data()+1, "oto", 3) != 0)
     506             :         break;
     507             :       return MCK_goto;   // "goto"
     508           0 :     case 'l':    // 4 strings to match.
     509             :       switch (Name[1]) {
     510             :       default: break;
     511           0 :       case 'e':  // 3 strings to match.
     512             :         switch (Name[2]) {
     513             :         default: break;
     514           0 :         case '1':        // 1 string to match.
     515           0 :           if (Name[3] != '6')
     516             :             break;
     517             :           return MCK_le16;       // "le16"
     518           0 :         case '3':        // 1 string to match.
     519           0 :           if (Name[3] != '2')
     520             :             break;
     521             :           return MCK_le32;       // "le32"
     522           0 :         case '6':        // 1 string to match.
     523           0 :           if (Name[3] != '4')
     524             :             break;
     525             :           return MCK_le64;       // "le64"
     526             :         }
     527             :         break;
     528             :       case 'o':  // 1 string to match.
     529           0 :         if (memcmp(Name.data()+2, "ck", 2) != 0)
     530             :           break;
     531             :         return MCK_lock;         // "lock"
     532             :       }
     533             :       break;
     534             :     }
     535             :     break;
     536             :   case 5:        // 1 string to match.
     537           0 :     if (memcmp(Name.data()+0, "callx", 5) != 0)
     538             :       break;
     539             :     return MCK_callx;    // "callx"
     540             :   case 9:        // 1 string to match.
     541           0 :     if (memcmp(Name.data()+0, "ld_pseudo", 9) != 0)
     542             :       break;
     543             :     return MCK_ld_95_pseudo;     // "ld_pseudo"
     544             :   }
     545             :   return InvalidMatchClass;
     546             : }
     547             : 
     548             : /// isSubclass - Compute whether \p A is a subclass of \p B.
     549             : static bool isSubclass(MatchClassKind A, MatchClassKind B) {
     550        5303 :   if (A == B)
     551             :     return true;
     552             : 
     553        2693 :   switch (A) {
     554             :   default:
     555             :     return false;
     556             : 
     557         621 :   case MCK_R0:
     558         621 :     return B == MCK_GPR;
     559             :   }
     560             : }
     561             : 
     562        4976 : static unsigned validateOperandClass(MCParsedAsmOperand &GOp, MatchClassKind Kind) {
     563             :   BPFOperand &Operand = (BPFOperand&)GOp;
     564        4976 :   if (Kind == InvalidMatchClass)
     565             :     return MCTargetAsmParser::Match_InvalidOperand;
     566             : 
     567        4972 :   if (Operand.isToken() && Kind <= MCK_LAST_TOKEN)
     568        2035 :     return isSubclass(matchTokenString(Operand.getToken()), Kind) ?
     569             :              MCTargetAsmParser::Match_Success :
     570             :              MCTargetAsmParser::Match_InvalidOperand;
     571             : 
     572        2937 :   switch (Kind) {
     573             :   default: break;
     574             :   // 'Imm' class
     575         122 :   case MCK_Imm: {
     576             :     DiagnosticPredicate DP(Operand.isImm());
     577         122 :     if (DP.isMatch())
     578             :       return MCTargetAsmParser::Match_Success;
     579             :     break;
     580             :     }
     581             :   } // end switch (Kind)
     582             : 
     583        2851 :   if (Operand.isReg()) {
     584             :     MatchClassKind OpKind;
     585             :     switch (Operand.getReg()) {
     586             :     default: OpKind = InvalidMatchClass; break;
     587             :     case BPF::W0: OpKind = MCK_GPR32; break;
     588             :     case BPF::R0: OpKind = MCK_R0; break;
     589             :     case BPF::W1: OpKind = MCK_GPR32; break;
     590             :     case BPF::R1: OpKind = MCK_GPR; break;
     591             :     case BPF::W2: OpKind = MCK_GPR32; break;
     592             :     case BPF::R2: OpKind = MCK_GPR; break;
     593             :     case BPF::W3: OpKind = MCK_GPR32; break;
     594             :     case BPF::R3: OpKind = MCK_GPR; break;
     595             :     case BPF::W4: OpKind = MCK_GPR32; break;
     596             :     case BPF::R4: OpKind = MCK_GPR; break;
     597             :     case BPF::W5: OpKind = MCK_GPR32; break;
     598             :     case BPF::R5: OpKind = MCK_GPR; break;
     599             :     case BPF::W6: OpKind = MCK_GPR32; break;
     600             :     case BPF::R6: OpKind = MCK_GPR; break;
     601             :     case BPF::W7: OpKind = MCK_GPR32; break;
     602             :     case BPF::R7: OpKind = MCK_GPR; break;
     603             :     case BPF::W8: OpKind = MCK_GPR32; break;
     604             :     case BPF::R8: OpKind = MCK_GPR; break;
     605             :     case BPF::W9: OpKind = MCK_GPR32; break;
     606             :     case BPF::R9: OpKind = MCK_GPR; break;
     607             :     case BPF::W10: OpKind = MCK_GPR32; break;
     608             :     case BPF::R10: OpKind = MCK_GPR; break;
     609             :     case BPF::W11: OpKind = MCK_GPR32; break;
     610             :     case BPF::R11: OpKind = MCK_GPR; break;
     611             :     }
     612         621 :     return isSubclass(OpKind, Kind) ? (unsigned)MCTargetAsmParser::Match_Success :
     613             :                                       getDiagKindFromRegisterClass(Kind);
     614             :   }
     615             : 
     616             :   if (Kind > MCK_LAST_TOKEN && Kind <= MCK_LAST_REGISTER)
     617             :     return getDiagKindFromRegisterClass(Kind);
     618             : 
     619             :   return MCTargetAsmParser::Match_InvalidOperand;
     620             : }
     621             : 
     622             : #ifndef NDEBUG
     623             : const char *getMatchClassName(MatchClassKind Kind) {
     624             :   switch (Kind) {
     625             :   case InvalidMatchClass: return "InvalidMatchClass";
     626             :   case OptionalMatchClass: return "OptionalMatchClass";
     627             :   case MCK__EXCLAIM_: return "MCK__EXCLAIM_";
     628             :   case MCK__38_: return "MCK__38_";
     629             :   case MCK__40_: return "MCK__40_";
     630             :   case MCK__41_: return "MCK__41_";
     631             :   case MCK__STAR_: return "MCK__STAR_";
     632             :   case MCK__43_: return "MCK__43_";
     633             :   case MCK__MINUS_: return "MCK__MINUS_";
     634             :   case MCK__47_: return "MCK__47_";
     635             :   case MCK__LT_: return "MCK__LT_";
     636             :   case MCK__61_: return "MCK__61_";
     637             :   case MCK__GT_: return "MCK__GT_";
     638             :   case MCK__91_: return "MCK__91_";
     639             :   case MCK__93_: return "MCK__93_";
     640             :   case MCK__94_: return "MCK__94_";
     641             :   case MCK_be16: return "MCK_be16";
     642             :   case MCK_be32: return "MCK_be32";
     643             :   case MCK_be64: return "MCK_be64";
     644             :   case MCK_call: return "MCK_call";
     645             :   case MCK_callx: return "MCK_callx";
     646             :   case MCK_exit: return "MCK_exit";
     647             :   case MCK_goto: return "MCK_goto";
     648             :   case MCK_if: return "MCK_if";
     649             :   case MCK_ld_95_pseudo: return "MCK_ld_95_pseudo";
     650             :   case MCK_le16: return "MCK_le16";
     651             :   case MCK_le32: return "MCK_le32";
     652             :   case MCK_le64: return "MCK_le64";
     653             :   case MCK_lea: return "MCK_lea";
     654             :   case MCK_ll: return "MCK_ll";
     655             :   case MCK_lock: return "MCK_lock";
     656             :   case MCK_nop: return "MCK_nop";
     657             :   case MCK_s: return "MCK_s";
     658             :   case MCK_skb: return "MCK_skb";
     659             :   case MCK_u16: return "MCK_u16";
     660             :   case MCK_u32: return "MCK_u32";
     661             :   case MCK_u64: return "MCK_u64";
     662             :   case MCK_u8: return "MCK_u8";
     663             :   case MCK__124_: return "MCK__124_";
     664             :   case MCK_R0: return "MCK_R0";
     665             :   case MCK_GPR: return "MCK_GPR";
     666             :   case MCK_GPR32: return "MCK_GPR32";
     667             :   case MCK_Imm: return "MCK_Imm";
     668             :   case NumMatchClassKinds: return "NumMatchClassKinds";
     669             :   }
     670             :   llvm_unreachable("unhandled MatchClassKind!");
     671             : }
     672             : 
     673             : #endif // NDEBUG
     674           0 : uint64_t BPFAsmParser::
     675             : ComputeAvailableFeatures(const FeatureBitset& FB) const {
     676             :   uint64_t Features = 0;
     677           0 :   return Features;
     678             : }
     679             : 
     680         100 : static bool checkAsmTiedOperandConstraints(const BPFAsmParser&AsmParser,
     681             :                                unsigned Kind,
     682             :                                const OperandVector &Operands,
     683             :                                uint64_t &ErrorInfo) {
     684             :   assert(Kind < CVT_NUM_SIGNATURES && "Invalid signature!");
     685         100 :   const uint8_t *Converter = ConversionTable[Kind];
     686         374 :   for (const uint8_t *p = Converter; *p; p+= 2) {
     687         274 :     switch (*p) {
     688          47 :     case CVT_Tied: {
     689          47 :       unsigned OpIdx = *(p+1);
     690             :       assert(OpIdx < (size_t)(std::end(TiedAsmOperandTable) -
     691             :                               std::begin(TiedAsmOperandTable)) &&
     692             :              "Tied operand not found");
     693          47 :       unsigned OpndNum1 = TiedAsmOperandTable[OpIdx][1];
     694          47 :       unsigned OpndNum2 = TiedAsmOperandTable[OpIdx][2];
     695          47 :       if (OpndNum1 != OpndNum2) {
     696           5 :         auto &SrcOp1 = Operands[OpndNum1];
     697           5 :         auto &SrcOp2 = Operands[OpndNum2];
     698           5 :         if (SrcOp1->isReg() && SrcOp2->isReg()) {
     699          10 :           if (!AsmParser.regsEqual(*SrcOp1, *SrcOp2)) {
     700           0 :             ErrorInfo = OpndNum2;
     701           0 :             return false;
     702             :           }
     703             :         }
     704             :       }
     705             :       break;
     706             :     }
     707             :     default:
     708             :       break;
     709             :     }
     710             :   }
     711             :   return true;
     712             : }
     713             : 
     714             : static const char *const MnemonicTable =
     715             :     "\000\001*\004call\005callx\004exit\004goto\002if\tld_pseudo\003lea\004l"
     716             :     "ock\003nop\002r0";
     717             : 
     718             : namespace {
     719             :   struct MatchEntry {
     720             :     uint8_t Mnemonic;
     721             :     uint16_t Opcode;
     722             :     uint8_t ConvertFn;
     723             :     uint8_t RequiredFeatures;
     724             :     uint8_t Classes[13];
     725           0 :     StringRef getMnemonic() const {
     726           0 :       return StringRef(MnemonicTable + Mnemonic + 1,
     727           0 :                        MnemonicTable[Mnemonic]);
     728             :     }
     729             :   };
     730             : 
     731             :   // Predicate for searching for an opcode.
     732             :   struct LessOpcode {
     733           0 :     bool operator()(const MatchEntry &LHS, StringRef RHS) {
     734           0 :       return LHS.getMnemonic() < RHS;
     735             :     }
     736           0 :     bool operator()(StringRef LHS, const MatchEntry &RHS) {
     737           0 :       return LHS < RHS.getMnemonic();
     738             :     }
     739             :     bool operator()(const MatchEntry &LHS, const MatchEntry &RHS) {
     740             :       return LHS.getMnemonic() < RHS.getMnemonic();
     741             :     }
     742             :   };
     743             : } // end anonymous namespace.
     744             : 
     745             : static const MatchEntry MatchTable0[] = {
     746             :   { 0 /*  */, BPF::MOV_rr, Convert__Reg1_0__Reg1_2, 0, { MCK_GPR, MCK__61_, MCK_GPR }, },
     747             :   { 0 /*  */, BPF::MOV_ri, Convert__Reg1_0__Imm1_2, 0, { MCK_GPR, MCK__61_, MCK_Imm }, },
     748             :   { 0 /*  */, BPF::MOV_rr_32, Convert__Reg1_0__Reg1_2, 0, { MCK_GPR32, MCK__61_, MCK_GPR32 }, },
     749             :   { 0 /*  */, BPF::MOV_ri_32, Convert__Reg1_0__Imm1_2, 0, { MCK_GPR32, MCK__61_, MCK_Imm }, },
     750             :   { 0 /*  */, BPF::AND_rr, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR, MCK__38_, MCK__61_, MCK_GPR }, },
     751             :   { 0 /*  */, BPF::AND_ri, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR, MCK__38_, MCK__61_, MCK_Imm }, },
     752             :   { 0 /*  */, BPF::MUL_rr, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR, MCK__STAR_, MCK__61_, MCK_GPR }, },
     753             :   { 0 /*  */, BPF::MUL_ri, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR, MCK__STAR_, MCK__61_, MCK_Imm }, },
     754             :   { 0 /*  */, BPF::ADD_rr, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR, MCK__43_, MCK__61_, MCK_GPR }, },
     755             :   { 0 /*  */, BPF::ADD_ri, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR, MCK__43_, MCK__61_, MCK_Imm }, },
     756             :   { 0 /*  */, BPF::SUB_rr, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR, MCK__MINUS_, MCK__61_, MCK_GPR }, },
     757             :   { 0 /*  */, BPF::SUB_ri, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR, MCK__MINUS_, MCK__61_, MCK_Imm }, },
     758             :   { 0 /*  */, BPF::DIV_rr, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR, MCK__47_, MCK__61_, MCK_GPR }, },
     759             :   { 0 /*  */, BPF::DIV_ri, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR, MCK__47_, MCK__61_, MCK_Imm }, },
     760             :   { 0 /*  */, BPF::NEG_64, Convert__Reg1_0__Tie0_0_3, 0, { MCK_GPR, MCK__61_, MCK__MINUS_, MCK_GPR }, },
     761             :   { 0 /*  */, BPF::BE16, Convert__Reg1_0__Tie0_0_3, 0, { MCK_GPR, MCK__61_, MCK_be16, MCK_GPR }, },
     762             :   { 0 /*  */, BPF::BE32, Convert__Reg1_0__Tie0_0_3, 0, { MCK_GPR, MCK__61_, MCK_be32, MCK_GPR }, },
     763             :   { 0 /*  */, BPF::BE64, Convert__Reg1_0__Tie0_0_3, 0, { MCK_GPR, MCK__61_, MCK_be64, MCK_GPR }, },
     764             :   { 0 /*  */, BPF::LE16, Convert__Reg1_0__Tie0_0_3, 0, { MCK_GPR, MCK__61_, MCK_le16, MCK_GPR }, },
     765             :   { 0 /*  */, BPF::LE32, Convert__Reg1_0__Tie0_0_3, 0, { MCK_GPR, MCK__61_, MCK_le32, MCK_GPR }, },
     766             :   { 0 /*  */, BPF::LE64, Convert__Reg1_0__Tie0_0_3, 0, { MCK_GPR, MCK__61_, MCK_le64, MCK_GPR }, },
     767             :   { 0 /*  */, BPF::LD_imm64, Convert__Reg1_0__Imm1_2, 0, { MCK_GPR, MCK__61_, MCK_Imm, MCK_ll }, },
     768             :   { 0 /*  */, BPF::XOR_rr, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR, MCK__94_, MCK__61_, MCK_GPR }, },
     769             :   { 0 /*  */, BPF::XOR_ri, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR, MCK__94_, MCK__61_, MCK_Imm }, },
     770             :   { 0 /*  */, BPF::OR_rr, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR, MCK__124_, MCK__61_, MCK_GPR }, },
     771             :   { 0 /*  */, BPF::OR_ri, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR, MCK__124_, MCK__61_, MCK_Imm }, },
     772             :   { 0 /*  */, BPF::AND_rr_32, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR32, MCK__38_, MCK__61_, MCK_GPR32 }, },
     773             :   { 0 /*  */, BPF::AND_ri_32, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR32, MCK__38_, MCK__61_, MCK_Imm }, },
     774             :   { 0 /*  */, BPF::MUL_rr_32, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR32, MCK__STAR_, MCK__61_, MCK_GPR32 }, },
     775             :   { 0 /*  */, BPF::MUL_ri_32, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR32, MCK__STAR_, MCK__61_, MCK_Imm }, },
     776             :   { 0 /*  */, BPF::ADD_rr_32, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR32, MCK__43_, MCK__61_, MCK_GPR32 }, },
     777             :   { 0 /*  */, BPF::ADD_ri_32, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR32, MCK__43_, MCK__61_, MCK_Imm }, },
     778             :   { 0 /*  */, BPF::SUB_rr_32, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR32, MCK__MINUS_, MCK__61_, MCK_GPR32 }, },
     779             :   { 0 /*  */, BPF::SUB_ri_32, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR32, MCK__MINUS_, MCK__61_, MCK_Imm }, },
     780             :   { 0 /*  */, BPF::DIV_rr_32, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR32, MCK__47_, MCK__61_, MCK_GPR32 }, },
     781             :   { 0 /*  */, BPF::DIV_ri_32, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR32, MCK__47_, MCK__61_, MCK_Imm }, },
     782             :   { 0 /*  */, BPF::NEG_32, Convert__Reg1_0__Tie0_0_3, 0, { MCK_GPR32, MCK__61_, MCK__MINUS_, MCK_GPR32 }, },
     783             :   { 0 /*  */, BPF::XOR_rr_32, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR32, MCK__94_, MCK__61_, MCK_GPR32 }, },
     784             :   { 0 /*  */, BPF::XOR_ri_32, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR32, MCK__94_, MCK__61_, MCK_Imm }, },
     785             :   { 0 /*  */, BPF::OR_rr_32, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR32, MCK__124_, MCK__61_, MCK_GPR32 }, },
     786             :   { 0 /*  */, BPF::OR_ri_32, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR32, MCK__124_, MCK__61_, MCK_Imm }, },
     787             :   { 0 /*  */, BPF::SLL_rr, Convert__Reg1_0__Tie0_0_0__Reg1_4, 0, { MCK_GPR, MCK__LT_, MCK__LT_, MCK__61_, MCK_GPR }, },
     788             :   { 0 /*  */, BPF::SLL_ri, Convert__Reg1_0__Tie0_0_0__Imm1_4, 0, { MCK_GPR, MCK__LT_, MCK__LT_, MCK__61_, MCK_Imm }, },
     789             :   { 0 /*  */, BPF::SRL_rr, Convert__Reg1_0__Tie0_0_0__Reg1_4, 0, { MCK_GPR, MCK__GT_, MCK__GT_, MCK__61_, MCK_GPR }, },
     790             :   { 0 /*  */, BPF::SRL_ri, Convert__Reg1_0__Tie0_0_0__Imm1_4, 0, { MCK_GPR, MCK__GT_, MCK__GT_, MCK__61_, MCK_Imm }, },
     791             :   { 0 /*  */, BPF::SLL_rr_32, Convert__Reg1_0__Tie0_0_0__Reg1_4, 0, { MCK_GPR32, MCK__LT_, MCK__LT_, MCK__61_, MCK_GPR32 }, },
     792             :   { 0 /*  */, BPF::SLL_ri_32, Convert__Reg1_0__Tie0_0_0__Imm1_4, 0, { MCK_GPR32, MCK__LT_, MCK__LT_, MCK__61_, MCK_Imm }, },
     793             :   { 0 /*  */, BPF::SRL_rr_32, Convert__Reg1_0__Tie0_0_0__Reg1_4, 0, { MCK_GPR32, MCK__GT_, MCK__GT_, MCK__61_, MCK_GPR32 }, },
     794             :   { 0 /*  */, BPF::SRL_ri_32, Convert__Reg1_0__Tie0_0_0__Imm1_4, 0, { MCK_GPR32, MCK__GT_, MCK__GT_, MCK__61_, MCK_Imm }, },
     795             :   { 0 /*  */, BPF::SRA_rr, Convert__Reg1_0__Tie0_0_0__Reg1_5, 0, { MCK_GPR, MCK_s, MCK__GT_, MCK__GT_, MCK__61_, MCK_GPR }, },
     796             :   { 0 /*  */, BPF::SRA_ri, Convert__Reg1_0__Tie0_0_0__Imm1_5, 0, { MCK_GPR, MCK_s, MCK__GT_, MCK__GT_, MCK__61_, MCK_Imm }, },
     797             :   { 0 /*  */, BPF::SRA_rr_32, Convert__Reg1_0__Tie0_0_0__Reg1_5, 0, { MCK_GPR32, MCK_s, MCK__GT_, MCK__GT_, MCK__61_, MCK_GPR32 }, },
     798             :   { 0 /*  */, BPF::SRA_ri_32, Convert__Reg1_0__Tie0_0_0__Imm1_5, 0, { MCK_GPR32, MCK_s, MCK__GT_, MCK__GT_, MCK__61_, MCK_Imm }, },
     799             :   { 0 /*  */, BPF::LDH, Convert__Reg1_0__Reg1_8__Imm1_9, 0, { MCK_GPR, MCK__61_, MCK__STAR_, MCK__40_, MCK_u16, MCK__STAR_, MCK__41_, MCK__40_, MCK_GPR, MCK_Imm, MCK__41_ }, },
     800             :   { 0 /*  */, BPF::LDW, Convert__Reg1_0__Reg1_8__Imm1_9, 0, { MCK_GPR, MCK__61_, MCK__STAR_, MCK__40_, MCK_u32, MCK__STAR_, MCK__41_, MCK__40_, MCK_GPR, MCK_Imm, MCK__41_ }, },
     801             :   { 0 /*  */, BPF::LDD, Convert__Reg1_0__Reg1_8__Imm1_9, 0, { MCK_GPR, MCK__61_, MCK__STAR_, MCK__40_, MCK_u64, MCK__STAR_, MCK__41_, MCK__40_, MCK_GPR, MCK_Imm, MCK__41_ }, },
     802             :   { 0 /*  */, BPF::LDB, Convert__Reg1_0__Reg1_8__Imm1_9, 0, { MCK_GPR, MCK__61_, MCK__STAR_, MCK__40_, MCK_u8, MCK__STAR_, MCK__41_, MCK__40_, MCK_GPR, MCK_Imm, MCK__41_ }, },
     803             :   { 0 /*  */, BPF::LDH32, Convert__Reg1_0__Reg1_8__Imm1_9, 0, { MCK_GPR32, MCK__61_, MCK__STAR_, MCK__40_, MCK_u16, MCK__STAR_, MCK__41_, MCK__40_, MCK_GPR, MCK_Imm, MCK__41_ }, },
     804             :   { 0 /*  */, BPF::LDW32, Convert__Reg1_0__Reg1_8__Imm1_9, 0, { MCK_GPR32, MCK__61_, MCK__STAR_, MCK__40_, MCK_u32, MCK__STAR_, MCK__41_, MCK__40_, MCK_GPR, MCK_Imm, MCK__41_ }, },
     805             :   { 0 /*  */, BPF::LDB32, Convert__Reg1_0__Reg1_8__Imm1_9, 0, { MCK_GPR32, MCK__61_, MCK__STAR_, MCK__40_, MCK_u8, MCK__STAR_, MCK__41_, MCK__40_, MCK_GPR, MCK_Imm, MCK__41_ }, },
     806             :   { 1 /* * */, BPF::STH, Convert__Reg1_10__Reg1_6__Imm1_7, 0, { MCK__STAR_, MCK__40_, MCK_u16, MCK__STAR_, MCK__41_, MCK__40_, MCK_GPR, MCK_Imm, MCK__41_, MCK__61_, MCK_GPR }, },
     807             :   { 1 /* * */, BPF::STH32, Convert__Reg1_10__Reg1_6__Imm1_7, 0, { MCK__STAR_, MCK__40_, MCK_u16, MCK__STAR_, MCK__41_, MCK__40_, MCK_GPR, MCK_Imm, MCK__41_, MCK__61_, MCK_GPR32 }, },
     808             :   { 1 /* * */, BPF::STW, Convert__Reg1_10__Reg1_6__Imm1_7, 0, { MCK__STAR_, MCK__40_, MCK_u32, MCK__STAR_, MCK__41_, MCK__40_, MCK_GPR, MCK_Imm, MCK__41_, MCK__61_, MCK_GPR }, },
     809             :   { 1 /* * */, BPF::STW32, Convert__Reg1_10__Reg1_6__Imm1_7, 0, { MCK__STAR_, MCK__40_, MCK_u32, MCK__STAR_, MCK__41_, MCK__40_, MCK_GPR, MCK_Imm, MCK__41_, MCK__61_, MCK_GPR32 }, },
     810             :   { 1 /* * */, BPF::STD, Convert__Reg1_10__Reg1_6__Imm1_7, 0, { MCK__STAR_, MCK__40_, MCK_u64, MCK__STAR_, MCK__41_, MCK__40_, MCK_GPR, MCK_Imm, MCK__41_, MCK__61_, MCK_GPR }, },
     811             :   { 1 /* * */, BPF::STB, Convert__Reg1_10__Reg1_6__Imm1_7, 0, { MCK__STAR_, MCK__40_, MCK_u8, MCK__STAR_, MCK__41_, MCK__40_, MCK_GPR, MCK_Imm, MCK__41_, MCK__61_, MCK_GPR }, },
     812             :   { 1 /* * */, BPF::STB32, Convert__Reg1_10__Reg1_6__Imm1_7, 0, { MCK__STAR_, MCK__40_, MCK_u8, MCK__STAR_, MCK__41_, MCK__40_, MCK_GPR, MCK_Imm, MCK__41_, MCK__61_, MCK_GPR32 }, },
     813             :   { 3 /* call */, BPF::JAL, Convert__Imm1_1, 0, { MCK_call, MCK_Imm }, },
     814             :   { 8 /* callx */, BPF::JALX, Convert__Imm1_1, 0, { MCK_callx, MCK_Imm }, },
     815             :   { 14 /* exit */, BPF::RET, Convert_NoOperands, 0, { MCK_exit }, },
     816             :   { 19 /* goto */, BPF::JMP, Convert__Imm1_1, 0, { MCK_goto, MCK_Imm }, },
     817             :   { 24 /* if */, BPF::JULT_rr, Convert__Reg1_1__Reg1_3__Imm1_5, 0, { MCK_if, MCK_GPR, MCK__LT_, MCK_GPR, MCK_goto, MCK_Imm }, },
     818             :   { 24 /* if */, BPF::JULT_ri, Convert__Reg1_1__Imm1_3__Imm1_5, 0, { MCK_if, MCK_GPR, MCK__LT_, MCK_Imm, MCK_goto, MCK_Imm }, },
     819             :   { 24 /* if */, BPF::JUGT_rr, Convert__Reg1_1__Reg1_3__Imm1_5, 0, { MCK_if, MCK_GPR, MCK__GT_, MCK_GPR, MCK_goto, MCK_Imm }, },
     820             :   { 24 /* if */, BPF::JUGT_ri, Convert__Reg1_1__Imm1_3__Imm1_5, 0, { MCK_if, MCK_GPR, MCK__GT_, MCK_Imm, MCK_goto, MCK_Imm }, },
     821             :   { 24 /* if */, BPF::JNE_rr, Convert__Reg1_1__Reg1_4__Imm1_6, 0, { MCK_if, MCK_GPR, MCK__EXCLAIM_, MCK__61_, MCK_GPR, MCK_goto, MCK_Imm }, },
     822             :   { 24 /* if */, BPF::JNE_ri, Convert__Reg1_1__Imm1_4__Imm1_6, 0, { MCK_if, MCK_GPR, MCK__EXCLAIM_, MCK__61_, MCK_Imm, MCK_goto, MCK_Imm }, },
     823             :   { 24 /* if */, BPF::JULE_rr, Convert__Reg1_1__Reg1_4__Imm1_6, 0, { MCK_if, MCK_GPR, MCK__LT_, MCK__61_, MCK_GPR, MCK_goto, MCK_Imm }, },
     824             :   { 24 /* if */, BPF::JULE_ri, Convert__Reg1_1__Imm1_4__Imm1_6, 0, { MCK_if, MCK_GPR, MCK__LT_, MCK__61_, MCK_Imm, MCK_goto, MCK_Imm }, },
     825             :   { 24 /* if */, BPF::JEQ_rr, Convert__Reg1_1__Reg1_4__Imm1_6, 0, { MCK_if, MCK_GPR, MCK__61_, MCK__61_, MCK_GPR, MCK_goto, MCK_Imm }, },
     826             :   { 24 /* if */, BPF::JEQ_ri, Convert__Reg1_1__Imm1_4__Imm1_6, 0, { MCK_if, MCK_GPR, MCK__61_, MCK__61_, MCK_Imm, MCK_goto, MCK_Imm }, },
     827             :   { 24 /* if */, BPF::JUGE_rr, Convert__Reg1_1__Reg1_4__Imm1_6, 0, { MCK_if, MCK_GPR, MCK__GT_, MCK__61_, MCK_GPR, MCK_goto, MCK_Imm }, },
     828             :   { 24 /* if */, BPF::JUGE_ri, Convert__Reg1_1__Imm1_4__Imm1_6, 0, { MCK_if, MCK_GPR, MCK__GT_, MCK__61_, MCK_Imm, MCK_goto, MCK_Imm }, },
     829             :   { 24 /* if */, BPF::JSLT_rr, Convert__Reg1_1__Reg1_4__Imm1_6, 0, { MCK_if, MCK_GPR, MCK_s, MCK__LT_, MCK_GPR, MCK_goto, MCK_Imm }, },
     830             :   { 24 /* if */, BPF::JSLT_ri, Convert__Reg1_1__Imm1_4__Imm1_6, 0, { MCK_if, MCK_GPR, MCK_s, MCK__LT_, MCK_Imm, MCK_goto, MCK_Imm }, },
     831             :   { 24 /* if */, BPF::JSGT_rr, Convert__Reg1_1__Reg1_4__Imm1_6, 0, { MCK_if, MCK_GPR, MCK_s, MCK__GT_, MCK_GPR, MCK_goto, MCK_Imm }, },
     832             :   { 24 /* if */, BPF::JSGT_ri, Convert__Reg1_1__Imm1_4__Imm1_6, 0, { MCK_if, MCK_GPR, MCK_s, MCK__GT_, MCK_Imm, MCK_goto, MCK_Imm }, },
     833             :   { 24 /* if */, BPF::JSLE_rr, Convert__Reg1_1__Reg1_5__Imm1_7, 0, { MCK_if, MCK_GPR, MCK_s, MCK__LT_, MCK__61_, MCK_GPR, MCK_goto, MCK_Imm }, },
     834             :   { 24 /* if */, BPF::JSLE_ri, Convert__Reg1_1__Imm1_5__Imm1_7, 0, { MCK_if, MCK_GPR, MCK_s, MCK__LT_, MCK__61_, MCK_Imm, MCK_goto, MCK_Imm }, },
     835             :   { 24 /* if */, BPF::JSGE_rr, Convert__Reg1_1__Reg1_5__Imm1_7, 0, { MCK_if, MCK_GPR, MCK_s, MCK__GT_, MCK__61_, MCK_GPR, MCK_goto, MCK_Imm }, },
     836             :   { 24 /* if */, BPF::JSGE_ri, Convert__Reg1_1__Imm1_5__Imm1_7, 0, { MCK_if, MCK_GPR, MCK_s, MCK__GT_, MCK__61_, MCK_Imm, MCK_goto, MCK_Imm }, },
     837             :   { 27 /* ld_pseudo */, BPF::LD_pseudo, Convert__Reg1_1__Imm1_2__Imm1_3, 0, { MCK_ld_95_pseudo, MCK_GPR, MCK_Imm, MCK_Imm }, },
     838             :   { 37 /* lea */, BPF::FI_ri, Convert__Reg1_1__Reg1_2__Imm1_3, 0, { MCK_lea, MCK_GPR, MCK_GPR, MCK_Imm }, },
     839             :   { 41 /* lock */, BPF::XADD32, Convert__Reg1_12__Reg1_7__Imm1_8__Tie0_12_12, 0, { MCK_lock, MCK__STAR_, MCK__40_, MCK_u32, MCK__STAR_, MCK__41_, MCK__40_, MCK_GPR, MCK_Imm, MCK__41_, MCK__43_, MCK__61_, MCK_GPR }, },
     840             :   { 41 /* lock */, BPF::XADD64, Convert__Reg1_12__Reg1_7__Imm1_8__Tie0_12_12, 0, { MCK_lock, MCK__STAR_, MCK__40_, MCK_u64, MCK__STAR_, MCK__41_, MCK__40_, MCK_GPR, MCK_Imm, MCK__41_, MCK__43_, MCK__61_, MCK_GPR }, },
     841             :   { 46 /* nop */, BPF::NOP, Convert__Imm1_1, 0, { MCK_nop, MCK_Imm }, },
     842             :   { 50 /* r0 */, BPF::LD_IND_H, Convert__imm_95_0__Reg1_9, 0, { MCK_R0, MCK__61_, MCK__STAR_, MCK__40_, MCK_u16, MCK__STAR_, MCK__41_, MCK_skb, MCK__91_, MCK_GPR, MCK__93_ }, },
     843             :   { 50 /* r0 */, BPF::LD_ABS_H, Convert__imm_95_0__Imm1_9, 0, { MCK_R0, MCK__61_, MCK__STAR_, MCK__40_, MCK_u16, MCK__STAR_, MCK__41_, MCK_skb, MCK__91_, MCK_Imm, MCK__93_ }, },
     844             :   { 50 /* r0 */, BPF::LD_IND_W, Convert__imm_95_0__Reg1_9, 0, { MCK_R0, MCK__61_, MCK__STAR_, MCK__40_, MCK_u32, MCK__STAR_, MCK__41_, MCK_skb, MCK__91_, MCK_GPR, MCK__93_ }, },
     845             :   { 50 /* r0 */, BPF::LD_ABS_W, Convert__imm_95_0__Imm1_9, 0, { MCK_R0, MCK__61_, MCK__STAR_, MCK__40_, MCK_u32, MCK__STAR_, MCK__41_, MCK_skb, MCK__91_, MCK_Imm, MCK__93_ }, },
     846             :   { 50 /* r0 */, BPF::LD_IND_B, Convert__imm_95_0__Reg1_9, 0, { MCK_R0, MCK__61_, MCK__STAR_, MCK__40_, MCK_u8, MCK__STAR_, MCK__41_, MCK_skb, MCK__91_, MCK_GPR, MCK__93_ }, },
     847             :   { 50 /* r0 */, BPF::LD_ABS_B, Convert__imm_95_0__Imm1_9, 0, { MCK_R0, MCK__61_, MCK__STAR_, MCK__40_, MCK_u8, MCK__STAR_, MCK__41_, MCK_skb, MCK__91_, MCK_Imm, MCK__93_ }, },
     848             : };
     849             : 
     850             : #include "llvm/Support/Debug.h"
     851             : #include "llvm/Support/Format.h"
     852             : 
     853         100 : unsigned BPFAsmParser::
     854             : MatchInstructionImpl(const OperandVector &Operands,
     855             :                      MCInst &Inst,
     856             :                      uint64_t &ErrorInfo,
     857             :                      bool matchingInlineAsm, unsigned VariantID) {
     858             :   // Eliminate obvious mismatches.
     859         100 :   if (Operands.size() > 13) {
     860           0 :     ErrorInfo = 13;
     861           0 :     return Match_InvalidOperand;
     862             :   }
     863             : 
     864             :   // Get the current feature set.
     865         100 :   uint64_t AvailableFeatures = getAvailableFeatures();
     866             : 
     867             :   // Get the instruction mnemonic, which is the first token.
     868         100 :   StringRef Mnemonic;
     869         100 :   if (Operands[0]->isToken())
     870          32 :     Mnemonic = ((BPFOperand&)*Operands[0]).getToken();
     871             : 
     872             :   // Some state to try to produce better error messages.
     873             :   bool HadMatchOtherThanFeatures = false;
     874             :   bool HadMatchOtherThanPredicate = false;
     875             :   unsigned RetCode = Match_InvalidOperand;
     876             :   uint64_t MissingFeatures = ~0ULL;
     877             :   // Set ErrorInfo to the operand that mismatches if it is
     878             :   // wrong for all instances of the instruction.
     879         100 :   ErrorInfo = ~0ULL;
     880             :   // Find the appropriate table for this asm variant.
     881             :   const MatchEntry *Start, *End;
     882         100 :   switch (VariantID) {
     883           0 :   default: llvm_unreachable("invalid variant!");
     884             :   case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
     885             :   }
     886             :   // Search the table.
     887             :   auto MnemonicRange = std::make_pair(Start, End);
     888         100 :   unsigned SIndex = Mnemonic.empty() ? 0 : 1;
     889         100 :   if (!Mnemonic.empty())
     890          64 :     MnemonicRange = std::equal_range(Start, End, Mnemonic.lower(), LessOpcode());
     891             : 
     892             :   DEBUG_WITH_TYPE("asm-matcher", dbgs() << "AsmMatcher: found " <<
     893             :   std::distance(MnemonicRange.first, MnemonicRange.second) << 
     894             :   " encodings with mnemonic '" << Mnemonic << "'\n");
     895             : 
     896             :   // Return a more specific error code if no mnemonics match.
     897         100 :   if (MnemonicRange.first == MnemonicRange.second)
     898             :     return Match_MnemonicFail;
     899             : 
     900        2583 :   for (const MatchEntry *it = MnemonicRange.first, *ie = MnemonicRange.second;
     901        2683 :        it != ie; ++it) {
     902        2683 :     bool HasRequiredFeatures =
     903        2683 :       (AvailableFeatures & it->RequiredFeatures) == it->RequiredFeatures;
     904             :     DEBUG_WITH_TYPE("asm-matcher", dbgs() << "Trying to match opcode "
     905             :                                           << MII.getName(it->Opcode) << "\n");
     906             :     bool OperandsValid = true;
     907        5076 :     for (unsigned FormalIdx = SIndex, ActualIdx = SIndex; FormalIdx != 13; ++FormalIdx) {
     908        5074 :       auto Formal = static_cast<MatchClassKind>(it->Classes[FormalIdx]);
     909             :       DEBUG_WITH_TYPE("asm-matcher",
     910             :                       dbgs() << "  Matching formal operand class " << getMatchClassName(Formal)
     911             :                              << " against actual operand at index " << ActualIdx);
     912        5074 :       if (ActualIdx < Operands.size())
     913             :         DEBUG_WITH_TYPE("asm-matcher", dbgs() << " (";
     914             :                         Operands[ActualIdx]->print(dbgs()); dbgs() << "): ");
     915             :       else
     916             :         DEBUG_WITH_TYPE("asm-matcher", dbgs() << ": ");
     917        5074 :       if (ActualIdx >= Operands.size()) {
     918             :         DEBUG_WITH_TYPE("asm-matcher", dbgs() << "actual operand index out of range ");
     919          98 :         OperandsValid = (Formal == InvalidMatchClass) || isSubclass(Formal, OptionalMatchClass);
     920           0 :         if (!OperandsValid) ErrorInfo = ActualIdx;
     921             :         break;
     922             :       }
     923             :       MCParsedAsmOperand &Actual = *Operands[ActualIdx];
     924        4976 :       unsigned Diag = validateOperandClass(Actual, Formal);
     925        4976 :       if (Diag == Match_Success) {
     926             :         DEBUG_WITH_TYPE("asm-matcher",
     927             :                         dbgs() << "match success using generic matcher\n");
     928        2393 :         ++ActualIdx;
     929        2393 :         continue;
     930             :       }
     931             :       // If the generic handler indicates an invalid operand
     932             :       // failure, check for a special case.
     933             :       if (Diag != Match_Success) {
     934        2583 :         unsigned TargetDiag = validateTargetOperandClass(Actual, Formal);
     935        2583 :         if (TargetDiag == Match_Success) {
     936             :           DEBUG_WITH_TYPE("asm-matcher",
     937             :                           dbgs() << "match success using target matcher\n");
     938           0 :           ++ActualIdx;
     939           0 :           continue;
     940             :         }
     941             :         // If the target matcher returned a specific error code use
     942             :         // that, else use the one from the generic matcher.
     943        2583 :         if (TargetDiag != Match_InvalidOperand && HasRequiredFeatures)
     944             :           Diag = TargetDiag;
     945             :       }
     946             :       // If current formal operand wasn't matched and it is optional
     947             :       // then try to match next formal operand
     948        2583 :       if (Diag == Match_InvalidOperand && isSubclass(Formal, OptionalMatchClass)) {
     949             :         DEBUG_WITH_TYPE("asm-matcher", dbgs() << "ignoring optional operand\n");
     950             :         continue;
     951             :       }
     952             :       // If this operand is broken for all of the instances of this
     953             :       // mnemonic, keep track of it so we can report loc info.
     954             :       // If we already had a match that only failed due to a
     955             :       // target predicate, that diagnostic is preferred.
     956        2583 :       if (!HadMatchOtherThanPredicate &&
     957        2490 :           (it == MnemonicRange.first || ErrorInfo <= ActualIdx)) {
     958         951 :         if (HasRequiredFeatures && (ErrorInfo != ActualIdx || Diag != Match_InvalidOperand))
     959             :           RetCode = Diag;
     960         951 :         ErrorInfo = ActualIdx;
     961             :       }
     962             :       // Otherwise, just reject this instance of the mnemonic.
     963             :       OperandsValid = false;
     964             :       break;
     965             :     }
     966             : 
     967        2683 :     if (!OperandsValid) {
     968             :       DEBUG_WITH_TYPE("asm-matcher", dbgs() << "Opcode result: multiple "
     969             :                                                "operand mismatches, ignoring "
     970             :                                                "this opcode\n");
     971             :       continue;
     972             :     }
     973         100 :     if (!HasRequiredFeatures) {
     974             :       HadMatchOtherThanFeatures = true;
     975           0 :       uint64_t NewMissingFeatures = it->RequiredFeatures & ~AvailableFeatures;
     976             :       DEBUG_WITH_TYPE("asm-matcher", dbgs() << "Missing target features: "
     977             :                                             << format_hex(NewMissingFeatures, 18)
     978             :                                             << "\n");
     979           0 :       if (countPopulation(NewMissingFeatures) <=
     980             :           countPopulation(MissingFeatures))
     981             :         MissingFeatures = NewMissingFeatures;
     982           0 :       continue;
     983             :     }
     984             : 
     985             :     Inst.clear();
     986             : 
     987         100 :     Inst.setOpcode(it->Opcode);
     988             :     // We have a potential match but have not rendered the operands.
     989             :     // Check the target predicate to handle any context sensitive
     990             :     // constraints.
     991             :     // For example, Ties that are referenced multiple times must be
     992             :     // checked here to ensure the input is the same for each match
     993             :     // constraints. If we leave it any later the ties will have been
     994             :     // canonicalized
     995             :     unsigned MatchResult;
     996         100 :     if ((MatchResult = checkEarlyTargetMatchPredicate(Inst, Operands)) != Match_Success) {
     997             :       Inst.clear();
     998             :       DEBUG_WITH_TYPE(
     999             :           "asm-matcher",
    1000             :           dbgs() << "Early target match predicate failed with diag code "
    1001             :                  << MatchResult << "\n");
    1002             :       RetCode = MatchResult;
    1003             :       HadMatchOtherThanPredicate = true;
    1004             :       continue;
    1005             :     }
    1006             : 
    1007         100 :     if (matchingInlineAsm) {
    1008           0 :       convertToMapAndConstraints(it->ConvertFn, Operands);
    1009           0 :       if (!checkAsmTiedOperandConstraints(*this, it->ConvertFn, Operands, ErrorInfo))
    1010             :         return Match_InvalidTiedOperand;
    1011             : 
    1012           0 :       return Match_Success;
    1013             :     }
    1014             : 
    1015             :     // We have selected a definite instruction, convert the parsed
    1016             :     // operands into the appropriate MCInst.
    1017         100 :     convertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);
    1018             : 
    1019             :     // We have a potential match. Check the target predicate to
    1020             :     // handle any context sensitive constraints.
    1021         100 :     if ((MatchResult = checkTargetMatchPredicate(Inst)) != Match_Success) {
    1022             :       DEBUG_WITH_TYPE("asm-matcher",
    1023             :                       dbgs() << "Target match predicate failed with diag code "
    1024             :                              << MatchResult << "\n");
    1025             :       Inst.clear();
    1026             :       RetCode = MatchResult;
    1027             :       HadMatchOtherThanPredicate = true;
    1028           0 :       continue;
    1029             :     }
    1030             : 
    1031         100 :     if (!checkAsmTiedOperandConstraints(*this, it->ConvertFn, Operands, ErrorInfo))
    1032           0 :       return Match_InvalidTiedOperand;
    1033             : 
    1034             :     DEBUG_WITH_TYPE(
    1035             :         "asm-matcher",
    1036             :         dbgs() << "Opcode result: complete match, selecting this opcode\n");
    1037             :     return Match_Success;
    1038             :   }
    1039             : 
    1040             :   // Okay, we had no match.  Try to return a useful error code.
    1041           0 :   if (HadMatchOtherThanPredicate || !HadMatchOtherThanFeatures)
    1042             :     return RetCode;
    1043             : 
    1044             :   // Missing feature matches return which features were missing
    1045           0 :   ErrorInfo = MissingFeatures;
    1046           0 :   return Match_MissingFeature;
    1047             : }
    1048             : 
    1049             : #endif // GET_MATCHER_IMPLEMENTATION
    1050             : 
    1051             : 
    1052             : #ifdef GET_MNEMONIC_SPELL_CHECKER
    1053             : #undef GET_MNEMONIC_SPELL_CHECKER
    1054             : 
    1055             : static std::string BPFMnemonicSpellCheck(StringRef S, uint64_t FBS, unsigned VariantID) {
    1056             :   const unsigned MaxEditDist = 2;
    1057             :   std::vector<StringRef> Candidates;
    1058             :   StringRef Prev = "";
    1059             : 
    1060             :   // Find the appropriate table for this asm variant.
    1061             :   const MatchEntry *Start, *End;
    1062             :   switch (VariantID) {
    1063             :   default: llvm_unreachable("invalid variant!");
    1064             :   case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
    1065             :   }
    1066             : 
    1067             :   for (auto I = Start; I < End; I++) {
    1068             :     // Ignore unsupported instructions.
    1069             :     if ((FBS & I->RequiredFeatures) != I->RequiredFeatures)
    1070             :       continue;
    1071             : 
    1072             :     StringRef T = I->getMnemonic();
    1073             :     // Avoid recomputing the edit distance for the same string.
    1074             :     if (T.equals(Prev))
    1075             :       continue;
    1076             : 
    1077             :     Prev = T;
    1078             :     unsigned Dist = S.edit_distance(T, false, MaxEditDist);
    1079             :     if (Dist <= MaxEditDist)
    1080             :       Candidates.push_back(T);
    1081             :   }
    1082             : 
    1083             :   if (Candidates.empty())
    1084             :     return "";
    1085             : 
    1086             :   std::string Res = ", did you mean: ";
    1087             :   unsigned i = 0;
    1088             :   for( ; i < Candidates.size() - 1; i++)
    1089             :     Res += Candidates[i].str() + ", ";
    1090             :   return Res + Candidates[i].str() + "?";
    1091             : }
    1092             : 
    1093             : #endif // GET_MNEMONIC_SPELL_CHECKER
    1094             : 

Generated by: LCOV version 1.13