Coverage Report

Created: 2024-01-17 10:31

/src/build/lib/Target/AVR/AVRGenAsmMatcher.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: AVR.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
  Feature_HasSRAMBit = 14,
59
  Feature_HasJMPCALLBit = 7,
60
  Feature_HasIJMPCALLBit = 6,
61
  Feature_HasEIJMPCALLBit = 3,
62
  Feature_HasADDSUBIWBit = 0,
63
  Feature_HasSmallStackBit = 15,
64
  Feature_HasMOVWBit = 10,
65
  Feature_HasLPMBit = 8,
66
  Feature_HasLPMXBit = 9,
67
  Feature_HasELPMBit = 4,
68
  Feature_HasELPMXBit = 5,
69
  Feature_HasSPMBit = 12,
70
  Feature_HasSPMXBit = 13,
71
  Feature_HasDESBit = 2,
72
  Feature_SupportsRMWBit = 18,
73
  Feature_SupportsMultiplicationBit = 17,
74
  Feature_HasBREAKBit = 1,
75
  Feature_HasTinyEncodingBit = 16,
76
  Feature_HasNonTinyEncodingBit = 11,
77
};
78
79
0
static unsigned MatchRegisterName(StringRef Name) {
80
0
  switch (Name.size()) {
81
0
  default: break;
82
0
  case 2:  // 11 strings to match.
83
0
    switch (Name[0]) {
84
0
    default: break;
85
0
    case 'S':  // 1 string to match.
86
0
      if (Name[1] != 'P')
87
0
        break;
88
0
      return 1;  // "SP"
89
0
    case 'r':  // 10 strings to match.
90
0
      switch (Name[1]) {
91
0
      default: break;
92
0
      case '0':  // 1 string to match.
93
0
        return 5;  // "r0"
94
0
      case '1':  // 1 string to match.
95
0
        return 6;  // "r1"
96
0
      case '2':  // 1 string to match.
97
0
        return 7;  // "r2"
98
0
      case '3':  // 1 string to match.
99
0
        return 8;  // "r3"
100
0
      case '4':  // 1 string to match.
101
0
        return 9;  // "r4"
102
0
      case '5':  // 1 string to match.
103
0
        return 10;  // "r5"
104
0
      case '6':  // 1 string to match.
105
0
        return 11;  // "r6"
106
0
      case '7':  // 1 string to match.
107
0
        return 12;  // "r7"
108
0
      case '8':  // 1 string to match.
109
0
        return 13;  // "r8"
110
0
      case '9':  // 1 string to match.
111
0
        return 14;  // "r9"
112
0
      }
113
0
      break;
114
0
    }
115
0
    break;
116
0
  case 3:  // 24 strings to match.
117
0
    switch (Name[0]) {
118
0
    default: break;
119
0
    case 'S':  // 2 strings to match.
120
0
      if (Name[1] != 'P')
121
0
        break;
122
0
      switch (Name[2]) {
123
0
      default: break;
124
0
      case 'H':  // 1 string to match.
125
0
        return 2;  // "SPH"
126
0
      case 'L':  // 1 string to match.
127
0
        return 3;  // "SPL"
128
0
      }
129
0
      break;
130
0
    case 'r':  // 22 strings to match.
131
0
      switch (Name[1]) {
132
0
      default: break;
133
0
      case '1':  // 10 strings to match.
134
0
        switch (Name[2]) {
135
0
        default: break;
136
0
        case '0':  // 1 string to match.
137
0
          return 15;  // "r10"
138
0
        case '1':  // 1 string to match.
139
0
          return 16;  // "r11"
140
0
        case '2':  // 1 string to match.
141
0
          return 17;  // "r12"
142
0
        case '3':  // 1 string to match.
143
0
          return 18;  // "r13"
144
0
        case '4':  // 1 string to match.
145
0
          return 19;  // "r14"
146
0
        case '5':  // 1 string to match.
147
0
          return 20;  // "r15"
148
0
        case '6':  // 1 string to match.
149
0
          return 21;  // "r16"
150
0
        case '7':  // 1 string to match.
151
0
          return 22;  // "r17"
152
0
        case '8':  // 1 string to match.
153
0
          return 23;  // "r18"
154
0
        case '9':  // 1 string to match.
155
0
          return 24;  // "r19"
156
0
        }
157
0
        break;
158
0
      case '2':  // 10 strings to match.
159
0
        switch (Name[2]) {
160
0
        default: break;
161
0
        case '0':  // 1 string to match.
162
0
          return 25;  // "r20"
163
0
        case '1':  // 1 string to match.
164
0
          return 26;  // "r21"
165
0
        case '2':  // 1 string to match.
166
0
          return 27;  // "r22"
167
0
        case '3':  // 1 string to match.
168
0
          return 28;  // "r23"
169
0
        case '4':  // 1 string to match.
170
0
          return 29;  // "r24"
171
0
        case '5':  // 1 string to match.
172
0
          return 30;  // "r25"
173
0
        case '6':  // 1 string to match.
174
0
          return 31;  // "r26"
175
0
        case '7':  // 1 string to match.
176
0
          return 32;  // "r27"
177
0
        case '8':  // 1 string to match.
178
0
          return 33;  // "r28"
179
0
        case '9':  // 1 string to match.
180
0
          return 34;  // "r29"
181
0
        }
182
0
        break;
183
0
      case '3':  // 2 strings to match.
184
0
        switch (Name[2]) {
185
0
        default: break;
186
0
        case '0':  // 1 string to match.
187
0
          return 35;  // "r30"
188
0
        case '1':  // 1 string to match.
189
0
          return 36;  // "r31"
190
0
        }
191
0
        break;
192
0
      }
193
0
      break;
194
0
    }
195
0
    break;
196
0
  case 5:  // 6 strings to match.
197
0
    switch (Name[0]) {
198
0
    default: break;
199
0
    case 'F':  // 1 string to match.
200
0
      if (memcmp(Name.data()+1, "LAGS", 4) != 0)
201
0
        break;
202
0
      return 4;  // "FLAGS"
203
0
    case 'r':  // 5 strings to match.
204
0
      switch (Name[1]) {
205
0
      default: break;
206
0
      case '1':  // 1 string to match.
207
0
        if (memcmp(Name.data()+2, ":r0", 3) != 0)
208
0
          break;
209
0
        return 37;  // "r1:r0"
210
0
      case '3':  // 1 string to match.
211
0
        if (memcmp(Name.data()+2, ":r2", 3) != 0)
212
0
          break;
213
0
        return 38;  // "r3:r2"
214
0
      case '5':  // 1 string to match.
215
0
        if (memcmp(Name.data()+2, ":r4", 3) != 0)
216
0
          break;
217
0
        return 39;  // "r5:r4"
218
0
      case '7':  // 1 string to match.
219
0
        if (memcmp(Name.data()+2, ":r6", 3) != 0)
220
0
          break;
221
0
        return 40;  // "r7:r6"
222
0
      case '9':  // 1 string to match.
223
0
        if (memcmp(Name.data()+2, ":r8", 3) != 0)
224
0
          break;
225
0
        return 41;  // "r9:r8"
226
0
      }
227
0
      break;
228
0
    }
229
0
    break;
230
0
  case 6:  // 1 string to match.
231
0
    if (memcmp(Name.data()+0, "r10:r9", 6) != 0)
232
0
      break;
233
0
    return 42;  // "r10:r9"
234
0
  case 7:  // 19 strings to match.
235
0
    if (Name[0] != 'r')
236
0
      break;
237
0
    switch (Name[1]) {
238
0
    default: break;
239
0
    case '1':  // 9 strings to match.
240
0
      switch (Name[2]) {
241
0
      default: break;
242
0
      case '1':  // 1 string to match.
243
0
        if (memcmp(Name.data()+3, ":r10", 4) != 0)
244
0
          break;
245
0
        return 43;  // "r11:r10"
246
0
      case '2':  // 1 string to match.
247
0
        if (memcmp(Name.data()+3, ":r11", 4) != 0)
248
0
          break;
249
0
        return 44;  // "r12:r11"
250
0
      case '3':  // 1 string to match.
251
0
        if (memcmp(Name.data()+3, ":r12", 4) != 0)
252
0
          break;
253
0
        return 45;  // "r13:r12"
254
0
      case '4':  // 1 string to match.
255
0
        if (memcmp(Name.data()+3, ":r13", 4) != 0)
256
0
          break;
257
0
        return 46;  // "r14:r13"
258
0
      case '5':  // 1 string to match.
259
0
        if (memcmp(Name.data()+3, ":r14", 4) != 0)
260
0
          break;
261
0
        return 47;  // "r15:r14"
262
0
      case '6':  // 1 string to match.
263
0
        if (memcmp(Name.data()+3, ":r15", 4) != 0)
264
0
          break;
265
0
        return 48;  // "r16:r15"
266
0
      case '7':  // 1 string to match.
267
0
        if (memcmp(Name.data()+3, ":r16", 4) != 0)
268
0
          break;
269
0
        return 49;  // "r17:r16"
270
0
      case '8':  // 1 string to match.
271
0
        if (memcmp(Name.data()+3, ":r17", 4) != 0)
272
0
          break;
273
0
        return 50;  // "r18:r17"
274
0
      case '9':  // 1 string to match.
275
0
        if (memcmp(Name.data()+3, ":r18", 4) != 0)
276
0
          break;
277
0
        return 51;  // "r19:r18"
278
0
      }
279
0
      break;
280
0
    case '2':  // 9 strings to match.
281
0
      switch (Name[2]) {
282
0
      default: break;
283
0
      case '0':  // 1 string to match.
284
0
        if (memcmp(Name.data()+3, ":r19", 4) != 0)
285
0
          break;
286
0
        return 52;  // "r20:r19"
287
0
      case '1':  // 1 string to match.
288
0
        if (memcmp(Name.data()+3, ":r20", 4) != 0)
289
0
          break;
290
0
        return 53;  // "r21:r20"
291
0
      case '2':  // 1 string to match.
292
0
        if (memcmp(Name.data()+3, ":r21", 4) != 0)
293
0
          break;
294
0
        return 54;  // "r22:r21"
295
0
      case '3':  // 1 string to match.
296
0
        if (memcmp(Name.data()+3, ":r22", 4) != 0)
297
0
          break;
298
0
        return 55;  // "r23:r22"
299
0
      case '4':  // 1 string to match.
300
0
        if (memcmp(Name.data()+3, ":r23", 4) != 0)
301
0
          break;
302
0
        return 56;  // "r24:r23"
303
0
      case '5':  // 1 string to match.
304
0
        if (memcmp(Name.data()+3, ":r24", 4) != 0)
305
0
          break;
306
0
        return 57;  // "r25:r24"
307
0
      case '6':  // 1 string to match.
308
0
        if (memcmp(Name.data()+3, ":r25", 4) != 0)
309
0
          break;
310
0
        return 58;  // "r26:r25"
311
0
      case '7':  // 1 string to match.
312
0
        if (memcmp(Name.data()+3, ":r26", 4) != 0)
313
0
          break;
314
0
        return 59;  // "r27:r26"
315
0
      case '9':  // 1 string to match.
316
0
        if (memcmp(Name.data()+3, ":r28", 4) != 0)
317
0
          break;
318
0
        return 60;  // "r29:r28"
319
0
      }
320
0
      break;
321
0
    case '3':  // 1 string to match.
322
0
      if (memcmp(Name.data()+2, "1:r30", 5) != 0)
323
0
        break;
324
0
      return 61;  // "r31:r30"
325
0
    }
326
0
    break;
327
0
  }
328
0
  return 0;
329
0
}
330
331
0
static unsigned MatchRegisterAltName(StringRef Name) {
332
0
  switch (Name.size()) {
333
0
  default: break;
334
0
  case 1:  // 3 strings to match.
335
0
    switch (Name[0]) {
336
0
    default: break;
337
0
    case 'X':  // 1 string to match.
338
0
      return 59;  // "X"
339
0
    case 'Y':  // 1 string to match.
340
0
      return 60;  // "Y"
341
0
    case 'Z':  // 1 string to match.
342
0
      return 61;  // "Z"
343
0
    }
344
0
    break;
345
0
  case 2:  // 6 strings to match.
346
0
    switch (Name[0]) {
347
0
    default: break;
348
0
    case 'x':  // 2 strings to match.
349
0
      switch (Name[1]) {
350
0
      default: break;
351
0
      case 'h':  // 1 string to match.
352
0
        return 32;  // "xh"
353
0
      case 'l':  // 1 string to match.
354
0
        return 31;  // "xl"
355
0
      }
356
0
      break;
357
0
    case 'y':  // 2 strings to match.
358
0
      switch (Name[1]) {
359
0
      default: break;
360
0
      case 'h':  // 1 string to match.
361
0
        return 34;  // "yh"
362
0
      case 'l':  // 1 string to match.
363
0
        return 33;  // "yl"
364
0
      }
365
0
      break;
366
0
    case 'z':  // 2 strings to match.
367
0
      switch (Name[1]) {
368
0
      default: break;
369
0
      case 'h':  // 1 string to match.
370
0
        return 36;  // "zh"
371
0
      case 'l':  // 1 string to match.
372
0
        return 35;  // "zl"
373
0
      }
374
0
      break;
375
0
    }
376
0
    break;
377
0
  }
378
0
  return 0;
379
0
}
380
381
#endif // GET_REGISTER_MATCHER
382
383
384
#ifdef GET_SUBTARGET_FEATURE_NAME
385
#undef GET_SUBTARGET_FEATURE_NAME
386
387
// User-level names for subtarget features that participate in
388
// instruction matching.
389
static const char *getSubtargetFeatureName(uint64_t Val) {
390
  switch(Val) {
391
  case Feature_HasSRAMBit: return "";
392
  case Feature_HasJMPCALLBit: return "";
393
  case Feature_HasIJMPCALLBit: return "";
394
  case Feature_HasEIJMPCALLBit: return "";
395
  case Feature_HasADDSUBIWBit: return "";
396
  case Feature_HasSmallStackBit: return "";
397
  case Feature_HasMOVWBit: return "";
398
  case Feature_HasLPMBit: return "";
399
  case Feature_HasLPMXBit: return "";
400
  case Feature_HasELPMBit: return "";
401
  case Feature_HasELPMXBit: return "";
402
  case Feature_HasSPMBit: return "";
403
  case Feature_HasSPMXBit: return "";
404
  case Feature_HasDESBit: return "";
405
  case Feature_SupportsRMWBit: return "";
406
  case Feature_SupportsMultiplicationBit: return "";
407
  case Feature_HasBREAKBit: return "";
408
  case Feature_HasTinyEncodingBit: return "";
409
  case Feature_HasNonTinyEncodingBit: return "";
410
  default: return "(unknown)";
411
  }
412
}
413
414
#endif // GET_SUBTARGET_FEATURE_NAME
415
416
417
#ifdef GET_MATCHER_IMPLEMENTATION
418
#undef GET_MATCHER_IMPLEMENTATION
419
420
enum {
421
  Tie0_1_1,
422
  Tie0_2_2,
423
  Tie1_2_2,
424
  Tie1_3_3,
425
};
426
427
static const uint8_t TiedAsmOperandTable[][3] = {
428
  /* Tie0_1_1 */ { 0, 1, 1 },
429
  /* Tie0_2_2 */ { 0, 2, 2 },
430
  /* Tie1_2_2 */ { 1, 2, 2 },
431
  /* Tie1_3_3 */ { 1, 3, 3 },
432
};
433
434
namespace {
435
enum OperatorConversionKind {
436
  CVT_Done,
437
  CVT_Reg,
438
  CVT_Tied,
439
  CVT_95_Reg,
440
  CVT_95_addImmOperands,
441
  CVT_imm_95_0,
442
  CVT_imm_95_5,
443
  CVT_imm_95_7,
444
  CVT_imm_95_6,
445
  CVT_imm_95_3,
446
  CVT_95_addImmCom8Operands,
447
  CVT_imm_95_2,
448
  CVT_imm_95_4,
449
  CVT_imm_95_1,
450
  CVT_95_addRegOperands,
451
  CVT_95_addMemriOperands,
452
  CVT_imm_95_255,
453
  CVT_NUM_CONVERTERS
454
};
455
456
enum InstructionConversionKind {
457
  Convert__Reg1_0__Tie0_1_1__Reg1_1,
458
  Convert__Reg1_0__Tie0_1_1__Imm1_1,
459
  Convert__Reg1_0__Tie0_1_1,
460
  Convert__Imm1_0,
461
  Convert__Imm1_0__Imm1_1,
462
  Convert__imm_95_0__Imm1_0,
463
  Convert_NoOperands,
464
  Convert__imm_95_5__Imm1_0,
465
  Convert__imm_95_7__Imm1_0,
466
  Convert__imm_95_6__Imm1_0,
467
  Convert__imm_95_3__Imm1_0,
468
  Convert__Reg1_0__Imm1_1,
469
  Convert__Reg1_0__Tie0_1_1__ImmCom81_1,
470
  Convert__imm_95_0,
471
  Convert__imm_95_5,
472
  Convert__imm_95_7,
473
  Convert__imm_95_2,
474
  Convert__Reg1_0__Tie0_1_1__Reg1_0,
475
  Convert__imm_95_4,
476
  Convert__imm_95_6,
477
  Convert__imm_95_3,
478
  Convert__imm_95_1,
479
  Convert__Reg1_0__Reg1_1,
480
  Convert__Reg1_1__Reg1_0,
481
  Convert__Reg1_0__Reg1_2__Tie1_3_3,
482
  Convert__Reg1_0__Reg1_1__Tie1_2_2,
483
  Convert__Reg1_0__Memri2_1,
484
  Convert__Imm1_0__Reg1_1,
485
  Convert__Reg1_0,
486
  Convert__Reg1_0__imm_95_255,
487
  Convert__Reg1_1__Tie0_2_2__Reg1_2__imm_95_0,
488
  Convert__Reg1_0__Tie0_1_1__Reg1_2__imm_95_0,
489
  Convert__Memri2_0__Reg1_1,
490
  CVT_NUM_SIGNATURES
491
};
492
493
} // end anonymous namespace
494
495
static const uint8_t ConversionTable[CVT_NUM_SIGNATURES][9] = {
496
  // Convert__Reg1_0__Tie0_1_1__Reg1_1
497
  { CVT_95_Reg, 1, CVT_Tied, Tie0_1_1, CVT_95_Reg, 2, CVT_Done },
498
  // Convert__Reg1_0__Tie0_1_1__Imm1_1
499
  { CVT_95_Reg, 1, CVT_Tied, Tie0_1_1, CVT_95_addImmOperands, 2, CVT_Done },
500
  // Convert__Reg1_0__Tie0_1_1
501
  { CVT_95_Reg, 1, CVT_Tied, Tie0_1_1, CVT_Done },
502
  // Convert__Imm1_0
503
  { CVT_95_addImmOperands, 1, CVT_Done },
504
  // Convert__Imm1_0__Imm1_1
505
  { CVT_95_addImmOperands, 1, CVT_95_addImmOperands, 2, CVT_Done },
506
  // Convert__imm_95_0__Imm1_0
507
  { CVT_imm_95_0, 0, CVT_95_addImmOperands, 1, CVT_Done },
508
  // Convert_NoOperands
509
  { CVT_Done },
510
  // Convert__imm_95_5__Imm1_0
511
  { CVT_imm_95_5, 0, CVT_95_addImmOperands, 1, CVT_Done },
512
  // Convert__imm_95_7__Imm1_0
513
  { CVT_imm_95_7, 0, CVT_95_addImmOperands, 1, CVT_Done },
514
  // Convert__imm_95_6__Imm1_0
515
  { CVT_imm_95_6, 0, CVT_95_addImmOperands, 1, CVT_Done },
516
  // Convert__imm_95_3__Imm1_0
517
  { CVT_imm_95_3, 0, CVT_95_addImmOperands, 1, CVT_Done },
518
  // Convert__Reg1_0__Imm1_1
519
  { CVT_95_Reg, 1, CVT_95_addImmOperands, 2, CVT_Done },
520
  // Convert__Reg1_0__Tie0_1_1__ImmCom81_1
521
  { CVT_95_Reg, 1, CVT_Tied, Tie0_1_1, CVT_95_addImmCom8Operands, 2, CVT_Done },
522
  // Convert__imm_95_0
523
  { CVT_imm_95_0, 0, CVT_Done },
524
  // Convert__imm_95_5
525
  { CVT_imm_95_5, 0, CVT_Done },
526
  // Convert__imm_95_7
527
  { CVT_imm_95_7, 0, CVT_Done },
528
  // Convert__imm_95_2
529
  { CVT_imm_95_2, 0, CVT_Done },
530
  // Convert__Reg1_0__Tie0_1_1__Reg1_0
531
  { CVT_95_Reg, 1, CVT_Tied, Tie0_1_1, CVT_95_Reg, 1, CVT_Done },
532
  // Convert__imm_95_4
533
  { CVT_imm_95_4, 0, CVT_Done },
534
  // Convert__imm_95_6
535
  { CVT_imm_95_6, 0, CVT_Done },
536
  // Convert__imm_95_3
537
  { CVT_imm_95_3, 0, CVT_Done },
538
  // Convert__imm_95_1
539
  { CVT_imm_95_1, 0, CVT_Done },
540
  // Convert__Reg1_0__Reg1_1
541
  { CVT_95_Reg, 1, CVT_95_Reg, 2, CVT_Done },
542
  // Convert__Reg1_1__Reg1_0
543
  { CVT_95_Reg, 2, CVT_95_Reg, 1, CVT_Done },
544
  // Convert__Reg1_0__Reg1_2__Tie1_3_3
545
  { CVT_95_Reg, 1, CVT_95_addRegOperands, 3, CVT_Tied, Tie1_3_3, CVT_Done },
546
  // Convert__Reg1_0__Reg1_1__Tie1_2_2
547
  { CVT_95_Reg, 1, CVT_95_addRegOperands, 2, CVT_Tied, Tie1_2_2, CVT_Done },
548
  // Convert__Reg1_0__Memri2_1
549
  { CVT_95_Reg, 1, CVT_95_addMemriOperands, 2, CVT_Done },
550
  // Convert__Imm1_0__Reg1_1
551
  { CVT_95_addImmOperands, 1, CVT_95_Reg, 2, CVT_Done },
552
  // Convert__Reg1_0
553
  { CVT_95_Reg, 1, CVT_Done },
554
  // Convert__Reg1_0__imm_95_255
555
  { CVT_95_Reg, 1, CVT_imm_95_255, 0, CVT_Done },
556
  // Convert__Reg1_1__Tie0_2_2__Reg1_2__imm_95_0
557
  { CVT_95_addRegOperands, 2, CVT_Tied, Tie0_2_2, CVT_95_Reg, 3, CVT_imm_95_0, 0, CVT_Done },
558
  // Convert__Reg1_0__Tie0_1_1__Reg1_2__imm_95_0
559
  { CVT_95_addRegOperands, 1, CVT_Tied, Tie0_1_1, CVT_95_Reg, 3, CVT_imm_95_0, 0, CVT_Done },
560
  // Convert__Memri2_0__Reg1_1
561
  { CVT_95_addMemriOperands, 1, CVT_95_Reg, 2, CVT_Done },
562
};
563
564
void AVRAsmParser::
565
convertToMCInst(unsigned Kind, MCInst &Inst, unsigned Opcode,
566
0
                const OperandVector &Operands) {
567
0
  assert(Kind < CVT_NUM_SIGNATURES && "Invalid signature!");
568
0
  const uint8_t *Converter = ConversionTable[Kind];
569
0
  unsigned OpIdx;
570
0
  Inst.setOpcode(Opcode);
571
0
  for (const uint8_t *p = Converter; *p; p += 2) {
572
0
    OpIdx = *(p + 1);
573
0
    switch (*p) {
574
0
    default: llvm_unreachable("invalid conversion entry!");
575
0
    case CVT_Reg:
576
0
      static_cast<AVROperand &>(*Operands[OpIdx]).addRegOperands(Inst, 1);
577
0
      break;
578
0
    case CVT_Tied: {
579
0
      assert(OpIdx < (size_t)(std::end(TiedAsmOperandTable) -
580
0
                              std::begin(TiedAsmOperandTable)) &&
581
0
             "Tied operand not found");
582
0
      unsigned TiedResOpnd = TiedAsmOperandTable[OpIdx][0];
583
0
      if (TiedResOpnd != (uint8_t)-1)
584
0
        Inst.addOperand(Inst.getOperand(TiedResOpnd));
585
0
      break;
586
0
    }
587
0
    case CVT_95_Reg:
588
0
      static_cast<AVROperand &>(*Operands[OpIdx]).addRegOperands(Inst, 1);
589
0
      break;
590
0
    case CVT_95_addImmOperands:
591
0
      static_cast<AVROperand &>(*Operands[OpIdx]).addImmOperands(Inst, 1);
592
0
      break;
593
0
    case CVT_imm_95_0:
594
0
      Inst.addOperand(MCOperand::createImm(0));
595
0
      break;
596
0
    case CVT_imm_95_5:
597
0
      Inst.addOperand(MCOperand::createImm(5));
598
0
      break;
599
0
    case CVT_imm_95_7:
600
0
      Inst.addOperand(MCOperand::createImm(7));
601
0
      break;
602
0
    case CVT_imm_95_6:
603
0
      Inst.addOperand(MCOperand::createImm(6));
604
0
      break;
605
0
    case CVT_imm_95_3:
606
0
      Inst.addOperand(MCOperand::createImm(3));
607
0
      break;
608
0
    case CVT_95_addImmCom8Operands:
609
0
      static_cast<AVROperand &>(*Operands[OpIdx]).addImmCom8Operands(Inst, 1);
610
0
      break;
611
0
    case CVT_imm_95_2:
612
0
      Inst.addOperand(MCOperand::createImm(2));
613
0
      break;
614
0
    case CVT_imm_95_4:
615
0
      Inst.addOperand(MCOperand::createImm(4));
616
0
      break;
617
0
    case CVT_imm_95_1:
618
0
      Inst.addOperand(MCOperand::createImm(1));
619
0
      break;
620
0
    case CVT_95_addRegOperands:
621
0
      static_cast<AVROperand &>(*Operands[OpIdx]).addRegOperands(Inst, 1);
622
0
      break;
623
0
    case CVT_95_addMemriOperands:
624
0
      static_cast<AVROperand &>(*Operands[OpIdx]).addMemriOperands(Inst, 2);
625
0
      break;
626
0
    case CVT_imm_95_255:
627
0
      Inst.addOperand(MCOperand::createImm(255));
628
0
      break;
629
0
    }
630
0
  }
631
0
}
632
633
void AVRAsmParser::
634
convertToMapAndConstraints(unsigned Kind,
635
0
                           const OperandVector &Operands) {
636
0
  assert(Kind < CVT_NUM_SIGNATURES && "Invalid signature!");
637
0
  unsigned NumMCOperands = 0;
638
0
  const uint8_t *Converter = ConversionTable[Kind];
639
0
  for (const uint8_t *p = Converter; *p; p += 2) {
640
0
    switch (*p) {
641
0
    default: llvm_unreachable("invalid conversion entry!");
642
0
    case CVT_Reg:
643
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
644
0
      Operands[*(p + 1)]->setConstraint("r");
645
0
      ++NumMCOperands;
646
0
      break;
647
0
    case CVT_Tied:
648
0
      ++NumMCOperands;
649
0
      break;
650
0
    case CVT_95_Reg:
651
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
652
0
      Operands[*(p + 1)]->setConstraint("r");
653
0
      NumMCOperands += 1;
654
0
      break;
655
0
    case CVT_95_addImmOperands:
656
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
657
0
      Operands[*(p + 1)]->setConstraint("m");
658
0
      NumMCOperands += 1;
659
0
      break;
660
0
    case CVT_imm_95_0:
661
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
662
0
      Operands[*(p + 1)]->setConstraint("");
663
0
      ++NumMCOperands;
664
0
      break;
665
0
    case CVT_imm_95_5:
666
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
667
0
      Operands[*(p + 1)]->setConstraint("");
668
0
      ++NumMCOperands;
669
0
      break;
670
0
    case CVT_imm_95_7:
671
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
672
0
      Operands[*(p + 1)]->setConstraint("");
673
0
      ++NumMCOperands;
674
0
      break;
675
0
    case CVT_imm_95_6:
676
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
677
0
      Operands[*(p + 1)]->setConstraint("");
678
0
      ++NumMCOperands;
679
0
      break;
680
0
    case CVT_imm_95_3:
681
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
682
0
      Operands[*(p + 1)]->setConstraint("");
683
0
      ++NumMCOperands;
684
0
      break;
685
0
    case CVT_95_addImmCom8Operands:
686
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
687
0
      Operands[*(p + 1)]->setConstraint("m");
688
0
      NumMCOperands += 1;
689
0
      break;
690
0
    case CVT_imm_95_2:
691
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
692
0
      Operands[*(p + 1)]->setConstraint("");
693
0
      ++NumMCOperands;
694
0
      break;
695
0
    case CVT_imm_95_4:
696
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
697
0
      Operands[*(p + 1)]->setConstraint("");
698
0
      ++NumMCOperands;
699
0
      break;
700
0
    case CVT_imm_95_1:
701
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
702
0
      Operands[*(p + 1)]->setConstraint("");
703
0
      ++NumMCOperands;
704
0
      break;
705
0
    case CVT_95_addRegOperands:
706
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
707
0
      Operands[*(p + 1)]->setConstraint("m");
708
0
      NumMCOperands += 1;
709
0
      break;
710
0
    case CVT_95_addMemriOperands:
711
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
712
0
      Operands[*(p + 1)]->setConstraint("m");
713
0
      NumMCOperands += 2;
714
0
      break;
715
0
    case CVT_imm_95_255:
716
0
      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
717
0
      Operands[*(p + 1)]->setConstraint("");
718
0
      ++NumMCOperands;
719
0
      break;
720
0
    }
721
0
  }
722
0
}
723
724
namespace {
725
726
/// MatchClassKind - The kinds of classes which participate in
727
/// instruction matching.
728
enum MatchClassKind {
729
  InvalidMatchClass = 0,
730
  OptionalMatchClass = 1,
731
  MCK__43_, // '+'
732
  MCK__MINUS_, // '-'
733
  MCK_LAST_TOKEN = MCK__MINUS_,
734
  MCK_Reg21, // derived register class
735
  MCK_CCR, // register class 'CCR'
736
  MCK_GPRSP, // register class 'GPRSP'
737
  MCK_ZREG, // register class 'ZREG'
738
  MCK_PTRDISPREGS, // register class 'PTRDISPREGS'
739
  MCK_PTRREGS, // register class 'PTRREGS'
740
  MCK_DREGSLD8lo, // register class 'DREGSLD8lo'
741
  MCK_IWREGS, // register class 'IWREGS'
742
  MCK_Reg16, // derived register class
743
  MCK_Reg17, // derived register class
744
  MCK_Reg15, // derived register class
745
  MCK_DLDREGS, // register class 'DLDREGS'
746
  MCK_DREGSlo, // register class 'DREGSlo'
747
  MCK_LD8lo, // register class 'LD8lo'
748
  MCK_Reg20, // derived register class
749
  MCK_Reg19, // derived register class
750
  MCK_Reg12, // derived register class
751
  MCK_Reg13, // derived register class
752
  MCK_DREGSMOVW, // register class 'DREGSMOVW'
753
  MCK_GPR8lo, // register class 'GPR8lo'
754
  MCK_LD8, // register class 'LD8'
755
  MCK_DREGS, // register class 'DREGS'
756
  MCK_GPR8, // register class 'GPR8'
757
  MCK_LAST_REGISTER = MCK_GPR8,
758
  MCK_Imm, // user defined class 'ImmAsmOperand'
759
  MCK_Memri, // user defined class 'MemriAsmOperand'
760
  MCK_Reg, // user defined class 'PtrRegAsmOperand'
761
  MCK_ImmCom8, // user defined class 'imm_com8_asmoperand'
762
  NumMatchClassKinds
763
};
764
765
} // end anonymous namespace
766
767
0
static unsigned getDiagKindFromRegisterClass(MatchClassKind RegisterClass) {
768
0
  return MCTargetAsmParser::Match_InvalidOperand;
769
0
}
770
771
0
static MatchClassKind matchTokenString(StringRef Name) {
772
0
  switch (Name.size()) {
773
0
  default: break;
774
0
  case 1:  // 2 strings to match.
775
0
    switch (Name[0]) {
776
0
    default: break;
777
0
    case '+':  // 1 string to match.
778
0
      return MCK__43_;  // "+"
779
0
    case '-':  // 1 string to match.
780
0
      return MCK__MINUS_;  // "-"
781
0
    }
782
0
    break;
783
0
  }
784
0
  return InvalidMatchClass;
785
0
}
786
787
/// isSubclass - Compute whether \p A is a subclass of \p B.
788
0
static bool isSubclass(MatchClassKind A, MatchClassKind B) {
789
0
  if (A == B)
790
0
    return true;
791
792
0
  switch (A) {
793
0
  default:
794
0
    return false;
795
796
0
  case MCK_Reg21:
797
0
    switch (B) {
798
0
    default: return false;
799
0
    case MCK_Reg17: return true;
800
0
    case MCK_Reg19: return true;
801
0
    case MCK_Reg13: return true;
802
0
    case MCK_DREGS: return true;
803
0
    }
804
805
0
  case MCK_ZREG:
806
0
    switch (B) {
807
0
    default: return false;
808
0
    case MCK_PTRDISPREGS: return true;
809
0
    case MCK_PTRREGS: return true;
810
0
    case MCK_IWREGS: return true;
811
0
    case MCK_DLDREGS: return true;
812
0
    case MCK_Reg12: return true;
813
0
    case MCK_Reg13: return true;
814
0
    case MCK_DREGSMOVW: return true;
815
0
    case MCK_DREGS: return true;
816
0
    }
817
818
0
  case MCK_PTRDISPREGS:
819
0
    switch (B) {
820
0
    default: return false;
821
0
    case MCK_PTRREGS: return true;
822
0
    case MCK_IWREGS: return true;
823
0
    case MCK_DLDREGS: return true;
824
0
    case MCK_Reg12: return true;
825
0
    case MCK_Reg13: return true;
826
0
    case MCK_DREGSMOVW: return true;
827
0
    case MCK_DREGS: return true;
828
0
    }
829
830
0
  case MCK_PTRREGS:
831
0
    switch (B) {
832
0
    default: return false;
833
0
    case MCK_IWREGS: return true;
834
0
    case MCK_DLDREGS: return true;
835
0
    case MCK_Reg12: return true;
836
0
    case MCK_Reg13: return true;
837
0
    case MCK_DREGSMOVW: return true;
838
0
    case MCK_DREGS: return true;
839
0
    }
840
841
0
  case MCK_DREGSLD8lo:
842
0
    switch (B) {
843
0
    default: return false;
844
0
    case MCK_Reg16: return true;
845
0
    case MCK_Reg17: return true;
846
0
    case MCK_Reg15: return true;
847
0
    case MCK_DLDREGS: return true;
848
0
    case MCK_Reg12: return true;
849
0
    case MCK_Reg13: return true;
850
0
    case MCK_DREGSMOVW: return true;
851
0
    case MCK_DREGS: return true;
852
0
    }
853
854
0
  case MCK_IWREGS:
855
0
    switch (B) {
856
0
    default: return false;
857
0
    case MCK_DLDREGS: return true;
858
0
    case MCK_Reg12: return true;
859
0
    case MCK_Reg13: return true;
860
0
    case MCK_DREGSMOVW: return true;
861
0
    case MCK_DREGS: return true;
862
0
    }
863
864
0
  case MCK_Reg16:
865
0
    switch (B) {
866
0
    default: return false;
867
0
    case MCK_Reg17: return true;
868
0
    case MCK_Reg15: return true;
869
0
    case MCK_Reg12: return true;
870
0
    case MCK_Reg13: return true;
871
0
    case MCK_DREGS: return true;
872
0
    }
873
874
0
  case MCK_Reg17:
875
0
    switch (B) {
876
0
    default: return false;
877
0
    case MCK_Reg13: return true;
878
0
    case MCK_DREGS: return true;
879
0
    }
880
881
0
  case MCK_Reg15:
882
0
    switch (B) {
883
0
    default: return false;
884
0
    case MCK_Reg12: return true;
885
0
    case MCK_Reg13: return true;
886
0
    case MCK_DREGS: return true;
887
0
    }
888
889
0
  case MCK_DLDREGS:
890
0
    switch (B) {
891
0
    default: return false;
892
0
    case MCK_Reg12: return true;
893
0
    case MCK_Reg13: return true;
894
0
    case MCK_DREGSMOVW: return true;
895
0
    case MCK_DREGS: return true;
896
0
    }
897
898
0
  case MCK_DREGSlo:
899
0
    switch (B) {
900
0
    default: return false;
901
0
    case MCK_Reg20: return true;
902
0
    case MCK_Reg19: return true;
903
0
    case MCK_DREGSMOVW: return true;
904
0
    case MCK_DREGS: return true;
905
0
    }
906
907
0
  case MCK_LD8lo:
908
0
    switch (B) {
909
0
    default: return false;
910
0
    case MCK_LD8: return true;
911
0
    case MCK_GPR8: return true;
912
0
    }
913
914
0
  case MCK_Reg20:
915
0
    switch (B) {
916
0
    default: return false;
917
0
    case MCK_Reg19: return true;
918
0
    case MCK_DREGS: return true;
919
0
    }
920
921
0
  case MCK_Reg19:
922
0
    return B == MCK_DREGS;
923
924
0
  case MCK_Reg12:
925
0
    switch (B) {
926
0
    default: return false;
927
0
    case MCK_Reg13: return true;
928
0
    case MCK_DREGS: return true;
929
0
    }
930
931
0
  case MCK_Reg13:
932
0
    return B == MCK_DREGS;
933
934
0
  case MCK_DREGSMOVW:
935
0
    return B == MCK_DREGS;
936
937
0
  case MCK_GPR8lo:
938
0
    return B == MCK_GPR8;
939
940
0
  case MCK_LD8:
941
0
    return B == MCK_GPR8;
942
0
  }
943
0
}
944
945
0
static unsigned validateOperandClass(MCParsedAsmOperand &GOp, MatchClassKind Kind) {
946
0
  AVROperand &Operand = (AVROperand &)GOp;
947
0
  if (Kind == InvalidMatchClass)
948
0
    return MCTargetAsmParser::Match_InvalidOperand;
949
950
0
  if (Operand.isToken() && Kind <= MCK_LAST_TOKEN)
951
0
    return isSubclass(matchTokenString(Operand.getToken()), Kind) ?
952
0
             MCTargetAsmParser::Match_Success :
953
0
             MCTargetAsmParser::Match_InvalidOperand;
954
955
0
  switch (Kind) {
956
0
  default: break;
957
  // 'Imm' class
958
0
  case MCK_Imm: {
959
0
    DiagnosticPredicate DP(Operand.isImm());
960
0
    if (DP.isMatch())
961
0
      return MCTargetAsmParser::Match_Success;
962
0
    break;
963
0
    }
964
  // 'Memri' class
965
0
  case MCK_Memri: {
966
0
    DiagnosticPredicate DP(Operand.isMemri());
967
0
    if (DP.isMatch())
968
0
      return MCTargetAsmParser::Match_Success;
969
0
    break;
970
0
    }
971
  // 'Reg' class
972
0
  case MCK_Reg: {
973
0
    DiagnosticPredicate DP(Operand.isReg());
974
0
    if (DP.isMatch())
975
0
      return MCTargetAsmParser::Match_Success;
976
0
    break;
977
0
    }
978
  // 'ImmCom8' class
979
0
  case MCK_ImmCom8: {
980
0
    DiagnosticPredicate DP(Operand.isImmCom8());
981
0
    if (DP.isMatch())
982
0
      return MCTargetAsmParser::Match_Success;
983
0
    break;
984
0
    }
985
0
  } // end switch (Kind)
986
987
0
  if (Operand.isReg()) {
988
0
    MatchClassKind OpKind;
989
0
    switch (Operand.getReg()) {
990
0
    default: OpKind = InvalidMatchClass; break;
991
0
    case AVR::R0: OpKind = MCK_GPR8lo; break;
992
0
    case AVR::R1: OpKind = MCK_GPR8lo; break;
993
0
    case AVR::R2: OpKind = MCK_GPR8lo; break;
994
0
    case AVR::R3: OpKind = MCK_GPR8lo; break;
995
0
    case AVR::R4: OpKind = MCK_GPR8lo; break;
996
0
    case AVR::R5: OpKind = MCK_GPR8lo; break;
997
0
    case AVR::R6: OpKind = MCK_GPR8lo; break;
998
0
    case AVR::R7: OpKind = MCK_GPR8lo; break;
999
0
    case AVR::R8: OpKind = MCK_GPR8lo; break;
1000
0
    case AVR::R9: OpKind = MCK_GPR8lo; break;
1001
0
    case AVR::R10: OpKind = MCK_GPR8lo; break;
1002
0
    case AVR::R11: OpKind = MCK_GPR8lo; break;
1003
0
    case AVR::R12: OpKind = MCK_GPR8lo; break;
1004
0
    case AVR::R13: OpKind = MCK_GPR8lo; break;
1005
0
    case AVR::R14: OpKind = MCK_GPR8lo; break;
1006
0
    case AVR::R15: OpKind = MCK_GPR8lo; break;
1007
0
    case AVR::R16: OpKind = MCK_LD8lo; break;
1008
0
    case AVR::R17: OpKind = MCK_LD8lo; break;
1009
0
    case AVR::R18: OpKind = MCK_LD8lo; break;
1010
0
    case AVR::R19: OpKind = MCK_LD8lo; break;
1011
0
    case AVR::R20: OpKind = MCK_LD8lo; break;
1012
0
    case AVR::R21: OpKind = MCK_LD8lo; break;
1013
0
    case AVR::R22: OpKind = MCK_LD8lo; break;
1014
0
    case AVR::R23: OpKind = MCK_LD8lo; break;
1015
0
    case AVR::R24: OpKind = MCK_LD8; break;
1016
0
    case AVR::R25: OpKind = MCK_LD8; break;
1017
0
    case AVR::R26: OpKind = MCK_LD8; break;
1018
0
    case AVR::R27: OpKind = MCK_LD8; break;
1019
0
    case AVR::R28: OpKind = MCK_LD8; break;
1020
0
    case AVR::R29: OpKind = MCK_LD8; break;
1021
0
    case AVR::R30: OpKind = MCK_LD8; break;
1022
0
    case AVR::R31: OpKind = MCK_LD8; break;
1023
0
    case AVR::SP: OpKind = MCK_GPRSP; break;
1024
0
    case AVR::R31R30: OpKind = MCK_ZREG; break;
1025
0
    case AVR::R29R28: OpKind = MCK_PTRDISPREGS; break;
1026
0
    case AVR::R27R26: OpKind = MCK_PTRREGS; break;
1027
0
    case AVR::R25R24: OpKind = MCK_IWREGS; break;
1028
0
    case AVR::R23R22: OpKind = MCK_DREGSLD8lo; break;
1029
0
    case AVR::R21R20: OpKind = MCK_DREGSLD8lo; break;
1030
0
    case AVR::R19R18: OpKind = MCK_DREGSLD8lo; break;
1031
0
    case AVR::R17R16: OpKind = MCK_DREGSLD8lo; break;
1032
0
    case AVR::R15R14: OpKind = MCK_DREGSlo; break;
1033
0
    case AVR::R13R12: OpKind = MCK_DREGSlo; break;
1034
0
    case AVR::R11R10: OpKind = MCK_DREGSlo; break;
1035
0
    case AVR::R9R8: OpKind = MCK_DREGSlo; break;
1036
0
    case AVR::R7R6: OpKind = MCK_DREGSlo; break;
1037
0
    case AVR::R5R4: OpKind = MCK_DREGSlo; break;
1038
0
    case AVR::R3R2: OpKind = MCK_DREGSlo; break;
1039
0
    case AVR::R1R0: OpKind = MCK_DREGSlo; break;
1040
0
    case AVR::R26R25: OpKind = MCK_Reg12; break;
1041
0
    case AVR::R24R23: OpKind = MCK_Reg15; break;
1042
0
    case AVR::R22R21: OpKind = MCK_Reg16; break;
1043
0
    case AVR::R20R19: OpKind = MCK_Reg16; break;
1044
0
    case AVR::R18R17: OpKind = MCK_Reg16; break;
1045
0
    case AVR::R16R15: OpKind = MCK_Reg21; break;
1046
0
    case AVR::R14R13: OpKind = MCK_Reg20; break;
1047
0
    case AVR::R12R11: OpKind = MCK_Reg20; break;
1048
0
    case AVR::R10R9: OpKind = MCK_Reg20; break;
1049
0
    case AVR::SREG: OpKind = MCK_CCR; break;
1050
0
    }
1051
0
    return isSubclass(OpKind, Kind) ? (unsigned)MCTargetAsmParser::Match_Success :
1052
0
                                      getDiagKindFromRegisterClass(Kind);
1053
0
  }
1054
1055
0
  if (Kind > MCK_LAST_TOKEN && Kind <= MCK_LAST_REGISTER)
1056
0
    return getDiagKindFromRegisterClass(Kind);
1057
1058
0
  return MCTargetAsmParser::Match_InvalidOperand;
1059
0
}
1060
1061
#ifndef NDEBUG
1062
0
const char *getMatchClassName(MatchClassKind Kind) {
1063
0
  switch (Kind) {
1064
0
  case InvalidMatchClass: return "InvalidMatchClass";
1065
0
  case OptionalMatchClass: return "OptionalMatchClass";
1066
0
  case MCK__43_: return "MCK__43_";
1067
0
  case MCK__MINUS_: return "MCK__MINUS_";
1068
0
  case MCK_Reg21: return "MCK_Reg21";
1069
0
  case MCK_CCR: return "MCK_CCR";
1070
0
  case MCK_GPRSP: return "MCK_GPRSP";
1071
0
  case MCK_ZREG: return "MCK_ZREG";
1072
0
  case MCK_PTRDISPREGS: return "MCK_PTRDISPREGS";
1073
0
  case MCK_PTRREGS: return "MCK_PTRREGS";
1074
0
  case MCK_DREGSLD8lo: return "MCK_DREGSLD8lo";
1075
0
  case MCK_IWREGS: return "MCK_IWREGS";
1076
0
  case MCK_Reg16: return "MCK_Reg16";
1077
0
  case MCK_Reg17: return "MCK_Reg17";
1078
0
  case MCK_Reg15: return "MCK_Reg15";
1079
0
  case MCK_DLDREGS: return "MCK_DLDREGS";
1080
0
  case MCK_DREGSlo: return "MCK_DREGSlo";
1081
0
  case MCK_LD8lo: return "MCK_LD8lo";
1082
0
  case MCK_Reg20: return "MCK_Reg20";
1083
0
  case MCK_Reg19: return "MCK_Reg19";
1084
0
  case MCK_Reg12: return "MCK_Reg12";
1085
0
  case MCK_Reg13: return "MCK_Reg13";
1086
0
  case MCK_DREGSMOVW: return "MCK_DREGSMOVW";
1087
0
  case MCK_GPR8lo: return "MCK_GPR8lo";
1088
0
  case MCK_LD8: return "MCK_LD8";
1089
0
  case MCK_DREGS: return "MCK_DREGS";
1090
0
  case MCK_GPR8: return "MCK_GPR8";
1091
0
  case MCK_Imm: return "MCK_Imm";
1092
0
  case MCK_Memri: return "MCK_Memri";
1093
0
  case MCK_Reg: return "MCK_Reg";
1094
0
  case MCK_ImmCom8: return "MCK_ImmCom8";
1095
0
  case NumMatchClassKinds: return "NumMatchClassKinds";
1096
0
  }
1097
0
  llvm_unreachable("unhandled MatchClassKind!");
1098
0
}
1099
1100
#endif // NDEBUG
1101
FeatureBitset AVRAsmParser::
1102
0
ComputeAvailableFeatures(const FeatureBitset &FB) const {
1103
0
  FeatureBitset Features;
1104
0
  if (FB[AVR::FeatureSRAM])
1105
0
    Features.set(Feature_HasSRAMBit);
1106
0
  if (FB[AVR::FeatureJMPCALL])
1107
0
    Features.set(Feature_HasJMPCALLBit);
1108
0
  if (FB[AVR::FeatureIJMPCALL])
1109
0
    Features.set(Feature_HasIJMPCALLBit);
1110
0
  if (FB[AVR::FeatureEIJMPCALL])
1111
0
    Features.set(Feature_HasEIJMPCALLBit);
1112
0
  if (FB[AVR::FeatureADDSUBIW])
1113
0
    Features.set(Feature_HasADDSUBIWBit);
1114
0
  if (FB[AVR::FeatureSmallStack])
1115
0
    Features.set(Feature_HasSmallStackBit);
1116
0
  if (FB[AVR::FeatureMOVW])
1117
0
    Features.set(Feature_HasMOVWBit);
1118
0
  if (FB[AVR::FeatureLPM])
1119
0
    Features.set(Feature_HasLPMBit);
1120
0
  if (FB[AVR::FeatureLPMX])
1121
0
    Features.set(Feature_HasLPMXBit);
1122
0
  if (FB[AVR::FeatureELPM])
1123
0
    Features.set(Feature_HasELPMBit);
1124
0
  if (FB[AVR::FeatureELPMX])
1125
0
    Features.set(Feature_HasELPMXBit);
1126
0
  if (FB[AVR::FeatureSPM])
1127
0
    Features.set(Feature_HasSPMBit);
1128
0
  if (FB[AVR::FeatureSPMX])
1129
0
    Features.set(Feature_HasSPMXBit);
1130
0
  if (FB[AVR::FeatureDES])
1131
0
    Features.set(Feature_HasDESBit);
1132
0
  if (FB[AVR::FeatureRMW])
1133
0
    Features.set(Feature_SupportsRMWBit);
1134
0
  if (FB[AVR::FeatureMultiplication])
1135
0
    Features.set(Feature_SupportsMultiplicationBit);
1136
0
  if (FB[AVR::FeatureBREAK])
1137
0
    Features.set(Feature_HasBREAKBit);
1138
0
  if (FB[AVR::FeatureTinyEncoding])
1139
0
    Features.set(Feature_HasTinyEncodingBit);
1140
0
  if (!FB[AVR::FeatureTinyEncoding])
1141
0
    Features.set(Feature_HasNonTinyEncodingBit);
1142
0
  return Features;
1143
0
}
1144
1145
static bool checkAsmTiedOperandConstraints(const AVRAsmParser&AsmParser,
1146
                               unsigned Kind,
1147
                               const OperandVector &Operands,
1148
0
                               uint64_t &ErrorInfo) {
1149
0
  assert(Kind < CVT_NUM_SIGNATURES && "Invalid signature!");
1150
0
  const uint8_t *Converter = ConversionTable[Kind];
1151
0
  for (const uint8_t *p = Converter; *p; p += 2) {
1152
0
    switch (*p) {
1153
0
    case CVT_Tied: {
1154
0
      unsigned OpIdx = *(p + 1);
1155
0
      assert(OpIdx < (size_t)(std::end(TiedAsmOperandTable) -
1156
0
                              std::begin(TiedAsmOperandTable)) &&
1157
0
             "Tied operand not found");
1158
0
      unsigned OpndNum1 = TiedAsmOperandTable[OpIdx][1];
1159
0
      unsigned OpndNum2 = TiedAsmOperandTable[OpIdx][2];
1160
0
      if (OpndNum1 != OpndNum2) {
1161
0
        auto &SrcOp1 = Operands[OpndNum1];
1162
0
        auto &SrcOp2 = Operands[OpndNum2];
1163
0
        if (!AsmParser.areEqualRegs(*SrcOp1, *SrcOp2)) {
1164
0
          ErrorInfo = OpndNum2;
1165
0
          return false;
1166
0
        }
1167
0
      }
1168
0
      break;
1169
0
    }
1170
0
    default:
1171
0
      break;
1172
0
    }
1173
0
  }
1174
0
  return true;
1175
0
}
1176
1177
static const char MnemonicTable[] =
1178
    "\003adc\003add\004adiw\003and\004andi\003asr\004bclr\003bld\004brbc\004"
