Coverage Report

Created: 2024-01-17 10:31

/src/build/lib/Target/Lanai/LanaiGenAsmMatcher.inc
Line
Count
Source (jump to first uncovered line)
1
/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
2
|*                                                                            *|
3
|* Assembly Matcher Source Fragment                                           *|
4
|*                                                                            *|
5
|* Automatically generated file, do not edit!                                 *|
6
|* From: Lanai.td                                                             *|
7
|*                                                                            *|
8
\*===----------------------------------------------------------------------===*/
9
10
11
#ifdef GET_ASSEMBLER_HEADER
12
#undef GET_ASSEMBLER_HEADER
13
  // This should be included into the middle of the declaration of
14
  // your subclasses implementation of MCTargetAsmParser.
15
  FeatureBitset ComputeAvailableFeatures(const FeatureBitset &FB) const;
16
  void convertToMCInst(unsigned Kind, MCInst &Inst, unsigned Opcode,
17
                       const OperandVector &Operands);
18
  void convertToMapAndConstraints(unsigned Kind,
19
                           const OperandVector &Operands) override;
20
  unsigned MatchInstructionImpl(const OperandVector &Operands,
21
                                MCInst &Inst,
22
                                uint64_t &ErrorInfo,
23
                                FeatureBitset &MissingFeatures,
24
                                bool matchingInlineAsm,
25
                                unsigned VariantID = 0);
26
  unsigned MatchInstructionImpl(const OperandVector &Operands,
27
                                MCInst &Inst,
28
                                uint64_t &ErrorInfo,
29
                                bool matchingInlineAsm,
30
0
                                unsigned VariantID = 0) {
31
0
    FeatureBitset MissingFeatures;
32
0
    return MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
33
0
                                matchingInlineAsm, VariantID);
34
0
  }
35
36
  ParseStatus MatchOperandParserImpl(
37
    OperandVector &Operands,
38
    StringRef Mnemonic,
39
    bool ParseForAllFeatures = false);
40
  ParseStatus tryCustomParseOperand(
41
    OperandVector &Operands,
42
    unsigned MCK);
