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: 135 210 64.3 %
Date: 2018-02-23 15:42:53 Functions: 6 7 85.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         192 : static unsigned MatchRegisterName(StringRef Name) {
      42         192 :   switch (Name.size()) {
      43             :   default: break;
      44         152 :   case 2:        // 20 strings to match.
      45         152 :     switch (Name[0]) {
      46             :     default: break;
      47          99 :     case 'r':    // 10 strings to match.
      48          99 :       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          33 :     case 'w':    // 10 strings to match.
      73          33 :       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           9 :     switch (Name[0]) {
     101             :     default: break;
     102           6 :     case 'r':    // 2 strings to match.
     103           6 :       if (Name[1] != '1')
     104             :         break;
     105           6 :       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           3 :       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             : const char 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          94 : void BPFAsmParser::
     253             : convertToMCInst(unsigned Kind, MCInst &Inst, unsigned Opcode,
     254             :                 const OperandVector &Operands) {
     255             :   assert(Kind < CVT_NUM_SIGNATURES && "Invalid signature!");
     256          94 :   const uint8_t *Converter = ConversionTable[Kind];
     257             :   unsigned OpIdx;
     258             :   Inst.setOpcode(Opcode);
     259         606 :   for (const uint8_t *p = Converter; *p; p+= 2) {
     260         256 :     OpIdx = *(p + 1);
     261         256 :     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          47 :     case CVT_Tied: {
     267             :       assert(OpIdx < (size_t)(std::end(TiedAsmOperandTable) -
     268             :                           std::begin(TiedAsmOperandTable)) &&
     269             :              "Tied operand not found");
     270          47 :       unsigned TiedResOpnd = TiedAsmOperandTable[OpIdx][0];
     271             :       Inst.addOperand(Inst.getOperand(TiedResOpnd));
     272             :       break;
     273             :     }
     274         130 :     case CVT_95_Reg:
     275         260 :       static_cast<BPFOperand&>(*Operands[OpIdx]).addRegOperands(Inst, 1);
     276             :       break;
     277          73 :     case CVT_95_addImmOperands:
     278          73 :       static_cast<BPFOperand&>(*Operands[OpIdx]).addImmOperands(Inst, 1);
     279             :       break;
     280             :     case CVT_imm_95_0:
     281          12 :       Inst.addOperand(MCOperand::createImm(0));
     282             :       break;
     283             :     }
     284             :   }
     285          94 : }
     286             : 
     287           0 : void BPFAsmParser::
     288             : convertToMapAndConstraints(unsigned Kind,
     289             :                            const OperandVector &Operands) {
     290             :   assert(Kind < CVT_NUM_SIGNATURES && "Invalid signature!");
     291             :   unsigned NumMCOperands = 0;
     292           0 :   const uint8_t *Converter = ConversionTable[Kind];
     293           0 :   for (const uint8_t *p = Converter; *p; p+= 2) {
     294           0 :     switch (*p) {
     295           0 :     default: llvm_unreachable("invalid conversion entry!");
     296           0 :     case CVT_Reg:
     297           0 :       Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
     298           0 :       Operands[*(p + 1)]->setConstraint("r");
     299           0 :       ++NumMCOperands;
     300           0 :       break;
     301           0 :     case CVT_Tied:
     302           0 :       ++NumMCOperands;
     303           0 :       break;
     304           0 :     case CVT_95_Reg:
     305           0 :       Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
     306           0 :       Operands[*(p + 1)]->setConstraint("r");
     307           0 :       NumMCOperands += 1;
     308           0 :       break;
     309           0 :     case CVT_95_addImmOperands:
     310           0 :       Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
     311           0 :       Operands[*(p + 1)]->setConstraint("m");
     312           0 :       NumMCOperands += 1;
     313           0 :       break;
     314           0 :     case CVT_imm_95_0:
     315           0 :       Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
     316           0 :       Operands[*(p + 1)]->setConstraint("");
     317           0 :       ++NumMCOperands;
     318           0 :       break;
     319             :     }
     320             :   }
     321           0 : }
     322             : 
     323             : namespace {
     324             : 
     325             : /// MatchClassKind - The kinds of classes which participate in
     326             : /// instruction matching.
     327             : enum MatchClassKind {
     328             :   InvalidMatchClass = 0,
     329             :   OptionalMatchClass = 1,
     330             :   MCK__EXCLAIM_, // '!'
     331             :   MCK__38_, // '&'
     332             :   MCK__40_, // '('
     333             :   MCK__41_, // ')'
     334             :   MCK__STAR_, // '*'
     335             :   MCK__43_, // '+'
     336             :   MCK__MINUS_, // '-'
     337             :   MCK__47_, // '/'
     338             :   MCK__LT_, // '<'
     339             :   MCK__61_, // '='
     340             :   MCK__GT_, // '>'
     341             :   MCK__91_, // '['
     342             :   MCK__93_, // ']'
     343             :   MCK__94_, // '^'
     344             :   MCK_be16, // 'be16'
     345             :   MCK_be32, // 'be32'
     346             :   MCK_be64, // 'be64'
     347             :   MCK_call, // 'call'
     348             :   MCK_callx, // 'callx'
     349             :   MCK_exit, // 'exit'
     350             :   MCK_goto, // 'goto'
     351             :   MCK_if, // 'if'
     352             :   MCK_ld_95_pseudo, // 'ld_pseudo'
     353             :   MCK_le16, // 'le16'
     354             :   MCK_le32, // 'le32'
     355             :   MCK_le64, // 'le64'
     356             :   MCK_lea, // 'lea'
     357             :   MCK_ll, // 'll'
     358             :   MCK_lock, // 'lock'
     359             :   MCK_nop, // 'nop'
     360             :   MCK_s, // 's'
     361             :   MCK_skb, // 'skb'
     362             :   MCK_u16, // 'u16'
     363             :   MCK_u32, // 'u32'
     364             :   MCK_u64, // 'u64'
     365             :   MCK_u8, // 'u8'
     366             :   MCK__124_, // '|'
     367             :   MCK_LAST_TOKEN = MCK__124_,
     368             :   MCK_R0, // register class 'R0'
     369             :   MCK_GPR, // register class 'GPR'
     370             :   MCK_GPR32, // register class 'GPR32'
     371             :   MCK_LAST_REGISTER = MCK_GPR32,
     372             :   MCK_Imm, // user defined class 'ImmAsmOperand'
     373             :   NumMatchClassKinds
     374             : };
     375             : 
     376             : }
     377             : 
     378             : static unsigned getDiagKindFromRegisterClass(MatchClassKind RegisterClass) {
     379             :   return MCTargetAsmParser::Match_InvalidOperand;
     380             : }
     381             : 
     382        1861 : static MatchClassKind matchTokenString(StringRef Name) {
     383        1861 :   switch (Name.size()) {
     384             :   default: break;
     385        1745 :   case 1:        // 16 strings to match.
     386        1745 :     switch (Name[0]) {
     387             :     default: break;
     388             :     case '!':    // 1 string to match.
     389             :       return MCK__EXCLAIM_;      // "!"
     390             :     case '&':        // 1 string to match.
     391             :       return MCK__38_;   // "&"
     392             :     case '(':    // 1 string to match.
     393             :       return MCK__40_;   // "("
     394             :     case ')':    // 1 string to match.
     395             :       return MCK__41_;   // ")"
     396             :     case '*':    // 1 string to match.
     397             :       return MCK__STAR_;         // "*"
     398             :     case '+':    // 1 string to match.
     399             :       return MCK__43_;   // "+"
     400             :     case '-':    // 1 string to match.
     401             :       return MCK__MINUS_;        // "-"
     402             :     case '/':    // 1 string to match.
     403             :       return MCK__47_;   // "/"
     404             :     case '<':         // 1 string to match.
     405             :       return MCK__LT_;   // "<"
     406             :     case '=':    // 1 string to match.
     407             :       return MCK__61_;   // "="
     408             :     case '>':         // 1 string to match.
     409             :       return MCK__GT_;   // ">"
     410             :     case '[':    // 1 string to match.
     411             :       return MCK__91_;   // "["
     412             :     case ']':    // 1 string to match.
     413             :       return MCK__93_;   // "]"
     414             :     case '^':    // 1 string to match.
     415             :       return MCK__94_;   // "^"
     416             :     case 's':    // 1 string to match.
     417             :       return MCK_s;      // "s"
     418             :     case '|':    // 1 string to match.
     419             :       return MCK__124_;  // "|"
     420             :     }
     421             :     break;
     422          31 :   case 2:        // 3 strings to match.
     423          31 :     switch (Name[0]) {
     424             :     default: break;
     425           0 :     case 'i':    // 1 string to match.
     426           0 :       if (Name[1] != 'f')
     427             :         break;
     428             :       return MCK_if;     // "if"
     429           4 :     case 'l':    // 1 string to match.
     430           4 :       if (Name[1] != 'l')
     431             :         break;
     432             :       return MCK_ll;     // "ll"
     433          27 :     case 'u':    // 1 string to match.
     434          27 :       if (Name[1] != '8')
     435             :         break;
     436             :       return MCK_u8;     // "u8"
     437             :     }
     438             :     break;
     439          56 :   case 3:        // 6 strings to match.
     440          56 :     switch (Name[0]) {
     441             :     default: break;
     442             :     case 'l':    // 1 string to match.
     443           0 :       if (memcmp(Name.data()+1, "ea", 2) != 0)
     444             :         break;
     445             :       return MCK_lea;    // "lea"
     446             :     case 'n':    // 1 string to match.
     447           0 :       if (memcmp(Name.data()+1, "op", 2) != 0)
     448             :         break;
     449             :       return MCK_nop;    // "nop"
     450             :     case 's':    // 1 string to match.
     451          15 :       if (memcmp(Name.data()+1, "kb", 2) != 0)
     452             :         break;
     453             :       return MCK_skb;    // "skb"
     454          41 :     case 'u':    // 3 strings to match.
     455          41 :       switch (Name[1]) {
     456             :       default: break;
     457          13 :       case '1':  // 1 string to match.
     458          13 :         if (Name[2] != '6')
     459             :           break;
     460             :         return MCK_u16;  // "u16"
     461          20 :       case '3':  // 1 string to match.
     462          20 :         if (Name[2] != '2')
     463             :           break;
     464             :         return MCK_u32;  // "u32"
     465           8 :       case '6':  // 1 string to match.
     466           8 :         if (Name[2] != '4')
     467             :           break;
     468             :         return MCK_u64;  // "u64"
     469             :       }
     470             :       break;
     471             :     }
     472             :     break;
     473          29 :   case 4:        // 10 strings to match.
     474          29 :     switch (Name[0]) {
     475             :     default: break;
     476           9 :     case 'b':    // 3 strings to match.
     477           9 :       if (Name[1] != 'e')
     478             :         break;
     479           9 :       switch (Name[2]) {
     480             :       default: break;
     481           2 :       case '1':  // 1 string to match.
     482           2 :         if (Name[3] != '6')
     483             :           break;
     484             :         return MCK_be16;         // "be16"
     485           3 :       case '3':  // 1 string to match.
     486           3 :         if (Name[3] != '2')
     487             :           break;
     488             :         return MCK_be32;         // "be32"
     489           4 :       case '6':  // 1 string to match.
     490           4 :         if (Name[3] != '4')
     491             :           break;
     492             :         return MCK_be64;         // "be64"
     493             :       }
     494             :       break;
     495             :     case 'c':    // 1 string to match.
     496           0 :       if (memcmp(Name.data()+1, "all", 3) != 0)
     497             :         break;
     498             :       return MCK_call;   // "call"
     499             :     case 'e':    // 1 string to match.
     500           0 :       if (memcmp(Name.data()+1, "xit", 3) != 0)
     501             :         break;
     502             :       return MCK_exit;   // "exit"
     503             :     case 'g':    // 1 string to match.
     504          20 :       if (memcmp(Name.data()+1, "oto", 3) != 0)
     505             :         break;
     506             :       return MCK_goto;   // "goto"
     507           0 :     case 'l':    // 4 strings to match.
     508           0 :       switch (Name[1]) {
     509             :       default: break;
     510           0 :       case 'e':  // 3 strings to match.
     511           0 :         switch (Name[2]) {
     512             :         default: break;
     513           0 :         case '1':        // 1 string to match.
     514           0 :           if (Name[3] != '6')
     515             :             break;
     516             :           return MCK_le16;       // "le16"
     517           0 :         case '3':        // 1 string to match.
     518           0 :           if (Name[3] != '2')
     519             :             break;
     520             :           return MCK_le32;       // "le32"
     521           0 :         case '6':        // 1 string to match.
     522           0 :           if (Name[3] != '4')
     523             :             break;
     524             :           return MCK_le64;       // "le64"
     525             :         }
     526             :         break;
     527             :       case 'o':  // 1 string to match.
     528           0 :         if (memcmp(Name.data()+2, "ck", 2) != 0)
     529             :           break;
     530             :         return MCK_lock;         // "lock"
     531             :       }
     532             :       break;
     533             :     }
     534             :     break;
     535             :   case 5:        // 1 string to match.
     536           0 :     if (memcmp(Name.data()+0, "callx", 5) != 0)
     537             :       break;
     538             :     return MCK_callx;    // "callx"
     539             :   case 9:        // 1 string to match.
     540           0 :     if (memcmp(Name.data()+0, "ld_pseudo", 9) != 0)
     541             :       break;
     542             :     return MCK_ld_95_pseudo;     // "ld_pseudo"
     543             :   }
     544             :   return InvalidMatchClass;
     545             : }
     546             : 
     547             : /// isSubclass - Compute whether \p A is a subclass of \p B.
     548             : static bool isSubclass(MatchClassKind A, MatchClassKind B) {
     549        6711 :   if (A == B)
     550             :     return true;
     551             : 
     552        2471 :   switch (A) {
     553             :   default:
     554             :     return false;
     555             : 
     556         582 :   case MCK_R0:
     557         582 :     return B == MCK_GPR;
     558             :   }
     559             : }
     560             : 
     561        4559 : static unsigned validateOperandClass(MCParsedAsmOperand &GOp, MatchClassKind Kind) {
     562             :   BPFOperand &Operand = (BPFOperand&)GOp;
     563        4559 :   if (Kind == InvalidMatchClass)
     564             :     return MCTargetAsmParser::Match_InvalidOperand;
     565             : 
     566        4555 :   if (Operand.isToken() && Kind <= MCK_LAST_TOKEN)
     567        1861 :     return isSubclass(matchTokenString(Operand.getToken()), Kind) ?
     568             :              MCTargetAsmParser::Match_Success :
     569             :              MCTargetAsmParser::Match_InvalidOperand;
     570             : 
     571        2694 :   switch (Kind) {
     572             :   default: break;
     573             :   // 'Imm' class
     574         110 :   case MCK_Imm:
     575         110 :     if (Operand.isImm())
     576             :       return MCTargetAsmParser::Match_Success;
     577             :     break;
     578             :   } // end switch (Kind)
     579             : 
     580        2617 :   if (Operand.isReg()) {
     581             :     MatchClassKind OpKind;
     582             :     switch (Operand.getReg()) {
     583             :     default: OpKind = InvalidMatchClass; break;
     584             :     case BPF::W0: OpKind = MCK_GPR32; break;
     585             :     case BPF::W1: OpKind = MCK_GPR32; break;
     586             :     case BPF::W2: OpKind = MCK_GPR32; break;
     587             :     case BPF::W3: OpKind = MCK_GPR32; break;
     588             :     case BPF::W4: OpKind = MCK_GPR32; break;
     589             :     case BPF::W5: OpKind = MCK_GPR32; break;
     590             :     case BPF::W6: OpKind = MCK_GPR32; break;
     591             :     case BPF::W7: OpKind = MCK_GPR32; break;
     592             :     case BPF::W8: OpKind = MCK_GPR32; break;
     593             :     case BPF::W9: OpKind = MCK_GPR32; break;
     594             :     case BPF::W10: OpKind = MCK_GPR32; break;
     595             :     case BPF::W11: OpKind = MCK_GPR32; break;
     596             :     case BPF::R0: OpKind = MCK_R0; break;
     597             :     case BPF::R1: OpKind = MCK_GPR; break;
     598             :     case BPF::R2: OpKind = MCK_GPR; break;
     599             :     case BPF::R3: OpKind = MCK_GPR; break;
     600             :     case BPF::R4: OpKind = MCK_GPR; break;
     601             :     case BPF::R5: OpKind = MCK_GPR; break;
     602             :     case BPF::R6: OpKind = MCK_GPR; break;
     603             :     case BPF::R7: OpKind = MCK_GPR; break;
     604             :     case BPF::R8: OpKind = MCK_GPR; break;
     605             :     case BPF::R9: OpKind = MCK_GPR; break;
     606             :     case BPF::R10: OpKind = MCK_GPR; break;
     607             :     case BPF::R11: OpKind = MCK_GPR; break;
     608             :     }
     609         582 :     return isSubclass(OpKind, Kind) ? (unsigned)MCTargetAsmParser::Match_Success :
     610             :                                       getDiagKindFromRegisterClass(Kind);
     611             :   }
     612             : 
     613             :   if (Kind > MCK_LAST_TOKEN && Kind <= MCK_LAST_REGISTER)
     614             :     return getDiagKindFromRegisterClass(Kind);
     615             : 
     616             :   return MCTargetAsmParser::Match_InvalidOperand;
     617             : }
     618             : 
     619             : #ifndef NDEBUG
     620             : const char *getMatchClassName(MatchClassKind Kind) {
     621             :   switch (Kind) {
     622             :   case InvalidMatchClass: return "InvalidMatchClass";
     623             :   case OptionalMatchClass: return "OptionalMatchClass";
     624             :   case MCK__EXCLAIM_: return "MCK__EXCLAIM_";
     625             :   case MCK__38_: return "MCK__38_";
     626             :   case MCK__40_: return "MCK__40_";
     627             :   case MCK__41_: return "MCK__41_";
     628             :   case MCK__STAR_: return "MCK__STAR_";
     629             :   case MCK__43_: return "MCK__43_";
     630             :   case MCK__MINUS_: return "MCK__MINUS_";
     631             :   case MCK__47_: return "MCK__47_";
     632             :   case MCK__LT_: return "MCK__LT_";
     633             :   case MCK__61_: return "MCK__61_";
     634             :   case MCK__GT_: return "MCK__GT_";
     635             :   case MCK__91_: return "MCK__91_";
     636             :   case MCK__93_: return "MCK__93_";
     637             :   case MCK__94_: return "MCK__94_";
     638             :   case MCK_be16: return "MCK_be16";
     639             :   case MCK_be32: return "MCK_be32";
     640             :   case MCK_be64: return "MCK_be64";
     641             :   case MCK_call: return "MCK_call";
     642             :   case MCK_callx: return "MCK_callx";
     643             :   case MCK_exit: return "MCK_exit";
     644             :   case MCK_goto: return "MCK_goto";
     645             :   case MCK_if: return "MCK_if";
     646             :   case MCK_ld_95_pseudo: return "MCK_ld_95_pseudo";
     647             :   case MCK_le16: return "MCK_le16";
     648             :   case MCK_le32: return "MCK_le32";
     649             :   case MCK_le64: return "MCK_le64";
     650             :   case MCK_lea: return "MCK_lea";
     651             :   case MCK_ll: return "MCK_ll";
     652             :   case MCK_lock: return "MCK_lock";
     653             :   case MCK_nop: return "MCK_nop";
     654             :   case MCK_s: return "MCK_s";
     655             :   case MCK_skb: return "MCK_skb";
     656             :   case MCK_u16: return "MCK_u16";
     657             :   case MCK_u32: return "MCK_u32";
     658             :   case MCK_u64: return "MCK_u64";
     659             :   case MCK_u8: return "MCK_u8";
     660             :   case MCK__124_: return "MCK__124_";
     661             :   case MCK_R0: return "MCK_R0";
     662             :   case MCK_GPR: return "MCK_GPR";
     663             :   case MCK_GPR32: return "MCK_GPR32";
     664             :   case MCK_Imm: return "MCK_Imm";
     665             :   case NumMatchClassKinds: return "NumMatchClassKinds";
     666             :   }
     667             :   llvm_unreachable("unhandled MatchClassKind!");
     668             : }
     669             : 
     670             : #endif // NDEBUG
     671             : uint64_t BPFAsmParser::
     672             : ComputeAvailableFeatures(const FeatureBitset& FB) const {
     673             :   uint64_t Features = 0;
     674             :   return Features;
     675             : }
     676             : 
     677          94 : static bool checkAsmTiedOperandConstraints(unsigned Kind,
     678             :                                const OperandVector &Operands,
     679             :                                uint64_t &ErrorInfo) {
     680             :   assert(Kind < CVT_NUM_SIGNATURES && "Invalid signature!");
     681          94 :   const uint8_t *Converter = ConversionTable[Kind];
     682         606 :   for (const uint8_t *p = Converter; *p; p+= 2) {
     683         256 :     switch (*p) {
     684          47 :     case CVT_Tied: {
     685          47 :       unsigned OpIdx = *(p+1);
     686             :       assert(OpIdx < (size_t)(std::end(TiedAsmOperandTable) -
     687             :                               std::begin(TiedAsmOperandTable)) &&
     688             :              "Tied operand not found");
     689          47 :       unsigned OpndNum1 = TiedAsmOperandTable[OpIdx][1];
     690          47 :       unsigned OpndNum2 = TiedAsmOperandTable[OpIdx][2];
     691          47 :       if (OpndNum1 != OpndNum2) {
     692           5 :         auto &SrcOp1 = Operands[OpndNum1];
     693           5 :         auto &SrcOp2 = Operands[OpndNum2];
     694          15 :         if (SrcOp1->isReg() && SrcOp2->isReg() &&
     695          10 :             SrcOp1->getReg() != SrcOp2->getReg()) {
     696           0 :           ErrorInfo = OpndNum2;
     697           0 :           return false;
     698             :         }
     699             :       }
     700             :       break;
     701             :     }
     702             :     default:
     703             :       break;
     704             :     }
     705             :   }
     706             :   return true;
     707             : }
     708             : 
     709             : static const char *const MnemonicTable =
     710             :     "\000\001*\004call\005callx\004exit\004goto\002if\tld_pseudo\003lea\004l"
     711             :     "ock\003nop\002r0";
     712             : 
     713             : namespace {
     714             :   struct MatchEntry {
     715             :     uint8_t Mnemonic;
     716             :     uint16_t Opcode;
     717             :     uint8_t ConvertFn;
     718             :     uint8_t RequiredFeatures;
     719             :     uint8_t Classes[13];
     720             :     StringRef getMnemonic() const {
     721         362 :       return StringRef(MnemonicTable + Mnemonic + 1,
     722         362 :                        MnemonicTable[Mnemonic]);
     723             :     }
     724             :   };
     725             : 
     726             :   // Predicate for searching for an opcode.
     727             :   struct LessOpcode {
     728             :     bool operator()(const MatchEntry &LHS, StringRef RHS) {
     729         392 :       return LHS.getMnemonic() < RHS;
     730             :     }
     731             :     bool operator()(StringRef LHS, const MatchEntry &RHS) {
     732         332 :       return LHS < RHS.getMnemonic();
     733             :     }
     734             :     bool operator()(const MatchEntry &LHS, const MatchEntry &RHS) {
     735             :       return LHS.getMnemonic() < RHS.getMnemonic();
     736             :     }
     737             :   };
     738             : } // end anonymous namespace.
     739             : 
     740             : static const MatchEntry MatchTable0[] = {
     741             :   { 0 /*  */, BPF::MOV_rr, Convert__Reg1_0__Reg1_2, 0, { MCK_GPR, MCK__61_, MCK_GPR }, },
     742             :   { 0 /*  */, BPF::MOV_ri, Convert__Reg1_0__Imm1_2, 0, { MCK_GPR, MCK__61_, MCK_Imm }, },
     743             :   { 0 /*  */, BPF::MOV_rr_32, Convert__Reg1_0__Reg1_2, 0, { MCK_GPR32, MCK__61_, MCK_GPR32 }, },
     744             :   { 0 /*  */, BPF::MOV_ri_32, Convert__Reg1_0__Imm1_2, 0, { MCK_GPR32, MCK__61_, MCK_Imm }, },
     745             :   { 0 /*  */, BPF::AND_rr, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR, MCK__38_, MCK__61_, MCK_GPR }, },
     746             :   { 0 /*  */, BPF::AND_ri, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR, MCK__38_, MCK__61_, MCK_Imm }, },
     747             :   { 0 /*  */, BPF::MUL_rr, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR, MCK__STAR_, MCK__61_, MCK_GPR }, },
     748             :   { 0 /*  */, BPF::MUL_ri, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR, MCK__STAR_, MCK__61_, MCK_Imm }, },
     749             :   { 0 /*  */, BPF::ADD_rr, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR, MCK__43_, MCK__61_, MCK_GPR }, },
     750             :   { 0 /*  */, BPF::ADD_ri, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR, MCK__43_, MCK__61_, MCK_Imm }, },
     751             :   { 0 /*  */, BPF::SUB_rr, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR, MCK__MINUS_, MCK__61_, MCK_GPR }, },
     752             :   { 0 /*  */, BPF::SUB_ri, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR, MCK__MINUS_, MCK__61_, MCK_Imm }, },
     753             :   { 0 /*  */, BPF::DIV_rr, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR, MCK__47_, MCK__61_, MCK_GPR }, },
     754             :   { 0 /*  */, BPF::DIV_ri, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR, MCK__47_, MCK__61_, MCK_Imm }, },
     755             :   { 0 /*  */, BPF::NEG_64, Convert__Reg1_0__Tie0_0_3, 0, { MCK_GPR, MCK__61_, MCK__MINUS_, MCK_GPR }, },
     756             :   { 0 /*  */, BPF::BE16, Convert__Reg1_0__Tie0_0_3, 0, { MCK_GPR, MCK__61_, MCK_be16, MCK_GPR }, },
     757             :   { 0 /*  */, BPF::BE32, Convert__Reg1_0__Tie0_0_3, 0, { MCK_GPR, MCK__61_, MCK_be32, MCK_GPR }, },
     758             :   { 0 /*  */, BPF::BE64, Convert__Reg1_0__Tie0_0_3, 0, { MCK_GPR, MCK__61_, MCK_be64, MCK_GPR }, },
     759             :   { 0 /*  */, BPF::LE16, Convert__Reg1_0__Tie0_0_3, 0, { MCK_GPR, MCK__61_, MCK_le16, MCK_GPR }, },
     760             :   { 0 /*  */, BPF::LE32, Convert__Reg1_0__Tie0_0_3, 0, { MCK_GPR, MCK__61_, MCK_le32, MCK_GPR }, },
     761             :   { 0 /*  */, BPF::LE64, Convert__Reg1_0__Tie0_0_3, 0, { MCK_GPR, MCK__61_, MCK_le64, MCK_GPR }, },
     762             :   { 0 /*  */, BPF::LD_imm64, Convert__Reg1_0__Imm1_2, 0, { MCK_GPR, MCK__61_, MCK_Imm, MCK_ll }, },
     763             :   { 0 /*  */, BPF::XOR_rr, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR, MCK__94_, MCK__61_, MCK_GPR }, },
     764             :   { 0 /*  */, BPF::XOR_ri, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR, MCK__94_, MCK__61_, MCK_Imm }, },
     765             :   { 0 /*  */, BPF::OR_rr, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR, MCK__124_, MCK__61_, MCK_GPR }, },
     766             :   { 0 /*  */, BPF::OR_ri, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR, MCK__124_, MCK__61_, MCK_Imm }, },
     767             :   { 0 /*  */, BPF::AND_rr_32, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR32, MCK__38_, MCK__61_, MCK_GPR32 }, },
     768             :   { 0 /*  */, BPF::AND_ri_32, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR32, MCK__38_, MCK__61_, MCK_Imm }, },
     769             :   { 0 /*  */, BPF::MUL_rr_32, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR32, MCK__STAR_, MCK__61_, MCK_GPR32 }, },
     770             :   { 0 /*  */, BPF::MUL_ri_32, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR32, MCK__STAR_, MCK__61_, MCK_Imm }, },
     771             :   { 0 /*  */, BPF::ADD_rr_32, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR32, MCK__43_, MCK__61_, MCK_GPR32 }, },
     772             :   { 0 /*  */, BPF::ADD_ri_32, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR32, MCK__43_, MCK__61_, MCK_Imm }, },
     773             :   { 0 /*  */, BPF::SUB_rr_32, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR32, MCK__MINUS_, MCK__61_, MCK_GPR32 }, },
     774             :   { 0 /*  */, BPF::SUB_ri_32, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR32, MCK__MINUS_, MCK__61_, MCK_Imm }, },
     775             :   { 0 /*  */, BPF::DIV_rr_32, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR32, MCK__47_, MCK__61_, MCK_GPR32 }, },
     776             :   { 0 /*  */, BPF::DIV_ri_32, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR32, MCK__47_, MCK__61_, MCK_Imm }, },
     777             :   { 0 /*  */, BPF::NEG_32, Convert__Reg1_0__Tie0_0_3, 0, { MCK_GPR32, MCK__61_, MCK__MINUS_, MCK_GPR32 }, },
     778             :   { 0 /*  */, BPF::XOR_rr_32, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR32, MCK__94_, MCK__61_, MCK_GPR32 }, },
     779             :   { 0 /*  */, BPF::XOR_ri_32, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR32, MCK__94_, MCK__61_, MCK_Imm }, },
     780             :   { 0 /*  */, BPF::OR_rr_32, Convert__Reg1_0__Tie0_0_0__Reg1_3, 0, { MCK_GPR32, MCK__124_, MCK__61_, MCK_GPR32 }, },
     781             :   { 0 /*  */, BPF::OR_ri_32, Convert__Reg1_0__Tie0_0_0__Imm1_3, 0, { MCK_GPR32, MCK__124_, MCK__61_, MCK_Imm }, },
     782             :   { 0 /*  */, BPF::SLL_rr, Convert__Reg1_0__Tie0_0_0__Reg1_4, 0, { MCK_GPR, MCK__LT_, MCK__LT_, MCK__61_, MCK_GPR }, },
     783             :   { 0 /*  */, BPF::SLL_ri, Convert__Reg1_0__Tie0_0_0__Imm1_4, 0, { MCK_GPR, MCK__LT_, MCK__LT_, MCK__61_, MCK_Imm }, },
     784             :   { 0 /*  */, BPF::SRL_rr, Convert__Reg1_0__Tie0_0_0__Reg1_4, 0, { MCK_GPR, MCK__GT_, MCK__GT_, MCK__61_, MCK_GPR }, },
     785             :   { 0 /*  */, BPF::SRL_ri, Convert__Reg1_0__Tie0_0_0__Imm1_4, 0, { MCK_GPR, MCK__GT_, MCK__GT_, MCK__61_, MCK_Imm }, },
     786             :   { 0 /*  */, BPF::SLL_rr_32, Convert__Reg1_0__Tie0_0_0__Reg1_4, 0, { MCK_GPR32, MCK__LT_, MCK__LT_, MCK__61_, MCK_GPR32 }, },
     787             :   { 0 /*  */, BPF::SLL_ri_32, Convert__Reg1_0__Tie0_0_0__Imm1_4, 0, { MCK_GPR32, MCK__LT_, MCK__LT_, MCK__61_, MCK_Imm }, },
     788             :   { 0 /*  */, BPF::SRL_rr_32, Convert__Reg1_0__Tie0_0_0__Reg1_4, 0, { MCK_GPR32, MCK__GT_, MCK__GT_, MCK__61_, MCK_GPR32 }, },
     789             :   { 0 /*  */, BPF::SRL_ri_32, Convert__Reg1_0__Tie0_0_0__Imm1_4, 0, { MCK_GPR32, MCK__GT_, MCK__GT_, MCK__61_, MCK_Imm }, },
     790             :   { 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 }, },
     791             :   { 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 }, },
     792             :   { 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 }, },
     793             :   { 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 }, },
     794             :   { 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_ }, },
     795             :   { 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_ }, },
     796             :   { 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_ }, },
     797             :   { 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_ }, },
     798             :   { 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 }, },
     799             :   { 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 }, },
     800             :   { 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 }, },
     801             :   { 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 }, },
     802             :   { 3 /* call */, BPF::JAL, Convert__Imm1_1, 0, { MCK_call, MCK_Imm }, },
     803             :   { 8 /* callx */, BPF::JALX, Convert__Imm1_1, 0, { MCK_callx, MCK_Imm }, },
     804             :   { 14 /* exit */, BPF::RET, Convert_NoOperands, 0, { MCK_exit }, },
     805             :   { 19 /* goto */, BPF::JMP, Convert__Imm1_1, 0, { MCK_goto, MCK_Imm }, },
     806             :   { 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 }, },
     807             :   { 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 }, },
     808             :   { 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 }, },
     809             :   { 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 }, },
     810             :   { 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 }, },
     811             :   { 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 }, },
     812             :   { 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 }, },
     813             :   { 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 }, },
     814             :   { 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 }, },
     815             :   { 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 }, },
     816             :   { 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 }, },
     817             :   { 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 }, },
     818             :   { 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 }, },
     819             :   { 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 }, },
     820             :   { 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 }, },
     821             :   { 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 }, },
     822             :   { 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 }, },
     823             :   { 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 }, },
     824             :   { 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 }, },
     825             :   { 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 }, },
     826             :   { 27 /* ld_pseudo */, BPF::LD_pseudo, Convert__Reg1_1__Imm1_2__Imm1_3, 0, { MCK_ld_95_pseudo, MCK_GPR, MCK_Imm, MCK_Imm }, },
     827             :   { 37 /* lea */, BPF::FI_ri, Convert__Reg1_1__Reg1_2__Imm1_3, 0, { MCK_lea, MCK_GPR, MCK_GPR, MCK_Imm }, },
     828             :   { 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 }, },
     829             :   { 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 }, },
     830             :   { 46 /* nop */, BPF::NOP, Convert__Imm1_1, 0, { MCK_nop, MCK_Imm }, },
     831             :   { 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_ }, },
     832             :   { 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_ }, },
     833             :   { 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_ }, },
     834             :   { 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_ }, },
     835             :   { 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_ }, },
     836             :   { 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_ }, },
     837             : };
     838             : 
     839             : #include "llvm/Support/Debug.h"
     840             : #include "llvm/Support/Format.h"
     841             : 
     842          94 : unsigned BPFAsmParser::
     843             : MatchInstructionImpl(const OperandVector &Operands,
     844             :                      MCInst &Inst,
     845             :                      uint64_t &ErrorInfo,
     846             :                      bool matchingInlineAsm, unsigned VariantID) {
     847             :   // Eliminate obvious mismatches.
     848          94 :   if (Operands.size() > 13) {
     849           0 :     ErrorInfo = 13;
     850           0 :     return Match_InvalidOperand;
     851             :   }
     852             : 
     853             :   // Get the current feature set.
     854          94 :   uint64_t AvailableFeatures = getAvailableFeatures();
     855             : 
     856             :   // Get the instruction mnemonic, which is the first token.
     857          94 :   StringRef Mnemonic;
     858          94 :   if (Operands[0]->isToken())
     859          29 :     Mnemonic = ((BPFOperand&)*Operands[0]).getToken();
     860             : 
     861             :   // Some state to try to produce better error messages.
     862             :   bool HadMatchOtherThanFeatures = false;
     863             :   bool HadMatchOtherThanPredicate = false;
     864             :   unsigned RetCode = Match_InvalidOperand;
     865             :   uint64_t MissingFeatures = ~0ULL;
     866             :   // Set ErrorInfo to the operand that mismatches if it is
     867             :   // wrong for all instances of the instruction.
     868          94 :   ErrorInfo = ~0ULL;
     869             :   // Find the appropriate table for this asm variant.
     870             :   const MatchEntry *Start, *End;
     871          94 :   switch (VariantID) {
     872           0 :   default: llvm_unreachable("invalid variant!");
     873             :   case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
     874             :   }
     875             :   // Search the table.
     876             :   auto MnemonicRange = std::make_pair(Start, End);
     877          94 :   unsigned SIndex = Mnemonic.empty() ? 0 : 1;
     878          94 :   if (!Mnemonic.empty())
     879          58 :     MnemonicRange = std::equal_range(Start, End, Mnemonic.lower(), LessOpcode());
     880             : 
     881             :   DEBUG_WITH_TYPE("asm-matcher", dbgs() << "AsmMatcher: found " <<
     882             :   std::distance(MnemonicRange.first, MnemonicRange.second) << 
     883             :   " encodings with mnemonic '" << Mnemonic << "'\n");
     884             : 
     885             :   // Return a more specific error code if no mnemonics match.
     886          94 :   if (MnemonicRange.first == MnemonicRange.second)
     887             :     return Match_MnemonicFail;
     888             : 
     889        2358 :   for (const MatchEntry *it = MnemonicRange.first, *ie = MnemonicRange.second;
     890        2452 :        it != ie; ++it) {
     891        2452 :     bool HasRequiredFeatures =
     892        2452 :       (AvailableFeatures & it->RequiredFeatures) == it->RequiredFeatures;
     893             :     DEBUG_WITH_TYPE("asm-matcher", dbgs() << "Trying to match opcode "
     894             :                                           << MII.getName(it->Opcode) << "\n");
     895             :     bool OperandsValid = true;
     896        6854 :     for (unsigned FormalIdx = SIndex, ActualIdx = SIndex; FormalIdx != 13; ++FormalIdx) {
     897        4651 :       auto Formal = static_cast<MatchClassKind>(it->Classes[FormalIdx]);
     898             :       DEBUG_WITH_TYPE("asm-matcher",
     899             :                       dbgs() << "  Matching formal operand class " << getMatchClassName(Formal)
     900             :                              << " against actual operand at index " << ActualIdx);
     901        4651 :       if (ActualIdx < Operands.size())
     902             :         DEBUG_WITH_TYPE("asm-matcher", dbgs() << " (";
     903             :                         Operands[ActualIdx]->print(dbgs()); dbgs() << "): ");
     904             :       else
     905             :         DEBUG_WITH_TYPE("asm-matcher", dbgs() << ": ");
     906        4651 :       if (ActualIdx >= Operands.size()) {
     907             :         DEBUG_WITH_TYPE("asm-matcher", dbgs() << "actual operand index out of range ");
     908          92 :         OperandsValid = (Formal == InvalidMatchClass) || isSubclass(Formal, OptionalMatchClass);
     909           0 :         if (!OperandsValid) ErrorInfo = ActualIdx;
     910             :         break;
     911             :       }
     912             :       MCParsedAsmOperand &Actual = *Operands[ActualIdx];
     913        4559 :       unsigned Diag = validateOperandClass(Actual, Formal);
     914        6760 :       if (Diag == Match_Success) {
     915             :         DEBUG_WITH_TYPE("asm-matcher",
     916             :                         dbgs() << "match success using generic matcher\n");
     917        2201 :         ++ActualIdx;
     918        2201 :         continue;
     919             :       }
     920             :       // If the generic handler indicates an invalid operand
     921             :       // failure, check for a special case.
     922             :       if (Diag != Match_Success) {
     923        2358 :         unsigned TargetDiag = validateTargetOperandClass(Actual, Formal);
     924        2358 :         if (TargetDiag == Match_Success) {
     925             :           DEBUG_WITH_TYPE("asm-matcher",
     926             :                           dbgs() << "match success using target matcher\n");
     927           0 :           ++ActualIdx;
     928           0 :           continue;
     929             :         }
     930             :         // If the target matcher returned a specific error code use
     931             :         // that, else use the one from the generic matcher.
     932        2358 :         if (TargetDiag != Match_InvalidOperand && HasRequiredFeatures)
     933             :           Diag = TargetDiag;
     934             :       }
     935             :       // If current formal operand wasn't matched and it is optional
     936             :       // then try to match next formal operand
     937        2358 :       if (Diag == Match_InvalidOperand && isSubclass(Formal, OptionalMatchClass)) {
     938             :         DEBUG_WITH_TYPE("asm-matcher", dbgs() << "ignoring optional operand\n");
     939           0 :         continue;
     940             :       }
     941             :       // If this operand is broken for all of the instances of this
     942             :       // mnemonic, keep track of it so we can report loc info.
     943             :       // If we already had a match that only failed due to a
     944             :       // target predicate, that diagnostic is preferred.
     945        4716 :       if (!HadMatchOtherThanPredicate &&
     946        2271 :           (it == MnemonicRange.first || ErrorInfo <= ActualIdx)) {
     947         918 :         if (HasRequiredFeatures && (ErrorInfo != ActualIdx || Diag != Match_InvalidOperand))
     948             :           RetCode = Diag;
     949         918 :         ErrorInfo = ActualIdx;
     950             :       }
     951             :       // Otherwise, just reject this instance of the mnemonic.
     952             :       OperandsValid = false;
     953             :       break;
     954             :     }
     955             : 
     956        2452 :     if (!OperandsValid) {
     957             :       DEBUG_WITH_TYPE("asm-matcher", dbgs() << "Opcode result: multiple "
     958             :                                                "operand mismatches, ignoring "
     959             :                                                "this opcode\n");
     960        2358 :       continue;
     961             :     }
     962          94 :     if (!HasRequiredFeatures) {
     963             :       HadMatchOtherThanFeatures = true;
     964           0 :       uint64_t NewMissingFeatures = it->RequiredFeatures & ~AvailableFeatures;
     965             :       DEBUG_WITH_TYPE("asm-matcher", dbgs() << "Missing target features: "
     966             :                                             << format_hex(NewMissingFeatures, 18)
     967             :                                             << "\n");
     968           0 :       if (countPopulation(NewMissingFeatures) <=
     969             :           countPopulation(MissingFeatures))
     970             :         MissingFeatures = NewMissingFeatures;
     971           0 :       continue;
     972             :     }
     973             : 
     974             :     Inst.clear();
     975             : 
     976          94 :     Inst.setOpcode(it->Opcode);
     977             :     // We have a potential match but have not rendered the operands.
     978             :     // Check the target predicate to handle any context sensitive
     979             :     // constraints.
     980             :     // For example, Ties that are referenced multiple times must be
     981             :     // checked here to ensure the input is the same for each match
     982             :     // constraints. If we leave it any later the ties will have been
     983             :     // canonicalized
     984             :     unsigned MatchResult;
     985          94 :     if ((MatchResult = checkEarlyTargetMatchPredicate(Inst, Operands)) != Match_Success) {
     986             :       Inst.clear();
     987             :       DEBUG_WITH_TYPE(
     988             :           "asm-matcher",
     989             :           dbgs() << "Early target match predicate failed with diag code "
     990             :                  << MatchResult << "\n");
     991             :       RetCode = MatchResult;
     992             :       HadMatchOtherThanPredicate = true;
     993           0 :       continue;
     994             :     }
     995             : 
     996          94 :     if (matchingInlineAsm) {
     997           0 :       convertToMapAndConstraints(it->ConvertFn, Operands);
     998           0 :       if (!checkAsmTiedOperandConstraints(it->ConvertFn, Operands, ErrorInfo))
     999             :         return Match_InvalidTiedOperand;
    1000             : 
    1001           0 :       return Match_Success;
    1002             :     }
    1003             : 
    1004             :     // We have selected a definite instruction, convert the parsed
    1005             :     // operands into the appropriate MCInst.
    1006          94 :     convertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);
    1007             : 
    1008             :     // We have a potential match. Check the target predicate to
    1009             :     // handle any context sensitive constraints.
    1010          94 :     if ((MatchResult = checkTargetMatchPredicate(Inst)) != Match_Success) {
    1011             :       DEBUG_WITH_TYPE("asm-matcher",
    1012             :                       dbgs() << "Target match predicate failed with diag code "
    1013             :                              << MatchResult << "\n");
    1014             :       Inst.clear();
    1015             :       RetCode = MatchResult;
    1016             :       HadMatchOtherThanPredicate = true;
    1017           0 :       continue;
    1018             :     }
    1019             : 
    1020          94 :       if (!checkAsmTiedOperandConstraints(it->ConvertFn, Operands, ErrorInfo))
    1021             :         return Match_InvalidTiedOperand;
    1022             : 
    1023             :     DEBUG_WITH_TYPE(
    1024             :         "asm-matcher",
    1025             :         dbgs() << "Opcode result: complete match, selecting this opcode\n");
    1026          94 :     return Match_Success;
    1027             :   }
    1028             : 
    1029             :   // Okay, we had no match.  Try to return a useful error code.
    1030           0 :   if (HadMatchOtherThanPredicate || !HadMatchOtherThanFeatures)
    1031             :     return RetCode;
    1032             : 
    1033             :   // Missing feature matches return which features were missing
    1034           0 :   ErrorInfo = MissingFeatures;
    1035           0 :   return Match_MissingFeature;
    1036             : }
    1037             : 
    1038             : #endif // GET_MATCHER_IMPLEMENTATION
    1039             : 
    1040             : 
    1041             : #ifdef GET_MNEMONIC_SPELL_CHECKER
    1042             : #undef GET_MNEMONIC_SPELL_CHECKER
    1043             : 
    1044             : static std::string BPFMnemonicSpellCheck(StringRef S, uint64_t FBS, unsigned VariantID) {
    1045             :   const unsigned MaxEditDist = 2;
    1046             :   std::vector<StringRef> Candidates;
    1047             :   StringRef Prev = "";
    1048             : 
    1049             :   // Find the appropriate table for this asm variant.
    1050             :   const MatchEntry *Start, *End;
    1051             :   switch (VariantID) {
    1052             :   default: llvm_unreachable("invalid variant!");
    1053             :   case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
    1054             :   }
    1055             : 
    1056             :   for (auto I = Start; I < End; I++) {
    1057             :     // Ignore unsupported instructions.
    1058             :     if ((FBS & I->RequiredFeatures) != I->RequiredFeatures)
    1059             :       continue;
    1060             : 
    1061             :     StringRef T = I->getMnemonic();
    1062             :     // Avoid recomputing the edit distance for the same string.
    1063             :     if (T.equals(Prev))
    1064             :       continue;
    1065             : 
    1066             :     Prev = T;
    1067             :     unsigned Dist = S.edit_distance(T, false, MaxEditDist);
    1068             :     if (Dist <= MaxEditDist)
    1069             :       Candidates.push_back(T);
    1070             :   }
    1071             : 
    1072             :   if (Candidates.empty())
    1073             :     return "";
    1074             : 
    1075             :   std::string Res = ", did you mean: ";
    1076             :   unsigned i = 0;
    1077             :   for( ; i < Candidates.size() - 1; i++)
    1078             :     Res += Candidates[i].str() + ", ";
    1079             :   return Res + Candidates[i].str() + "?";
    1080             : }
    1081             : 
    1082             : #endif // GET_MNEMONIC_SPELL_CHECKER
    1083             : 

Generated by: LCOV version 1.13