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 switch (A) {
633 default:
634 return false;
635
636 case MCK_Reg1:
637 return B == MCK_GPR;
638 }
639}
640
641static unsigned validateOperandClass(MCParsedAsmOperand &GOp, MatchClassKind Kind) {
642 LanaiOperand &Operand = (LanaiOperand &)GOp;
643 if (Kind == InvalidMatchClass)
644 return MCTargetAsmParser::Match_InvalidOperand;
645
646 if (Operand.isToken() && Kind <= MCK_LAST_TOKEN)
647 return isSubclass(matchTokenString(Operand.getToken()), Kind) ?
648 MCTargetAsmParser::Match_Success :
649 MCTargetAsmParser::Match_InvalidOperand;
650
651 switch (Kind) {
652 default: break;
653 // 'BrTarget' class
654 case MCK_BrTarget: {
655 DiagnosticPredicate DP(Operand.isBrTarget());
656 if (DP.isMatch())
657 return MCTargetAsmParser::Match_Success;
658 break;
659 }
660 // 'CallTarget' class
661 case MCK_CallTarget: {
662 DiagnosticPredicate DP(Operand.isCallTarget());
663 if (DP.isMatch())
664 return MCTargetAsmParser::Match_Success;
665 break;
666 }
667 // 'CondCode' class
668 case MCK_CondCode: {
669 DiagnosticPredicate DP(Operand.isCondCode());
670 if (DP.isMatch())
671 return MCTargetAsmParser::Match_Success;
672 break;
673 }
674 // 'HiImm16And' class
675 case MCK_HiImm16And: {
676 DiagnosticPredicate DP(Operand.isHiImm16And());
677 if (DP.isMatch())
678 return MCTargetAsmParser::Match_Success;
679 break;
680 }
681 // 'HiImm16' class
682 case MCK_HiImm16: {
683 DiagnosticPredicate DP(Operand.isHiImm16());
684 if (DP.isMatch())
685 return MCTargetAsmParser::Match_Success;
686 break;
687 }
688 // 'Imm10' class
689 case MCK_Imm10: {
690 DiagnosticPredicate DP(Operand.isImm10());
691 if (DP.isMatch())
692 return MCTargetAsmParser::Match_Success;
693 break;
694 }
695 // 'Imm' class
696 case MCK_Imm: {
697 DiagnosticPredicate DP(Operand.isImm());
698 if (DP.isMatch())
699 return MCTargetAsmParser::Match_Success;
700 break;
701 }
702 // 'ImmShift' class
703 case MCK_ImmShift: {
704 DiagnosticPredicate DP(Operand.isImmShift());
705 if (DP.isMatch())
706 return MCTargetAsmParser::Match_Success;
707 break;
708 }
709 // 'LoImm16And' class
710 case MCK_LoImm16And: {
711 DiagnosticPredicate DP(Operand.isLoImm16And());
712 if (DP.isMatch())
713 return MCTargetAsmParser::Match_Success;
714 break;
715 }
716 // 'LoImm16' class
717 case MCK_LoImm16: {
718 DiagnosticPredicate DP(Operand.isLoImm16());
719 if (DP.isMatch())
720 return MCTargetAsmParser::Match_Success;
721 break;
722 }
723 // 'LoImm21' class
724 case MCK_LoImm21: {
725 DiagnosticPredicate DP(Operand.isLoImm21());
726 if (DP.isMatch())
727 return MCTargetAsmParser::Match_Success;
728 break;
729 }
730 // 'MemImm' class
731 case MCK_MemImm: {
732 DiagnosticPredicate DP(Operand.isMemImm());
733 if (DP.isMatch())
734 return MCTargetAsmParser::Match_Success;
735 break;
736 }
737 // 'MemRegImm' class
738 case MCK_MemRegImm: {
739 DiagnosticPredicate DP(Operand.isMemRegImm());
740 if (DP.isMatch())
741 return MCTargetAsmParser::Match_Success;
742 break;
743 }
744 // 'MemRegReg' class
745 case MCK_MemRegReg: {
746 DiagnosticPredicate DP(Operand.isMemRegReg());
747 if (DP.isMatch())
748 return MCTargetAsmParser::Match_Success;
749 break;
750 }
751 // 'MemSpls' class
752 case MCK_MemSpls: {
753 DiagnosticPredicate DP(Operand.isMemSpls());
754 if (DP.isMatch())
755 return MCTargetAsmParser::Match_Success;
756 break;
757 }
758 } // end switch (Kind)
759
760 if (Operand.isReg()) {
761 MatchClassKind OpKind;
762 switch (Operand.getReg().id()) {
763 default: OpKind = InvalidMatchClass; break;
764 case Lanai::R0: OpKind = MCK_GPR; break;
765 case Lanai::R1: OpKind = MCK_GPR; break;
766 case Lanai::R2: OpKind = MCK_GPR; break;
767 case Lanai::R3: OpKind = MCK_GPR; break;
768 case Lanai::R4: OpKind = MCK_GPR; break;
769 case Lanai::R5: OpKind = MCK_GPR; break;
770 case Lanai::R6: OpKind = MCK_GPR; break;
771 case Lanai::R7: OpKind = MCK_GPR; break;
772 case Lanai::R8: OpKind = MCK_GPR; break;
773 case Lanai::R9: OpKind = MCK_GPR; break;
774 case Lanai::R10: OpKind = MCK_GPR; break;
775 case Lanai::R11: OpKind = MCK_GPR; break;
776 case Lanai::R12: OpKind = MCK_GPR; break;
777 case Lanai::R13: OpKind = MCK_GPR; break;
778 case Lanai::R14: OpKind = MCK_GPR; break;
779 case Lanai::R15: OpKind = MCK_GPR; break;
780 case Lanai::R16: OpKind = MCK_GPR; break;
781 case Lanai::R17: OpKind = MCK_GPR; break;
782 case Lanai::R18: OpKind = MCK_GPR; break;
783 case Lanai::R19: OpKind = MCK_GPR; break;
784 case Lanai::R20: OpKind = MCK_GPR; break;
785 case Lanai::R21: OpKind = MCK_GPR; break;
786 case Lanai::R22: OpKind = MCK_GPR; break;
787 case Lanai::R23: OpKind = MCK_GPR; break;
788 case Lanai::R24: OpKind = MCK_GPR; break;
789 case Lanai::R25: OpKind = MCK_GPR; break;
790 case Lanai::R26: OpKind = MCK_GPR; break;
791 case Lanai::R27: OpKind = MCK_GPR; break;
792 case Lanai::R28: OpKind = MCK_GPR; break;
793 case Lanai::R29: OpKind = MCK_GPR; break;
794 case Lanai::R30: OpKind = MCK_GPR; break;
795 case Lanai::R31: OpKind = MCK_GPR; break;
796 case Lanai::PC: OpKind = MCK_Reg1; break;
797 case Lanai::SP: OpKind = MCK_Reg1; break;
798 case Lanai::FP: OpKind = MCK_Reg1; break;
799 case Lanai::RV: OpKind = MCK_Reg1; break;
800 case Lanai::RR1: OpKind = MCK_Reg1; break;
801 case Lanai::RR2: OpKind = MCK_Reg1; break;
802 case Lanai::RCA: OpKind = MCK_Reg1; break;
803 case Lanai::SR: OpKind = MCK_CCR; break;
804 }
805 return isSubclass(OpKind, Kind) ? (unsigned)MCTargetAsmParser::Match_Success :
806 getDiagKindFromRegisterClass(Kind);
807 }
808
809 if (Kind > MCK_LAST_TOKEN && Kind <= MCK_LAST_REGISTER)
810 return getDiagKindFromRegisterClass(Kind);
811
812 return MCTargetAsmParser::Match_InvalidOperand;
813}
814
815#ifndef NDEBUG
816const char *getMatchClassName(MatchClassKind Kind) {
817 switch (Kind) {
818 case InvalidMatchClass: return "InvalidMatchClass";
819 case OptionalMatchClass: return "OptionalMatchClass";
820 case MCK__EXCLAIM_: return "MCK__EXCLAIM_";
821 case MCK__PCT_fp: return "MCK__PCT_fp";
822 case MCK__PCT_pc: return "MCK__PCT_pc";
823 case MCK__MINUS_4: return "MCK__MINUS_4";
824 case MCK__DOT_r: return "MCK__DOT_r";
825 case MCK__91_: return "MCK__91_";
826 case MCK__93_: return "MCK__93_";
827 case MCK_add: return "MCK_add";
828 case MCK_return: return "MCK_return";
829 case MCK_CCR: return "MCK_CCR";
830 case MCK_Reg1: return "MCK_Reg1";
831 case MCK_GPR: return "MCK_GPR";
832 case MCK_BrTarget: return "MCK_BrTarget";
833 case MCK_CallTarget: return "MCK_CallTarget";
834 case MCK_CondCode: return "MCK_CondCode";
835 case MCK_HiImm16And: return "MCK_HiImm16And";
836 case MCK_HiImm16: return "MCK_HiImm16";
837 case MCK_Imm10: return "MCK_Imm10";
838 case MCK_Imm: return "MCK_Imm";
839 case MCK_ImmShift: return "MCK_ImmShift";
840 case MCK_LoImm16And: return "MCK_LoImm16And";
841 case MCK_LoImm16: return "MCK_LoImm16";
842 case MCK_LoImm21: return "MCK_LoImm21";
843 case MCK_MemImm: return "MCK_MemImm";
844 case MCK_MemRegImm: return "MCK_MemRegImm";
845 case MCK_MemRegReg: return "MCK_MemRegReg";
846 case MCK_MemSpls: return "MCK_MemSpls";
847 case NumMatchClassKinds: return "NumMatchClassKinds";
848 }
849 llvm_unreachable("unhandled MatchClassKind!");
850}
851
852#endif // NDEBUG
853FeatureBitset LanaiAsmParser::
854ComputeAvailableFeatures(const FeatureBitset &FB) const {
855 FeatureBitset Features;
856 return Features;
857}
858
859static bool checkAsmTiedOperandConstraints(const LanaiAsmParser&AsmParser,
860 unsigned Kind, const OperandVector &Operands,
861 uint64_t &ErrorInfo) {
862 assert(Kind < CVT_NUM_SIGNATURES && "Invalid signature!");
863 const uint8_t *Converter = ConversionTable[Kind];
864 for (const uint8_t *p = Converter; *p; p += 2) {
865 switch (*p) {
866 case CVT_Tied: {
867 unsigned OpIdx = *(p + 1);
868 assert(OpIdx < (size_t)(std::end(TiedAsmOperandTable) -
869 std::begin(TiedAsmOperandTable)) &&
870 "Tied operand not found");
871 unsigned OpndNum1 = TiedAsmOperandTable[OpIdx][1];
872 unsigned OpndNum2 = TiedAsmOperandTable[OpIdx][2];
873 if (OpndNum1 != OpndNum2) {
874 auto &SrcOp1 = Operands[OpndNum1];
875 auto &SrcOp2 = Operands[OpndNum2];
876 if (!AsmParser.areEqualRegs(*SrcOp1, *SrcOp2)) {
877 ErrorInfo = OpndNum2;
878 return false;
879 }
880 }
881 break;
882 }
883 default:
884 break;
885 }
886 }
887 return true;
888}
889
890static const char MnemonicTable[] =
891 "\021#adjcallstackdown\017#adjcallstackup\014#adjdynalloc\003add\005add."
892 "f\004addc\006addc.f\003and\005and.f\001b\002bt\002ld\004ld.b\004ld.h\005"
893 "leadz\005log_0\005log_1\005log_2\005log_3\005log_4\003mov\003nop\002or\004"
894 "or.f\004popc\001s\004sel.\002sh\004sh.f\003sha\005sha.f\002st\004st.b\004"
895 "st.h\003sub\005sub.f\004subb\006subb.f\006trailz\003uld\005uld.b\005uld"
896 ".h\003xor\005xor.f";
897
898// Feature bitsets.
899enum : uint8_t {
900 AMFBS_None,
901};
902
903static constexpr FeatureBitset FeatureBitsets[] = {
904 {}, // AMFBS_None
905};
906
907namespace {
908 struct MatchEntry {
909 uint8_t Mnemonic;
910 uint16_t Opcode;
911 uint8_t ConvertFn;
912 uint8_t RequiredFeaturesIdx;
913 uint8_t Classes[7];
914 StringRef getMnemonic() const {
915 return StringRef(MnemonicTable + Mnemonic + 1,
916 MnemonicTable[Mnemonic]);
917 }
918 };
919
920 // Predicate for searching for an opcode.
921 struct LessOpcode {
922 bool operator()(const MatchEntry &LHS, StringRef RHS) {
923 return LHS.getMnemonic() < RHS;
924 }
925 bool operator()(StringRef LHS, const MatchEntry &RHS) {
926 return LHS < RHS.getMnemonic();
927 }
928 bool operator()(const MatchEntry &LHS, const MatchEntry &RHS) {
929 return LHS.getMnemonic() < RHS.getMnemonic();
930 }
931 };
932} // end anonymous namespace
933
934static const MatchEntry MatchTable0[] = {
935 { 0 /* #ADJCALLSTACKDOWN */, Lanai::ADJCALLSTACKDOWN, Convert__Imm1_0__Imm1_1, AMFBS_None, { MCK_Imm, MCK_Imm }, },
936 { 18 /* #ADJCALLSTACKUP */, Lanai::ADJCALLSTACKUP, Convert__Imm1_0__Imm1_1, AMFBS_None, { MCK_Imm, MCK_Imm }, },
937 { 34 /* #ADJDYNALLOC */, Lanai::ADJDYNALLOC, Convert__Reg1_0__Reg1_1, AMFBS_None, { MCK_GPR, MCK_GPR }, },
938 { 47 /* add */, Lanai::ADD_I_HI, Convert__Reg1_2__Reg1_0__HiImm161_1, AMFBS_None, { MCK_GPR, MCK_HiImm16, MCK_GPR }, },
939 { 47 /* add */, Lanai::ADD_I_LO, Convert__Reg1_2__Reg1_0__LoImm161_1, AMFBS_None, { MCK_GPR, MCK_LoImm16, MCK_GPR }, },
940 { 47 /* add */, Lanai::ADD_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
941 { 51 /* add.f */, Lanai::ADD_F_I_HI, Convert__Reg1_2__Reg1_0__HiImm161_1, AMFBS_None, { MCK_GPR, MCK_HiImm16, MCK_GPR }, },
942 { 51 /* add.f */, Lanai::ADD_F_I_LO, Convert__Reg1_2__Reg1_0__LoImm161_1, AMFBS_None, { MCK_GPR, MCK_LoImm16, MCK_GPR }, },
943 { 51 /* add.f */, Lanai::ADD_F_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
944 { 57 /* addc */, Lanai::ADDC_I_HI, Convert__Reg1_2__Reg1_0__HiImm161_1, AMFBS_None, { MCK_GPR, MCK_HiImm16, MCK_GPR }, },
945 { 57 /* addc */, Lanai::ADDC_I_LO, Convert__Reg1_2__Reg1_0__LoImm161_1, AMFBS_None, { MCK_GPR, MCK_LoImm16, MCK_GPR }, },
946 { 57 /* addc */, Lanai::ADDC_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
947 { 62 /* addc.f */, Lanai::ADDC_F_I_HI, Convert__Reg1_2__Reg1_0__HiImm161_1, AMFBS_None, { MCK_GPR, MCK_HiImm16, MCK_GPR }, },
948 { 62 /* addc.f */, Lanai::ADDC_F_I_LO, Convert__Reg1_2__Reg1_0__LoImm161_1, AMFBS_None, { MCK_GPR, MCK_LoImm16, MCK_GPR }, },
949 { 62 /* addc.f */, Lanai::ADDC_F_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
950 { 69 /* and */, Lanai::AND_I_HI, Convert__Reg1_2__Reg1_0__HiImm16And1_1, AMFBS_None, { MCK_GPR, MCK_HiImm16And, MCK_GPR }, },
951 { 69 /* and */, Lanai::AND_I_LO, Convert__Reg1_2__Reg1_0__LoImm16And1_1, AMFBS_None, { MCK_GPR, MCK_LoImm16And, MCK_GPR }, },
952 { 69 /* and */, Lanai::AND_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
953 { 73 /* and.f */, Lanai::AND_F_I_HI, Convert__Reg1_2__Reg1_0__HiImm16And1_1, AMFBS_None, { MCK_GPR, MCK_HiImm16And, MCK_GPR }, },
954 { 73 /* and.f */, Lanai::AND_F_I_LO, Convert__Reg1_2__Reg1_0__LoImm16And1_1, AMFBS_None, { MCK_GPR, MCK_LoImm16And, MCK_GPR }, },
955 { 73 /* and.f */, Lanai::AND_F_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
956 { 79 /* b */, Lanai::BRIND_CC, Convert__Reg1_1__Imm1_0, AMFBS_None, { MCK_Imm, MCK_GPR }, },
957 { 79 /* b */, Lanai::BRCC, Convert__BrTarget1_1__Imm1_0, AMFBS_None, { MCK_Imm, MCK_BrTarget }, },
958 { 79 /* b */, Lanai::BRR, Convert__Imm1_2__Imm1_0, AMFBS_None, { MCK_Imm, MCK__DOT_r, MCK_Imm }, },
959 { 79 /* b */, Lanai::BRIND_CCA, Convert__Reg1_1__Reg1_3__Imm1_0, AMFBS_None, { MCK_Imm, MCK_GPR, MCK_add, MCK_GPR }, },
960 { 81 /* bt */, Lanai::JR, Convert__Reg1_0, AMFBS_None, { MCK_GPR }, },
961 { 81 /* bt */, Lanai::BT, Convert__BrTarget1_0, AMFBS_None, { MCK_BrTarget }, },
962 { 84 /* ld */, Lanai::LDADDR, Convert__Reg1_1__MemImm1_0, AMFBS_None, { MCK_MemImm, MCK_GPR }, },
963 { 84 /* ld */, Lanai::LDW_RI, Convert__Reg1_1__MemRegImm3_0, AMFBS_None, { MCK_MemRegImm, MCK_GPR }, },
964 { 84 /* ld */, Lanai::LDW_RR, Convert__Reg1_1__MemRegReg3_0, AMFBS_None, { MCK_MemRegReg, MCK_GPR }, },
965 { 84 /* ld */, Lanai::RET, Convert_NoOperands, AMFBS_None, { MCK__MINUS_4, MCK__91_, MCK__PCT_fp, MCK__93_, MCK__PCT_pc, MCK__EXCLAIM_, MCK_return }, },
966 { 87 /* ld.b */, Lanai::LDBs_RR, Convert__Reg1_1__MemRegReg3_0, AMFBS_None, { MCK_MemRegReg, MCK_GPR }, },
967 { 87 /* ld.b */, Lanai::LDBs_RI, Convert__Reg1_1__MemSpls3_0, AMFBS_None, { MCK_MemSpls, MCK_GPR }, },
968 { 92 /* ld.h */, Lanai::LDHs_RR, Convert__Reg1_1__MemRegReg3_0, AMFBS_None, { MCK_MemRegReg, MCK_GPR }, },
969 { 92 /* ld.h */, Lanai::LDHs_RI, Convert__Reg1_1__MemSpls3_0, AMFBS_None, { MCK_MemSpls, MCK_GPR }, },
970 { 97 /* leadz */, Lanai::LEADZ, Convert__Reg1_1__Reg1_0, AMFBS_None, { MCK_GPR, MCK_GPR }, },
971 { 103 /* log_0 */, Lanai::LOG0, Convert_NoOperands, AMFBS_None, { }, },
972 { 109 /* log_1 */, Lanai::LOG1, Convert_NoOperands, AMFBS_None, { }, },
973 { 115 /* log_2 */, Lanai::LOG2, Convert_NoOperands, AMFBS_None, { }, },
974 { 121 /* log_3 */, Lanai::LOG3, Convert_NoOperands, AMFBS_None, { }, },
975 { 127 /* log_4 */, Lanai::LOG4, Convert_NoOperands, AMFBS_None, { }, },
976 { 133 /* mov */, Lanai::ADD_R, Convert__Reg1_1__Reg1_0__regR0__imm_95_0, AMFBS_None, { MCK_GPR, MCK_GPR }, },
977 { 133 /* mov */, Lanai::AND_I_HI, Convert__Reg1_1__regR1__HiImm16And1_0, AMFBS_None, { MCK_HiImm16And, MCK_GPR }, },
978 { 133 /* mov */, Lanai::ADD_I_HI, Convert__Reg1_1__regR0__HiImm161_0, AMFBS_None, { MCK_HiImm16, MCK_GPR }, },
979 { 133 /* mov */, Lanai::AND_I_LO, Convert__Reg1_1__regR1__LoImm16And1_0, AMFBS_None, { MCK_LoImm16And, MCK_GPR }, },
980 { 133 /* mov */, Lanai::ADD_I_LO, Convert__Reg1_1__regR0__LoImm161_0, AMFBS_None, { MCK_LoImm16, MCK_GPR }, },
981 { 133 /* mov */, Lanai::SLI, Convert__Reg1_1__LoImm211_0, AMFBS_None, { MCK_LoImm21, MCK_GPR }, },
982 { 137 /* nop */, Lanai::NOP, Convert_NoOperands, AMFBS_None, { }, },
983 { 141 /* or */, Lanai::OR_I_HI, Convert__Reg1_2__Reg1_0__HiImm161_1, AMFBS_None, { MCK_GPR, MCK_HiImm16, MCK_GPR }, },
984 { 141 /* or */, Lanai::OR_I_LO, Convert__Reg1_2__Reg1_0__LoImm161_1, AMFBS_None, { MCK_GPR, MCK_LoImm16, MCK_GPR }, },
985 { 141 /* or */, Lanai::OR_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
986 { 144 /* or.f */, Lanai::OR_F_I_HI, Convert__Reg1_2__Reg1_0__HiImm161_1, AMFBS_None, { MCK_GPR, MCK_HiImm16, MCK_GPR }, },
987 { 144 /* or.f */, Lanai::OR_F_I_LO, Convert__Reg1_2__Reg1_0__LoImm161_1, AMFBS_None, { MCK_GPR, MCK_LoImm16, MCK_GPR }, },
988 { 144 /* or.f */, Lanai::OR_F_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
989 { 149 /* popc */, Lanai::POPC, Convert__Reg1_1__Reg1_0, AMFBS_None, { MCK_GPR, MCK_GPR }, },
990 { 154 /* s */, Lanai::SCC, Convert__Reg1_1__Imm1_0, AMFBS_None, { MCK_Imm, MCK_GPR }, },
991 { 156 /* sel. */, Lanai::SELECT, Convert__Reg1_3__Reg1_1__Reg1_2__Imm1_0, AMFBS_None, { MCK_Imm, MCK_GPR, MCK_GPR, MCK_GPR }, },
992 { 161 /* sh */, Lanai::SL_I, Convert__Reg1_2__Reg1_0__ImmShift1_1, AMFBS_None, { MCK_GPR, MCK_ImmShift, MCK_GPR }, },
993 { 161 /* sh */, Lanai::SHL_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
994 { 164 /* sh.f */, Lanai::SL_F_I, Convert__Reg1_2__Reg1_0__ImmShift1_1, AMFBS_None, { MCK_GPR, MCK_ImmShift, MCK_GPR }, },
995 { 164 /* sh.f */, Lanai::SHL_F_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
996 { 169 /* sha */, Lanai::SA_I, Convert__Reg1_2__Reg1_0__ImmShift1_1, AMFBS_None, { MCK_GPR, MCK_ImmShift, MCK_GPR }, },
997 { 169 /* sha */, Lanai::SRA_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
998 { 173 /* sha.f */, Lanai::SA_F_I, Convert__Reg1_2__Reg1_0__ImmShift1_1, AMFBS_None, { MCK_GPR, MCK_ImmShift, MCK_GPR }, },
999 { 173 /* sha.f */, Lanai::SRA_F_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
1000 { 179 /* st */, Lanai::STADDR, Convert__Reg1_0__MemImm1_1, AMFBS_None, { MCK_GPR, MCK_MemImm }, },
1001 { 179 /* st */, Lanai::SW_RI, Convert__Reg1_0__MemRegImm3_1, AMFBS_None, { MCK_GPR, MCK_MemRegImm }, },
1002 { 179 /* st */, Lanai::SW_RR, Convert__Reg1_0__MemRegReg3_1, AMFBS_None, { MCK_GPR, MCK_MemRegReg }, },
1003 { 182 /* st.b */, Lanai::STB_RR, Convert__Reg1_0__MemRegReg3_1, AMFBS_None, { MCK_GPR, MCK_MemRegReg }, },
1004 { 182 /* st.b */, Lanai::STB_RI, Convert__Reg1_0__MemSpls3_1, AMFBS_None, { MCK_GPR, MCK_MemSpls }, },
1005 { 187 /* st.h */, Lanai::STH_RR, Convert__Reg1_0__MemRegReg3_1, AMFBS_None, { MCK_GPR, MCK_MemRegReg }, },
1006 { 187 /* st.h */, Lanai::STH_RI, Convert__Reg1_0__MemSpls3_1, AMFBS_None, { MCK_GPR, MCK_MemSpls }, },
1007 { 192 /* sub */, Lanai::SUB_I_HI, Convert__Reg1_2__Reg1_0__HiImm161_1, AMFBS_None, { MCK_GPR, MCK_HiImm16, MCK_GPR }, },
1008 { 192 /* sub */, Lanai::SUB_I_LO, Convert__Reg1_2__Reg1_0__LoImm161_1, AMFBS_None, { MCK_GPR, MCK_LoImm16, MCK_GPR }, },
1009 { 192 /* sub */, Lanai::SUB_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
1010 { 196 /* sub.f */, Lanai::SUB_F_I_HI, Convert__Reg1_2__Reg1_0__HiImm161_1, AMFBS_None, { MCK_GPR, MCK_HiImm16, MCK_GPR }, },
1011 { 196 /* sub.f */, Lanai::SUB_F_I_LO, Convert__Reg1_2__Reg1_0__LoImm161_1, AMFBS_None, { MCK_GPR, MCK_LoImm16, MCK_GPR }, },
1012 { 196 /* sub.f */, Lanai::SUB_F_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
1013 { 202 /* subb */, Lanai::SUBB_I_HI, Convert__Reg1_2__Reg1_0__HiImm161_1, AMFBS_None, { MCK_GPR, MCK_HiImm16, MCK_GPR }, },
1014 { 202 /* subb */, Lanai::SUBB_I_LO, Convert__Reg1_2__Reg1_0__LoImm161_1, AMFBS_None, { MCK_GPR, MCK_LoImm16, MCK_GPR }, },
1015 { 202 /* subb */, Lanai::SUBB_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
1016 { 207 /* subb.f */, Lanai::SUBB_F_I_HI, Convert__Reg1_2__Reg1_0__HiImm161_1, AMFBS_None, { MCK_GPR, MCK_HiImm16, MCK_GPR }, },
1017 { 207 /* subb.f */, Lanai::SUBB_F_I_LO, Convert__Reg1_2__Reg1_0__LoImm161_1, AMFBS_None, { MCK_GPR, MCK_LoImm16, MCK_GPR }, },
1018 { 207 /* subb.f */, Lanai::SUBB_F_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
1019 { 214 /* trailz */, Lanai::TRAILZ, Convert__Reg1_1__Reg1_0, AMFBS_None, { MCK_GPR, MCK_GPR }, },
1020 { 221 /* uld */, Lanai::LDW_RI, Convert__Reg1_1__MemRegImm3_0, AMFBS_None, { MCK_MemRegImm, MCK_GPR }, },
1021 { 221 /* uld */, Lanai::LDWz_RR, Convert__Reg1_1__MemRegReg3_0, AMFBS_None, { MCK_MemRegReg, MCK_GPR }, },
1022 { 225 /* uld.b */, Lanai::LDBz_RR, Convert__Reg1_1__MemRegReg3_0, AMFBS_None, { MCK_MemRegReg, MCK_GPR }, },
1023 { 225 /* uld.b */, Lanai::LDBz_RI, Convert__Reg1_1__MemSpls3_0, AMFBS_None, { MCK_MemSpls, MCK_GPR }, },
1024 { 231 /* uld.h */, Lanai::LDHz_RR, Convert__Reg1_1__MemRegReg3_0, AMFBS_None, { MCK_MemRegReg, MCK_GPR }, },
1025 { 231 /* uld.h */, Lanai::LDHz_RI, Convert__Reg1_1__MemSpls3_0, AMFBS_None, { MCK_MemSpls, MCK_GPR }, },
1026 { 237 /* xor */, Lanai::XOR_I_HI, Convert__Reg1_2__Reg1_0__HiImm161_1, AMFBS_None, { MCK_GPR, MCK_HiImm16, MCK_GPR }, },
1027 { 237 /* xor */, Lanai::XOR_I_LO, Convert__Reg1_2__Reg1_0__LoImm161_1, AMFBS_None, { MCK_GPR, MCK_LoImm16, MCK_GPR }, },
1028 { 237 /* xor */, Lanai::XOR_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
1029 { 241 /* xor.f */, Lanai::XOR_F_I_HI, Convert__Reg1_2__Reg1_0__HiImm161_1, AMFBS_None, { MCK_GPR, MCK_HiImm16, MCK_GPR }, },
1030 { 241 /* xor.f */, Lanai::XOR_F_I_LO, Convert__Reg1_2__Reg1_0__LoImm161_1, AMFBS_None, { MCK_GPR, MCK_LoImm16, MCK_GPR }, },
1031 { 241 /* xor.f */, Lanai::XOR_F_R, Convert__Reg1_3__Reg1_1__Reg1_2__CondCode1_0, AMFBS_None, { MCK_CondCode, MCK_GPR, MCK_GPR, MCK_GPR }, },
1032};
1033
1034#include "llvm/Support/Debug.h"
1035#include "llvm/Support/Format.h"
1036
1037unsigned LanaiAsmParser::
1038MatchInstructionImpl(const OperandVector &Operands,
1039 MCInst &Inst,
1040 uint64_t &ErrorInfo,
1041 FeatureBitset &MissingFeatures,
1042 bool matchingInlineAsm, unsigned VariantID) {
1043 // Eliminate obvious mismatches.
1044 if (Operands.size() > 8) {
1045 ErrorInfo = 8;
1046 return Match_InvalidOperand;
1047 }
1048
1049 // Get the current feature set.
1050 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
1051
1052 // Get the instruction mnemonic, which is the first token.
1053 StringRef Mnemonic = ((LanaiOperand &)*Operands[0]).getToken();
1054
1055 // Some state to try to produce better error messages.
1056 bool HadMatchOtherThanFeatures = false;
1057 bool HadMatchOtherThanPredicate = false;
1058 unsigned RetCode = Match_InvalidOperand;
1059 MissingFeatures.set();
1060 // Set ErrorInfo to the operand that mismatches if it is
1061 // wrong for all instances of the instruction.
1062 ErrorInfo = ~0ULL;
1063 // Find the appropriate table for this asm variant.
1064 const MatchEntry *Start, *End;
1065 switch (VariantID) {
1066 default: llvm_unreachable("invalid variant!");
1067 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
1068 }
1069 // Search the table.
1070 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
1071
1072 DEBUG_WITH_TYPE("asm-matcher", dbgs() << "AsmMatcher: found " <<
1073 std::distance(MnemonicRange.first, MnemonicRange.second) <<
1074 " encodings with mnemonic '" << Mnemonic << "'\n");
1075
1076 // Return a more specific error code if no mnemonics match.
1077 if (MnemonicRange.first == MnemonicRange.second)
1078 return Match_MnemonicFail;
1079
1080 for (const MatchEntry *it = MnemonicRange.first, *ie = MnemonicRange.second;
1081 it != ie; ++it) {
1082 const FeatureBitset &RequiredFeatures = FeatureBitsets[it->RequiredFeaturesIdx];
1083 bool HasRequiredFeatures =
1084 (AvailableFeatures & RequiredFeatures) == RequiredFeatures;
1085 DEBUG_WITH_TYPE("asm-matcher", dbgs() << "Trying to match opcode "
1086 << MII.getName(it->Opcode) << "\n");
1087 // equal_range guarantees that instruction mnemonic matches.
1088 assert(Mnemonic == it->getMnemonic());
1089 bool OperandsValid = true;
1090 for (unsigned FormalIdx = 0, ActualIdx = 1; FormalIdx != 7; ++FormalIdx) {
1091 auto Formal = static_cast<MatchClassKind>(it->Classes[FormalIdx]);
1092 DEBUG_WITH_TYPE("asm-matcher",
1093 dbgs() << " Matching formal operand class " << getMatchClassName(Formal)
1094 << " against actual operand at index " << ActualIdx);
1095 if (ActualIdx < Operands.size())
1096 DEBUG_WITH_TYPE("asm-matcher", dbgs() << " (";
1097 Operands[ActualIdx]->print(dbgs()); dbgs() << "): ");
1098 else
1099 DEBUG_WITH_TYPE("asm-matcher", dbgs() << ": ");
1100 if (ActualIdx >= Operands.size()) {
1101 DEBUG_WITH_TYPE("asm-matcher", dbgs() << "actual operand index out of range\n");
1102 if (Formal == InvalidMatchClass) {
1103 break;
1104 }
1105 if (isSubclass(Formal, OptionalMatchClass)) {
1106 continue;
1107 }
1108 OperandsValid = false;
1109 ErrorInfo = ActualIdx;
1110 break;
1111 }
1112 MCParsedAsmOperand &Actual = *Operands[ActualIdx];
1113 unsigned Diag = validateOperandClass(Actual, Formal);
1114 if (Diag == Match_Success) {
1115 DEBUG_WITH_TYPE("asm-matcher",
1116 dbgs() << "match success using generic matcher\n");
1117 ++ActualIdx;
1118 continue;
1119 }
1120 // If the generic handler indicates an invalid operand
1121 // failure, check for a special case.
1122 if (Diag != Match_Success) {
1123 unsigned TargetDiag = validateTargetOperandClass(Actual, Formal);
1124 if (TargetDiag == Match_Success) {
1125 DEBUG_WITH_TYPE("asm-matcher",
1126 dbgs() << "match success using target matcher\n");
1127 ++ActualIdx;
1128 continue;
1129 }
1130 // If the target matcher returned a specific error code use
1131 // that, else use the one from the generic matcher.
1132 if (TargetDiag != Match_InvalidOperand && HasRequiredFeatures)
1133 Diag = TargetDiag;
1134 }
1135 // If current formal operand wasn't matched and it is optional
1136 // then try to match next formal operand
1137 if (Diag == Match_InvalidOperand && isSubclass(Formal, OptionalMatchClass)) {
1138 DEBUG_WITH_TYPE("asm-matcher", dbgs() << "ignoring optional operand\n");
1139 continue;
1140 }
1141 // If this operand is broken for all of the instances of this
1142 // mnemonic, keep track of it so we can report loc info.
1143 // If we already had a match that only failed due to a
1144 // target predicate, that diagnostic is preferred.
1145 if (!HadMatchOtherThanPredicate &&
1146 (it == MnemonicRange.first || ErrorInfo <= ActualIdx)) {
1147 if (HasRequiredFeatures && (ErrorInfo != ActualIdx || Diag != Match_InvalidOperand))
1148 RetCode = Diag;
1149 ErrorInfo = ActualIdx;
1150 }
1151 // Otherwise, just reject this instance of the mnemonic.
1152 OperandsValid = false;
1153 break;
1154 }
1155
1156 if (!OperandsValid) {
1157 DEBUG_WITH_TYPE("asm-matcher", dbgs() << "Opcode result: multiple "
1158 "operand mismatches, ignoring "
1159 "this opcode\n");
1160 continue;
1161 }
1162 if (!HasRequiredFeatures) {
1163 HadMatchOtherThanFeatures = true;
1164 FeatureBitset NewMissingFeatures = RequiredFeatures & ~AvailableFeatures;
1165 DEBUG_WITH_TYPE("asm-matcher", dbgs() << "Missing target features:";
1166 for (unsigned I = 0, E = NewMissingFeatures.size(); I != E; ++I)
1167 if (NewMissingFeatures[I])
1168 dbgs() << ' ' << I;
1169 dbgs() << "\n");
1170 if (NewMissingFeatures.count() <=
1171 MissingFeatures.count())
1172 MissingFeatures = NewMissingFeatures;
1173 continue;
1174 }
1175
1176 Inst.clear();
1177
1178 Inst.setOpcode(it->Opcode);
1179 // We have a potential match but have not rendered the operands.
1180 // Check the target predicate to handle any context sensitive
1181 // constraints.
1182 // For example, Ties that are referenced multiple times must be
1183 // checked here to ensure the input is the same for each match
1184 // constraints. If we leave it any later the ties will have been
1185 // canonicalized
1186 unsigned MatchResult;
1187 if ((MatchResult = checkEarlyTargetMatchPredicate(Inst, Operands)) != Match_Success) {
1188 Inst.clear();
1189 DEBUG_WITH_TYPE(
1190 "asm-matcher",
1191 dbgs() << "Early target match predicate failed with diag code "
1192 << MatchResult << "\n");
1193 RetCode = MatchResult;
1194 HadMatchOtherThanPredicate = true;
1195 continue;
1196 }
1197
1198 if (matchingInlineAsm) {
1199 convertToMapAndConstraints(it->ConvertFn, Operands);
1200 if (!checkAsmTiedOperandConstraints(*this, it->ConvertFn, Operands,
1201 ErrorInfo))
1202 return Match_InvalidTiedOperand;
1203
1204 return Match_Success;
1205 }
1206
1207 // We have selected a definite instruction, convert the parsed
1208 // operands into the appropriate MCInst.
1209 convertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);
1210
1211 // We have a potential match. Check the target predicate to
1212 // handle any context sensitive constraints.
1213 if ((MatchResult = checkTargetMatchPredicate(Inst)) != Match_Success) {
1214 DEBUG_WITH_TYPE("asm-matcher",
1215 dbgs() << "Target match predicate failed with diag code "
1216 << MatchResult << "\n");
1217 Inst.clear();
1218 RetCode = MatchResult;
1219 HadMatchOtherThanPredicate = true;
1220 continue;
1221 }
1222
1223 if (!checkAsmTiedOperandConstraints(*this, it->ConvertFn, Operands,
1224 ErrorInfo))
1225 return Match_InvalidTiedOperand;
1226
1227 DEBUG_WITH_TYPE(
1228 "asm-matcher",
1229 dbgs() << "Opcode result: complete match, selecting this opcode\n");
1230 return Match_Success;
1231 }
1232
1233 // Okay, we had no match. Try to return a useful error code.
1234 if (HadMatchOtherThanPredicate || !HadMatchOtherThanFeatures)
1235 return RetCode;
1236
1237 ErrorInfo = 0;
1238 return Match_MissingFeature;
1239}
1240
1241namespace {
1242 struct OperandMatchEntry {
1243 uint8_t Mnemonic;
1244 uint8_t OperandMask;
1245 uint8_t Class;
1246 uint8_t RequiredFeaturesIdx;
1247
1248 StringRef getMnemonic() const {
1249 return StringRef(MnemonicTable + Mnemonic + 1,
1250 MnemonicTable[Mnemonic]);
1251 }
1252 };
1253
1254 // Predicate for searching for an opcode.
1255 struct LessOpcodeOperand {
1256 bool operator()(const OperandMatchEntry &LHS, StringRef RHS) {
1257 return LHS.getMnemonic() < RHS;
1258 }
1259 bool operator()(StringRef LHS, const OperandMatchEntry &RHS) {
1260 return LHS < RHS.getMnemonic();
1261 }
1262 bool operator()(const OperandMatchEntry &LHS, const OperandMatchEntry &RHS) {
1263 return LHS.getMnemonic() < RHS.getMnemonic();
1264 }
1265 };
1266} // end anonymous namespace
1267
1268static const OperandMatchEntry OperandMatchTable[20] = {
1269 /* Operand List Mnemonic, Mask, Operand Class, Features */
1270 { 84 /* ld */, 1 /* 0 */, MCK_MemImm, AMFBS_None },
1271 { 84 /* ld */, 1 /* 0 */, MCK_MemRegImm, AMFBS_None },
1272 { 84 /* ld */, 1 /* 0 */, MCK_MemRegReg, AMFBS_None },
1273 { 87 /* ld.b */, 1 /* 0 */, MCK_MemRegReg, AMFBS_None },
1274 { 87 /* ld.b */, 1 /* 0 */, MCK_MemSpls, AMFBS_None },
1275 { 92 /* ld.h */, 1 /* 0 */, MCK_MemRegReg, AMFBS_None },
1276 { 92 /* ld.h */, 1 /* 0 */, MCK_MemSpls, AMFBS_None },
1277 { 179 /* st */, 2 /* 1 */, MCK_MemImm, AMFBS_None },
1278 { 179 /* st */, 2 /* 1 */, MCK_MemRegImm, AMFBS_None },
1279 { 179 /* st */, 2 /* 1 */, MCK_MemRegReg, AMFBS_None },
1280 { 182 /* st.b */, 2 /* 1 */, MCK_MemRegReg, AMFBS_None },
1281 { 182 /* st.b */, 2 /* 1 */, MCK_MemSpls, AMFBS_None },
1282 { 187 /* st.h */, 2 /* 1 */, MCK_MemRegReg, AMFBS_None },
1283 { 187 /* st.h */, 2 /* 1 */, MCK_MemSpls, AMFBS_None },
1284 { 221 /* uld */, 1 /* 0 */, MCK_MemRegImm, AMFBS_None },
1285 { 221 /* uld */, 1 /* 0 */, MCK_MemRegReg, AMFBS_None },
1286 { 225 /* uld.b */, 1 /* 0 */, MCK_MemRegReg, AMFBS_None },
1287 { 225 /* uld.b */, 1 /* 0 */, MCK_MemSpls, AMFBS_None },
1288 { 231 /* uld.h */, 1 /* 0 */, MCK_MemRegReg, AMFBS_None },
1289 { 231 /* uld.h */, 1 /* 0 */, MCK_MemSpls, AMFBS_None },
1290};
1291
1292ParseStatus LanaiAsmParser::
1293tryCustomParseOperand(OperandVector &Operands,
1294 unsigned MCK) {
1295
1296 switch(MCK) {
1297 case MCK_MemImm:
1298 return parseMemoryOperand(Operands);
1299 case MCK_MemRegImm:
1300 return parseMemoryOperand(Operands);
1301 case MCK_MemRegReg:
1302 return parseMemoryOperand(Operands);
1303 case MCK_MemSpls:
1304 return parseMemoryOperand(Operands);
1305 default:
1306 return ParseStatus::NoMatch;
1307 }
1308 return ParseStatus::NoMatch;
1309}
1310
1311ParseStatus LanaiAsmParser::
1312MatchOperandParserImpl(OperandVector &Operands,
1313 StringRef Mnemonic,
1314 bool ParseForAllFeatures) {
1315 // Get the current feature set.
1316 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
1317
1318 // Get the next operand index.
1319 unsigned NextOpNum = Operands.size() - 1;
1320 // Search the table.
1321 auto MnemonicRange =
1322 std::equal_range(std::begin(OperandMatchTable), std::end(OperandMatchTable),
1323 Mnemonic, LessOpcodeOperand());
1324
1325 if (MnemonicRange.first == MnemonicRange.second)
1326 return ParseStatus::NoMatch;
1327
1328 for (const OperandMatchEntry *it = MnemonicRange.first,
1329 *ie = MnemonicRange.second; it != ie; ++it) {
1330 // equal_range guarantees that instruction mnemonic matches.
1331 assert(Mnemonic == it->getMnemonic());
1332
1333 // check if the available features match
1334 const FeatureBitset &RequiredFeatures = FeatureBitsets[it->RequiredFeaturesIdx];
1335 if (!ParseForAllFeatures && (AvailableFeatures & RequiredFeatures) != RequiredFeatures)
1336 continue;
1337
1338 // check if the operand in question has a custom parser.
1339 if (!(it->OperandMask & (1 << NextOpNum)))
1340 continue;
1341
1342 // call custom parse method to handle the operand
1343 ParseStatus Result = tryCustomParseOperand(Operands, it->Class);
1344 if (!Result.isNoMatch())
1345 return Result;
1346 }
1347
1348 // Okay, we had no match.
1349 return ParseStatus::NoMatch;
1350}
1351
1352#endif // GET_MATCHER_IMPLEMENTATION
1353
1354
1355#ifdef GET_MNEMONIC_SPELL_CHECKER
1356#undef GET_MNEMONIC_SPELL_CHECKER
1357
1358static std::string LanaiMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID) {
1359 const unsigned MaxEditDist = 2;
1360 std::vector<StringRef> Candidates;
1361 StringRef Prev = "";
1362
1363 // Find the appropriate table for this asm variant.
1364 const MatchEntry *Start, *End;
1365 switch (VariantID) {
1366 default: llvm_unreachable("invalid variant!");
1367 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
1368 }
1369
1370 for (auto I = Start; I < End; I++) {
1371 // Ignore unsupported instructions.
1372 const FeatureBitset &RequiredFeatures = FeatureBitsets[I->RequiredFeaturesIdx];
1373 if ((FBS & RequiredFeatures) != RequiredFeatures)
1374 continue;
1375
1376 StringRef T = I->getMnemonic();
1377 // Avoid recomputing the edit distance for the same string.
1378 if (T == Prev)
1379 continue;
1380
1381 Prev = T;
1382 unsigned Dist = S.edit_distance(T, false, MaxEditDist);
1383 if (Dist <= MaxEditDist)
1384 Candidates.push_back(T);
1385 }
1386
1387 if (Candidates.empty())
1388 return "";
1389
1390 std::string Res = ", did you mean: ";
1391 unsigned i = 0;
1392 for (; i < Candidates.size() - 1; i++)
1393 Res += Candidates[i].str() + ", ";
1394 return Res + Candidates[i].str() + "?";
1395}
1396
1397#endif // GET_MNEMONIC_SPELL_CHECKER
1398
1399
1400#ifdef GET_MNEMONIC_CHECKER
1401#undef GET_MNEMONIC_CHECKER
1402
1403static bool LanaiCheckMnemonic(StringRef Mnemonic,
1404 const FeatureBitset &AvailableFeatures,
1405 unsigned VariantID) {
1406 // Find the appropriate table for this asm variant.
1407 const MatchEntry *Start, *End;
1408 switch (VariantID) {
1409 default: llvm_unreachable("invalid variant!");
1410 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
1411 }
1412
1413 // Search the table.
1414 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
1415
1416 if (MnemonicRange.first == MnemonicRange.second)
1417 return false;
1418
1419 for (const MatchEntry *it = MnemonicRange.first, *ie = MnemonicRange.second;
1420 it != ie; ++it) {
1421 const FeatureBitset &RequiredFeatures =
1422 FeatureBitsets[it->RequiredFeaturesIdx];
1423 if ((AvailableFeatures & RequiredFeatures) == RequiredFeatures)
1424 return true;
1425 }
1426 return false;
1427}
1428
1429#endif // GET_MNEMONIC_CHECKER
1430
1431