1179
    "brbs\004brcc\004brcs\005break\004breq\004brge\004brhc\004brhs\004brid\004"
1180
    "brie\004brlo\004brlt\004brmi\004brne\004brpl\004brsh\004brtc\004brts\004"
1181
    "brvc\004brvs\004bset\003bst\004call\003cbi\003cbr\003clc\003clh\003cli\003"
1182
    "cln\003clr\003cls\003clt\003clv\003clz\003com\002cp\003cpc\003cpi\004cp"
1183
    "se\003dec\003des\006eicall\005eijmp\004elpm\003eor\004fmul\005fmuls\006"
1184
    "fmulsu\005icall\004ijmp\002in\003inc\003jmp\003lac\003las\003lat\002ld\003"
1185
    "ldd\003ldi\003lds\003lpm\003lsl\003lsr\003mov\004movw\003mul\004muls\005"
1186
    "mulsu\003neg\003nop\002or\003ori\003out\003pop\004push\005rcall\003ret\004"
1187
    "reti\004rjmp\003rol\003ror\003sbc\004sbci\003sbi\004sbic\004sbis\004sbi"
1188
    "w\003sbr\004sbrc\004sbrs\003sec\003seh\003sei\003sen\003ser\003ses\003s"
1189
    "et\003sev\003sez\005sleep\003spm\002st\003std\003sts\003sub\004subi\004"
