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: 114 231 49.4 %
Date: 2017-09-14 15:23:50 Functions: 5 7 71.4 %
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, bool matchingInlineAsm,
      22             :                                 unsigned VariantID = 0);
      23             : #endif // GET_ASSEMBLER_HEADER_INFO
      24             : 
      25             : 
      26             : #ifdef GET_OPERAND_DIAGNOSTIC_TYPES
      27             : #undef GET_OPERAND_DIAGNOSTIC_TYPES
      28             : 
      29             : #endif // GET_OPERAND_DIAGNOSTIC_TYPES
      30             : 
      31             : 
      32             : #ifdef GET_REGISTER_MATCHER
      33             : #undef GET_REGISTER_MATCHER
      34             : 
      35             : // Flags for subtarget features that participate in instruction matching.
      36             : enum SubtargetFeatureFlag : uint8_t {
      37             :   Feature_None = 0
      38             : };
      39             : 
      40         154 : static unsigned MatchRegisterName(StringRef Name) {
      41         154 :   switch (Name.size()) {
      42             :   default: break;
      43         114 :   case 2:        // 10 strings to match.
      44         228 :     if (Name[0] != 'r')
      45             :       break;
      46         188 :     switch (Name[1]) {
      47             :     default: break;
      48             :     case '0':    // 1 string to match.
      49             :       return 1;  // "r0"
      50             :     case '1':    // 1 string to match.
      51             :       return 2;  // "r1"
      52             :     case '2':    // 1 string to match.
      53             :       return 3;  // "r2"
      54             :     case '3':    // 1 string to match.
      55             :       return 4;  // "r3"
      56             :     case '4':    // 1 string to match.
      57             :       return 5;  // "r4"
      58             :     case '5':    // 1 string to match.
      59             :       return 6;  // "r5"
      60             :     case '6':    // 1 string to match.
      61             :       return 7;  // "r6"
      62             :     case '7':    // 1 string to match.
      63             :       return 8;  // "r7"
      64             :     case '8':    // 1 string to match.
      65             :       return 9;  // "r8"
      66             :     case '9':    // 1 string to match.
      67             :       return 10;         // "r9"
      68             :     }
      69             :     break;
      70           6 :   case 3:        // 2 strings to match.
      71           6 :     if (memcmp(Name.data()+0, "r1", 2) != 0)
      72             :       break;
      73          12 :     switch (Name[2]) {
      74             :     default: break;
      75             :     case '0':    // 1 string to match.
      76             :       return 11;         // "r10"
      77           0 :     case '1':    // 1 string to match.
      78           0 :       return 12;         // "r11"
      79             :     }
      80             :     break;
      81             :   }
      82             :   return 0;
      83             : }
      84             : 
      85             : #endif // GET_REGISTER_MATCHER
      86             : 
      87             : 
      88             : #ifdef GET_SUBTARGET_FEATURE_NAME
      89             : #undef GET_SUBTARGET_FEATURE_NAME
      90             : 
      91             : // User-level names for subtarget features that participate in
      92             : // instruction matching.
      93             : static const char *getSubtargetFeatureName(uint64_t Val) {
      94             :   return "(unknown)";
      95             : }
      96             : 
      97             : #endif // GET_SUBTARGET_FEATURE_NAME
      98             : 
      99             : 
     100             : #ifdef GET_MATCHER_IMPLEMENTATION
     101             : #undef GET_MATCHER_IMPLEMENTATION
     102             : 
     103             : namespace {
     104             : enum OperatorConversionKind {
     105             :   CVT_Done,
     106             :   CVT_Reg,
     107             :   CVT_Tied,
     108             :   CVT_95_Reg,
     109             :   CVT_95_addImmOperands,
     110             :   CVT_imm_95_0,
     111             :   CVT_NUM_CONVERTERS
     112             : };
     113             : 
     114             : enum InstructionConversionKind {
     115             :   Convert__Reg1_0__Reg1_2,
     116             :   Convert__Reg1_0__Imm1_2,
     117             :   Convert__Reg1_0__Tie0__Reg1_3,
     118             :   Convert__Reg1_0__Tie0__Imm1_3,
     119             :   Convert__Reg1_0__Tie0__Reg1_4,
     120             :   Convert__Reg1_0__Tie0__Imm1_4,
     121             :   Convert__Reg1_0__Tie0__Reg1_5,
     122             :   Convert__Reg1_0__Tie0__Imm1_5,
     123             :   Convert__Reg1_0__Reg1_8__Imm1_9,
     124             :   Convert__Imm1_2__Imm1_3,
     125             :   Convert__Reg1_3__Reg1_5__Reg1_7__Imm1_6__Reg1_9__Reg1_11,
     126             :   Convert__Reg1_3__Reg1_5__Imm1_7__Imm1_6__Reg1_9__Reg1_11,
     127             :   Convert__Reg1_10__Reg1_6__Imm1_7,
     128             :   Convert__Reg1_1__Tie0,
     129             :   Convert__Imm1_1,
     130             :   Convert_NoOperands,
     131             :   Convert__Reg1_1__Reg1_3__Imm1_5,
     132             :   Convert__Reg1_1__Imm1_3__Imm1_5,
     133             :   Convert__Reg1_1__Reg1_4__Imm1_6,
     134             :   Convert__Reg1_1__Imm1_4__Imm1_6,
     135             :   Convert__Reg1_1__Reg1_5__Imm1_7,
     136             :   Convert__Reg1_1__Imm1_5__Imm1_7,
     137             :   Convert__Reg1_1__Imm1_2__Imm1_3,
     138             :   Convert__Reg1_1__Reg1_2__Imm1_3,
     139             :   Convert__Reg1_12__Reg1_7__Imm1_8__Tie0,
     140             :   Convert__imm_95_0__Reg1_9,
     141             :   Convert__imm_95_0__Imm1_9,
     142             :   CVT_NUM_SIGNATURES
     143             : };
     144             : 
     145             : } // end anonymous namespace
     146             : 
     147             : static const uint8_t ConversionTable[CVT_NUM_SIGNATURES][13] = {
     148             :   // Convert__Reg1_0__Reg1_2
     149             :   { CVT_95_Reg, 0, CVT_95_Reg, 2, CVT_Done },
     150             :   // Convert__Reg1_0__Imm1_2
     151             :   { CVT_95_Reg, 0, CVT_95_addImmOperands, 2, CVT_Done },
     152             :   // Convert__Reg1_0__Tie0__Reg1_3
     153             :   { CVT_95_Reg, 0, CVT_Tied, 0, CVT_95_Reg, 3, CVT_Done },
     154             :   // Convert__Reg1_0__Tie0__Imm1_3
     155             :   { CVT_95_Reg, 0, CVT_Tied, 0, CVT_95_addImmOperands, 3, CVT_Done },
     156             :   // Convert__Reg1_0__Tie0__Reg1_4
     157             :   { CVT_95_Reg, 0, CVT_Tied, 0, CVT_95_Reg, 4, CVT_Done },
     158             :   // Convert__Reg1_0__Tie0__Imm1_4
     159             :   { CVT_95_Reg, 0, CVT_Tied, 0, CVT_95_addImmOperands, 4, CVT_Done },
     160             :   // Convert__Reg1_0__Tie0__Reg1_5
     161             :   { CVT_95_Reg, 0, CVT_Tied, 0, CVT_95_Reg, 5, CVT_Done },
     162             :   // Convert__Reg1_0__Tie0__Imm1_5
     163             :   { CVT_95_Reg, 0, CVT_Tied, 0, CVT_95_addImmOperands, 5, CVT_Done },
     164             :   // Convert__Reg1_0__Reg1_8__Imm1_9
     165             :   { CVT_95_Reg, 0, CVT_95_Reg, 8, CVT_95_addImmOperands, 9, CVT_Done },
     166             :   // Convert__Imm1_2__Imm1_3
     167             :   { CVT_95_addImmOperands, 2, CVT_95_addImmOperands, 3, CVT_Done },
     168             :   // Convert__Reg1_3__Reg1_5__Reg1_7__Imm1_6__Reg1_9__Reg1_11
     169             :   { CVT_95_Reg, 3, CVT_95_Reg, 5, CVT_95_Reg, 7, CVT_95_addImmOperands, 6, CVT_95_Reg, 9, CVT_95_Reg, 11, CVT_Done },
     170             :   // Convert__Reg1_3__Reg1_5__Imm1_7__Imm1_6__Reg1_9__Reg1_11
     171             :   { CVT_95_Reg, 3, CVT_95_Reg, 5, CVT_95_addImmOperands, 7, CVT_95_addImmOperands, 6, CVT_95_Reg, 9, CVT_95_Reg, 11, CVT_Done },
     172             :   // Convert__Reg1_10__Reg1_6__Imm1_7
     173             :   { CVT_95_Reg, 10, CVT_95_Reg, 6, CVT_95_addImmOperands, 7, CVT_Done },
     174             :   // Convert__Reg1_1__Tie0
     175             :   { CVT_95_Reg, 1, CVT_Tied, 0, CVT_Done },
     176             :   // Convert__Imm1_1
     177             :   { CVT_95_addImmOperands, 1, CVT_Done },
     178             :   // Convert_NoOperands
     179             :   { CVT_Done },
     180             :   // Convert__Reg1_1__Reg1_3__Imm1_5
     181             :   { CVT_95_Reg, 1, CVT_95_Reg, 3, CVT_95_addImmOperands, 5, CVT_Done },
     182             :   // Convert__Reg1_1__Imm1_3__Imm1_5
     183             :   { CVT_95_Reg, 1, CVT_95_addImmOperands, 3, CVT_95_addImmOperands, 5, CVT_Done },
     184             :   // Convert__Reg1_1__Reg1_4__Imm1_6
     185             :   { CVT_95_Reg, 1, CVT_95_Reg, 4, CVT_95_addImmOperands, 6, CVT_Done },
     186             :   // Convert__Reg1_1__Imm1_4__Imm1_6
     187             :   { CVT_95_Reg, 1, CVT_95_addImmOperands, 4, CVT_95_addImmOperands, 6, CVT_Done },
     188             :   // Convert__Reg1_1__Reg1_5__Imm1_7
     189             :   { CVT_95_Reg, 1, CVT_95_Reg, 5, CVT_95_addImmOperands, 7, CVT_Done },
     190             :   // Convert__Reg1_1__Imm1_5__Imm1_7
     191             :   { CVT_95_Reg, 1, CVT_95_addImmOperands, 5, CVT_95_addImmOperands, 7, CVT_Done },
     192             :   // Convert__Reg1_1__Imm1_2__Imm1_3
     193             :   { CVT_95_Reg, 1, CVT_95_addImmOperands, 2, CVT_95_addImmOperands, 3, CVT_Done },
     194             :   // Convert__Reg1_1__Reg1_2__Imm1_3
     195             :   { CVT_95_Reg, 1, CVT_95_Reg, 2, CVT_95_addImmOperands, 3, CVT_Done },
     196             :   // Convert__Reg1_12__Reg1_7__Imm1_8__Tie0
     197             :   { CVT_95_Reg, 12, CVT_95_Reg, 7, CVT_95_addImmOperands, 8, CVT_Tied, 0, CVT_Done },
     198             :   // Convert__imm_95_0__Reg1_9
     199             :   { CVT_imm_95_0, 0, CVT_95_Reg, 9, CVT_Done },
     200             :   // Convert__imm_95_0__Imm1_9
     201             :   { CVT_imm_95_0, 0, CVT_95_addImmOperands, 9, CVT_Done },
     202             : };
     203             : 
     204          69 : void BPFAsmParser::
     205             : convertToMCInst(unsigned Kind, MCInst &Inst, unsigned Opcode,
     206             :                 const OperandVector &Operands) {
     207             :   assert(Kind < CVT_NUM_SIGNATURES && "Invalid signature!");
     208          69 :   const uint8_t *Converter = ConversionTable[Kind];
     209             :   unsigned OpIdx;
     210         138 :   Inst.setOpcode(Opcode);
     211         255 :   for (const uint8_t *p = Converter; *p; p+= 2) {
     212         186 :     OpIdx = *(p + 1);
     213         186 :     switch (*p) {
     214           0 :     default: llvm_unreachable("invalid conversion entry!");
     215           0 :     case CVT_Reg:
     216           0 :       static_cast<BPFOperand&>(*Operands[OpIdx]).addRegOperands(Inst, 1);
     217             :       break;
     218          25 :     case CVT_Tied:
     219          25 :       Inst.addOperand(Inst.getOperand(OpIdx));
     220             :       break;
     221          94 :     case CVT_95_Reg:
     222         282 :       static_cast<BPFOperand&>(*Operands[OpIdx]).addRegOperands(Inst, 1);
     223             :       break;
     224          61 :     case CVT_95_addImmOperands:
     225         183 :       static_cast<BPFOperand&>(*Operands[OpIdx]).addImmOperands(Inst, 1);
     226             :       break;
     227           6 :     case CVT_imm_95_0:
     228          12 :       Inst.addOperand(MCOperand::createImm(0));
     229             :       break;
     230             :     }
     231             :   }
     232          69 : }
     233             : 
     234           0 : void BPFAsmParser::
     235             : convertToMapAndConstraints(unsigned Kind,
     236             :                            const OperandVector &Operands) {
     237             :   assert(Kind < CVT_NUM_SIGNATURES && "Invalid signature!");
     238           0 :   unsigned NumMCOperands = 0;
     239           0 :   const uint8_t *Converter = ConversionTable[Kind];
     240           0 :   for (const uint8_t *p = Converter; *p; p+= 2) {
     241           0 :     switch (*p) {
     242           0 :     default: llvm_unreachable("invalid conversion entry!");
     243           0 :     case CVT_Reg:
     244           0 :       Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
     245           0 :       Operands[*(p + 1)]->setConstraint("r");
     246           0 :       ++NumMCOperands;
     247           0 :       break;
     248           0 :     case CVT_Tied:
     249           0 :       ++NumMCOperands;
     250           0 :       break;
     251           0 :     case CVT_95_Reg:
     252           0 :       Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
     253           0 :       Operands[*(p + 1)]->setConstraint("r");
     254           0 :       NumMCOperands += 1;
     255           0 :       break;
     256           0 :     case CVT_95_addImmOperands:
     257           0 :       Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
     258           0 :       Operands[*(p + 1)]->setConstraint("m");
     259           0 :       NumMCOperands += 1;
     260           0 :       break;
     261           0 :     case CVT_imm_95_0:
     262           0 :       Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
     263           0 :       Operands[*(p + 1)]->setConstraint("");
     264           0 :       ++NumMCOperands;
     265           0 :       break;
     266             :     }
     267             :   }
     268           0 : }
     269             : 
     270             : namespace {
     271             : 
     272             : /// MatchClassKind - The kinds of classes which participate in
     273             : /// instruction matching.
     274             : enum MatchClassKind {
     275             :   InvalidMatchClass = 0,
     276             :   OptionalMatchClass = 1,
     277             :   MCK__EXCLAIM_, // '!'
     278             :   MCK__35_, // '#'
     279             :   MCK__38_, // '&'
     280             :   MCK__40_, // '('
     281             :   MCK__41_, // ')'
     282             :   MCK__STAR_, // '*'
     283             :   MCK__43_, // '+'
     284             :   MCK__MINUS_, // '-'
     285             :   MCK__47_, // '/'
     286             :   MCK__COLON_, // ':'
     287             :   MCK__LT_, // '<'
     288             :   MCK__61_, // '='
     289             :   MCK__GT_, // '>'
     290             :   MCK__63_, // '?'
     291             :   MCK_ADJCALLSTACKDOWN, // 'ADJCALLSTACKDOWN'
     292             :   MCK_ADJCALLSTACKUP, // 'ADJCALLSTACKUP'
     293             :   MCK_PSEUDO, // 'PSEUDO'
     294             :   MCK_Select, // 'Select'
     295             :   MCK__91_, // '['
     296             :   MCK__93_, // ']'
     297             :   MCK__94_, // '^'
     298             :   MCK_bswap16, // 'bswap16'
     299             :   MCK_bswap32, // 'bswap32'
     300             :   MCK_bswap64, // 'bswap64'
     301             :   MCK_call, // 'call'
     302             :   MCK_exit, // 'exit'
     303             :   MCK_goto, // 'goto'
     304             :   MCK_if, // 'if'
     305             :   MCK_ld_95_pseudo, // 'ld_pseudo'
     306             :   MCK_lea, // 'lea'
     307             :   MCK_ll, // 'll'
     308             :   MCK_lock, // 'lock'
     309             :   MCK_nop, // 'nop'
     310             :   MCK_s, // 's'
     311             :   MCK_skb, // 'skb'
     312             :   MCK_u16, // 'u16'
     313             :   MCK_u32, // 'u32'
     314             :   MCK_u64, // 'u64'
     315             :   MCK_u8, // 'u8'
     316             :   MCK__124_, // '|'
     317             :   MCK_R0, // register class 'R0'
     318             :   MCK_GPR, // register class 'GPR'
     319             :   MCK_Imm, // user defined class 'ImmAsmOperand'
     320             :   NumMatchClassKinds
     321             : };
     322             : 
     323             : }
     324             : 
     325        1280 : static MatchClassKind matchTokenString(StringRef Name) {
     326        1280 :   switch (Name.size()) {
     327             :   default: break;
     328        1173 :   case 1:        // 19 strings to match.
     329        2346 :     switch (Name[0]) {
     330             :     default: break;
     331             :     case '!':    // 1 string to match.
     332             :       return MCK__EXCLAIM_;      // "!"
     333             :     case '#':    // 1 string to match.
     334             :       return MCK__35_;   // "#"
     335             :     case '&':        // 1 string to match.
     336             :       return MCK__38_;   // "&"
     337             :     case '(':    // 1 string to match.
     338             :       return MCK__40_;   // "("
     339             :     case ')':    // 1 string to match.
     340             :       return MCK__41_;   // ")"
     341             :     case '*':    // 1 string to match.
     342             :       return MCK__STAR_;         // "*"
     343             :     case '+':    // 1 string to match.
     344             :       return MCK__43_;   // "+"
     345             :     case '-':    // 1 string to match.
     346             :       return MCK__MINUS_;        // "-"
     347             :     case '/':    // 1 string to match.
     348             :       return MCK__47_;   // "/"
     349             :     case ':':    // 1 string to match.
     350             :       return MCK__COLON_;        // ":"
     351             :     case '<':         // 1 string to match.
     352             :       return MCK__LT_;   // "<"
     353             :     case '=':    // 1 string to match.
     354             :       return MCK__61_;   // "="
     355             :     case '>':         // 1 string to match.
     356             :       return MCK__GT_;   // ">"
     357             :     case '?':    // 1 string to match.
     358             :       return MCK__63_;   // "?"
     359             :     case '[':    // 1 string to match.
     360             :       return MCK__91_;   // "["
     361             :     case ']':    // 1 string to match.
     362             :       return MCK__93_;   // "]"
     363             :     case '^':    // 1 string to match.
     364             :       return MCK__94_;   // "^"
     365             :     case 's':    // 1 string to match.
     366             :       return MCK_s;      // "s"
     367             :     case '|':    // 1 string to match.
     368             :       return MCK__124_;  // "|"
     369             :     }
     370             :     break;
     371          31 :   case 2:        // 3 strings to match.
     372          62 :     switch (Name[0]) {
     373             :     default: break;
     374           0 :     case 'i':    // 1 string to match.
     375           0 :       if (Name[1] != 'f')
     376             :         break;
     377             :       return MCK_if;     // "if"
     378           4 :     case 'l':    // 1 string to match.
     379           8 :       if (Name[1] != 'l')
     380             :         break;
     381             :       return MCK_ll;     // "ll"
     382          27 :     case 'u':    // 1 string to match.
     383          54 :       if (Name[1] != '8')
     384             :         break;
     385             :       return MCK_u8;     // "u8"
     386             :     }
     387             :     break;
     388          56 :   case 3:        // 6 strings to match.
     389         112 :     switch (Name[0]) {
     390             :     default: break;
     391           0 :     case 'l':    // 1 string to match.
     392           0 :       if (memcmp(Name.data()+1, "ea", 2) != 0)
     393             :         break;
     394             :       return MCK_lea;    // "lea"
     395           0 :     case 'n':    // 1 string to match.
     396           0 :       if (memcmp(Name.data()+1, "op", 2) != 0)
     397             :         break;
     398             :       return MCK_nop;    // "nop"
     399          15 :     case 's':    // 1 string to match.
     400          15 :       if (memcmp(Name.data()+1, "kb", 2) != 0)
     401             :         break;
     402             :       return MCK_skb;    // "skb"
     403          41 :     case 'u':    // 3 strings to match.
     404          82 :       switch (Name[1]) {
     405             :       default: break;
     406          13 :       case '1':  // 1 string to match.
     407          26 :         if (Name[2] != '6')
     408             :           break;
     409             :         return MCK_u16;  // "u16"
     410          20 :       case '3':  // 1 string to match.
     411          40 :         if (Name[2] != '2')
     412             :           break;
     413             :         return MCK_u32;  // "u32"
     414           8 :       case '6':  // 1 string to match.
     415          16 :         if (Name[2] != '4')
     416             :           break;
     417             :         return MCK_u64;  // "u64"
     418             :       }
     419             :       break;
     420             :     }
     421             :     break;
     422          20 :   case 4:        // 4 strings to match.
     423          40 :     switch (Name[0]) {
     424             :     default: break;
     425           0 :     case 'c':    // 1 string to match.
     426           0 :       if (memcmp(Name.data()+1, "all", 3) != 0)
     427             :         break;
     428             :       return MCK_call;   // "call"
     429           0 :     case 'e':    // 1 string to match.
     430           0 :       if (memcmp(Name.data()+1, "xit", 3) != 0)
     431             :         break;
     432             :       return MCK_exit;   // "exit"
     433          20 :     case 'g':    // 1 string to match.
     434          20 :       if (memcmp(Name.data()+1, "oto", 3) != 0)
     435             :         break;
     436             :       return MCK_goto;   // "goto"
     437           0 :     case 'l':    // 1 string to match.
     438           0 :       if (memcmp(Name.data()+1, "ock", 3) != 0)
     439             :         break;
     440             :       return MCK_lock;   // "lock"
     441             :     }
     442             :     break;
     443           0 :   case 6:        // 2 strings to match.
     444           0 :     switch (Name[0]) {
     445             :     default: break;
     446           0 :     case 'P':    // 1 string to match.
     447           0 :       if (memcmp(Name.data()+1, "SEUDO", 5) != 0)
     448             :         break;
     449             :       return MCK_PSEUDO;         // "PSEUDO"
     450           0 :     case 'S':    // 1 string to match.
     451           0 :       if (memcmp(Name.data()+1, "elect", 5) != 0)
     452             :         break;
     453             :       return MCK_Select;         // "Select"
     454             :     }
     455             :     break;
     456           0 :   case 7:        // 3 strings to match.
     457           0 :     if (memcmp(Name.data()+0, "bswap", 5) != 0)
     458             :       break;
     459           0 :     switch (Name[5]) {
     460             :     default: break;
     461           0 :     case '1':    // 1 string to match.
     462           0 :       if (Name[6] != '6')
     463             :         break;
     464             :       return MCK_bswap16;        // "bswap16"
     465           0 :     case '3':    // 1 string to match.
     466           0 :       if (Name[6] != '2')
     467             :         break;
     468             :       return MCK_bswap32;        // "bswap32"
     469           0 :     case '6':    // 1 string to match.
     470           0 :       if (Name[6] != '4')
     471             :         break;
     472             :       return MCK_bswap64;        // "bswap64"
     473             :     }
     474             :     break;
     475           0 :   case 9:        // 1 string to match.
     476           0 :     if (memcmp(Name.data()+0, "ld_pseudo", 9) != 0)
     477             :       break;
     478             :     return MCK_ld_95_pseudo;     // "ld_pseudo"
     479           0 :   case 14:       // 1 string to match.
     480           0 :     if (memcmp(Name.data()+0, "ADJCALLSTACKUP", 14) != 0)
     481             :       break;
     482             :     return MCK_ADJCALLSTACKUP;   // "ADJCALLSTACKUP"
     483           0 :   case 16:       // 1 string to match.
     484           0 :     if (memcmp(Name.data()+0, "ADJCALLSTACKDOWN", 16) != 0)
     485             :       break;
     486             :     return MCK_ADJCALLSTACKDOWN;         // "ADJCALLSTACKDOWN"
     487             :   }
     488             :   return InvalidMatchClass;
     489             : }
     490             : 
     491             : /// isSubclass - Compute whether \p A is a subclass of \p B.
     492             : static bool isSubclass(MatchClassKind A, MatchClassKind B) {
     493        3365 :   if (A == B)
     494             :     return true;
     495             : 
     496        1163 :   switch (A) {
     497             :   default:
     498             :     return false;
     499             : 
     500         434 :   case MCK_R0:
     501         434 :     return B == MCK_GPR;
     502             :   }
     503             : }
     504             : 
     505        2467 : static unsigned validateOperandClass(MCParsedAsmOperand &GOp, MatchClassKind Kind) {
     506        2467 :   BPFOperand &Operand = (BPFOperand&)GOp;
     507        2467 :   if (Kind == InvalidMatchClass)
     508             :     return MCTargetAsmParser::Match_InvalidOperand;
     509             : 
     510        4926 :   if (Operand.isToken())
     511        1280 :     return isSubclass(matchTokenString(Operand.getToken()), Kind) ?
     512             :              MCTargetAsmParser::Match_Success :
     513             :              MCTargetAsmParser::Match_InvalidOperand;
     514             : 
     515        1183 :   switch (Kind) {
     516             :   default: break;
     517             :   // 'Imm' class
     518          65 :   case MCK_Imm:
     519          65 :     if (Operand.isImm())
     520             :       return MCTargetAsmParser::Match_Success;
     521             :     break;
     522             :   } // end switch (Kind)
     523             : 
     524        1118 :   if (Operand.isReg()) {
     525             :     MatchClassKind OpKind;
     526        2178 :     switch (Operand.getReg()) {
     527             :     default: OpKind = InvalidMatchClass; break;
     528             :     case BPF::R0: OpKind = MCK_R0; break;
     529             :     case BPF::R1: OpKind = MCK_GPR; break;
     530             :     case BPF::R2: OpKind = MCK_GPR; break;
     531             :     case BPF::R3: OpKind = MCK_GPR; break;
     532             :     case BPF::R4: OpKind = MCK_GPR; break;
     533             :     case BPF::R5: OpKind = MCK_GPR; break;
     534             :     case BPF::R6: OpKind = MCK_GPR; break;
     535             :     case BPF::R7: OpKind = MCK_GPR; break;
     536             :     case BPF::R8: OpKind = MCK_GPR; break;
     537             :     case BPF::R9: OpKind = MCK_GPR; break;
     538             :     case BPF::R10: OpKind = MCK_GPR; break;
     539             :     case BPF::R11: OpKind = MCK_GPR; break;
     540             :     }
     541         434 :     return isSubclass(OpKind, Kind) ? MCTargetAsmParser::Match_Success :
     542             :                                       MCTargetAsmParser::Match_InvalidOperand;
     543             :   }
     544             : 
     545             :   return MCTargetAsmParser::Match_InvalidOperand;
     546             : }
     547             : 
     548             : uint64_t BPFAsmParser::
     549             : ComputeAvailableFeatures(const FeatureBitset& FB) const {
     550           1 :   uint64_t Features = 0;
     551             :   return Features;
     552             : }
     553             : 
     554             : static const char *const MnemonicTable =
     555             :     "\000\001#\001*\007bswap16\007bswap32\007bswap64\004call\004exit\004goto"
     556             :     "\002if\tld_pseudo\003lea\004lock\003nop\002r0";
     557             : 
     558             : namespace {
     559             :   struct MatchEntry {
     560             :     uint8_t Mnemonic;
     561             :     uint16_t Opcode;
     562             :     uint8_t ConvertFn;
     563             :     uint8_t RequiredFeatures;
     564             :     uint8_t Classes[13];
     565             :     StringRef getMnemonic() const {
     566         349 :       return StringRef(MnemonicTable + Mnemonic + 1,
     567         349 :                        MnemonicTable[Mnemonic]);
     568             :     }
     569             :   };
     570             : 
     571             :   // Predicate for searching for an opcode.
     572             :   struct LessOpcode {
     573             :     bool operator()(const MatchEntry &LHS, StringRef RHS) {
     574         388 :       return LHS.getMnemonic() < RHS;
     575             :     }
     576             :     bool operator()(StringRef LHS, const MatchEntry &RHS) {
     577         310 :       return LHS < RHS.getMnemonic();
     578             :     }
     579             :     bool operator()(const MatchEntry &LHS, const MatchEntry &RHS) {
     580             :       return LHS.getMnemonic() < RHS.getMnemonic();
     581             :     }
     582             :   };
     583             : } // end anonymous namespace.
     584             : 
     585             : static const MatchEntry MatchTable0[] = {
     586             :   { 0 /*  */, BPF::MOV_rr, Convert__Reg1_0__Reg1_2, 0, { MCK_GPR, MCK__61_, MCK_GPR }, },
     587             :   { 0 /*  */, BPF::MOV_ri, Convert__Reg1_0__Imm1_2, 0, { MCK_GPR, MCK__61_, MCK_Imm }, },
     588             :   { 0 /*  */, BPF::AND_rr, Convert__Reg1_0__Tie0__Reg1_3, 0, { MCK_GPR, MCK__38_, MCK__61_, MCK_GPR }, },
     589             :   { 0 /*  */, BPF::AND_ri, Convert__Reg1_0__Tie0__Imm1_3, 0, { MCK_GPR, MCK__38_, MCK__61_, MCK_Imm }, },
     590             :   { 0 /*  */, BPF::MUL_rr, Convert__Reg1_0__Tie0__Reg1_3, 0, { MCK_GPR, MCK__STAR_, MCK__61_, MCK_GPR }, },
     591             :   { 0 /*  */, BPF::MUL_ri, Convert__Reg1_0__Tie0__Imm1_3, 0, { MCK_GPR, MCK__STAR_, MCK__61_, MCK_Imm }, },
     592             :   { 0 /*  */, BPF::ADD_rr, Convert__Reg1_0__Tie0__Reg1_3, 0, { MCK_GPR, MCK__43_, MCK__61_, MCK_GPR }, },
     593             :   { 0 /*  */, BPF::ADD_ri, Convert__Reg1_0__Tie0__Imm1_3, 0, { MCK_GPR, MCK__43_, MCK__61_, MCK_Imm }, },
     594             :   { 0 /*  */, BPF::SUB_rr, Convert__Reg1_0__Tie0__Reg1_3, 0, { MCK_GPR, MCK__MINUS_, MCK__61_, MCK_GPR }, },
     595             :   { 0 /*  */, BPF::SUB_ri, Convert__Reg1_0__Tie0__Imm1_3, 0, { MCK_GPR, MCK__MINUS_, MCK__61_, MCK_Imm }, },
     596             :   { 0 /*  */, BPF::DIV_rr, Convert__Reg1_0__Tie0__Reg1_3, 0, { MCK_GPR, MCK__47_, MCK__61_, MCK_GPR }, },
     597             :   { 0 /*  */, BPF::DIV_ri, Convert__Reg1_0__Tie0__Imm1_3, 0, { MCK_GPR, MCK__47_, MCK__61_, MCK_Imm }, },
     598             :   { 0 /*  */, BPF::LD_imm64, Convert__Reg1_0__Imm1_2, 0, { MCK_GPR, MCK__61_, MCK_Imm, MCK_ll }, },
     599             :   { 0 /*  */, BPF::XOR_rr, Convert__Reg1_0__Tie0__Reg1_3, 0, { MCK_GPR, MCK__94_, MCK__61_, MCK_GPR }, },
     600             :   { 0 /*  */, BPF::XOR_ri, Convert__Reg1_0__Tie0__Imm1_3, 0, { MCK_GPR, MCK__94_, MCK__61_, MCK_Imm }, },
     601             :   { 0 /*  */, BPF::OR_rr, Convert__Reg1_0__Tie0__Reg1_3, 0, { MCK_GPR, MCK__124_, MCK__61_, MCK_GPR }, },
     602             :   { 0 /*  */, BPF::OR_ri, Convert__Reg1_0__Tie0__Imm1_3, 0, { MCK_GPR, MCK__124_, MCK__61_, MCK_Imm }, },
     603             :   { 0 /*  */, BPF::SLL_rr, Convert__Reg1_0__Tie0__Reg1_4, 0, { MCK_GPR, MCK__LT_, MCK__LT_, MCK__61_, MCK_GPR }, },
     604             :   { 0 /*  */, BPF::SLL_ri, Convert__Reg1_0__Tie0__Imm1_4, 0, { MCK_GPR, MCK__LT_, MCK__LT_, MCK__61_, MCK_Imm }, },
     605             :   { 0 /*  */, BPF::SRL_rr, Convert__Reg1_0__Tie0__Reg1_4, 0, { MCK_GPR, MCK__GT_, MCK__GT_, MCK__61_, MCK_GPR }, },
     606             :   { 0 /*  */, BPF::SRL_ri, Convert__Reg1_0__Tie0__Imm1_4, 0, { MCK_GPR, MCK__GT_, MCK__GT_, MCK__61_, MCK_Imm }, },
     607             :   { 0 /*  */, BPF::SRA_rr, Convert__Reg1_0__Tie0__Reg1_5, 0, { MCK_GPR, MCK_s, MCK__GT_, MCK__GT_, MCK__61_, MCK_GPR }, },
     608             :   { 0 /*  */, BPF::SRA_ri, Convert__Reg1_0__Tie0__Imm1_5, 0, { MCK_GPR, MCK_s, MCK__GT_, MCK__GT_, MCK__61_, MCK_Imm }, },
     609             :   { 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_ }, },
     610             :   { 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_ }, },
     611             :   { 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_ }, },
     612             :   { 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_ }, },
     613             :   { 1 /* # */, BPF::ADJCALLSTACKDOWN, Convert__Imm1_2__Imm1_3, 0, { MCK__35_, MCK_ADJCALLSTACKDOWN, MCK_Imm, MCK_Imm }, },
     614             :   { 1 /* # */, BPF::ADJCALLSTACKUP, Convert__Imm1_2__Imm1_3, 0, { MCK__35_, MCK_ADJCALLSTACKUP, MCK_Imm, MCK_Imm }, },
     615             :   { 1 /* # */, BPF::Select, Convert__Reg1_3__Reg1_5__Reg1_7__Imm1_6__Reg1_9__Reg1_11, 0, { MCK__35_, MCK_Select, MCK_PSEUDO, MCK_GPR, MCK__61_, MCK_GPR, MCK_Imm, MCK_GPR, MCK__63_, MCK_GPR, MCK__COLON_, MCK_GPR }, },
     616             :   { 1 /* # */, BPF::Select_Ri, Convert__Reg1_3__Reg1_5__Imm1_7__Imm1_6__Reg1_9__Reg1_11, 0, { MCK__35_, MCK_Select, MCK_PSEUDO, MCK_GPR, MCK__61_, MCK_GPR, MCK_Imm, MCK_Imm, MCK__63_, MCK_GPR, MCK__COLON_, MCK_GPR }, },
     617             :   { 3 /* * */, 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 }, },
     618             :   { 3 /* * */, 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 }, },
     619             :   { 3 /* * */, 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 }, },
     620             :   { 3 /* * */, 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 }, },
     621             :   { 5 /* bswap16 */, BPF::BSWAP16, Convert__Reg1_1__Tie0, 0, { MCK_bswap16, MCK_GPR }, },
     622             :   { 13 /* bswap32 */, BPF::BSWAP32, Convert__Reg1_1__Tie0, 0, { MCK_bswap32, MCK_GPR }, },
     623             :   { 21 /* bswap64 */, BPF::BSWAP64, Convert__Reg1_1__Tie0, 0, { MCK_bswap64, MCK_GPR }, },
     624             :   { 29 /* call */, BPF::JAL, Convert__Imm1_1, 0, { MCK_call, MCK_Imm }, },
     625             :   { 34 /* exit */, BPF::RET, Convert_NoOperands, 0, { MCK_exit }, },
     626             :   { 39 /* goto */, BPF::JMP, Convert__Imm1_1, 0, { MCK_goto, MCK_Imm }, },
     627             :   { 44 /* if */, BPF::JULT_rr, Convert__Reg1_1__Reg1_3__Imm1_5, 0, { MCK_if, MCK_GPR, MCK__LT_, MCK_GPR, MCK_goto, MCK_Imm }, },
     628             :   { 44 /* if */, BPF::JULT_ri, Convert__Reg1_1__Imm1_3__Imm1_5, 0, { MCK_if, MCK_GPR, MCK__LT_, MCK_Imm, MCK_goto, MCK_Imm }, },
     629             :   { 44 /* if */, BPF::JUGT_rr, Convert__Reg1_1__Reg1_3__Imm1_5, 0, { MCK_if, MCK_GPR, MCK__GT_, MCK_GPR, MCK_goto, MCK_Imm }, },
     630             :   { 44 /* if */, BPF::JUGT_ri, Convert__Reg1_1__Imm1_3__Imm1_5, 0, { MCK_if, MCK_GPR, MCK__GT_, MCK_Imm, MCK_goto, MCK_Imm }, },
     631             :   { 44 /* 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 }, },
     632             :   { 44 /* 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 }, },
     633             :   { 44 /* 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 }, },
     634             :   { 44 /* 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 }, },
     635             :   { 44 /* 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 }, },
     636             :   { 44 /* 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 }, },
     637             :   { 44 /* 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 }, },
     638             :   { 44 /* 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 }, },
     639             :   { 44 /* 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 }, },
     640             :   { 44 /* 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 }, },
     641             :   { 44 /* 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 }, },
     642             :   { 44 /* 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 }, },
     643             :   { 44 /* 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 }, },
     644             :   { 44 /* 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 }, },
     645             :   { 44 /* 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 }, },
     646             :   { 44 /* 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 }, },
     647             :   { 47 /* ld_pseudo */, BPF::LD_pseudo, Convert__Reg1_1__Imm1_2__Imm1_3, 0, { MCK_ld_95_pseudo, MCK_GPR, MCK_Imm, MCK_Imm }, },
     648             :   { 57 /* lea */, BPF::FI_ri, Convert__Reg1_1__Reg1_2__Imm1_3, 0, { MCK_lea, MCK_GPR, MCK_GPR, MCK_Imm }, },
     649             :   { 61 /* lock */, BPF::XADD32, Convert__Reg1_12__Reg1_7__Imm1_8__Tie0, 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 }, },
     650             :   { 61 /* lock */, BPF::XADD64, Convert__Reg1_12__Reg1_7__Imm1_8__Tie0, 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 }, },
     651             :   { 66 /* nop */, BPF::NOP, Convert__Imm1_1, 0, { MCK_nop, MCK_Imm }, },
     652             :   { 70 /* 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_ }, },
     653             :   { 70 /* 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_ }, },
     654             :   { 70 /* 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_ }, },
     655             :   { 70 /* 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_ }, },
     656             :   { 70 /* 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_ }, },
     657             :   { 70 /* 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_ }, },
     658             : };
     659             : 
     660           0 : std::string BPFMnemonicSpellCheck(StringRef S, uint64_t FBS) {
     661           0 :   const unsigned MaxEditDist = 2;
     662           0 :   std::vector<StringRef> Candidates;
     663           0 :   StringRef Prev = "";
     664           0 :   auto End = std::end(MatchTable0);
     665             : 
     666           0 :   for (auto I = std::begin(MatchTable0); I < End; I++) {
     667             :     // Ignore unsupported instructions.
     668           0 :     if ((FBS & I->RequiredFeatures) != I->RequiredFeatures)
     669           0 :       continue;
     670             : 
     671           0 :     StringRef T = I->getMnemonic();
     672             :     // Avoid recomputing the edit distance for the same string.
     673           0 :     if (T.equals(Prev))
     674           0 :       continue;
     675             : 
     676           0 :     Prev = T;
     677           0 :     unsigned Dist = S.edit_distance(T, false, MaxEditDist);
     678           0 :     if (Dist <= MaxEditDist)
     679           0 :       Candidates.push_back(T);
     680             :   }
     681             : 
     682           0 :   if (Candidates.empty())
     683           0 :     return "";
     684             : 
     685           0 :   std::string Res = ", did you mean: ";
     686           0 :   unsigned i = 0;
     687           0 :   for( ; i < Candidates.size() - 1; i++)
     688           0 :     Res += Candidates[i].str() + ", ";
     689           0 :   return Res + Candidates[i].str() + "?";
     690             : }
     691             : 
     692          69 : unsigned BPFAsmParser::
     693             : MatchInstructionImpl(const OperandVector &Operands,
     694             :                      MCInst &Inst, uint64_t &ErrorInfo,
     695             :                      bool matchingInlineAsm, unsigned VariantID) {
     696             :   // Eliminate obvious mismatches.
     697         138 :   if (Operands.size() > 13) {
     698           0 :     ErrorInfo = 13;
     699           0 :     return Match_InvalidOperand;
     700             :   }
     701             : 
     702             :   // Get the current feature set.
     703          69 :   uint64_t AvailableFeatures = getAvailableFeatures();
     704             : 
     705             :   // Get the instruction mnemonic, which is the first token.
     706          69 :   StringRef Mnemonic;
     707         207 :   if (Operands[0]->isToken())
     708          96 :     Mnemonic = ((BPFOperand&)*Operands[0]).getToken();
     709             : 
     710             :   // Some state to try to produce better error messages.
     711          69 :   bool HadMatchOtherThanFeatures = false;
     712          69 :   bool HadMatchOtherThanPredicate = false;
     713          69 :   unsigned RetCode = Match_InvalidOperand;
     714          69 :   uint64_t MissingFeatures = ~0ULL;
     715             :   // Set ErrorInfo to the operand that mismatches if it is
     716             :   // wrong for all instances of the instruction.
     717          69 :   ErrorInfo = ~0ULL;
     718             :   // Find the appropriate table for this asm variant.
     719             :   const MatchEntry *Start, *End;
     720          69 :   switch (VariantID) {
     721           0 :   default: llvm_unreachable("invalid variant!");
     722          69 :   case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
     723             :   }
     724             :   // Search the table.
     725         138 :   auto MnemonicRange = std::make_pair(Start, End);
     726          69 :   unsigned SIndex = Mnemonic.empty() ? 0 : 1;
     727          69 :   if (!Mnemonic.empty())
     728         128 :     MnemonicRange = std::equal_range(Start, End, Mnemonic.lower(), LessOpcode());
     729             : 
     730             :   // Return a more specific error code if no mnemonics match.
     731          69 :   if (MnemonicRange.first == MnemonicRange.second)
     732             :     return Match_MnemonicFail;
     733             : 
     734         996 :   for (const MatchEntry *it = MnemonicRange.first, *ie = MnemonicRange.second;
     735        1065 :        it != ie; ++it) {
     736             :     bool OperandsValid = true;
     737        4007 :     for (unsigned FormalIdx = SIndex, ActualIdx = SIndex; FormalIdx != 13; ++FormalIdx) {
     738        2534 :       auto Formal = static_cast<MatchClassKind>(it->Classes[FormalIdx]);
     739        5068 :       if (ActualIdx >= Operands.size()) {
     740          67 :         OperandsValid = (Formal == InvalidMatchClass) || isSubclass(Formal, OptionalMatchClass);
     741           0 :         if (!OperandsValid) ErrorInfo = ActualIdx;
     742             :         break;
     743             :       }
     744        7401 :       MCParsedAsmOperand &Actual = *Operands[ActualIdx];
     745        2467 :       unsigned Diag = validateOperandClass(Actual, Formal);
     746        3938 :       if (Diag == Match_Success) {
     747        1471 :         ++ActualIdx;
     748        1471 :         continue;
     749             :       }
     750             :       // If the generic handler indicates an invalid operand
     751             :       // failure, check for a special case.
     752         996 :       if (Diag == Match_InvalidOperand) {
     753         996 :         Diag = validateTargetOperandClass(Actual, Formal);
     754         996 :         if (Diag == Match_Success) {
     755           0 :           ++ActualIdx;
     756           0 :           continue;
     757             :         }
     758             :       }
     759             :       // If current formal operand wasn't matched and it is optional
     760             :       // then try to match next formal operand
     761         996 :       if (Diag == Match_InvalidOperand && isSubclass(Formal, OptionalMatchClass)) {
     762           0 :         continue;
     763             :       }
     764             :       // If this operand is broken for all of the instances of this
     765             :       // mnemonic, keep track of it so we can report loc info.
     766             :       // If we already had a match that only failed due to a
     767             :       // target predicate, that diagnostic is preferred.
     768        1992 :       if (!HadMatchOtherThanPredicate &&
     769         937 :           (it == MnemonicRange.first || ErrorInfo <= ActualIdx)) {
     770         472 :         ErrorInfo = ActualIdx;
     771             :         // InvalidOperand is the default. Prefer specificity.
     772         472 :         if (Diag != Match_InvalidOperand)
     773           0 :           RetCode = Diag;
     774             :       }
     775             :       // Otherwise, just reject this instance of the mnemonic.
     776             :       OperandsValid = false;
     777             :       break;
     778             :     }
     779             : 
     780        1065 :     if (!OperandsValid) continue;
     781          69 :     if ((AvailableFeatures & it->RequiredFeatures) != it->RequiredFeatures) {
     782           0 :       HadMatchOtherThanFeatures = true;
     783           0 :       uint64_t NewMissingFeatures = it->RequiredFeatures & ~AvailableFeatures;
     784           0 :       if (countPopulation(NewMissingFeatures) <=
     785           0 :           countPopulation(MissingFeatures))
     786           0 :         MissingFeatures = NewMissingFeatures;
     787           0 :       continue;
     788             :     }
     789             : 
     790          69 :     Inst.clear();
     791             : 
     792         138 :     Inst.setOpcode(it->Opcode);
     793             :     // We have a potential match but have not rendered the operands.
     794             :     // Check the target predicate to handle any context sensitive
     795             :     // constraints.
     796             :     // For example, Ties that are referenced multiple times must be
     797             :     // checked here to ensure the input is the same for each match
     798             :     // constraints. If we leave it any later the ties will have been
     799             :     // canonicalized
     800             :     unsigned MatchResult;
     801          69 :     if ((MatchResult = checkEarlyTargetMatchPredicate(Inst, Operands)) != Match_Success) {
     802           0 :       Inst.clear();
     803           0 :       RetCode = MatchResult;
     804           0 :       HadMatchOtherThanPredicate = true;
     805           0 :       continue;
     806             :     }
     807             : 
     808          69 :     if (matchingInlineAsm) {
     809           0 :       convertToMapAndConstraints(it->ConvertFn, Operands);
     810           0 :       return Match_Success;
     811             :     }
     812             : 
     813             :     // We have selected a definite instruction, convert the parsed
     814             :     // operands into the appropriate MCInst.
     815          69 :     convertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);
     816             : 
     817             :     // We have a potential match. Check the target predicate to
     818             :     // handle any context sensitive constraints.
     819          69 :     if ((MatchResult = checkTargetMatchPredicate(Inst)) != Match_Success) {
     820           0 :       Inst.clear();
     821           0 :       RetCode = MatchResult;
     822           0 :       HadMatchOtherThanPredicate = true;
     823           0 :       continue;
     824             :     }
     825             : 
     826             :     return Match_Success;
     827             :   }
     828             : 
     829             :   // Okay, we had no match.  Try to return a useful error code.
     830           0 :   if (HadMatchOtherThanPredicate || !HadMatchOtherThanFeatures)
     831             :     return RetCode;
     832             : 
     833             :   // Missing feature matches return which features were missing
     834           0 :   ErrorInfo = MissingFeatures;
     835           0 :   return Match_MissingFeature;
     836             : }
     837             : 
     838             : #endif // GET_MATCHER_IMPLEMENTATION
     839             : 

Generated by: LCOV version 1.13