43
44
#endif // GET_ASSEMBLER_HEADER
45
46
47
#ifdef GET_OPERAND_DIAGNOSTIC_TYPES
48
#undef GET_OPERAND_DIAGNOSTIC_TYPES
49
50
#endif // GET_OPERAND_DIAGNOSTIC_TYPES
51
52
53
#ifdef GET_REGISTER_MATCHER
54
#undef GET_REGISTER_MATCHER
55
56
// Bits for subtarget features that participate in instruction matching.
57
enum SubtargetFeatureBits : uint8_t {
58
};
59
60
0
static unsigned MatchRegisterName(StringRef Name) {
61
0
  switch (Name.size()) {
62
0
  default: break;
63
0
  case 2:  // 15 strings to match.
64
0
    switch (Name[0]) {
65
0
    default: break;
66
0
    case 'f':  // 1 string to match.
67
0
      if (Name[1] != 'p')
68
0
        break;
69
0
      return 1;  // "fp"
70
0
    case 'p':  // 1 string to match.
71
0
      if (Name[1] != 'c')
72
0
        break;
73
0
      return 2;  // "pc"
74
0
    case 'r':  // 11 strings to match.
75
0
      switch (Name[1]) {
76
0
      default: break;
77
0
      case '0':  // 1 string to match.
78
0
        return 7;  // "r0"
79
0
      case '1':  // 1 string to match.
80
0
        return 8;  // "r1"
81
0
      case '2':  // 1 string to match.
82
0
        return 9;  // "r2"
83
0
      case '3':  // 1 string to match.
84
0
        return 10;  // "r3"
85
0
      case '4':  // 1 string to match.
86
0
        return 11;  // "r4"
87
0
      case '5':  // 1 string to match.
88
0
        return 12;  // "r5"
89
0
      case '6':  // 1 string to match.
90
0
        return 13;  // "r6"
91
0
      case '7':  // 1 string to match.
92
0
        return 14;  // "r7"
93
0
      case '8':  // 1 string to match.
94
0
        return 15;  // "r8"
95
0
      case '9':  // 1 string to match.
96
0
        return 16;  // "r9"
97
0
      case 'v':  // 1 string to match.
98
0
        return 4;  // "rv"
99
0
      }
100
0
      break;
101
0
    case 's':  // 2 strings to match.
102
0
      switch (Name[1]) {
103
0
      default: break;
104
0
      case 'p':  // 1 string to match.
105
0
        return 5;  // "sp"
106
0
      case 'w':  // 1 string to match.
107
0
        return 6;  // "sw"
108
0
      }
109
0
      break;
110
0
    }
111
0
    break;
112
0
  case 3:  // 25 strings to match.
113
0
    if (Name[0] != 'r')
114
0
      break;
115
0
    switch (Name[1]) {
116
0
    default: break;
117
0
    case '1':  // 10 strings to match.
118
0
      switch (Name[2]) {
119
0
      default: break;
120
0
      case '0':  // 1 string to match.
121
0
        return 17;  // "r10"
122
0
      case '1':  // 1 string to match.
123
0
        return 18;  // "r11"
124
0
      case '2':  // 1 string to match.
125
0
        return 19;  // "r12"
126
0
      case '3':  // 1 string to match.
127
0
        return 20;  // "r13"
128
0
      case '4':  // 1 string to match.
129
0
        return 21;  // "r14"
130
0
      case '5':  // 1 string to match.
131
0
        return 22;  // "r15"
132
0
      case '6':  // 1 string to match.
133
0
        return 23;  // "r16"
134
0
      case '7':  // 1 string to match.
135
0
        return 24;  // "r17"
136
0
      case '8':  // 1 string to match.
137
0
        return 25;  // "r18"
138
0
      case '9':  // 1 string to match.
139
0
        return 26;  // "r19"
140
0
      }
141
0
      break;
142
0
    case '2':  // 10 strings to match.
143
0
      switch (Name[2]) {
144
0
      default: break;
145
0
      case '0':  // 1 string to match.
146
0
        return 27;  // "r20"
147
0
      case '1':  // 1 string to match.
148
0
        return 28;  // "r21"
149
0
      case '2':  // 1 string to match.
150
0
        return 29;  // "r22"
151
0
      case '3':  // 1 string to match.
152
0
        return 30;  // "r23"
153
0
      case '4':  // 1 string to match.
154
0
        return 31;  // "r24"
155
0
      case '5':  // 1 string to match.
156
0
        return 32;  // "r25"
157
0
      case '6':  // 1 string to match.
158
0
        return 33;  // "r26"
159
0
      case '7':  // 1 string to match.
160
0
        return 34;  // "r27"
161
0
      case '8':  // 1 string to match.
162
0
        return 35;  // "r28"
163
0
      case '9':  // 1 string to match.
164
0
        return 36;  // "r29"
165
0
      }
166
0
      break;
167
0
    case '3':  // 2 strings to match.
168
0
      switch (Name[2]) {
169
0
      default: break;
170
0
      case '0':  // 1 string to match.
171
0
        return 37;  // "r30"
172
0
      case '1':  // 1 string to match.
173
0
        return 38;  // "r31"
174
0
      }
175
0
      break;
176
0
    case 'c':  // 1 string to match.
177
0
      if (Name[2] != 'a')
178
0
        break;
179
0
      return 3;  // "rca"
180
0
    case 'r':  // 2 strings to match.
181
0
      switch (Name[2]) {
182
0
      default: break;
183
0
      case '1':  // 1 string to match.
184
0
        return 39;  // "rr1"
185
0
      case '2':  // 1 string to match.
186
0
        return 40;  // "rr2"
187
0
      }
188
0
      break;
189
0
    }
190
0
    break;
191
0
  }
192
0
  return 0;
193
0
}
194
195
#endif // GET_REGISTER_MATCHER
196
197
198
#ifdef GET_SUBTARGET_FEATURE_NAME
199
#undef GET_SUBTARGET_FEATURE_NAME
200
201
// User-level names for subtarget features that participate in
202
// instruction matching.
203
static const char *getSubtargetFeatureName(uint64_t Val) {
204
  return "(unknown)";
205
}
206
207
#endif // GET_SUBTARGET_FEATURE_NAME
208
209
210
#ifdef GET_MATCHER_IMPLEMENTATION
211
#undef GET_MATCHER_IMPLEMENTATION
212
213
static const uint8_t TiedAsmOperandTable[][3] = { /* empty  */ {0, 0, 0} };
214
215
namespace {
216
enum OperatorConversionKind {
217
  CVT_Done,
218
  CVT_Reg,
219
  CVT_Tied,
220
  CVT_95_addImmOperands,
221
  CVT_95_Reg,
222
  CVT_95_addHiImm16Operands,
223
  CVT_95_addLoImm16Operands,
224
  CVT_95_addCondCodeOperands,
225
  CVT_95_addHiImm16AndOperands,
226
  CVT_95_addLoImm16AndOperands,
227
  CVT_95_addBrTargetOperands,
228
  CVT_95_addMemImmOperands,
229
  CVT_95_addMemRegImmOperands,
230
  CVT_95_addMemRegRegOperands,
231
  CVT_95_addMemSplsOperands,
232
  CVT_regR0,
233
  CVT_imm_95_0,
234
  CVT_regR1,
235
  CVT_95_addLoImm21Operands,
236
  CVT_95_addImmShiftOperands,
237
  CVT_NUM_CONVERTERS
238
};
239
240
enum InstructionConversionKind {
241
  Convert__Imm1_0__Imm1_1,
242
  Convert__Reg1_0__Reg1_1,
243
  Convert__Reg1_2__Reg1_0__HiImm161_1,
244
  Convert__Reg1_2__Reg1_0__LoImm161_1,
245
  Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0,
246
  Convert__Reg1_2__Reg1_0__HiImm16And1_1,
247
  Convert__Reg1_2__Reg1_0__LoImm16And1_1,
248
  Convert__Reg1_1__Imm1_0,
249
  Convert__BrTarget1_1__Imm1_0,
250
  Convert__Imm1_2__Imm1_0,
251
  Convert__Reg1_1__Reg1_3__Imm1_0,
252
  Convert__Reg1_0,
253
  Convert__BrTarget1_0,
254
  Convert__Reg1_1__MemImm1_0,
255
  Convert__Reg1_1__MemRegImm3_0,
256
  Convert__Reg1_1__MemRegReg3_0,
257
  Convert_NoOperands,
258
  Convert__Reg1_1__MemSpls3_0,
259
  Convert__Reg1_1__Reg1_0,
260
  Convert__Reg1_1__Reg1_0__regR0__imm_95_0,
261
  Convert__Reg1_1__regR1__HiImm16And1_0,
262
  Convert__Reg1_1__regR0__HiImm161_0,
263
  Convert__Reg1_1__regR1__LoImm16And1_0,
264
  Convert__Reg1_1__regR0__LoImm161_0,
265
  Convert__Reg1_1__LoImm211_0,
266
  Convert__Reg1_3__Reg1_1__Reg1_2__Imm1_0,
267
  Convert__Reg1_2__Reg1_0__ImmShift1_1,
268
  Convert__Reg1_0__MemImm1_1,
269
  Convert__Reg1_0__MemRegImm3_1,
270
  Convert__Reg1_0__MemRegReg3_1,
271
  Convert__Reg1_0__MemSpls3_1,
272
  CVT_NUM_SIGNATURES
273
};
274
275
} // end anonymous namespace
276
277
static const uint8_t ConversionTable[CVT_NUM_SIGNATURES][9] = {
278
  // Convert__Imm1_0__Imm1_1
279
  { CVT_95_addImmOperands, 1, CVT_95_addImmOperands, 2, CVT_Done },
280
  // Convert__Reg1_0__Reg1_1
281
  { CVT_95_Reg, 1, CVT_95_Reg, 2, CVT_Done },
282
  // Convert__Reg1_2__Reg1_0__HiImm161_1
283
  { CVT_95_Reg, 3, CVT_95_Reg, 1, CVT_95_addHiImm16Operands, 2, CVT_Done },
284
  // Convert__Reg1_2__Reg1_0__LoImm161_1
285
  { CVT_95_Reg, 3, CVT_95_Reg, 1, CVT_95_addLoImm16Operands, 2, CVT_Done },
286
  // Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0
287
  { CVT_95_Reg, 4, CVT_95_Reg, 2, CVT_95_Reg, 3, CVT_95_addCondCodeOperands, 1, CVT_Done },
288
  // Convert__Reg1_2__Reg1_0__HiImm16And1_1
289
  { CVT_95_Reg, 3, CVT_95_Reg, 1, CVT_95_addHiImm16AndOperands, 2, CVT_Done },
290
  // Convert__Reg1_2__Reg1_0__LoImm16And1_1
291
  { CVT_95_Reg, 3, CVT_95_Reg, 1, CVT_95_addLoImm16AndOperands, 2, CVT_Done },
292
  // Convert__Reg1_1__Imm1_0
293
  { CVT_95_Reg, 2, CVT_95_addImmOperands, 1, CVT_Done },
294
  // Convert__BrTarget1_1__Imm1_0
295
  { CVT_95_addBrTargetOperands, 2, CVT_95_addImmOperands, 1, CVT_Done },
296
  // Convert__Imm1_2__Imm1_0
297
  { CVT_95_addImmOperands, 3, CVT_95_addImmOperands, 1, CVT_Done },
298
  // Convert__Reg1_1__Reg1_3__Imm1_0
299
  { CVT_95_Reg, 2, CVT_95_Reg, 4, CVT_95_addImmOperands, 1, CVT_Done },
300
  // Convert__Reg1_0
301
  { CVT_95_Reg, 1, CVT_Done },
302
  // Convert__BrTarget1_0
303
  { CVT_95_addBrTargetOperands, 1, CVT_Done },
304
  // Convert__Reg1_1__MemImm1_0
305
  { CVT_95_Reg, 2, CVT_95_addMemImmOperands, 1, CVT_Done },
306
  // Convert__Reg1_1__MemRegImm3_0
307
  { CVT_95_Reg, 2, CVT_95_addMemRegImmOperands, 1, CVT_Done },
308
  // Convert__Reg1_1__MemRegReg3_0
309
  { CVT_95_Reg, 2, CVT_95_addMemRegRegOperands, 1, CVT_Done },
310
  // Convert_NoOperands
311
  { CVT_Done },
312
  // Convert__Reg1_1__MemSpls3_0
313
  { CVT_95_Reg, 2, CVT_95_addMemSplsOperands, 1, CVT_Done },
314
  // Convert__Reg1_1__Reg1_0
315
  { CVT_95_Reg, 2, CVT_95_Reg, 1, CVT_Done },
316
  // Convert__Reg1_1__Reg1_0__regR0__imm_95_0
317
  { CVT_95_Reg, 2, CVT_95_Reg, 1, CVT_regR0, 0, CVT_imm_95_0, 0, CVT_Done },
318
  // Convert__Reg1_1__regR1__HiImm16And1_0
319
  { CVT_95_Reg, 2, CVT_regR1, 0, CVT_95_addHiImm16AndOperands, 1, CVT_Done },
320
  // Convert__Reg1_1__regR0__HiImm161_0
321
  { CVT_95_Reg, 2, CVT_regR0, 0, CVT_95_addHiImm16Operands, 1, CVT_Done },
322
  // Convert__Reg1_1__regR1__LoImm16And1_0
323
  { CVT_95_Reg, 2, CVT_regR1, 0, CVT_95_addLoImm16AndOperands, 1, CVT_Done },
324
  // Convert__Reg1_1__regR0__LoImm161_0
325
  { CVT_95_Reg, 2, CVT_regR0, 0, CVT_95_addLoImm16Operands, 1, CVT_Done },
326
  // Convert__Reg1_1__LoImm211_0
327
  { CVT_95_Reg, 2, CVT_95_addLoImm21Operands, 1, CVT_Done },
328
  // Convert__Reg1_3__Reg1_1__Reg1_2__Imm1_0
329
  { CVT_95_Reg, 4, CVT_95_Reg, 2, CVT_95_Reg, 3, CVT_95_addImmOperands, 1, CVT_Done },
330
  // Convert__Reg1_2__Reg1_0__ImmShift1_1
331
  { CVT_95_Reg, 3, CVT_95_Reg, 1, CVT_95_addImmShiftOperands, 2, CVT_Done },
332
  // Convert__Reg1_0__MemImm1_1
333
  { CVT_95_Reg, 1, CVT_95_addMemImmOperands, 2, CVT_Done },
334
  // Convert__Reg1_0__MemRegImm3_1
335
  { CVT_95_Reg, 1, CVT_95_addMemRegImmOperands, 2, CVT_Done },
336
  // Convert__Reg1_0__MemRegReg3_1
337
  { CVT_95_Reg, 1, CVT_95_addMemRegRegOperands, 2, CVT_Done },
338
  // Convert__Reg1_0__MemSpls3_1
339
  { CVT_95_Reg, 1, CVT_95_addMemSplsOperands, 2, CVT_Done },
340
};
341
342
void LanaiAsmParser::
343
convertToMCInst(unsigned Kind, MCInst &Inst, unsigned Opcode,
344
0
                const OperandVector &Operands) {
345
0
  assert(Kind < CVT_NUM_SIGNATURES && "Invalid signature!");
346
0
  const uint8_t *Converter = ConversionTable[Kind];
347
0
  unsigned OpIdx;
348
0
  Inst.setOpcode(Opcode);
349
0
  for (const uint8_t *p = Converter; *p; p += 2) {
350
0
    OpIdx = *(p + 1);
351
0
    switch (*p) {
352
0
    default: llvm_unreachable("invalid conversion entry!");
353
0
    case CVT_Reg:
354
0
      static_cast<LanaiOperand &>(*Operands[OpIdx]).addRegOperands(Inst, 1);
355
0
      break;
356
0
    case CVT_Tied: {
357
0
      assert(OpIdx < (size_t)(std::end(TiedAsmOperandTable) -
358
0
                              std::begin(TiedAsmOperandTable)) &&
359
0
             "Tied operand not found");
360
0
      unsigned TiedResOpnd = TiedAsmOperandTable[OpIdx][0];
361
0
      if (TiedResOpnd != (uint8_t)-1)
362
0
        Inst.addOperand(Inst.getOperand(TiedResOpnd));
363
0
      break;
364
0
    }
365
0
    case CVT_95_addImmOperands:
366
0
      static_cast<LanaiOperand &>(*Operands[OpIdx]).addImmOperands(Inst, 1);
367
0
      break;
368
0
    case CVT_95_Reg:
369
0
      static_cast<LanaiOperand &>(*Operands[OpIdx]).addRegOperands(Inst, 1);
370
0
      break;
371
0
    case CVT_95_addHiImm16Operands:
372
0
      static_cast<LanaiOperand &>(*Operands[OpIdx]).addHiImm16Operands(Inst, 1);
373
0
      break;
374
0
    case CVT_95_addLoImm16Operands:
375
0
      static_cast<LanaiOperand &>(*Operands[OpIdx]).addLoImm16Operands(Inst, 1);
376
0
      break;
377
0
    case CVT_95_addCondCodeOperands:
378
0
      static_cast<LanaiOperand &>(*Operands[OpIdx]).addCondCodeOperands(Inst, 1);
379
0
      break;
380
0
    case CVT_95_addHiImm16AndOperands:
381
0
      static_cast<LanaiOperand &>(*Operands[OpIdx]).addHiImm16AndOperands(Inst, 1);
382
0
      break;
383
0
    case CVT_95_addLoImm16AndOperands:
384
0
      static_cast<LanaiOperand &>(*Operands[OpIdx]).addLoImm16AndOperands(Inst, 1);
385
0
      break;
386
0
    case CVT_95_addBrTargetOperands:
387
0
      static_cast<LanaiOperand &>(*Operands[OpIdx]).addBrTargetOperands(Inst, 1);
388
0
      break;
389
0
    case CVT_95_addMemImmOperands:
390
0
      static_cast<LanaiOperand &>(*Operands[OpIdx]).addMemImmOperands(Inst, 1);
391
0
      break;
392
0
    case CVT_95_addMemRegImmOperands:
393
0
      static_cast<LanaiOperand &>(*Operands[OpIdx]).addMemRegImmOperands(Inst, 3);
394
0
      break;
395
0
    case CVT_95_addMemRegRegOperands:
396
0
      static_cast<LanaiOperand &>(*Operands[OpIdx]).addMemRegRegOperands(Inst, 3);
397
0
      break;
398
0
    case CVT_95_addMemSplsOperands:
399
0
      static_cast<LanaiOperand &>(*Operands[OpIdx]).addMemSplsOperands(Inst, 3);
400
0
      break;
401
0
    case CVT_regR0:
402
0
      Inst.addOperand(MCOperand::createReg(Lanai::R0));
403
0
      break;
404
0
    case CVT_imm_95_0:
405
0
      Inst.addOperand(MCOperand::createImm(0));
406
0
      break;
407
0
    case CVT_regR1:
408
0
      Inst.addOperand(MCOperand::createReg(Lanai::R1));
409
0
      break;
410
0
    case CVT_95_addLoImm21Operands:
411
0
      static_cast<LanaiOperand &>(*Operands[OpIdx]).addLoImm21Operands(Inst, 1);
412
0
      break;
413
0
    case CVT_95_addImmShiftOperands:
414
0
      static_cast<LanaiOperand &>(*Operands[OpIdx]).addImmShiftOperands(Inst, 1);
415
0
      break;
416
0
    }
417
0
  }
418
0
}
419
420
void LanaiAsmParser::
421
convertToMapAndConstraints(unsigned Kind,
422
0
                           const OperandVector &Operands) {
423
0
  assert(Kind < CVT_NUM_SIGNATURES && "Invalid signature!");
424
0
  unsigned NumMCOperands = 0;
425
0
  const uint8_t *Converter = ConversionTable[Kind];
426
0
  for (const uint8_t *p = Converter; *p; p += 2) {
427
0
    switch (*p) {
428
0
    default: llvm_unreachable("invalid conversion entry!");
429
0
    case CVT_Reg:
430
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
431
0
      Operands[*(p + 1)]->setConstraint("r");
432
0
      ++NumMCOperands;
433
0
      break;
434
0
    case CVT_Tied:
435
0
      ++NumMCOperands;
436
0
      break;
437
0
    case CVT_95_addImmOperands:
438
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
439
0
      Operands[*(p + 1)]->setConstraint("m");
440
0
      NumMCOperands += 1;
441
0
      break;
442
0
    case CVT_95_Reg:
443
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
444
0
      Operands[*(p + 1)]->setConstraint("r");
445
0
      NumMCOperands += 1;
446
0
      break;
447
0
    case CVT_95_addHiImm16Operands:
448
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
449
0
      Operands[*(p + 1)]->setConstraint("m");
450
0
      NumMCOperands += 1;
451
0
      break;
452
0
    case CVT_95_addLoImm16Operands:
453
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
454
0
      Operands[*(p + 1)]->setConstraint("m");
455
0
      NumMCOperands += 1;
456
0
      break;
457
0
    case CVT_95_addCondCodeOperands:
458
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
459
0
      Operands[*(p + 1)]->setConstraint("m");
460
0
      NumMCOperands += 1;
461
0
      break;
462
0
    case CVT_95_addHiImm16AndOperands:
463
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
464
0
      Operands[*(p + 1)]->setConstraint("m");
465
0
      NumMCOperands += 1;
466
0
      break;
467
0
    case CVT_95_addLoImm16AndOperands:
468
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
469
0
      Operands[*(p + 1)]->setConstraint("m");
470
0
      NumMCOperands += 1;
471
0
      break;
472
0
    case CVT_95_addBrTargetOperands:
473
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
474
0
      Operands[*(p + 1)]->setConstraint("m");
475
0
      NumMCOperands += 1;
476
0
      break;
477
0
    case CVT_95_addMemImmOperands:
478
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
479
0
      Operands[*(p + 1)]->setConstraint("m");
480
0
      NumMCOperands += 1;
481
0
      break;
482
0
    case CVT_95_addMemRegImmOperands:
483
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
484
0
      Operands[*(p + 1)]->setConstraint("m");
485
0
      NumMCOperands += 3;
486
0
      break;
487
0
    case CVT_95_addMemRegRegOperands:
488
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
489
0
      Operands[*(p + 1)]->setConstraint("m");
490
0
      NumMCOperands += 3;
491
0
      break;
492
0
    case CVT_95_addMemSplsOperands:
493
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
494
0
      Operands[*(p + 1)]->setConstraint("m");
495
0
      NumMCOperands += 3;
496
0
      break;
497
0
    case CVT_regR0:
498
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
499
0
      Operands[*(p + 1)]->setConstraint("m");
500
0
      ++NumMCOperands;
501
0
      break;
502
0
    case CVT_imm_95_0:
503
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
504
0
      Operands[*(p + 1)]->setConstraint("");
505
0
      ++NumMCOperands;
506
0
      break;
507
0
    case CVT_regR1:
508
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
509
0
      Operands[*(p + 1)]->setConstraint("m");
510
0
      ++NumMCOperands;
511
0
      break;
512
0
    case CVT_95_addLoImm21Operands:
513
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
514
0
      Operands[*(p + 1)]->setConstraint("m");
515
0
      NumMCOperands += 1;
516
0
      break;
517
0
    case CVT_95_addImmShiftOperands:
518
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
519
0
      Operands[*(p + 1)]->setConstraint("m");
520
0
      NumMCOperands += 1;
521
0
      break;
522
0
    }
523
0
  }
524
0
}
525
526
namespace {
527
528
/// MatchClassKind - The kinds of classes which participate in
529
/// instruction matching.
530
enum MatchClassKind {
531
  InvalidMatchClass = 0,
532
  OptionalMatchClass = 1,
533
  MCK__EXCLAIM_, // '!'
534
  MCK__PCT_fp, // '%fp'
535
  MCK__PCT_pc, // '%pc'
536
  MCK__MINUS_4, // '-4'
537
  MCK__DOT_r, // '.r'
538
  MCK__91_, // '['
539
  MCK__93_, // ']'
540
  MCK_add, // 'add'
541
  MCK_return, // 'return'
542
  MCK_LAST_TOKEN = MCK_return,
543
  MCK_CCR, // register class 'CCR'
544
  MCK_Reg1, // derived register class
545
  MCK_GPR, // register class 'GPR'
546
  MCK_LAST_REGISTER = MCK_GPR,
547
  MCK_BrTarget, // user defined class 'BrTargetAsmOperand'
548
  MCK_CallTarget, // user defined class 'CallTargetAsmOperand'
549
  MCK_CondCode, // user defined class 'CondCodeOperand'
550
  MCK_HiImm16And, // user defined class 'HiImm16AndAsmOperand'
551
  MCK_HiImm16, // user defined class 'HiImm16AsmOperand'
552
  MCK_Imm10, // user defined class 'Imm10AsmOperand'
553
  MCK_Imm, // user defined class 'ImmAsmOperand'
554
  MCK_ImmShift, // user defined class 'ImmShiftAsmOperand'
555
  MCK_LoImm16And, // user defined class 'LoImm16AndAsmOperand'
556
  MCK_LoImm16, // user defined class 'LoImm16AsmOperand'
557
  MCK_LoImm21, // user defined class 'LoImm21AsmOperand'
558
  MCK_MemImm, // user defined class 'MemImmAsmOperand'
559
  MCK_MemRegImm, // user defined class 'MemRegImmAsmOperand'
560
  MCK_MemRegReg, // user defined class 'MemRegRegAsmOperand'
561
  MCK_MemSpls, // user defined class 'MemSplsAsmOperand'
562
  NumMatchClassKinds
563
};
564
565
} // end anonymous namespace
566
567
0
static unsigned getDiagKindFromRegisterClass(MatchClassKind RegisterClass) {
568
0
  return MCTargetAsmParser::Match_InvalidOperand;
569
0
}
570
571
0
static MatchClassKind matchTokenString(StringRef Name) {
572
0
  switch (Name.size()) {
573
0
  default: break;
574
0
  case 1:  // 3 strings to match.
575
0
    switch (Name[0]) {
576
0
    default: break;
577
0
    case '!':  // 1 string to match.
578
0
      return MCK__EXCLAIM_;  // "!"
579
0
    case '[':  // 1 string to match.
580
0
      return MCK__91_;  // "["
581
0
    case ']':  // 1 string to match.
582
0
      return MCK__93_;  // "]"
583
0
    }
584
0
    break;
585
0
  case 2:  // 2 strings to match.
586
0
    switch (Name[0]) {
587
0
    default: break;
588
0
    case '-':  // 1 string to match.
589
0
      if (Name[1] != '4')
590
0
        break;
591
0
      return MCK__MINUS_4;  // "-4"
592
0
    case '.':  // 1 string to match.
593
0
      if (Name[1] != 'r')
594
0
        break;
595
0
      return MCK__DOT_r;  // ".r"
596
0
    }
597
0
    break;
598
0
  case 3:  // 3 strings to match.
599
0
    switch (Name[0]) {
600
0
    default: break;
601
0
    case '%':  // 2 strings to match.
602
0
      switch (Name[1]) {
603
0
      default: break;
604
0
      case 'f':  // 1 string to match.
605
0
        if (Name[2] != 'p')
606
0
          break;
607
0
        return MCK__PCT_fp;  // "%fp"
608
0
      case 'p':  // 1 string to match.
609
0
        if (Name[2] != 'c')
610
0
          break;
611
0
        return MCK__PCT_pc;  // "%pc"
612
0
      }
613
0
      break;
614
0
    case 'a':  // 1 string to match.
615
0
      if (memcmp(Name.data()+1, "dd", 2) != 0)
616
0
        break;
617
0
      return MCK_add;  // "add"
618
0
    }
619
0
    break;
620
0
  case 6:  // 1 string to match.
621
0
    if (memcmp(Name.data()+0, "return", 6) != 0)
622
0
      break;
623
0
    return MCK_return;  // "return"
624
0
  }
625
0
  return InvalidMatchClass;
626
0
}
627
628
/// isSubclass - Compute whether \p A is a subclass of \p B.
629
0
static bool isSubclass(MatchClassKind A, MatchClassKind B) {
630
0
  if (A == B)
631
0
    return true;
632
633
0
  switch (A) {
634
0
  default:
635
0
    return false;
636
637
0
  case MCK_Reg1:
638
0
    return B == MCK_GPR;
639
0
  }
640
0
}
641
642
0
static unsigned validateOperandClass(MCParsedAsmOperand &GOp, MatchClassKind Kind) {
643
0
  LanaiOperand &Operand = (LanaiOperand &)GOp;
644
0
  if (Kind == InvalidMatchClass)
645
0
    return MCTargetAsmParser::Match_InvalidOperand;
646
647
0
  if (Operand.isToken() && Kind <= MCK_LAST_TOKEN)
648
0
    return isSubclass(matchTokenString(Operand.getToken()), Kind) ?
649
0
             MCTargetAsmParser::Match_Success :
650
0
             MCTargetAsmParser::Match_InvalidOperand;
651
652
0
  switch (Kind) {
653
0
  default: break;
654
  // 'BrTarget' class
655
0
  case MCK_BrTarget: {
656
0
    DiagnosticPredicate DP(Operand.isBrTarget());
657
0
    if (DP.isMatch())
658
0
      return MCTargetAsmParser::Match_Success;
659
0
    break;
660
0
    }
661
  // 'CallTarget' class
662
0
  case MCK_CallTarget: {
663
0
    DiagnosticPredicate DP(Operand.isCallTarget());
664
0
    if (DP.isMatch())
665
0
      return MCTargetAsmParser::Match_Success;
666
0
    break;
667
0
    }
668
  // 'CondCode' class
669
0
  case MCK_CondCode: {
670
0
    DiagnosticPredicate DP(Operand.isCondCode());
671
0
    if (DP.isMatch())
672
0
      return MCTargetAsmParser::Match_Success;
673
0
    break;
674
0
    }
675
  // 'HiImm16And' class
676
0
  case MCK_HiImm16And: {
677
0
    DiagnosticPredicate DP(Operand.isHiImm16And());
678
0
    if (DP.isMatch())
679
0
      return MCTargetAsmParser::Match_Success;
680
0
    break;
681
0
    }
682
  // 'HiImm16' class
683
0
  case MCK_HiImm16: {
684
0
    DiagnosticPredicate DP(Operand.isHiImm16());
685
0
    if (DP.isMatch())
686
0
      return MCTargetAsmParser::Match_Success;
687
0
    break;
688
0
    }
689
  // 'Imm10' class
690
0
  case MCK_Imm10: {
691
0
    DiagnosticPredicate DP(Operand.isImm10());
692
0
    if (DP.isMatch())
693
0
      return MCTargetAsmParser::Match_Success;
694
0
    break;
695
0
    }
696
  // 'Imm' class
697
0
  case MCK_Imm: {
698
0
    DiagnosticPredicate DP(Operand.isImm());
699
0
    if (DP.isMatch())
700
0
      return MCTargetAsmParser::Match_Success;
701
0
    break;
702
0
    }
703
  // 'ImmShift' class
704
0
  case MCK_ImmShift: {
705
0
    DiagnosticPredicate DP(Operand.isImmShift());
706
0
    if (DP.isMatch())
707
0
      return MCTargetAsmParser::Match_Success;
708
0
    break;
709
0
    }
710
  // 'LoImm16And' class
711
0
  case MCK_LoImm16And: {
712
0
    DiagnosticPredicate DP(Operand.isLoImm16And());
713
0
    if (DP.isMatch())
714
0
      return MCTargetAsmParser::Match_Success;
715
0
    break;
716
0
    }
717
  // 'LoImm16' class
718
0
  case MCK_LoImm16: {
719
0
    DiagnosticPredicate DP(Operand.isLoImm16());
720
0
    if (DP.isMatch())
721
0
      return MCTargetAsmParser::Match_Success;
722
0
    break;
723
0
    }
724
  // 'LoImm21' class
725
0
  case MCK_LoImm21: {
726
0
    DiagnosticPredicate DP(Operand.isLoImm21());
727
0
    if (DP.isMatch())
728
0
      return MCTargetAsmParser::Match_Success;
729
0
    break;
730
0
    }
731
  // 'MemImm' class
732
0
  case MCK_MemImm: {
733
0
    DiagnosticPredicate DP(Operand.isMemImm());
734
0
    if (DP.isMatch())
735
0
      return MCTargetAsmParser::Match_Success;
736
0
    break;
737
0
    }
738
  // 'MemRegImm' class
739
0
  case MCK_MemRegImm: {
740
0
    DiagnosticPredicate DP(Operand.isMemRegImm());
741
0
    if (DP.isMatch())
742
0
      return MCTargetAsmParser::Match_Success;
743
0
    break;
744
0
    }
745
  // 'MemRegReg' class
746
0
  case MCK_MemRegReg: {
747
0
    DiagnosticPredicate DP(Operand.isMemRegReg());
748
0
    if (DP.isMatch())
749
0
      return MCTargetAsmParser::Match_Success;
750
0
    break;
751
0
    }
752
  // 'MemSpls' class
753
0
  case MCK_MemSpls: {
754
0
    DiagnosticPredicate DP(Operand.isMemSpls());
755
0
    if (DP.isMatch())
756
0
      return MCTargetAsmParser::Match_Success;
757
0
    break;
758
0
    }
759
0
  } // end switch (Kind)
760
761
0
  if (Operand.isReg()) {
762
0
    MatchClassKind OpKind;
763
0
    switch (Operand.getReg()) {
764
0
    default: OpKind = InvalidMatchClass; break;
765
0
    case Lanai::R0: OpKind = MCK_GPR; break;
766
0
    case Lanai::R1: OpKind = MCK_GPR; break;
767
0
    case Lanai::R2: OpKind = MCK_GPR; break;
768
0
    case Lanai::R3: OpKind = MCK_GPR; break;
769
0
    case Lanai::R4: OpKind = MCK_GPR; break;
770
0
    case Lanai::R5: OpKind = MCK_GPR; break;
771
0
    case Lanai::R6: OpKind = MCK_GPR; break;
772
0
    case Lanai::R7: OpKind = MCK_GPR; break;
773
0
    case Lanai::R8: OpKind = MCK_GPR; break;
774
0
    case Lanai::R9: OpKind = MCK_GPR; break;
775
0
    case Lanai::R10: OpKind = MCK_GPR; break;
776
0
    case Lanai::R11: OpKind = MCK_GPR; break;
777
0
    case Lanai::R12: OpKind = MCK_GPR; break;
778
0
    case Lanai::R13: OpKind = MCK_GPR; break;
779
0
    case Lanai::R14: OpKind = MCK_GPR; break;
780
0
    case Lanai::R15: OpKind = MCK_GPR; break;
781
0
    case Lanai::R16: OpKind = MCK_GPR; break;
782
0
    case Lanai::R17: OpKind = MCK_GPR; break;
783
0
    case Lanai::R18: OpKind = MCK_GPR; break;
784
0
    case Lanai::R19: OpKind = MCK_GPR; break;
785
0
    case Lanai::R20: OpKind = MCK_GPR; break;
786
0
    case Lanai::R21: OpKind = MCK_GPR; break;
787
0
    case Lanai::R22: OpKind = MCK_GPR; break;
788
0
    case Lanai::R23: OpKind = MCK_GPR; break;
789
0
    case Lanai::R24: OpKind = MCK_GPR; break;
790
0
    case Lanai::R25: OpKind = MCK_GPR; break;
791
0
    case Lanai::R26: OpKind = MCK_GPR; break;
792
0
    case Lanai::R27: OpKind = MCK_GPR; break;
793
0
    case Lanai::R28: OpKind = MCK_GPR; break;
794
0
    case Lanai::R29: OpKind = MCK_GPR; break;
795
0
    case Lanai::R30: OpKind = MCK_GPR; break;
796
0
    case Lanai::R31: OpKind = MCK_GPR; break;
797
0
    case Lanai::PC: OpKind = MCK_Reg1; break;
798
0
    case Lanai::SP: OpKind = MCK_Reg1; break;
799
0
    case Lanai::FP: OpKind = MCK_Reg1; break;
800
0
    case Lanai::RV: OpKind = MCK_Reg1; break;
801
0
    case Lanai::RR1: OpKind = MCK_Reg1; break;
802
0
    case Lanai::RR2: OpKind = MCK_Reg1; break;
803
0
    case Lanai::RCA: OpKind = MCK_Reg1; break;
804
0
    case Lanai::SR: OpKind = MCK_CCR; break;
805
0
    }
806
0
    return isSubclass(OpKind, Kind) ? (unsigned)MCTargetAsmParser::Match_Success :
807
0
                                      getDiagKindFromRegisterClass(Kind);
808
0
  }
809
810
0
  if (Kind > MCK_LAST_TOKEN && Kind <= MCK_LAST_REGISTER)
811
0
    return getDiagKindFromRegisterClass(Kind);
812
813
0
  return MCTargetAsmParser::Match_InvalidOperand;
814
0
}
815
816
#ifndef NDEBUG
817
0
const char *getMatchClassName(MatchClassKind Kind) {
818
0
  switch (Kind) {
819
0
  case InvalidMatchClass: return "InvalidMatchClass";
820
0
  case OptionalMatchClass: return "OptionalMatchClass";
821
0
  case MCK__EXCLAIM_: return "MCK__EXCLAIM_";
822
0
  case MCK__PCT_fp: return "MCK__PCT_fp";
823
0
  case MCK__PCT_pc: return "MCK__PCT_pc";
824
0
  case MCK__MINUS_4: return "MCK__MINUS_4";
825
0
  case MCK__DOT_r: return "MCK__DOT_r";
826
0
  case MCK__91_: return "MCK__91_";
827
0
  case MCK__93_: return "MCK__93_";
828
0
  case MCK_add: return "MCK_add";
829
0
  case MCK_return: return "MCK_return";
830
0
  case MCK_CCR: return "MCK_CCR";
831
0
  case MCK_Reg1: return "MCK_Reg1";
832
0
  case MCK_GPR: return "MCK_GPR";
833
0
  case MCK_BrTarget: return "MCK_BrTarget";
834
0
  case MCK_CallTarget: return "MCK_CallTarget";
835
0
  case MCK_CondCode: return "MCK_CondCode";
836
0
  case MCK_HiImm16And: return "MCK_HiImm16And";
837
0
  case MCK_HiImm16: return "MCK_HiImm16";
838
0
  case MCK_Imm10: return "MCK_Imm10";
839
0
  case MCK_Imm: return "MCK_Imm";
840
0
  case MCK_ImmShift: return "MCK_ImmShift";
841
0
  case MCK_LoImm16And: return "MCK_LoImm16And";
842
0
  case MCK_LoImm16: return "MCK_LoImm16";
843
0
  case MCK_LoImm21: return "MCK_LoImm21";
844
0
  case MCK_MemImm: return "MCK_MemImm";
845
0
  case MCK_MemRegImm: return "MCK_MemRegImm";
846
0
  case MCK_MemRegReg: return "MCK_MemRegReg";
847
0
  case MCK_MemSpls: return "MCK_MemSpls";
848
0
  case NumMatchClassKinds: return "NumMatchClassKinds";
849
0
  }
850
0
  llvm_unreachable("unhandled MatchClassKind!");
851
0
}
852
853
#endif // NDEBUG
854
FeatureBitset LanaiAsmParser::
855
0
ComputeAvailableFeatures(const FeatureBitset &FB) const {
856
0
  FeatureBitset Features;
857
0
  return Features;
858
0
}
859
860
static bool checkAsmTiedOperandConstraints(const LanaiAsmParser&AsmParser,
861
                               unsigned Kind,
862
                               const OperandVector &Operands,
863
0
                               uint64_t &ErrorInfo) {
864
0
  assert(Kind < CVT_NUM_SIGNATURES && "Invalid signature!");
865
0
  const uint8_t *Converter = ConversionTable[Kind];
866
0
  for (const uint8_t *p = Converter; *p; p += 2) {
867
0
    switch (*p) {
868
0
    case CVT_Tied: {
869
0
      unsigned OpIdx = *(p + 1);
870
0
      assert(OpIdx < (size_t)(std::end(TiedAsmOperandTable) -
871
0
                              std::begin(TiedAsmOperandTable)) &&
872
0
             "Tied operand not found");
873
0
      unsigned OpndNum1 = TiedAsmOperandTable[OpIdx][1];
874
0
      unsigned OpndNum2 = TiedAsmOperandTable[OpIdx][2];
875
0
      if (OpndNum1 != OpndNum2) {
876
0
        auto &SrcOp1 = Operands[OpndNum1];
877
0
        auto &SrcOp2 = Operands[OpndNum2];
878
0
        if (!AsmParser.areEqualRegs(*SrcOp1, *SrcOp2)) {
879
0
          ErrorInfo = OpndNum2;
880
0
          return false;
881
0
        }
882
0
      }
883
0
      break;
884
0
    }
885
0
    default:
886
0
      break;
887
0
    }
888
0
  }
889
0
  return true;
890
0
}
891
892
static const char MnemonicTable[] =
893
    "\021#adjcallstackdown\017#adjcallstackup\014#adjdynalloc\003add\005add."