1190
    "swap\003tst\003wdr\003xch";
1191
1192
// Feature bitsets.
1193
enum : uint8_t {
1194
  AMFBS_None,
1195
  AMFBS_HasADDSUBIW,
1196
  AMFBS_HasBREAK,
1197
  AMFBS_HasDES,
1198
  AMFBS_HasEIJMPCALL,
1199
  AMFBS_HasELPM,
1200
  AMFBS_HasELPMX,
1201
  AMFBS_HasIJMPCALL,
1202
  AMFBS_HasJMPCALL,
1203
  AMFBS_HasLPM,
1204
  AMFBS_HasLPMX,
1205
  AMFBS_HasMOVW,
1206
  AMFBS_HasSPM,
1207
  AMFBS_HasSPMX,
1208
  AMFBS_HasSRAM,
1209
  AMFBS_SupportsMultiplication,
1210
  AMFBS_SupportsRMW,
1211
  AMFBS_HasSRAM_HasNonTinyEncoding,
1212
  AMFBS_HasSRAM_HasTinyEncoding,
1213
};
1214
1215
static constexpr FeatureBitset FeatureBitsets[] = {
1216
  {}, // AMFBS_None
1217
  {Feature_HasADDSUBIWBit, },
1218
  {Feature_HasBREAKBit, },
1219
  {Feature_HasDESBit, },
1220
  {Feature_HasEIJMPCALLBit, },
1221
  {Feature_HasELPMBit, },
1222
  {Feature_HasELPMXBit, },
1223
  {Feature_HasIJMPCALLBit, },
1224
  {Feature_HasJMPCALLBit, },
1225
  {Feature_HasLPMBit, },
1226
  {Feature_HasLPMXBit, },
1227
  {Feature_HasMOVWBit, },
1228
  {Feature_HasSPMBit, },
1229
  {Feature_HasSPMXBit, },
1230
  {Feature_HasSRAMBit, },
1231
  {Feature_SupportsMultiplicationBit, },
1232
  {Feature_SupportsRMWBit, },
1233
  {Feature_HasSRAMBit, Feature_HasNonTinyEncodingBit, },
1234
  {Feature_HasSRAMBit, Feature_HasTinyEncodingBit, },
1235
};
1236
1237
namespace {
1238
  struct MatchEntry {
1239
    uint16_t Mnemonic;
1240
    uint16_t Opcode;
1241
    uint8_t ConvertFn;
1242
    uint8_t RequiredFeaturesIdx;
1243
    uint8_t Classes[3];
1244
0
    StringRef getMnemonic() const {
1245
0
      return StringRef(MnemonicTable + Mnemonic + 1,
1246
0
                       MnemonicTable[Mnemonic]);
1247
0
    }
1248
  };
1249
1250
  // Predicate for searching for an opcode.
1251
  struct LessOpcode {
1252
0
    bool operator()(const MatchEntry &LHS, StringRef RHS) {
1253
0
      return LHS.getMnemonic() < RHS;
1254
0
    }
1255
0
    bool operator()(StringRef LHS, const MatchEntry &RHS) {
1256
0
      return LHS < RHS.getMnemonic();
1257
0
    }
1258
0
    bool operator()(const MatchEntry &LHS, const MatchEntry &RHS) {
1259
0
      return LHS.getMnemonic() < RHS.getMnemonic();
1260
0
    }
1261
  };
1262
} // end anonymous namespace
1263
1264
static const MatchEntry MatchTable0[] = {
1265
  { 0 /* adc */, AVR::ADCRdRr, Convert__Reg1_0__Tie0_1_1__Reg1_1, AMFBS_None, { MCK_GPR8, MCK_GPR8 }, },
1266
  { 4 /* add */, AVR::ADDRdRr, Convert__Reg1_0__Tie0_1_1__Reg1_1, AMFBS_None, { MCK_GPR8, MCK_GPR8 }, },
1267
  { 8 /* adiw */, AVR::ADIWRdK, Convert__Reg1_0__Tie0_1_1__Imm1_1, AMFBS_HasADDSUBIW, { MCK_IWREGS, MCK_Imm }, },
1268
  { 13 /* and */, AVR::ANDRdRr, Convert__Reg1_0__Tie0_1_1__Reg1_1, AMFBS_None, { MCK_GPR8, MCK_GPR8 }, },
1269
  { 17 /* andi */, AVR::ANDIRdK, Convert__Reg1_0__Tie0_1_1__Imm1_1, AMFBS_None, { MCK_LD8, MCK_Imm }, },
1270
  { 22 /* asr */, AVR::ASRRd, Convert__Reg1_0__Tie0_1_1, AMFBS_None, { MCK_GPR8 }, },
1271
  { 26 /* bclr */, AVR::BCLRs, Convert__Imm1_0, AMFBS_None, { MCK_Imm }, },
1272
  { 31 /* bld */, AVR::BLD, Convert__Reg1_0__Tie0_1_1__Imm1_1, AMFBS_None, { MCK_GPR8, MCK_Imm }, },
1273
  { 35 /* brbc */, AVR::BRBCsk, Convert__Imm1_0__Imm1_1, AMFBS_None, { MCK_Imm, MCK_Imm }, },
1274
  { 40 /* brbs */, AVR::BRBSsk, Convert__Imm1_0__Imm1_1, AMFBS_None, { MCK_Imm, MCK_Imm }, },
1275
  { 45 /* brcc */, AVR::BRBCsk, Convert__imm_95_0__Imm1_0, AMFBS_None, { MCK_Imm }, },
1276
  { 50 /* brcs */, AVR::BRBSsk, Convert__imm_95_0__Imm1_0, AMFBS_None, { MCK_Imm }, },
1277
  { 55 /* break */, AVR::BREAK, Convert_NoOperands, AMFBS_HasBREAK, {  }, },
1278
  { 61 /* breq */, AVR::BREQk, Convert__Imm1_0, AMFBS_None, { MCK_Imm }, },
1279
  { 66 /* brge */, AVR::BRGEk, Convert__Imm1_0, AMFBS_None, { MCK_Imm }, },
1280
  { 71 /* brhc */, AVR::BRBCsk, Convert__imm_95_5__Imm1_0, AMFBS_None, { MCK_Imm }, },
1281
  { 76 /* brhs */, AVR::BRBSsk, Convert__imm_95_5__Imm1_0, AMFBS_None, { MCK_Imm }, },
1282
  { 81 /* brid */, AVR::BRBCsk, Convert__imm_95_7__Imm1_0, AMFBS_None, { MCK_Imm }, },
1283
  { 86 /* brie */, AVR::BRBSsk, Convert__imm_95_7__Imm1_0, AMFBS_None, { MCK_Imm }, },
1284
  { 91 /* brlo */, AVR::BRLOk, Convert__Imm1_0, AMFBS_None, { MCK_Imm }, },
1285
  { 96 /* brlt */, AVR::BRLTk, Convert__Imm1_0, AMFBS_None, { MCK_Imm }, },
1286
  { 101 /* brmi */, AVR::BRMIk, Convert__Imm1_0, AMFBS_None, { MCK_Imm }, },
1287
  { 106 /* brne */, AVR::BRNEk, Convert__Imm1_0, AMFBS_None, { MCK_Imm }, },
1288
  { 111 /* brpl */, AVR::BRPLk, Convert__Imm1_0, AMFBS_None, { MCK_Imm }, },
1289
  { 116 /* brsh */, AVR::BRSHk, Convert__Imm1_0, AMFBS_None, { MCK_Imm }, },
1290
  { 121 /* brtc */, AVR::BRBCsk, Convert__imm_95_6__Imm1_0, AMFBS_None, { MCK_Imm }, },
1291
  { 126 /* brts */, AVR::BRBSsk, Convert__imm_95_6__Imm1_0, AMFBS_None, { MCK_Imm }, },
1292
  { 131 /* brvc */, AVR::BRBCsk, Convert__imm_95_3__Imm1_0, AMFBS_None, { MCK_Imm }, },
1293
  { 136 /* brvs */, AVR::BRBSsk, Convert__imm_95_3__Imm1_0, AMFBS_None, { MCK_Imm }, },
1294
  { 141 /* bset */, AVR::BSETs, Convert__Imm1_0, AMFBS_None, { MCK_Imm }, },
1295
  { 146 /* bst */, AVR::BST, Convert__Reg1_0__Imm1_1, AMFBS_None, { MCK_GPR8, MCK_Imm }, },
1296
  { 150 /* call */, AVR::CALLk, Convert__Imm1_0, AMFBS_HasJMPCALL, { MCK_Imm }, },
1297
  { 155 /* cbi */, AVR::CBIAb, Convert__Imm1_0__Imm1_1, AMFBS_None, { MCK_Imm, MCK_Imm }, },
1298
  { 159 /* cbr */, AVR::ANDIRdK, Convert__Reg1_0__Tie0_1_1__ImmCom81_1, AMFBS_None, { MCK_LD8, MCK_ImmCom8 }, },
1299
  { 163 /* clc */, AVR::BCLRs, Convert__imm_95_0, AMFBS_None, {  }, },
1300
  { 167 /* clh */, AVR::BCLRs, Convert__imm_95_5, AMFBS_None, {  }, },
1301
  { 171 /* cli */, AVR::BCLRs, Convert__imm_95_7, AMFBS_None, {  }, },
1302
  { 175 /* cln */, AVR::BCLRs, Convert__imm_95_2, AMFBS_None, {  }, },
1303
  { 179 /* clr */, AVR::EORRdRr, Convert__Reg1_0__Tie0_1_1__Reg1_0, AMFBS_None, { MCK_GPR8 }, },
1304
  { 183 /* cls */, AVR::BCLRs, Convert__imm_95_4, AMFBS_None, {  }, },
1305
  { 187 /* clt */, AVR::BCLRs, Convert__imm_95_6, AMFBS_None, {  }, },
1306
  { 191 /* clv */, AVR::BCLRs, Convert__imm_95_3, AMFBS_None, {  }, },
1307
  { 195 /* clz */, AVR::BCLRs, Convert__imm_95_1, AMFBS_None, {  }, },
1308
  { 199 /* com */, AVR::COMRd, Convert__Reg1_0__Tie0_1_1, AMFBS_None, { MCK_GPR8 }, },
1309
  { 203 /* cp */, AVR::CPRdRr, Convert__Reg1_0__Reg1_1, AMFBS_None, { MCK_GPR8, MCK_GPR8 }, },
1310
  { 206 /* cpc */, AVR::CPCRdRr, Convert__Reg1_0__Reg1_1, AMFBS_None, { MCK_GPR8, MCK_GPR8 }, },
1311
  { 210 /* cpi */, AVR::CPIRdK, Convert__Reg1_0__Imm1_1, AMFBS_None, { MCK_LD8, MCK_Imm }, },
1312
  { 214 /* cpse */, AVR::CPSE, Convert__Reg1_0__Reg1_1, AMFBS_None, { MCK_GPR8, MCK_GPR8 }, },
1313
  { 219 /* dec */, AVR::DECRd, Convert__Reg1_0__Tie0_1_1, AMFBS_None, { MCK_GPR8 }, },
1314
  { 223 /* des */, AVR::DESK, Convert__Imm1_0, AMFBS_HasDES, { MCK_Imm }, },
1315
  { 227 /* eicall */, AVR::EICALL, Convert_NoOperands, AMFBS_HasEIJMPCALL, {  }, },
1316
  { 234 /* eijmp */, AVR::EIJMP, Convert_NoOperands, AMFBS_HasEIJMPCALL, {  }, },
1317
  { 240 /* elpm */, AVR::ELPM, Convert_NoOperands, AMFBS_HasELPM, {  }, },
1318
  { 240 /* elpm */, AVR::ELPMRdZ, Convert__Reg1_0__Reg1_1, AMFBS_HasELPMX, { MCK_GPR8, MCK_ZREG }, },
1319
  { 240 /* elpm */, AVR::ELPMRdZPi, Convert__Reg1_0__Reg1_1, AMFBS_HasELPMX, { MCK_GPR8, MCK_ZREG, MCK__43_ }, },
1320
  { 245 /* eor */, AVR::EORRdRr, Convert__Reg1_0__Tie0_1_1__Reg1_1, AMFBS_None, { MCK_GPR8, MCK_GPR8 }, },
1321
  { 249 /* fmul */, AVR::FMUL, Convert__Reg1_0__Reg1_1, AMFBS_SupportsMultiplication, { MCK_LD8lo, MCK_LD8lo }, },
1322
  { 254 /* fmuls */, AVR::FMULS, Convert__Reg1_0__Reg1_1, AMFBS_SupportsMultiplication, { MCK_LD8lo, MCK_LD8lo }, },
1323
  { 260 /* fmulsu */, AVR::FMULSU, Convert__Reg1_0__Reg1_1, AMFBS_SupportsMultiplication, { MCK_LD8lo, MCK_LD8lo }, },
1324
  { 267 /* icall */, AVR::ICALL, Convert_NoOperands, AMFBS_HasIJMPCALL, {  }, },
1325
  { 273 /* ijmp */, AVR::IJMP, Convert_NoOperands, AMFBS_HasIJMPCALL, {  }, },
1326
  { 278 /* in */, AVR::INRdA, Convert__Reg1_0__Imm1_1, AMFBS_None, { MCK_GPR8, MCK_Imm }, },
1327
  { 281 /* inc */, AVR::INCRd, Convert__Reg1_0__Tie0_1_1, AMFBS_None, { MCK_GPR8 }, },
1328
  { 285 /* jmp */, AVR::JMPk, Convert__Imm1_0, AMFBS_HasJMPCALL, { MCK_Imm }, },
1329
  { 289 /* lac */, AVR::LACZRd, Convert__Reg1_1__Reg1_0, AMFBS_SupportsRMW, { MCK_ZREG, MCK_GPR8 }, },
1330
  { 293 /* las */, AVR::LASZRd, Convert__Reg1_1__Reg1_0, AMFBS_SupportsRMW, { MCK_ZREG, MCK_GPR8 }, },
1331
  { 297 /* lat */, AVR::LATZRd, Convert__Reg1_1__Reg1_0, AMFBS_SupportsRMW, { MCK_ZREG, MCK_GPR8 }, },
1332
  { 301 /* ld */, AVR::LDRdPtr, Convert__Reg1_0__Reg1_1, AMFBS_HasSRAM, { MCK_GPR8, MCK_Reg }, },
1333
  { 301 /* ld */, AVR::LDRdPtrPd, Convert__Reg1_0__Reg1_2__Tie1_3_3, AMFBS_HasSRAM, { MCK_GPR8, MCK__MINUS_, MCK_Reg }, },
1334
  { 301 /* ld */, AVR::LDRdPtrPi, Convert__Reg1_0__Reg1_1__Tie1_2_2, AMFBS_HasSRAM, { MCK_GPR8, MCK_Reg, MCK__43_ }, },
1335
  { 304 /* ldd */, AVR::LDDRdPtrQ, Convert__Reg1_0__Memri2_1, AMFBS_HasSRAM_HasNonTinyEncoding, { MCK_GPR8, MCK_Memri }, },
1336
  { 308 /* ldi */, AVR::LDIRdK, Convert__Reg1_0__Imm1_1, AMFBS_None, { MCK_LD8, MCK_Imm }, },
1337
  { 312 /* lds */, AVR::LDSRdKTiny, Convert__Reg1_0__Imm1_1, AMFBS_HasSRAM_HasTinyEncoding, { MCK_LD8, MCK_Imm }, },
1338
  { 312 /* lds */, AVR::LDSRdK, Convert__Reg1_0__Imm1_1, AMFBS_HasSRAM_HasNonTinyEncoding, { MCK_GPR8, MCK_Imm }, },
1339
  { 316 /* lpm */, AVR::LPM, Convert_NoOperands, AMFBS_HasLPM, {  }, },
1340
  { 316 /* lpm */, AVR::LPMRdZ, Convert__Reg1_0__Reg1_1, AMFBS_HasLPMX, { MCK_GPR8, MCK_ZREG }, },
1341
  { 316 /* lpm */, AVR::LPMRdZPi, Convert__Reg1_0__Reg1_1, AMFBS_HasLPMX, { MCK_GPR8, MCK_ZREG, MCK__43_ }, },
1342
  { 320 /* lsl */, AVR::ADDRdRr, Convert__Reg1_0__Tie0_1_1__Reg1_0, AMFBS_None, { MCK_GPR8 }, },
1343
  { 324 /* lsr */, AVR::LSRRd, Convert__Reg1_0__Tie0_1_1, AMFBS_None, { MCK_GPR8 }, },
1344
  { 328 /* mov */, AVR::MOVRdRr, Convert__Reg1_0__Reg1_1, AMFBS_None, { MCK_GPR8, MCK_GPR8 }, },
1345
  { 332 /* movw */, AVR::MOVWRdRr, Convert__Reg1_0__Reg1_1, AMFBS_HasMOVW, { MCK_DREGS, MCK_DREGS }, },
1346
  { 337 /* mul */, AVR::MULRdRr, Convert__Reg1_0__Reg1_1, AMFBS_SupportsMultiplication, { MCK_GPR8, MCK_GPR8 }, },
1347
  { 341 /* muls */, AVR::MULSRdRr, Convert__Reg1_0__Reg1_1, AMFBS_SupportsMultiplication, { MCK_LD8, MCK_LD8 }, },
1348
  { 346 /* mulsu */, AVR::MULSURdRr, Convert__Reg1_0__Reg1_1, AMFBS_SupportsMultiplication, { MCK_LD8lo, MCK_LD8lo }, },
1349
  { 352 /* neg */, AVR::NEGRd, Convert__Reg1_0__Tie0_1_1, AMFBS_None, { MCK_GPR8 }, },
1350
  { 356 /* nop */, AVR::NOP, Convert_NoOperands, AMFBS_None, {  }, },
1351
  { 360 /* or */, AVR::ORRdRr, Convert__Reg1_0__Tie0_1_1__Reg1_1, AMFBS_None, { MCK_GPR8, MCK_GPR8 }, },
1352
  { 363 /* ori */, AVR::ORIRdK, Convert__Reg1_0__Tie0_1_1__Imm1_1, AMFBS_None, { MCK_LD8, MCK_Imm }, },
1353
  { 367 /* out */, AVR::OUTARr, Convert__Imm1_0__Reg1_1, AMFBS_None, { MCK_Imm, MCK_GPR8 }, },
1354
  { 371 /* pop */, AVR::POPRd, Convert__Reg1_0, AMFBS_HasSRAM, { MCK_GPR8 }, },
1355
  { 375 /* push */, AVR::PUSHRr, Convert__Reg1_0, AMFBS_HasSRAM, { MCK_GPR8 }, },
1356
  { 380 /* rcall */, AVR::RCALLk, Convert__Imm1_0, AMFBS_None, { MCK_Imm }, },
1357
  { 386 /* ret */, AVR::RET, Convert_NoOperands, AMFBS_None, {  }, },
1358
  { 390 /* reti */, AVR::RETI, Convert_NoOperands, AMFBS_None, {  }, },
1359
  { 395 /* rjmp */, AVR::RJMPk, Convert__Imm1_0, AMFBS_None, { MCK_Imm }, },
1360
  { 400 /* rol */, AVR::ADCRdRr, Convert__Reg1_0__Tie0_1_1__Reg1_0, AMFBS_None, { MCK_GPR8 }, },
1361
  { 404 /* ror */, AVR::RORRd, Convert__Reg1_0__Tie0_1_1, AMFBS_None, { MCK_GPR8 }, },
1362
  { 408 /* sbc */, AVR::SBCRdRr, Convert__Reg1_0__Tie0_1_1__Reg1_1, AMFBS_None, { MCK_GPR8, MCK_GPR8 }, },
1363
  { 412 /* sbci */, AVR::SBCIRdK, Convert__Reg1_0__Tie0_1_1__Imm1_1, AMFBS_None, { MCK_LD8, MCK_Imm }, },
1364
  { 417 /* sbi */, AVR::SBIAb, Convert__Imm1_0__Imm1_1, AMFBS_None, { MCK_Imm, MCK_Imm }, },
1365
  { 421 /* sbic */, AVR::SBICAb, Convert__Imm1_0__Imm1_1, AMFBS_None, { MCK_Imm, MCK_Imm }, },
1366
  { 426 /* sbis */, AVR::SBISAb, Convert__Imm1_0__Imm1_1, AMFBS_None, { MCK_Imm, MCK_Imm }, },
1367
  { 431 /* sbiw */, AVR::SBIWRdK, Convert__Reg1_0__Tie0_1_1__Imm1_1, AMFBS_HasADDSUBIW, { MCK_IWREGS, MCK_Imm }, },
1368
  { 436 /* sbr */, AVR::ORIRdK, Convert__Reg1_0__Tie0_1_1__Imm1_1, AMFBS_None, { MCK_LD8, MCK_Imm }, },
1369
  { 440 /* sbrc */, AVR::SBRCRrB, Convert__Reg1_0__Imm1_1, AMFBS_None, { MCK_GPR8, MCK_Imm }, },
1370
  { 445 /* sbrs */, AVR::SBRSRrB, Convert__Reg1_0__Imm1_1, AMFBS_None, { MCK_GPR8, MCK_Imm }, },
1371
  { 450 /* sec */, AVR::BSETs, Convert__imm_95_0, AMFBS_None, {  }, },
1372
  { 454 /* seh */, AVR::BSETs, Convert__imm_95_5, AMFBS_None, {  }, },
1373
  { 458 /* sei */, AVR::BSETs, Convert__imm_95_7, AMFBS_None, {  }, },
1374
  { 462 /* sen */, AVR::BSETs, Convert__imm_95_2, AMFBS_None, {  }, },
1375
  { 466 /* ser */, AVR::LDIRdK, Convert__Reg1_0__imm_95_255, AMFBS_None, { MCK_LD8 }, },
1376
  { 470 /* ses */, AVR::BSETs, Convert__imm_95_4, AMFBS_None, {  }, },
1377
  { 474 /* set */, AVR::BSETs, Convert__imm_95_6, AMFBS_None, {  }, },
1378
  { 478 /* sev */, AVR::BSETs, Convert__imm_95_3, AMFBS_None, {  }, },
1379
  { 482 /* sez */, AVR::BSETs, Convert__imm_95_1, AMFBS_None, {  }, },
1380
  { 486 /* sleep */, AVR::SLEEP, Convert_NoOperands, AMFBS_None, {  }, },
1381
  { 492 /* spm */, AVR::SPM, Convert_NoOperands, AMFBS_HasSPM, {  }, },
1382
  { 492 /* spm */, AVR::SPMZPi, Convert__Reg1_0, AMFBS_HasSPMX, { MCK_ZREG, MCK__43_ }, },
1383
  { 496 /* st */, AVR::STPtrRr, Convert__Reg1_0__Reg1_1, AMFBS_HasSRAM, { MCK_Reg, MCK_GPR8 }, },
1384
  { 496 /* st */, AVR::STPtrPdRr, Convert__Reg1_1__Tie0_2_2__Reg1_2__imm_95_0, AMFBS_HasSRAM, { MCK__MINUS_, MCK_Reg, MCK_GPR8 }, },
1385
  { 496 /* st */, AVR::STPtrPiRr, Convert__Reg1_0__Tie0_1_1__Reg1_2__imm_95_0, AMFBS_HasSRAM, { MCK_Reg, MCK__43_, MCK_GPR8 }, },
1386
  { 499 /* std */, AVR::STDPtrQRr, Convert__Memri2_0__Reg1_1, AMFBS_HasSRAM_HasNonTinyEncoding, { MCK_Memri, MCK_GPR8 }, },
1387
  { 503 /* sts */, AVR::STSKRrTiny, Convert__Imm1_0__Reg1_1, AMFBS_HasSRAM_HasTinyEncoding, { MCK_Imm, MCK_LD8 }, },
1388
  { 503 /* sts */, AVR::STSKRr, Convert__Imm1_0__Reg1_1, AMFBS_HasSRAM_HasNonTinyEncoding, { MCK_Imm, MCK_GPR8 }, },
1389
  { 507 /* sub */, AVR::SUBRdRr, Convert__Reg1_0__Tie0_1_1__Reg1_1, AMFBS_None, { MCK_GPR8, MCK_GPR8 }, },
1390
  { 511 /* subi */, AVR::SUBIRdK, Convert__Reg1_0__Tie0_1_1__Imm1_1, AMFBS_None, { MCK_LD8, MCK_Imm }, },
1391
  { 516 /* swap */, AVR::SWAPRd, Convert__Reg1_0__Tie0_1_1, AMFBS_None, { MCK_GPR8 }, },
1392
  { 521 /* tst */, AVR::ANDRdRr, Convert__Reg1_0__Tie0_1_1__Reg1_0, AMFBS_None, { MCK_GPR8 }, },
1393
  { 525 /* wdr */, AVR::WDR, Convert_NoOperands, AMFBS_None, {  }, },
1394
  { 529 /* xch */, AVR::XCHZRd, Convert__Reg1_1__Reg1_0, AMFBS_SupportsRMW, { MCK_ZREG, MCK_GPR8 }, },
1395
};
1396
1397
#include "llvm/Support/Debug.h"
1398
#include "llvm/Support/Format.h"
1399
1400
unsigned AVRAsmParser::
1401
MatchInstructionImpl(const OperandVector &Operands,
1402
                     MCInst &Inst,
1403
                     uint64_t &ErrorInfo,
1404
                     FeatureBitset &MissingFeatures,
1405
0
                     bool matchingInlineAsm, unsigned VariantID) {
1406
  // Eliminate obvious mismatches.
1407
0
  if (Operands.size() > 4) {
1408
0
    ErrorInfo = 4;
1409
0
    return Match_InvalidOperand;
1410
0
  }
1411
1412
  // Get the current feature set.
1413
0
  const FeatureBitset &AvailableFeatures = getAvailableFeatures();
1414
1415
  // Get the instruction mnemonic, which is the first token.
1416
0
  StringRef Mnemonic = ((AVROperand &)*Operands[0]).getToken();
1417
1418
  // Some state to try to produce better error messages.
1419
0
  bool HadMatchOtherThanFeatures = false;
1420
0
  bool HadMatchOtherThanPredicate = false;
1421
0
  unsigned RetCode = Match_InvalidOperand;
1422
0
  MissingFeatures.set();
1423
  // Set ErrorInfo to the operand that mismatches if it is
1424
  // wrong for all instances of the instruction.
1425
0
  ErrorInfo = ~0ULL;
1426
  // Find the appropriate table for this asm variant.
1427
0
  const MatchEntry *Start, *End;
1428
0
  switch (VariantID) {
1429
0
  default: llvm_unreachable("invalid variant!");
1430
0
  case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
1431
0
  }
1432
  // Search the table.
1433
0
  auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
1434
1435
0
  DEBUG_WITH_TYPE("asm-matcher", dbgs() << "AsmMatcher: found " <<
1436
0
  std::distance(MnemonicRange.first, MnemonicRange.second) <<
1437
0
  " encodings with mnemonic '" << Mnemonic << "'\n");
1438
1439
  // Return a more specific error code if no mnemonics match.
1440
0
  if (MnemonicRange.first == MnemonicRange.second)
1441
0
    return Match_MnemonicFail;
1442
1443
0
  for (const MatchEntry *it = MnemonicRange.first, *ie = MnemonicRange.second;
1444
0
       it != ie; ++it) {
1445
0
    const FeatureBitset &RequiredFeatures = FeatureBitsets[it->RequiredFeaturesIdx];
1446
0
    bool HasRequiredFeatures =
1447
0
      (AvailableFeatures & RequiredFeatures) == RequiredFeatures;
1448
0
    DEBUG_WITH_TYPE("asm-matcher", dbgs() << "Trying to match opcode "
1449
0
                                          << MII.getName(it->Opcode) << "\n");
1450
    // equal_range guarantees that instruction mnemonic matches.
1451
0
    assert(Mnemonic == it->getMnemonic());
1452
0
    bool OperandsValid = true;
1453
0
    for (unsigned FormalIdx = 0, ActualIdx = 1; FormalIdx != 3; ++FormalIdx) {
1454
0
      auto Formal = static_cast<MatchClassKind>(it->Classes[FormalIdx]);
1455
0
      DEBUG_WITH_TYPE("asm-matcher",
1456
0
                      dbgs() << "  Matching formal operand class " << getMatchClassName(Formal)
1457
0
                             << " against actual operand at index " << ActualIdx);
1458
0
      if (ActualIdx < Operands.size())
1459
0
        DEBUG_WITH_TYPE("asm-matcher", dbgs() << " (";
1460
0
                        Operands[ActualIdx]->print(dbgs()); dbgs() << "): ");
1461
0
      else
1462
0
        DEBUG_WITH_TYPE("asm-matcher", dbgs() << ": ");
1463
0
      if (ActualIdx >= Operands.size()) {
1464
0
        DEBUG_WITH_TYPE("asm-matcher", dbgs() << "actual operand index out of range\n");
1465
0
        if (Formal == InvalidMatchClass) {
1466
0
          break;
1467
0
        }
1468
0
        if (isSubclass(Formal, OptionalMatchClass)) {
1469
0
          continue;
1470
0
        }
1471
0
        OperandsValid = false;
1472
0
        ErrorInfo = ActualIdx;
1473
0
        break;
1474
0
      }
1475
0
      MCParsedAsmOperand &Actual = *Operands[ActualIdx];
1476
0
      unsigned Diag = validateOperandClass(Actual, Formal);
1477
0
      if (Diag == Match_Success) {
1478
0
        DEBUG_WITH_TYPE("asm-matcher",
1479
0
                        dbgs() << "match success using generic matcher\n");
1480
0
        ++ActualIdx;
1481
0
        continue;
1482
0
      }
1483
      // If the generic handler indicates an invalid operand
1484
      // failure, check for a special case.
1485
0
      if (Diag != Match_Success) {
1486
0
        unsigned TargetDiag = validateTargetOperandClass(Actual, Formal);
1487
0
        if (TargetDiag == Match_Success) {
1488
0
          DEBUG_WITH_TYPE("asm-matcher",
1489
0
                          dbgs() << "match success using target matcher\n");
1490
0
          ++ActualIdx;
1491
0
          continue;
1492
0
        }
1493
        // If the target matcher returned a specific error code use
1494
        // that, else use the one from the generic matcher.
1495
0
        if (TargetDiag != Match_InvalidOperand && HasRequiredFeatures)
1496
0
          Diag = TargetDiag;
1497
0
      }
1498
      // If current formal operand wasn't matched and it is optional
1499
      // then try to match next formal operand
1500
0
      if (Diag == Match_InvalidOperand && isSubclass(Formal, OptionalMatchClass)) {
1501
0
        DEBUG_WITH_TYPE("asm-matcher", dbgs() << "ignoring optional operand\n");
1502
0
        continue;
1503
0
      }
1504
      // If this operand is broken for all of the instances of this
1505
      // mnemonic, keep track of it so we can report loc info.
1506
      // If we already had a match that only failed due to a
1507
      // target predicate, that diagnostic is preferred.
1508
0
      if (!HadMatchOtherThanPredicate &&
1509
0
          (it == MnemonicRange.first || ErrorInfo <= ActualIdx)) {
1510
0
        if (HasRequiredFeatures && (ErrorInfo != ActualIdx || Diag != Match_InvalidOperand))
1511
0
          RetCode = Diag;
1512
0
        ErrorInfo = ActualIdx;
1513
0
      }
1514
      // Otherwise, just reject this instance of the mnemonic.
1515
0
      OperandsValid = false;
1516
0
      break;
1517
0
    }
1518
1519
0
    if (!OperandsValid) {
1520
0
      DEBUG_WITH_TYPE("asm-matcher", dbgs() << "Opcode result: multiple "
1521
0
                                               "operand mismatches, ignoring "
1522
0
                                               "this opcode\n");
1523
0
      continue;
1524
0
    }
1525
0
    if (!HasRequiredFeatures) {
1526
0
      HadMatchOtherThanFeatures = true;
1527
0
      FeatureBitset NewMissingFeatures = RequiredFeatures & ~AvailableFeatures;
1528
0
      DEBUG_WITH_TYPE("asm-matcher", dbgs() << "Missing target features:";
1529
0
                      for (unsigned I = 0, E = NewMissingFeatures.size(); I != E; ++I)
1530
0
                        if (NewMissingFeatures[I])
1531
0
                          dbgs() << ' ' << I;
1532
0
                      dbgs() << "\n");
1533
0
      if (NewMissingFeatures.count() <=
1534
0
          MissingFeatures.count())
1535
0
        MissingFeatures = NewMissingFeatures;
1536
0
      continue;
1537
0
    }
1538
1539
0
    Inst.clear();
1540
1541
0
    Inst.setOpcode(it->Opcode);
1542
    // We have a potential match but have not rendered the operands.
1543
    // Check the target predicate to handle any context sensitive
1544
    // constraints.
1545
    // For example, Ties that are referenced multiple times must be
1546
    // checked here to ensure the input is the same for each match
1547
    // constraints. If we leave it any later the ties will have been
1548
    // canonicalized
1549
0
    unsigned MatchResult;
1550
0
    if ((MatchResult = checkEarlyTargetMatchPredicate(Inst, Operands)) != Match_Success) {
1551
0
      Inst.clear();
1552
0
      DEBUG_WITH_TYPE(
1553
0
          "asm-matcher",
1554
0
          dbgs() << "Early target match predicate failed with diag code "
1555
0
                 << MatchResult << "\n");
1556
0
      RetCode = MatchResult;
1557
0
      HadMatchOtherThanPredicate = true;
1558
0
      continue;
1559
0
    }
1560
1561
0
    if (matchingInlineAsm) {
1562
0
      convertToMapAndConstraints(it->ConvertFn, Operands);
1563
0
      if (!checkAsmTiedOperandConstraints(*this, it->ConvertFn, Operands, ErrorInfo))
1564
0
        return Match_InvalidTiedOperand;
1565
1566
0
      return Match_Success;
1567
0
    }
1568
1569
    // We have selected a definite instruction, convert the parsed
1570
    // operands into the appropriate MCInst.
1571
0
    convertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);
1572
1573
    // We have a potential match. Check the target predicate to
1574
    // handle any context sensitive constraints.
1575
0
    if ((MatchResult = checkTargetMatchPredicate(Inst)) != Match_Success) {
1576
0
      DEBUG_WITH_TYPE("asm-matcher",
1577
0
                      dbgs() << "Target match predicate failed with diag code "
1578
0
                             << MatchResult << "\n");
1579
0
      Inst.clear();
1580
0
      RetCode = MatchResult;
1581
0
      HadMatchOtherThanPredicate = true;
1582
0
      continue;
1583
0
    }
1584
1585
0
    if (!checkAsmTiedOperandConstraints(*this, it->ConvertFn, Operands, ErrorInfo))
1586
0
      return Match_InvalidTiedOperand;
1587
1588
0
    DEBUG_WITH_TYPE(
1589
0
        "asm-matcher",
1590
0
        dbgs() << "Opcode result: complete match, selecting this opcode\n");
1591
0
    return Match_Success;
1592
0
  }
