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