894
    "f\004addc\006addc.f\003and\005and.f\001b\002bt\002ld\004ld.b\004ld.h\005"
895
    "leadz\005log_0\005log_1\005log_2\005log_3\005log_4\003mov\003nop\002or\004"
896
    "or.f\004popc\001s\004sel.\002sh\004sh.f\003sha\005sha.f\002st\004st.b\004"
897
    "st.h\003sub\005sub.f\004subb\006subb.f\006trailz\003uld\005uld.b\005uld"
898
    ".h\003xor\005xor.f";
899
900
// Feature bitsets.
901
enum : uint8_t {
902
  AMFBS_None,
903
};
904
905
static constexpr FeatureBitset FeatureBitsets[] = {
906
  {}, // AMFBS_None
907
};
908
909
namespace {
910
  struct MatchEntry {
911
    uint8_t Mnemonic;
912
    uint16_t Opcode;
913
    uint8_t ConvertFn;
914
    uint8_t RequiredFeaturesIdx;
915
    uint8_t Classes[7];
916
0
    StringRef getMnemonic() const {
917
0
      return StringRef(MnemonicTable + Mnemonic + 1,
918
0
                       MnemonicTable[Mnemonic]);
919
0
    }
920
  };
921
922
  // Predicate for searching for an opcode.
923
  struct LessOpcode {
924
0
    bool operator()(const MatchEntry &LHS, StringRef RHS) {
925
0
      return LHS.getMnemonic() < RHS;
926
0
    }
927
0
    bool operator()(StringRef LHS, const MatchEntry &RHS) {
928
0
      return LHS < RHS.getMnemonic();
929
0
    }
930
0
    bool operator()(const MatchEntry &LHS, const MatchEntry &RHS) {
931
0
      return LHS.getMnemonic() < RHS.getMnemonic();
932
0
    }
933
  };
934
} // end anonymous namespace
935
936
static const MatchEntry MatchTable0[] = {
937
  { 0 /* #ADJCALLSTACKDOWN */, Lanai::ADJCALLSTACKDOWN, Convert__Imm1_0__Imm1_1, AMFBS_None, { MCK_Imm, MCK_Imm }, },
938
  { 18 /* #ADJCALLSTACKUP */, Lanai::ADJCALLSTACKUP, Convert__Imm1_0__Imm1_1, AMFBS_None, { MCK_Imm, MCK_Imm }, },
939
  { 34 /* #ADJDYNALLOC */, Lanai::ADJDYNALLOC, Convert__Reg1_0__Reg1_1, AMFBS_None, { MCK_GPR, MCK_GPR }, },
940
  { 47 /* add */, Lanai::ADD_I_HI, Convert__Reg1_2__Reg1_0__HiImm161_1, AMFBS_None, { MCK_GPR, MCK_HiImm16, MCK_GPR }, },
941
  { 47 /* add */, Lanai::ADD_I_LO, Convert__Reg1_2__Reg1_0__LoImm161_1, AMFBS_None, { MCK_GPR, MCK_LoImm16, MCK_GPR }, },
942
  { 47 /* add */, Lanai::ADD_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
943
  { 51 /* add.f */, Lanai::ADD_F_I_HI, Convert__Reg1_2__Reg1_0__HiImm161_1, AMFBS_None, { MCK_GPR, MCK_HiImm16, MCK_GPR }, },
944
  { 51 /* add.f */, Lanai::ADD_F_I_LO, Convert__Reg1_2__Reg1_0__LoImm161_1, AMFBS_None, { MCK_GPR, MCK_LoImm16, MCK_GPR }, },
945
  { 51 /* add.f */, Lanai::ADD_F_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
946
  { 57 /* addc */, Lanai::ADDC_I_HI, Convert__Reg1_2__Reg1_0__HiImm161_1, AMFBS_None, { MCK_GPR, MCK_HiImm16, MCK_GPR }, },
947
  { 57 /* addc */, Lanai::ADDC_I_LO, Convert__Reg1_2__Reg1_0__LoImm161_1, AMFBS_None, { MCK_GPR, MCK_LoImm16, MCK_GPR }, },
948
  { 57 /* addc */, Lanai::ADDC_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
949
  { 62 /* addc.f */, Lanai::ADDC_F_I_HI, Convert__Reg1_2__Reg1_0__HiImm161_1, AMFBS_None, { MCK_GPR, MCK_HiImm16, MCK_GPR }, },
950
  { 62 /* addc.f */, Lanai::ADDC_F_I_LO, Convert__Reg1_2__Reg1_0__LoImm161_1, AMFBS_None, { MCK_GPR, MCK_LoImm16, MCK_GPR }, },
951
  { 62 /* addc.f */, Lanai::ADDC_F_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
952
  { 69 /* and */, Lanai::AND_I_HI, Convert__Reg1_2__Reg1_0__HiImm16And1_1, AMFBS_None, { MCK_GPR, MCK_HiImm16And, MCK_GPR }, },
953
  { 69 /* and */, Lanai::AND_I_LO, Convert__Reg1_2__Reg1_0__LoImm16And1_1, AMFBS_None, { MCK_GPR, MCK_LoImm16And, MCK_GPR }, },
954
  { 69 /* and */, Lanai::AND_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
955
  { 73 /* and.f */, Lanai::AND_F_I_HI, Convert__Reg1_2__Reg1_0__HiImm16And1_1, AMFBS_None, { MCK_GPR, MCK_HiImm16And, MCK_GPR }, },
956
  { 73 /* and.f */, Lanai::AND_F_I_LO, Convert__Reg1_2__Reg1_0__LoImm16And1_1, AMFBS_None, { MCK_GPR, MCK_LoImm16And, MCK_GPR }, },
957
  { 73 /* and.f */, Lanai::AND_F_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
958
  { 79 /* b */, Lanai::BRIND_CC, Convert__Reg1_1__Imm1_0, AMFBS_None, { MCK_Imm, MCK_GPR }, },
959
  { 79 /* b */, Lanai::BRCC, Convert__BrTarget1_1__Imm1_0, AMFBS_None, { MCK_Imm, MCK_BrTarget }, },
960
  { 79 /* b */, Lanai::BRR, Convert__Imm1_2__Imm1_0, AMFBS_None, { MCK_Imm, MCK__DOT_r, MCK_Imm }, },
961
  { 79 /* b */, Lanai::BRIND_CCA, Convert__Reg1_1__Reg1_3__Imm1_0, AMFBS_None, { MCK_Imm, MCK_GPR, MCK_add, MCK_GPR }, },
962
  { 81 /* bt */, Lanai::JR, Convert__Reg1_0, AMFBS_None, { MCK_GPR }, },
963
  { 81 /* bt */, Lanai::BT, Convert__BrTarget1_0, AMFBS_None, { MCK_BrTarget }, },
964
  { 84 /* ld */, Lanai::LDADDR, Convert__Reg1_1__MemImm1_0, AMFBS_None, { MCK_MemImm, MCK_GPR }, },
965
  { 84 /* ld */, Lanai::LDW_RI, Convert__Reg1_1__MemRegImm3_0, AMFBS_None, { MCK_MemRegImm, MCK_GPR }, },
966
  { 84 /* ld */, Lanai::LDW_RR, Convert__Reg1_1__MemRegReg3_0, AMFBS_None, { MCK_MemRegReg, MCK_GPR }, },
967
  { 84 /* ld */, Lanai::RET, Convert_NoOperands, AMFBS_None, { MCK__MINUS_4, MCK__91_, MCK__PCT_fp, MCK__93_, MCK__PCT_pc, MCK__EXCLAIM_, MCK_return }, },
968
  { 87 /* ld.b */, Lanai::LDBs_RR, Convert__Reg1_1__MemRegReg3_0, AMFBS_None, { MCK_MemRegReg, MCK_GPR }, },
969
  { 87 /* ld.b */, Lanai::LDBs_RI, Convert__Reg1_1__MemSpls3_0, AMFBS_None, { MCK_MemSpls, MCK_GPR }, },
970
  { 92 /* ld.h */, Lanai::LDHs_RR, Convert__Reg1_1__MemRegReg3_0, AMFBS_None, { MCK_MemRegReg, MCK_GPR }, },
971
  { 92 /* ld.h */, Lanai::LDHs_RI, Convert__Reg1_1__MemSpls3_0, AMFBS_None, { MCK_MemSpls, MCK_GPR }, },
972
  { 97 /* leadz */, Lanai::LEADZ, Convert__Reg1_1__Reg1_0, AMFBS_None, { MCK_GPR, MCK_GPR }, },
973
  { 103 /* log_0 */, Lanai::LOG0, Convert_NoOperands, AMFBS_None, {  }, },
974
  { 109 /* log_1 */, Lanai::LOG1, Convert_NoOperands, AMFBS_None, {  }, },
975
  { 115 /* log_2 */, Lanai::LOG2, Convert_NoOperands, AMFBS_None, {  }, },
976
  { 121 /* log_3 */, Lanai::LOG3, Convert_NoOperands, AMFBS_None, {  }, },
977
  { 127 /* log_4 */, Lanai::LOG4, Convert_NoOperands, AMFBS_None, {  }, },
978
  { 133 /* mov */, Lanai::ADD_R, Convert__Reg1_1__Reg1_0__regR0__imm_95_0, AMFBS_None, { MCK_GPR, MCK_GPR }, },
979
  { 133 /* mov */, Lanai::AND_I_HI, Convert__Reg1_1__regR1__HiImm16And1_0, AMFBS_None, { MCK_HiImm16And, MCK_GPR }, },
980
  { 133 /* mov */, Lanai::ADD_I_HI, Convert__Reg1_1__regR0__HiImm161_0, AMFBS_None, { MCK_HiImm16, MCK_GPR }, },
981
  { 133 /* mov */, Lanai::AND_I_LO, Convert__Reg1_1__regR1__LoImm16And1_0, AMFBS_None, { MCK_LoImm16And, MCK_GPR }, },
982
  { 133 /* mov */, Lanai::ADD_I_LO, Convert__Reg1_1__regR0__LoImm161_0, AMFBS_None, { MCK_LoImm16, MCK_GPR }, },
983
  { 133 /* mov */, Lanai::SLI, Convert__Reg1_1__LoImm211_0, AMFBS_None, { MCK_LoImm21, MCK_GPR }, },
984
  { 137 /* nop */, Lanai::NOP, Convert_NoOperands, AMFBS_None, {  }, },
985
  { 141 /* or */, Lanai::OR_I_HI, Convert__Reg1_2__Reg1_0__HiImm161_1, AMFBS_None, { MCK_GPR, MCK_HiImm16, MCK_GPR }, },
986
  { 141 /* or */, Lanai::OR_I_LO, Convert__Reg1_2__Reg1_0__LoImm161_1, AMFBS_None, { MCK_GPR, MCK_LoImm16, MCK_GPR }, },
987
  { 141 /* or */, Lanai::OR_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
988
  { 144 /* or.f */, Lanai::OR_F_I_HI, Convert__Reg1_2__Reg1_0__HiImm161_1, AMFBS_None, { MCK_GPR, MCK_HiImm16, MCK_GPR }, },
989
  { 144 /* or.f */, Lanai::OR_F_I_LO, Convert__Reg1_2__Reg1_0__LoImm161_1, AMFBS_None, { MCK_GPR, MCK_LoImm16, MCK_GPR }, },
990
  { 144 /* or.f */, Lanai::OR_F_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
991
  { 149 /* popc */, Lanai::POPC, Convert__Reg1_1__Reg1_0, AMFBS_None, { MCK_GPR, MCK_GPR }, },
992
  { 154 /* s */, Lanai::SCC, Convert__Reg1_1__Imm1_0, AMFBS_None, { MCK_Imm, MCK_GPR }, },
993
  { 156 /* sel. */, Lanai::SELECT, Convert__Reg1_3__Reg1_1__Reg1_2__Imm1_0, AMFBS_None, { MCK_Imm, MCK_GPR, MCK_GPR, MCK_GPR }, },
994
  { 161 /* sh */, Lanai::SL_I, Convert__Reg1_2__Reg1_0__ImmShift1_1, AMFBS_None, { MCK_GPR, MCK_ImmShift, MCK_GPR }, },
995
  { 161 /* sh */, Lanai::SHL_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
996
  { 164 /* sh.f */, Lanai::SL_F_I, Convert__Reg1_2__Reg1_0__ImmShift1_1, AMFBS_None, { MCK_GPR, MCK_ImmShift, MCK_GPR }, },
997
  { 164 /* sh.f */, Lanai::SHL_F_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
998
  { 169 /* sha */, Lanai::SA_I, Convert__Reg1_2__Reg1_0__ImmShift1_1, AMFBS_None, { MCK_GPR, MCK_ImmShift, MCK_GPR }, },
999
  { 169 /* sha */, Lanai::SRA_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
1000
  { 173 /* sha.f */, Lanai::SA_F_I, Convert__Reg1_2__Reg1_0__ImmShift1_1, AMFBS_None, { MCK_GPR, MCK_ImmShift, MCK_GPR }, },
1001
  { 173 /* sha.f */, Lanai::SRA_F_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
1002
  { 179 /* st */, Lanai::STADDR, Convert__Reg1_0__MemImm1_1, AMFBS_None, { MCK_GPR, MCK_MemImm }, },
1003
  { 179 /* st */, Lanai::SW_RI, Convert__Reg1_0__MemRegImm3_1, AMFBS_None, { MCK_GPR, MCK_MemRegImm }, },
1004
  { 179 /* st */, Lanai::SW_RR, Convert__Reg1_0__MemRegReg3_1, AMFBS_None, { MCK_GPR, MCK_MemRegReg }, },
1005
  { 182 /* st.b */, Lanai::STB_RR, Convert__Reg1_0__MemRegReg3_1, AMFBS_None, { MCK_GPR, MCK_MemRegReg }, },
1006
  { 182 /* st.b */, Lanai::STB_RI, Convert__Reg1_0__MemSpls3_1, AMFBS_None, { MCK_GPR, MCK_MemSpls }, },
1007
  { 187 /* st.h */, Lanai::STH_RR, Convert__Reg1_0__MemRegReg3_1, AMFBS_None, { MCK_GPR, MCK_MemRegReg }, },
1008
  { 187 /* st.h */, Lanai::STH_RI, Convert__Reg1_0__MemSpls3_1, AMFBS_None, { MCK_GPR, MCK_MemSpls }, },
1009
  { 192 /* sub */, Lanai::SUB_I_HI, Convert__Reg1_2__Reg1_0__HiImm161_1, AMFBS_None, { MCK_GPR, MCK_HiImm16, MCK_GPR }, },
1010
  { 192 /* sub */, Lanai::SUB_I_LO, Convert__Reg1_2__Reg1_0__LoImm161_1, AMFBS_None, { MCK_GPR, MCK_LoImm16, MCK_GPR }, },
1011
  { 192 /* sub */, Lanai::SUB_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
1012
  { 196 /* sub.f */, Lanai::SUB_F_I_HI, Convert__Reg1_2__Reg1_0__HiImm161_1, AMFBS_None, { MCK_GPR, MCK_HiImm16, MCK_GPR }, },
1013
  { 196 /* sub.f */, Lanai::SUB_F_I_LO, Convert__Reg1_2__Reg1_0__LoImm161_1, AMFBS_None, { MCK_GPR, MCK_LoImm16, MCK_GPR }, },
1014
  { 196 /* sub.f */, Lanai::SUB_F_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
1015
  { 202 /* subb */, Lanai::SUBB_I_HI, Convert__Reg1_2__Reg1_0__HiImm161_1, AMFBS_None, { MCK_GPR, MCK_HiImm16, MCK_GPR }, },
1016
  { 202 /* subb */, Lanai::SUBB_I_LO, Convert__Reg1_2__Reg1_0__LoImm161_1, AMFBS_None, { MCK_GPR, MCK_LoImm16, MCK_GPR }, },
1017
  { 202 /* subb */, Lanai::SUBB_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
1018
  { 207 /* subb.f */, Lanai::SUBB_F_I_HI, Convert__Reg1_2__Reg1_0__HiImm161_1, AMFBS_None, { MCK_GPR, MCK_HiImm16, MCK_GPR }, },
1019
  { 207 /* subb.f */, Lanai::SUBB_F_I_LO, Convert__Reg1_2__Reg1_0__LoImm161_1, AMFBS_None, { MCK_GPR, MCK_LoImm16, MCK_GPR }, },
1020
  { 207 /* subb.f */, Lanai::SUBB_F_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
1021
  { 214 /* trailz */, Lanai::TRAILZ, Convert__Reg1_1__Reg1_0, AMFBS_None, { MCK_GPR, MCK_GPR }, },
1022
  { 221 /* uld */, Lanai::LDW_RI, Convert__Reg1_1__MemRegImm3_0, AMFBS_None, { MCK_MemRegImm, MCK_GPR }, },
1023
  { 221 /* uld */, Lanai::LDWz_RR, Convert__Reg1_1__MemRegReg3_0, AMFBS_None, { MCK_MemRegReg, MCK_GPR }, },
1024
  { 225 /* uld.b */, Lanai::LDBz_RR, Convert__Reg1_1__MemRegReg3_0, AMFBS_None, { MCK_MemRegReg, MCK_GPR }, },
1025
  { 225 /* uld.b */, Lanai::LDBz_RI, Convert__Reg1_1__MemSpls3_0, AMFBS_None, { MCK_MemSpls, MCK_GPR }, },
1026
  { 231 /* uld.h */, Lanai::LDHz_RR, Convert__Reg1_1__MemRegReg3_0, AMFBS_None, { MCK_MemRegReg, MCK_GPR }, },
1027
  { 231 /* uld.h */, Lanai::LDHz_RI, Convert__Reg1_1__MemSpls3_0, AMFBS_None, { MCK_MemSpls, MCK_GPR }, },
1028
  { 237 /* xor */, Lanai::XOR_I_HI, Convert__Reg1_2__Reg1_0__HiImm161_1, AMFBS_None, { MCK_GPR, MCK_HiImm16, MCK_GPR }, },
1029
  { 237 /* xor */, Lanai::XOR_I_LO, Convert__Reg1_2__Reg1_0__LoImm161_1, AMFBS_None, { MCK_GPR, MCK_LoImm16, MCK_GPR }, },
1030
  { 237 /* xor */, Lanai::XOR_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
1031
  { 241 /* xor.f */, Lanai::XOR_F_I_HI, Convert__Reg1_2__Reg1_0__HiImm161_1, AMFBS_None, { MCK_GPR, MCK_HiImm16, MCK_GPR }, },
1032
  { 241 /* xor.f */, Lanai::XOR_F_I_LO, Convert__Reg1_2__Reg1_0__LoImm161_1, AMFBS_None, { MCK_GPR, MCK_LoImm16, MCK_GPR }, },
1033
  { 241 /* xor.f */, Lanai::XOR_F_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
1034
};
1035
1036
#include "llvm/Support/Debug.h"
1037
#include "llvm/Support/Format.h"
1038
1039
unsigned LanaiAsmParser::
1040
MatchInstructionImpl(const OperandVector &Operands,
1041
                     MCInst &Inst,
1042
                     uint64_t &ErrorInfo,
1043
                     FeatureBitset &MissingFeatures,
1044
0
                     bool matchingInlineAsm, unsigned VariantID) {
1045
  // Eliminate obvious mismatches.
1046
0
  if (Operands.size() > 8) {
1047
0
    ErrorInfo = 8;
1048
0
    return Match_InvalidOperand;
1049
0
  }
1050
1051
  // Get the current feature set.
1052
0
  const FeatureBitset &AvailableFeatures = getAvailableFeatures();
1053
1054
  // Get the instruction mnemonic, which is the first token.
1055
0
  StringRef Mnemonic = ((LanaiOperand &)*Operands[0]).getToken();
1056
1057
  // Some state to try to produce better error messages.
1058
0
  bool HadMatchOtherThanFeatures = false;
1059
0
  bool HadMatchOtherThanPredicate = false;
1060
0
  unsigned RetCode = Match_InvalidOperand;
1061
0
  MissingFeatures.set();
1062
  // Set ErrorInfo to the operand that mismatches if it is
1063
  // wrong for all instances of the instruction.
1064
0
  ErrorInfo = ~0ULL;
1065
  // Find the appropriate table for this asm variant.
1066
0
  const MatchEntry *Start, *End;
1067
0
  switch (VariantID) {
1068
0
  default: llvm_unreachable("invalid variant!");
1069
0
  case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
1070
0
  }
1071
  // Search the table.
1072
0
  auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
1073
1074
0
  DEBUG_WITH_TYPE("asm-matcher", dbgs() << "AsmMatcher: found " <<
1075
0
  std::distance(MnemonicRange.first, MnemonicRange.second) <<
1076
0
  " encodings with mnemonic '" << Mnemonic << "'\n");
1077
1078
  // Return a more specific error code if no mnemonics match.
1079
0
  if (MnemonicRange.first == MnemonicRange.second)
1080
0
    return Match_MnemonicFail;
1081
1082
0
  for (const MatchEntry *it = MnemonicRange.first, *ie = MnemonicRange.second;
1083
0
       it != ie; ++it) {
1084
0
    const FeatureBitset &RequiredFeatures = FeatureBitsets[it->RequiredFeaturesIdx];
1085
0
    bool HasRequiredFeatures =
1086
0
      (AvailableFeatures & RequiredFeatures) == RequiredFeatures;
1087
0
    DEBUG_WITH_TYPE("asm-matcher", dbgs() << "Trying to match opcode "
1088
0
                                          << MII.getName(it->Opcode) << "\n");
1089
    // equal_range guarantees that instruction mnemonic matches.
1090
0
    assert(Mnemonic == it->getMnemonic());
1091
0
    bool OperandsValid = true;
1092
0
    for (unsigned FormalIdx = 0, ActualIdx = 1; FormalIdx != 7; ++FormalIdx) {
1093
0
      auto Formal = static_cast<MatchClassKind>(it->Classes[FormalIdx]);
1094
0
      DEBUG_WITH_TYPE("asm-matcher",
1095
0
                      dbgs() << "  Matching formal operand class " << getMatchClassName(Formal)
1096
0
                             << " against actual operand at index " << ActualIdx);
1097
0
      if (ActualIdx < Operands.size())
1098
0
        DEBUG_WITH_TYPE("asm-matcher", dbgs() << " (";
1099
0
                        Operands[ActualIdx]->print(dbgs()); dbgs() << "): ");
1100
0
      else
1101
0
        DEBUG_WITH_TYPE("asm-matcher", dbgs() << ": ");
1102
0
      if (ActualIdx >= Operands.size()) {
1103
0
        DEBUG_WITH_TYPE("asm-matcher", dbgs() << "actual operand index out of range\n");
1104
0
        if (Formal == InvalidMatchClass) {
1105
0
          break;
1106
0
        }
1107
0
        if (isSubclass(Formal, OptionalMatchClass)) {
1108
0
          continue;
1109
0
        }
1110
0
        OperandsValid = false;
1111
0
        ErrorInfo = ActualIdx;
1112
0
        break;
1113
0
      }
1114
0
      MCParsedAsmOperand &Actual = *Operands[ActualIdx];
1115
0
      unsigned Diag = validateOperandClass(Actual, Formal);
1116
0
      if (Diag == Match_Success) {
1117
0
        DEBUG_WITH_TYPE("asm-matcher",
1118
0
                        dbgs() << "match success using generic matcher\n");
1119
0
        ++ActualIdx;
1120
0
        continue;
1121
0
      }
1122
      // If the generic handler indicates an invalid operand
1123
      // failure, check for a special case.
1124
0
      if (Diag != Match_Success) {
1125
0
        unsigned TargetDiag = validateTargetOperandClass(Actual, Formal);
1126
0
        if (TargetDiag == Match_Success) {
1127
0
          DEBUG_WITH_TYPE("asm-matcher",
1128
0
                          dbgs() << "match success using target matcher\n");
1129
0
          ++ActualIdx;
1130
0
          continue;
1131
0
        }
1132
        // If the target matcher returned a specific error code use
1133
        // that, else use the one from the generic matcher.
1134
0
        if (TargetDiag != Match_InvalidOperand && HasRequiredFeatures)
1135
0
          Diag = TargetDiag;
1136
0
      }
1137
      // If current formal operand wasn't matched and it is optional
1138
      // then try to match next formal operand
1139
0
      if (Diag == Match_InvalidOperand && isSubclass(Formal, OptionalMatchClass)) {
1140
0
        DEBUG_WITH_TYPE("asm-matcher", dbgs() << "ignoring optional operand\n");
1141
0
        continue;
1142
0
      }
1143
      // If this operand is broken for all of the instances of this
1144
      // mnemonic, keep track of it so we can report loc info.
1145
      // If we already had a match that only failed due to a
1146
      // target predicate, that diagnostic is preferred.
1147
0
      if (!HadMatchOtherThanPredicate &&
1148
0
          (it == MnemonicRange.first || ErrorInfo <= ActualIdx)) {
1149
0
        if (HasRequiredFeatures && (ErrorInfo != ActualIdx || Diag != Match_InvalidOperand))
1150
0
          RetCode = Diag;
1151
0
        ErrorInfo = ActualIdx;
1152
0
      }
1153
      // Otherwise, just reject this instance of the mnemonic.
1154
0
      OperandsValid = false;
1155
0
      break;
1156
0
    }
1157
1158
0
    if (!OperandsValid) {
1159
0
      DEBUG_WITH_TYPE("asm-matcher", dbgs() << "Opcode result: multiple "
1160
0
                                               "operand mismatches, ignoring "
1161
0
                                               "this opcode\n");
1162
0
      continue;
1163
0
    }
1164
0
    if (!HasRequiredFeatures) {
1165
0
      HadMatchOtherThanFeatures = true;
1166
0
      FeatureBitset NewMissingFeatures = RequiredFeatures & ~AvailableFeatures;
1167
0
      DEBUG_WITH_TYPE("asm-matcher", dbgs() << "Missing target features:";
1168
0
                      for (unsigned I = 0, E = NewMissingFeatures.size(); I != E; ++I)
1169
0
                        if (NewMissingFeatures[I])
1170
0
                          dbgs() << ' ' << I;
1171
0
                      dbgs() << "\n");
1172
0
      if (NewMissingFeatures.count() <=
1173
0
          MissingFeatures.count())
1174
0
        MissingFeatures = NewMissingFeatures;
1175
0
      continue;
1176
0
    }
1177
1178
0
    Inst.clear();
1179
1180
0
    Inst.setOpcode(it->Opcode);
1181
    // We have a potential match but have not rendered the operands.
1182
    // Check the target predicate to handle any context sensitive
1183
    // constraints.
1184
    // For example, Ties that are referenced multiple times must be
1185
    // checked here to ensure the input is the same for each match
1186
    // constraints. If we leave it any later the ties will have been
1187
    // canonicalized
1188
0
    unsigned MatchResult;
1189
0
    if ((MatchResult = checkEarlyTargetMatchPredicate(Inst, Operands)) != Match_Success) {
1190
0
      Inst.clear();
1191
0
      DEBUG_WITH_TYPE(
1192
0
          "asm-matcher",
1193
0
          dbgs() << "Early target match predicate failed with diag code "
1194
0
                 << MatchResult << "\n");
1195
0
      RetCode = MatchResult;
1196
0
      HadMatchOtherThanPredicate = true;
1197
0
      continue;
1198
0
    }
1199
1200
0
    if (matchingInlineAsm) {
1201
0
      convertToMapAndConstraints(it->ConvertFn, Operands);
1202
0
      if (!checkAsmTiedOperandConstraints(*this, it->ConvertFn, Operands, ErrorInfo))
1203
0
        return Match_InvalidTiedOperand;
1204
1205
0
      return Match_Success;
1206
0
    }
1207
1208
    // We have selected a definite instruction, convert the parsed
1209
    // operands into the appropriate MCInst.
1210
0
    convertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);
1211
1212
    // We have a potential match. Check the target predicate to
1213
    // handle any context sensitive constraints.
1214
0
    if ((MatchResult = checkTargetMatchPredicate(Inst)) != Match_Success) {
1215
0
      DEBUG_WITH_TYPE("asm-matcher",
1216
0
                      dbgs() << "Target match predicate failed with diag code "
1217
0
                             << MatchResult << "\n");
1218
0
      Inst.clear();
1219
0
      RetCode = MatchResult;
1220
0
      HadMatchOtherThanPredicate = true;
1221
0
      continue;
1222
0
    }
1223
1224
0
    if (!checkAsmTiedOperandConstraints(*this, it->ConvertFn, Operands, ErrorInfo))
1225
0
      return Match_InvalidTiedOperand;
1226
1227
0
    DEBUG_WITH_TYPE(
1228
0
        "asm-matcher",
1229
0
        dbgs() << "Opcode result: complete match, selecting this opcode\n");
1230
0
    return Match_Success;
1231
0
  }
1232
1233
  // Okay, we had no match.  Try to return a useful error code.
1234
0
  if (HadMatchOtherThanPredicate || !HadMatchOtherThanFeatures)
1235
0
    return RetCode;
1236
1237
0
  ErrorInfo = 0;
1238
0
  return Match_MissingFeature;
1239
0
}
1240
1241
namespace {
1242
  struct OperandMatchEntry {
1243
    uint8_t Mnemonic;
1244
    uint8_t OperandMask;
1245
    uint8_t Class;
1246
    uint8_t RequiredFeaturesIdx;
1247
1248
0
    StringRef getMnemonic() const {
1249
0
      return StringRef(MnemonicTable + Mnemonic + 1,
1250
0
                       MnemonicTable[Mnemonic]);
1251
0
    }
1252
  };
1253
1254
  // Predicate for searching for an opcode.
1255
  struct LessOpcodeOperand {
1256
0
    bool operator()(const OperandMatchEntry &LHS, StringRef RHS) {
1257
0
      return LHS.getMnemonic()  < RHS;
1258
0
    }
1259
0
    bool operator()(StringRef LHS, const OperandMatchEntry &RHS) {
1260
0
      return LHS < RHS.getMnemonic();
1261
0
    }
1262
0
    bool operator()(const OperandMatchEntry &LHS, const OperandMatchEntry &RHS) {
1263
0
      return LHS.getMnemonic() < RHS.getMnemonic();
1264
0
    }
1265
  };
1266
} // end anonymous namespace
1267
1268
static const OperandMatchEntry OperandMatchTable[20] = {
1269
  /* Operand List Mnemonic, Mask, Operand Class, Features */
1270
  { 84 /* ld */, 1 /* 0 */, MCK_MemImm, AMFBS_None },
1271
  { 84 /* ld */, 1 /* 0 */, MCK_MemRegImm, AMFBS_None },
1272
  { 84 /* ld */, 1 /* 0 */, MCK_MemRegReg, AMFBS_None },
1273
  { 87 /* ld.b */, 1 /* 0 */, MCK_MemRegReg, AMFBS_None },
1274
  { 87 /* ld.b */, 1 /* 0 */, MCK_MemSpls, AMFBS_None },
1275
  { 92 /* ld.h */, 1 /* 0 */, MCK_MemRegReg, AMFBS_None },
1276
  { 92 /* ld.h */, 1 /* 0 */, MCK_MemSpls, AMFBS_None },
1277
  { 179 /* st */, 2 /* 1 */, MCK_MemImm, AMFBS_None },
1278
  { 179 /* st */, 2 /* 1 */, MCK_MemRegImm, AMFBS_None },
1279
  { 179 /* st */, 2 /* 1 */, MCK_MemRegReg, AMFBS_None },
1280
  { 182 /* st.b */, 2 /* 1 */, MCK_MemRegReg, AMFBS_None },
1281
  { 182 /* st.b */, 2 /* 1 */, MCK_MemSpls, AMFBS_None },
1282
  { 187 /* st.h */, 2 /* 1 */, MCK_MemRegReg, AMFBS_None },
1283
  { 187 /* st.h */, 2 /* 1 */, MCK_MemSpls, AMFBS_None },
1284
  { 221 /* uld */, 1 /* 0 */, MCK_MemRegImm, AMFBS_None },
1285
  { 221 /* uld */, 1 /* 0 */, MCK_MemRegReg, AMFBS_None },
1286
  { 225 /* uld.b */, 1 /* 0 */, MCK_MemRegReg, AMFBS_None },
1287
  { 225 /* uld.b */, 1 /* 0 */, MCK_MemSpls, AMFBS_None },
1288
  { 231 /* uld.h */, 1 /* 0 */, MCK_MemRegReg, AMFBS_None },
1289
  { 231 /* uld.h */, 1 /* 0 */, MCK_MemSpls, AMFBS_None },
1290
};
1291
1292
ParseStatus LanaiAsmParser::
1293
tryCustomParseOperand(OperandVector &Operands,
1294
0
                      unsigned MCK) {
1295
1296
0
  switch(MCK) {
1297
0
  case MCK_MemImm:
1298
0
    return parseMemoryOperand(Operands);
1299
0
  case MCK_MemRegImm:
1300
0
    return parseMemoryOperand(Operands);
1301
0
  case MCK_MemRegReg:
1302
0
    return parseMemoryOperand(Operands);
1303
0
  case MCK_MemSpls:
1304
0
    return parseMemoryOperand(Operands);
1305
0
  default:
1306
0
    return ParseStatus::NoMatch;
1307
0
  }
1308
0
  return ParseStatus::NoMatch;
1309
0
}
1310
1311
ParseStatus LanaiAsmParser::
1312
MatchOperandParserImpl(OperandVector &Operands,
1313
                       StringRef Mnemonic,
1314
0
                       bool ParseForAllFeatures) {
1315
  // Get the current feature set.
1316
0
  const FeatureBitset &AvailableFeatures = getAvailableFeatures();
1317
1318
  // Get the next operand index.
1319
0
  unsigned NextOpNum = Operands.size() - 1;
1320
  // Search the table.
1321
0
  auto MnemonicRange =
1322
0
    std::equal_range(std::begin(OperandMatchTable), std::end(OperandMatchTable),
1323
0
                     Mnemonic, LessOpcodeOperand());
1324
1325
0
  if (MnemonicRange.first == MnemonicRange.second)
1326
0
    return ParseStatus::NoMatch;
1327
1328
0
  for (const OperandMatchEntry *it = MnemonicRange.first,
1329
0
       *ie = MnemonicRange.second; it != ie; ++it) {
1330
    // equal_range guarantees that instruction mnemonic matches.
1331
0
    assert(Mnemonic == it->getMnemonic());
1332
1333
    // check if the available features match
1334
0
    const FeatureBitset &RequiredFeatures = FeatureBitsets[it->RequiredFeaturesIdx];
1335
0
    if (!ParseForAllFeatures && (AvailableFeatures & RequiredFeatures) != RequiredFeatures)
1336
0
      continue;
1337
1338
    // check if the operand in question has a custom parser.
1339
0
    if (!(it->OperandMask & (1 << NextOpNum)))
1340
0
      continue;
1341
1342
    // call custom parse method to handle the operand
1343
0
    ParseStatus Result = tryCustomParseOperand(Operands, it->Class);
1344
0
    if (!Result.isNoMatch())
1345
0
      return Result;
1346
0
  }
1347
1348
  // Okay, we had no match.
1349
0
  return ParseStatus::NoMatch;
1350
0
}
1351
1352
#endif // GET_MATCHER_IMPLEMENTATION
1353
1354
1355
#ifdef GET_MNEMONIC_SPELL_CHECKER
1356
#undef GET_MNEMONIC_SPELL_CHECKER
1357
1358
static std::string LanaiMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID) {
1359
  const unsigned MaxEditDist = 2;
1360
  std::vector<StringRef> Candidates;
1361
  StringRef Prev = "";
1362
1363
  // Find the appropriate table for this asm variant.
1364
  const MatchEntry *Start, *End;
1365
  switch (VariantID) {
1366
  default: llvm_unreachable("invalid variant!");
1367
  case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
1368
  }
1369
1370
  for (auto I = Start; I < End; I++) {
1371
    // Ignore unsupported instructions.
1372
    const FeatureBitset &RequiredFeatures = FeatureBitsets[I->RequiredFeaturesIdx];
1373
    if ((FBS & RequiredFeatures) != RequiredFeatures)
1374
      continue;
1375
1376
    StringRef T = I->getMnemonic();
1377
    // Avoid recomputing the edit distance for the same string.
1378
    if (T.equals(Prev))
1379
      continue;
1380
1381
    Prev = T;
1382
    unsigned Dist = S.edit_distance(T, false, MaxEditDist);
1383
    if (Dist <= MaxEditDist)
1384
      Candidates.push_back(T);
1385
  }
1386
1387
  if (Candidates.empty())
1388
    return "";
1389
1390
  std::string Res = ", did you mean: ";
1391
  unsigned i = 0;
1392
  for (; i < Candidates.size() - 1; i++)
1393
    Res += Candidates[i].str() + ", ";
1394
  return Res + Candidates[i].str() + "?";
1395
}
1396
1397
#endif // GET_MNEMONIC_SPELL_CHECKER
1398
1399
1400
#ifdef GET_MNEMONIC_CHECKER
1401
#undef GET_MNEMONIC_CHECKER
1402
1403
static bool LanaiCheckMnemonic(StringRef Mnemonic,
1404
                                const FeatureBitset &AvailableFeatures,
1405
                                unsigned VariantID) {
1406
  // Find the appropriate table for this asm variant.
1407
  const MatchEntry *Start, *End;
1408
  switch (VariantID) {
1409
  default: llvm_unreachable("invalid variant!");
1410
  case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
1411
  }
1412
1413
  // Search the table.
1414
  auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
1415
1416
  if (MnemonicRange.first == MnemonicRange.second)
1417
    return false;
1418
1419
  for (const MatchEntry *it = MnemonicRange.first, *ie = MnemonicRange.second;
1420
       it != ie; ++it) {
1421
    const FeatureBitset &RequiredFeatures =
1422
      FeatureBitsets[it->RequiredFeaturesIdx];
1423
    if ((AvailableFeatures & RequiredFeatures) == RequiredFeatures)
1424
      return true;
1425
  }
1426
  return false;
1427
}
1428
1429
#endif // GET_MNEMONIC_CHECKER
1430