1593
1594
  // Okay, we had no match.  Try to return a useful error code.
1595
0
  if (HadMatchOtherThanPredicate || !HadMatchOtherThanFeatures)
1596
0
    return RetCode;
1597
1598
0
  ErrorInfo = 0;
1599
0
  return Match_MissingFeature;
1600
0
}
1601
1602
namespace {
1603
  struct OperandMatchEntry {
1604
    uint16_t Mnemonic;
1605
    uint8_t OperandMask;
1606
    uint8_t Class;
1607
    uint8_t RequiredFeaturesIdx;
1608
1609
0
    StringRef getMnemonic() const {
1610
0
      return StringRef(MnemonicTable + Mnemonic + 1,
1611
0
                       MnemonicTable[Mnemonic]);
1612
0
    }
1613
  };
1614
1615
  // Predicate for searching for an opcode.
1616
  struct LessOpcodeOperand {
1617
0
    bool operator()(const OperandMatchEntry &LHS, StringRef RHS) {
1618
0
      return LHS.getMnemonic()  < RHS;
1619
0
    }
1620
0
    bool operator()(StringRef LHS, const OperandMatchEntry &RHS) {
1621
0
      return LHS < RHS.getMnemonic();
1622
0
    }
1623
0
    bool operator()(const OperandMatchEntry &LHS, const OperandMatchEntry &RHS) {
1624
0
      return LHS.getMnemonic() < RHS.getMnemonic();
1625
0
    }
1626
  };
1627
} // end anonymous namespace
1628
1629
static const OperandMatchEntry OperandMatchTable[2] = {
1630
  /* Operand List Mnemonic, Mask, Operand Class, Features */
1631
  { 304 /* ldd */, 2 /* 1 */, MCK_Memri, AMFBS_HasSRAM_HasNonTinyEncoding },
1632
  { 499 /* std */, 1 /* 0 */, MCK_Memri, AMFBS_HasSRAM_HasNonTinyEncoding },
1633
};
1634
1635
ParseStatus AVRAsmParser::
1636
tryCustomParseOperand(OperandVector &Operands,
1637
0
                      unsigned MCK) {
1638
1639
0
  switch(MCK) {
1640
0
  case MCK_Memri:
1641
0
    return parseMemriOperand(Operands);
1642
0
  default:
1643
0
    return ParseStatus::NoMatch;
1644
0
  }
1645
0
  return ParseStatus::NoMatch;
1646
0
}
1647
1648
ParseStatus AVRAsmParser::
1649
MatchOperandParserImpl(OperandVector &Operands,
1650
                       StringRef Mnemonic,
1651
0
                       bool ParseForAllFeatures) {
1652
  // Get the current feature set.
1653
0
  const FeatureBitset &AvailableFeatures = getAvailableFeatures();
1654
1655
  // Get the next operand index.
1656
0
  unsigned NextOpNum = Operands.size() - 1;
1657
  // Search the table.
1658
0
  auto MnemonicRange =
1659
0
    std::equal_range(std::begin(OperandMatchTable), std::end(OperandMatchTable),
1660
0
                     Mnemonic, LessOpcodeOperand());
1661
1662
0
  if (MnemonicRange.first == MnemonicRange.second)
1663
0
    return ParseStatus::NoMatch;
1664
1665
0
  for (const OperandMatchEntry *it = MnemonicRange.first,
1666
0
       *ie = MnemonicRange.second; it != ie; ++it) {
1667
    // equal_range guarantees that instruction mnemonic matches.
1668
0
    assert(Mnemonic == it->getMnemonic());
1669
1670
    // check if the available features match
1671
0
    const FeatureBitset &RequiredFeatures = FeatureBitsets[it->RequiredFeaturesIdx];
1672
0
    if (!ParseForAllFeatures && (AvailableFeatures & RequiredFeatures) != RequiredFeatures)
1673
0
      continue;
1674
1675
    // check if the operand in question has a custom parser.
1676
0
    if (!(it->OperandMask & (1 << NextOpNum)))
1677
0
      continue;
1678
1679
    // call custom parse method to handle the operand
1680
0
    ParseStatus Result = tryCustomParseOperand(Operands, it->Class);
1681
0
    if (!Result.isNoMatch())
1682
0
      return Result;
1683
0
  }
1684
1685
  // Okay, we had no match.
1686
0
  return ParseStatus::NoMatch;
1687
0
}
1688
1689
#endif // GET_MATCHER_IMPLEMENTATION
1690
1691
1692
#ifdef GET_MNEMONIC_SPELL_CHECKER
1693
#undef GET_MNEMONIC_SPELL_CHECKER
1694
1695
static std::string AVRMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID) {
1696
  const unsigned MaxEditDist = 2;
1697
  std::vector<StringRef> Candidates;
1698
  StringRef Prev = "";
1699
1700
  // Find the appropriate table for this asm variant.
1701
  const MatchEntry *Start, *End;
1702
  switch (VariantID) {
1703
  default: llvm_unreachable("invalid variant!");
1704
  case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
1705
  }
1706
1707
  for (auto I = Start; I < End; I++) {
1708
    // Ignore unsupported instructions.
1709
    const FeatureBitset &RequiredFeatures = FeatureBitsets[I->RequiredFeaturesIdx];
1710
    if ((FBS & RequiredFeatures) != RequiredFeatures)
1711
      continue;
1712
1713
    StringRef T = I->getMnemonic();
1714
    // Avoid recomputing the edit distance for the same string.
1715
    if (T.equals(Prev))
1716
      continue;
1717
1718
    Prev = T;
1719
    unsigned Dist = S.edit_distance(T, false, MaxEditDist);
1720
    if (Dist <= MaxEditDist)
1721
      Candidates.push_back(T);
1722
  }
1723
1724
  if (Candidates.empty())
1725
    return "";
1726
1727
  std::string Res = ", did you mean: ";
1728
  unsigned i = 0;
1729
  for (; i < Candidates.size() - 1; i++)
1730
    Res += Candidates[i].str() + ", ";
1731
  return Res + Candidates[i].str() + "?";
1732
}
1733
1734
#endif // GET_MNEMONIC_SPELL_CHECKER
1735
1736
1737
#ifdef GET_MNEMONIC_CHECKER
1738
#undef GET_MNEMONIC_CHECKER
1739
1740
static bool AVRCheckMnemonic(StringRef Mnemonic,
1741
                                const FeatureBitset &AvailableFeatures,
1742
                                unsigned VariantID) {
1743
  // Find the appropriate table for this asm variant.
1744
  const MatchEntry *Start, *End;
1745
  switch (VariantID) {
1746
  default: llvm_unreachable("invalid variant!");
1747
  case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
1748
  }
1749
1750
  // Search the table.
1751
  auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
1752
1753
  if (MnemonicRange.first == MnemonicRange.second)
1754
    return false;
1755
1756
  for (const MatchEntry *it = MnemonicRange.first, *ie = MnemonicRange.second;
1757
       it != ie; ++it) {
1758
    const FeatureBitset &RequiredFeatures =
1759
      FeatureBitsets[it->RequiredFeaturesIdx];
1760
    if ((AvailableFeatures & RequiredFeatures) == RequiredFeatures)
1761
      return true;
1762
  }
1763
  return false;
1764
}
1765
1766
#endif // GET_MNEMONIC_CHECKER
1767