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