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