Line data Source code
1 : /*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
2 : |* *|
3 : |* Assembly Matcher Source Fragment *|
4 : |* *|
5 : |* Automatically generated file, do not edit! *|
6 : |* *|
7 : \*===----------------------------------------------------------------------===*/
8 :
9 :
10 : #ifdef GET_ASSEMBLER_HEADER
11 : #undef GET_ASSEMBLER_HEADER
12 : // This should be included into the middle of the declaration of
13 : // your subclasses implementation of MCTargetAsmParser.
14 : uint64_t ComputeAvailableFeatures(const FeatureBitset& FB) const;
15 : void convertToMCInst(unsigned Kind, MCInst &Inst, unsigned Opcode,
16 : const OperandVector &Operands);
17 : void convertToMapAndConstraints(unsigned Kind,
18 : const OperandVector &Operands) override;
19 : unsigned MatchInstructionImpl(const OperandVector &Operands,
20 : MCInst &Inst,
21 : uint64_t &ErrorInfo, bool matchingInlineAsm,
22 : unsigned VariantID = 0);
23 : #endif // GET_ASSEMBLER_HEADER_INFO
24 :
25 :
26 : #ifdef GET_OPERAND_DIAGNOSTIC_TYPES
27 : #undef GET_OPERAND_DIAGNOSTIC_TYPES
28 :
29 : Match_InvalidSImm12,
30 : END_OPERAND_DIAGNOSTIC_TYPES
31 : #endif // GET_OPERAND_DIAGNOSTIC_TYPES
32 :
33 :
34 : #ifdef GET_REGISTER_MATCHER
35 : #undef GET_REGISTER_MATCHER
36 :
37 : // Flags for subtarget features that participate in instruction matching.
38 : enum SubtargetFeatureFlag : uint8_t {
39 : Feature_None = 0
40 : };
41 :
42 0 : static unsigned MatchRegisterName(StringRef Name) {
43 0 : switch (Name.size()) {
44 : default: break;
45 : case 2: // 10 strings to match.
46 0 : if (Name[0] != 'x')
47 : break;
48 0 : switch (Name[1]) {
49 : default: break;
50 : case '0': // 1 string to match.
51 : return 1; // "x0"
52 : case '1': // 1 string to match.
53 : return 3; // "x1"
54 : case '2': // 1 string to match.
55 : return 5; // "x2"
56 : case '3': // 1 string to match.
57 : return 7; // "x3"
58 : case '4': // 1 string to match.
59 : return 9; // "x4"
60 : case '5': // 1 string to match.
61 : return 11; // "x5"
62 : case '6': // 1 string to match.
63 : return 13; // "x6"
64 : case '7': // 1 string to match.
65 : return 15; // "x7"
66 : case '8': // 1 string to match.
67 : return 17; // "x8"
68 : case '9': // 1 string to match.
69 : return 19; // "x9"
70 : }
71 : break;
72 : case 3: // 22 strings to match.
73 0 : if (Name[0] != 'x')
74 : break;
75 0 : switch (Name[1]) {
76 : default: break;
77 : case '1': // 10 strings to match.
78 0 : switch (Name[2]) {
79 : default: break;
80 : case '0': // 1 string to match.
81 : return 21; // "x10"
82 : case '1': // 1 string to match.
83 : return 23; // "x11"
84 : case '2': // 1 string to match.
85 : return 25; // "x12"
86 : case '3': // 1 string to match.
87 : return 27; // "x13"
88 : case '4': // 1 string to match.
89 : return 29; // "x14"
90 : case '5': // 1 string to match.
91 : return 31; // "x15"
92 : case '6': // 1 string to match.
93 : return 33; // "x16"
94 : case '7': // 1 string to match.
95 : return 35; // "x17"
96 : case '8': // 1 string to match.
97 : return 37; // "x18"
98 : case '9': // 1 string to match.
99 : return 39; // "x19"
100 : }
101 : break;
102 : case '2': // 10 strings to match.
103 0 : switch (Name[2]) {
104 : default: break;
105 : case '0': // 1 string to match.
106 : return 41; // "x20"
107 : case '1': // 1 string to match.
108 : return 43; // "x21"
109 : case '2': // 1 string to match.
110 : return 45; // "x22"
111 : case '3': // 1 string to match.
112 : return 47; // "x23"
113 : case '4': // 1 string to match.
114 : return 49; // "x24"
115 : case '5': // 1 string to match.
116 : return 51; // "x25"
117 : case '6': // 1 string to match.
118 : return 53; // "x26"
119 : case '7': // 1 string to match.
120 : return 55; // "x27"
121 : case '8': // 1 string to match.
122 : return 57; // "x28"
123 : case '9': // 1 string to match.
124 : return 59; // "x29"
125 : }
126 : break;
127 : case '3': // 2 strings to match.
128 0 : switch (Name[2]) {
129 : default: break;
130 : case '0': // 1 string to match.
131 : return 61; // "x30"
132 : case '1': // 1 string to match.
133 0 : return 63; // "x31"
134 : }
135 : break;
136 : }
137 : break;
138 : }
139 : return 0;
140 : }
141 :
142 0 : static unsigned MatchRegisterAltName(StringRef Name) {
143 0 : switch (Name.size()) {
144 : default: break;
145 : case 2: // 29 strings to match.
146 0 : switch (Name[0]) {
147 : default: break;
148 : case 'a': // 8 strings to match.
149 0 : switch (Name[1]) {
150 : default: break;
151 : case '0': // 1 string to match.
152 : return 21; // "a0"
153 : case '1': // 1 string to match.
154 : return 23; // "a1"
155 : case '2': // 1 string to match.
156 : return 25; // "a2"
157 : case '3': // 1 string to match.
158 : return 27; // "a3"
159 : case '4': // 1 string to match.
160 : return 29; // "a4"
161 : case '5': // 1 string to match.
162 : return 31; // "a5"
163 : case '6': // 1 string to match.
164 : return 33; // "a6"
165 : case '7': // 1 string to match.
166 : return 35; // "a7"
167 : }
168 : break;
169 : case 'g': // 1 string to match.
170 0 : if (Name[1] != 'p')
171 : break;
172 : return 7; // "gp"
173 : case 'r': // 1 string to match.
174 0 : if (Name[1] != 'a')
175 : break;
176 : return 3; // "ra"
177 : case 's': // 11 strings to match.
178 0 : switch (Name[1]) {
179 : default: break;
180 : case '0': // 1 string to match.
181 : return 17; // "s0"
182 : case '1': // 1 string to match.
183 : return 19; // "s1"
184 : case '2': // 1 string to match.
185 : return 37; // "s2"
186 : case '3': // 1 string to match.
187 : return 39; // "s3"
188 : case '4': // 1 string to match.
189 : return 41; // "s4"
190 : case '5': // 1 string to match.
191 : return 43; // "s5"
192 : case '6': // 1 string to match.
193 : return 45; // "s6"
194 : case '7': // 1 string to match.
195 : return 47; // "s7"
196 : case '8': // 1 string to match.
197 : return 49; // "s8"
198 : case '9': // 1 string to match.
199 : return 51; // "s9"
200 : case 'p': // 1 string to match.
201 : return 5; // "sp"
202 : }
203 : break;
204 : case 't': // 8 strings to match.
205 0 : switch (Name[1]) {
206 : default: break;
207 : case '0': // 1 string to match.
208 : return 11; // "t0"
209 : case '1': // 1 string to match.
210 : return 13; // "t1"
211 : case '2': // 1 string to match.
212 : return 15; // "t2"
213 : case '3': // 1 string to match.
214 : return 57; // "t3"
215 : case '4': // 1 string to match.
216 : return 59; // "t4"
217 : case '5': // 1 string to match.
218 : return 61; // "t5"
219 : case '6': // 1 string to match.
220 : return 63; // "t6"
221 : case 'p': // 1 string to match.
222 : return 9; // "tp"
223 : }
224 : break;
225 : }
226 : break;
227 : case 3: // 2 strings to match.
228 0 : if (memcmp(Name.data()+0, "s1", 2) != 0)
229 : break;
230 0 : switch (Name[2]) {
231 : default: break;
232 : case '0': // 1 string to match.
233 : return 53; // "s10"
234 : case '1': // 1 string to match.
235 0 : return 55; // "s11"
236 : }
237 : break;
238 : case 4: // 1 string to match.
239 0 : if (memcmp(Name.data()+0, "zero", 4) != 0)
240 : break;
241 : return 1; // "zero"
242 : }
243 : return 0;
244 : }
245 :
246 : #endif // GET_REGISTER_MATCHER
247 :
248 :
249 : #ifdef GET_SUBTARGET_FEATURE_NAME
250 : #undef GET_SUBTARGET_FEATURE_NAME
251 :
252 : // User-level names for subtarget features that participate in
253 : // instruction matching.
254 : static const char *getSubtargetFeatureName(uint64_t Val) {
255 : return "(unknown)";
256 : }
257 :
258 : #endif // GET_SUBTARGET_FEATURE_NAME
259 :
260 :
261 : #ifdef GET_MATCHER_IMPLEMENTATION
262 : #undef GET_MATCHER_IMPLEMENTATION
263 :
264 : namespace {
265 : enum OperatorConversionKind {
266 : CVT_Done,
267 : CVT_Reg,
268 : CVT_Tied,
269 : CVT_95_Reg,
270 : CVT_95_addImmOperands,
271 : CVT_NUM_CONVERTERS
272 : };
273 :
274 : enum InstructionConversionKind {
275 : Convert__Reg1_0__Reg1_1__Reg1_2,
276 : Convert__Reg1_0__Reg1_1__SImm121_2,
277 : CVT_NUM_SIGNATURES
278 : };
279 :
280 : } // end anonymous namespace
281 :
282 : static const uint8_t ConversionTable[CVT_NUM_SIGNATURES][7] = {
283 : // Convert__Reg1_0__Reg1_1__Reg1_2
284 : { CVT_95_Reg, 1, CVT_95_Reg, 2, CVT_95_Reg, 3, CVT_Done },
285 : // Convert__Reg1_0__Reg1_1__SImm121_2
286 : { CVT_95_Reg, 1, CVT_95_Reg, 2, CVT_95_addImmOperands, 3, CVT_Done },
287 : };
288 :
289 0 : void RISCVAsmParser::
290 : convertToMCInst(unsigned Kind, MCInst &Inst, unsigned Opcode,
291 : const OperandVector &Operands) {
292 : assert(Kind < CVT_NUM_SIGNATURES && "Invalid signature!");
293 0 : const uint8_t *Converter = ConversionTable[Kind];
294 : unsigned OpIdx;
295 0 : Inst.setOpcode(Opcode);
296 0 : for (const uint8_t *p = Converter; *p; p+= 2) {
297 0 : OpIdx = *(p + 1);
298 0 : switch (*p) {
299 0 : default: llvm_unreachable("invalid conversion entry!");
300 : case CVT_Reg:
301 0 : static_cast<RISCVOperand&>(*Operands[OpIdx]).addRegOperands(Inst, 1);
302 : break;
303 : case CVT_Tied:
304 0 : Inst.addOperand(Inst.getOperand(OpIdx));
305 : break;
306 : case CVT_95_Reg:
307 0 : static_cast<RISCVOperand&>(*Operands[OpIdx]).addRegOperands(Inst, 1);
308 : break;
309 : case CVT_95_addImmOperands:
310 0 : static_cast<RISCVOperand&>(*Operands[OpIdx]).addImmOperands(Inst, 1);
311 : break;
312 : }
313 : }
314 0 : }
315 :
316 0 : void RISCVAsmParser::
317 : convertToMapAndConstraints(unsigned Kind,
318 : const OperandVector &Operands) {
319 : assert(Kind < CVT_NUM_SIGNATURES && "Invalid signature!");
320 0 : unsigned NumMCOperands = 0;
321 0 : const uint8_t *Converter = ConversionTable[Kind];
322 0 : for (const uint8_t *p = Converter; *p; p+= 2) {
323 0 : switch (*p) {
324 0 : default: llvm_unreachable("invalid conversion entry!");
325 : case CVT_Reg:
326 0 : Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
327 0 : Operands[*(p + 1)]->setConstraint("r");
328 0 : ++NumMCOperands;
329 0 : break;
330 : case CVT_Tied:
331 0 : ++NumMCOperands;
332 0 : break;
333 : case CVT_95_Reg:
334 0 : Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
335 0 : Operands[*(p + 1)]->setConstraint("r");
336 0 : NumMCOperands += 1;
337 0 : break;
338 : case CVT_95_addImmOperands:
339 0 : Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);
340 0 : Operands[*(p + 1)]->setConstraint("m");
341 0 : NumMCOperands += 1;
342 0 : break;
343 : }
344 : }
345 0 : }
346 :
347 : namespace {
348 :
349 : /// MatchClassKind - The kinds of classes which participate in
350 : /// instruction matching.
351 : enum MatchClassKind {
352 : InvalidMatchClass = 0,
353 : OptionalMatchClass = 1,
354 : MCK_GPR, // register class 'GPR'
355 : MCK_GPR64, // register class 'GPR64'
356 : MCK_Imm, // user defined class 'ImmAsmOperand'
357 : MCK_SImm12, // user defined class 'anonymous_633'
358 : NumMatchClassKinds
359 : };
360 :
361 : }
362 :
363 : static MatchClassKind matchTokenString(StringRef Name) {
364 : return InvalidMatchClass;
365 : }
366 :
367 : /// isSubclass - Compute whether \p A is a subclass of \p B.
368 : static bool isSubclass(MatchClassKind A, MatchClassKind B) {
369 0 : if (A == B)
370 : return true;
371 :
372 : return false;
373 : }
374 :
375 0 : static unsigned validateOperandClass(MCParsedAsmOperand &GOp, MatchClassKind Kind) {
376 0 : RISCVOperand &Operand = (RISCVOperand&)GOp;
377 0 : if (Kind == InvalidMatchClass)
378 : return MCTargetAsmParser::Match_InvalidOperand;
379 :
380 0 : if (Operand.isToken())
381 : return isSubclass(matchTokenString(Operand.getToken()), Kind) ?
382 : MCTargetAsmParser::Match_Success :
383 : MCTargetAsmParser::Match_InvalidOperand;
384 :
385 0 : switch (Kind) {
386 : default: break;
387 : // 'Imm' class
388 : case MCK_Imm:
389 0 : if (Operand.isImm())
390 : return MCTargetAsmParser::Match_Success;
391 : break;
392 : // 'SImm12' class
393 : case MCK_SImm12:
394 0 : if (Operand.isSImm12())
395 : return MCTargetAsmParser::Match_Success;
396 0 : return RISCVAsmParser::Match_InvalidSImm12;
397 : } // end switch (Kind)
398 :
399 0 : if (Operand.isReg()) {
400 : MatchClassKind OpKind;
401 0 : switch (Operand.getReg()) {
402 : default: OpKind = InvalidMatchClass; break;
403 : case RISCV::X0_32: OpKind = MCK_GPR; break;
404 : case RISCV::X1_32: OpKind = MCK_GPR; break;
405 : case RISCV::X2_32: OpKind = MCK_GPR; break;
406 : case RISCV::X3_32: OpKind = MCK_GPR; break;
407 : case RISCV::X4_32: OpKind = MCK_GPR; break;
408 : case RISCV::X5_32: OpKind = MCK_GPR; break;
409 : case RISCV::X6_32: OpKind = MCK_GPR; break;
410 : case RISCV::X7_32: OpKind = MCK_GPR; break;
411 : case RISCV::X8_32: OpKind = MCK_GPR; break;
412 : case RISCV::X9_32: OpKind = MCK_GPR; break;
413 : case RISCV::X10_32: OpKind = MCK_GPR; break;
414 : case RISCV::X11_32: OpKind = MCK_GPR; break;
415 : case RISCV::X12_32: OpKind = MCK_GPR; break;
416 : case RISCV::X13_32: OpKind = MCK_GPR; break;
417 : case RISCV::X14_32: OpKind = MCK_GPR; break;
418 : case RISCV::X15_32: OpKind = MCK_GPR; break;
419 : case RISCV::X16_32: OpKind = MCK_GPR; break;
420 : case RISCV::X17_32: OpKind = MCK_GPR; break;
421 : case RISCV::X18_32: OpKind = MCK_GPR; break;
422 : case RISCV::X19_32: OpKind = MCK_GPR; break;
423 : case RISCV::X20_32: OpKind = MCK_GPR; break;
424 : case RISCV::X21_32: OpKind = MCK_GPR; break;
425 : case RISCV::X22_32: OpKind = MCK_GPR; break;
426 : case RISCV::X23_32: OpKind = MCK_GPR; break;
427 : case RISCV::X24_32: OpKind = MCK_GPR; break;
428 : case RISCV::X25_32: OpKind = MCK_GPR; break;
429 : case RISCV::X26_32: OpKind = MCK_GPR; break;
430 : case RISCV::X27_32: OpKind = MCK_GPR; break;
431 : case RISCV::X28_32: OpKind = MCK_GPR; break;
432 : case RISCV::X29_32: OpKind = MCK_GPR; break;
433 : case RISCV::X30_32: OpKind = MCK_GPR; break;
434 : case RISCV::X31_32: OpKind = MCK_GPR; break;
435 : case RISCV::X0_64: OpKind = MCK_GPR64; break;
436 : case RISCV::X1_64: OpKind = MCK_GPR64; break;
437 : case RISCV::X2_64: OpKind = MCK_GPR64; break;
438 : case RISCV::X3_64: OpKind = MCK_GPR64; break;
439 : case RISCV::X4_64: OpKind = MCK_GPR64; break;
440 : case RISCV::X5_64: OpKind = MCK_GPR64; break;
441 : case RISCV::X6_64: OpKind = MCK_GPR64; break;
442 : case RISCV::X7_64: OpKind = MCK_GPR64; break;
443 : case RISCV::X8_64: OpKind = MCK_GPR64; break;
444 : case RISCV::X9_64: OpKind = MCK_GPR64; break;
445 : case RISCV::X10_64: OpKind = MCK_GPR64; break;
446 : case RISCV::X11_64: OpKind = MCK_GPR64; break;
447 : case RISCV::X12_64: OpKind = MCK_GPR64; break;
448 : case RISCV::X13_64: OpKind = MCK_GPR64; break;
449 : case RISCV::X14_64: OpKind = MCK_GPR64; break;
450 : case RISCV::X15_64: OpKind = MCK_GPR64; break;
451 : case RISCV::X16_64: OpKind = MCK_GPR64; break;
452 : case RISCV::X17_64: OpKind = MCK_GPR64; break;
453 : case RISCV::X18_64: OpKind = MCK_GPR64; break;
454 : case RISCV::X19_64: OpKind = MCK_GPR64; break;
455 : case RISCV::X20_64: OpKind = MCK_GPR64; break;
456 : case RISCV::X21_64: OpKind = MCK_GPR64; break;
457 : case RISCV::X22_64: OpKind = MCK_GPR64; break;
458 : case RISCV::X23_64: OpKind = MCK_GPR64; break;
459 : case RISCV::X24_64: OpKind = MCK_GPR64; break;
460 : case RISCV::X25_64: OpKind = MCK_GPR64; break;
461 : case RISCV::X26_64: OpKind = MCK_GPR64; break;
462 : case RISCV::X27_64: OpKind = MCK_GPR64; break;
463 : case RISCV::X28_64: OpKind = MCK_GPR64; break;
464 : case RISCV::X29_64: OpKind = MCK_GPR64; break;
465 : case RISCV::X30_64: OpKind = MCK_GPR64; break;
466 : case RISCV::X31_64: OpKind = MCK_GPR64; break;
467 : }
468 0 : return isSubclass(OpKind, Kind) ? MCTargetAsmParser::Match_Success :
469 : MCTargetAsmParser::Match_InvalidOperand;
470 : }
471 :
472 : return MCTargetAsmParser::Match_InvalidOperand;
473 : }
474 :
475 : uint64_t RISCVAsmParser::
476 : ComputeAvailableFeatures(const FeatureBitset& FB) const {
477 0 : uint64_t Features = 0;
478 : return Features;
479 : }
480 :
481 : static const char *const MnemonicTable =
482 : "\003add\004addi\003and\004andi\002or\003ori\003sll\003slt\004slti\005sl"
483 : "tiu\004sltu\003sra\003srl\003sub\003xor\004xori";
484 :
485 : namespace {
486 : struct MatchEntry {
487 : uint8_t Mnemonic;
488 : uint16_t Opcode;
489 : uint8_t ConvertFn;
490 : uint8_t RequiredFeatures;
491 : uint8_t Classes[3];
492 : StringRef getMnemonic() const {
493 0 : return StringRef(MnemonicTable + Mnemonic + 1,
494 0 : MnemonicTable[Mnemonic]);
495 : }
496 : };
497 :
498 : // Predicate for searching for an opcode.
499 : struct LessOpcode {
500 0 : bool operator()(const MatchEntry &LHS, StringRef RHS) {
501 0 : return LHS.getMnemonic() < RHS;
502 : }
503 0 : bool operator()(StringRef LHS, const MatchEntry &RHS) {
504 0 : return LHS < RHS.getMnemonic();
505 : }
506 : bool operator()(const MatchEntry &LHS, const MatchEntry &RHS) {
507 : return LHS.getMnemonic() < RHS.getMnemonic();
508 : }
509 : };
510 : } // end anonymous namespace.
511 :
512 : static const MatchEntry MatchTable0[] = {
513 : { 0 /* add */, RISCV::ADD, Convert__Reg1_0__Reg1_1__Reg1_2, 0, { MCK_GPR, MCK_GPR, MCK_GPR }, },
514 : { 4 /* addi */, RISCV::ADDI, Convert__Reg1_0__Reg1_1__SImm121_2, 0, { MCK_GPR, MCK_GPR, MCK_SImm12 }, },
515 : { 9 /* and */, RISCV::AND, Convert__Reg1_0__Reg1_1__Reg1_2, 0, { MCK_GPR, MCK_GPR, MCK_GPR }, },
516 : { 13 /* andi */, RISCV::ANDI, Convert__Reg1_0__Reg1_1__SImm121_2, 0, { MCK_GPR, MCK_GPR, MCK_SImm12 }, },
517 : { 18 /* or */, RISCV::OR, Convert__Reg1_0__Reg1_1__Reg1_2, 0, { MCK_GPR, MCK_GPR, MCK_GPR }, },
518 : { 21 /* ori */, RISCV::ORI, Convert__Reg1_0__Reg1_1__SImm121_2, 0, { MCK_GPR, MCK_GPR, MCK_SImm12 }, },
519 : { 25 /* sll */, RISCV::SLL, Convert__Reg1_0__Reg1_1__Reg1_2, 0, { MCK_GPR, MCK_GPR, MCK_GPR }, },
520 : { 29 /* slt */, RISCV::SLT, Convert__Reg1_0__Reg1_1__Reg1_2, 0, { MCK_GPR, MCK_GPR, MCK_GPR }, },
521 : { 33 /* slti */, RISCV::SLTI, Convert__Reg1_0__Reg1_1__SImm121_2, 0, { MCK_GPR, MCK_GPR, MCK_SImm12 }, },
522 : { 38 /* sltiu */, RISCV::SLTIU, Convert__Reg1_0__Reg1_1__SImm121_2, 0, { MCK_GPR, MCK_GPR, MCK_SImm12 }, },
523 : { 44 /* sltu */, RISCV::SLTU, Convert__Reg1_0__Reg1_1__Reg1_2, 0, { MCK_GPR, MCK_GPR, MCK_GPR }, },
524 : { 49 /* sra */, RISCV::SRA, Convert__Reg1_0__Reg1_1__Reg1_2, 0, { MCK_GPR, MCK_GPR, MCK_GPR }, },
525 : { 53 /* srl */, RISCV::SRL, Convert__Reg1_0__Reg1_1__Reg1_2, 0, { MCK_GPR, MCK_GPR, MCK_GPR }, },
526 : { 57 /* sub */, RISCV::SUB, Convert__Reg1_0__Reg1_1__Reg1_2, 0, { MCK_GPR, MCK_GPR, MCK_GPR }, },
527 : { 61 /* xor */, RISCV::XOR, Convert__Reg1_0__Reg1_1__Reg1_2, 0, { MCK_GPR, MCK_GPR, MCK_GPR }, },
528 : { 65 /* xori */, RISCV::XORI, Convert__Reg1_0__Reg1_1__SImm121_2, 0, { MCK_GPR, MCK_GPR, MCK_SImm12 }, },
529 : };
530 :
531 0 : std::string RISCVMnemonicSpellCheck(StringRef S, uint64_t FBS) {
532 0 : const unsigned MaxEditDist = 2;
533 0 : std::vector<StringRef> Candidates;
534 0 : StringRef Prev = "";
535 0 : auto End = std::end(MatchTable0);
536 :
537 0 : for (auto I = std::begin(MatchTable0); I < End; I++) {
538 : // Ignore unsupported instructions.
539 0 : if ((FBS & I->RequiredFeatures) != I->RequiredFeatures)
540 0 : continue;
541 :
542 0 : StringRef T = I->getMnemonic();
543 : // Avoid recomputing the edit distance for the same string.
544 0 : if (T.equals(Prev))
545 : continue;
546 :
547 0 : Prev = T;
548 0 : unsigned Dist = S.edit_distance(T, false, MaxEditDist);
549 0 : if (Dist <= MaxEditDist)
550 0 : Candidates.push_back(T);
551 : }
552 :
553 0 : if (Candidates.empty())
554 0 : return "";
555 :
556 0 : std::string Res = ", did you mean: ";
557 0 : unsigned i = 0;
558 0 : for( ; i < Candidates.size() - 1; i++)
559 0 : Res += Candidates[i].str() + ", ";
560 0 : return Res + Candidates[i].str() + "?";
561 : }
562 :
563 0 : unsigned RISCVAsmParser::
564 : MatchInstructionImpl(const OperandVector &Operands,
565 : MCInst &Inst, uint64_t &ErrorInfo,
566 : bool matchingInlineAsm, unsigned VariantID) {
567 : // Eliminate obvious mismatches.
568 0 : if (Operands.size() > 4) {
569 0 : ErrorInfo = 4;
570 0 : return Match_InvalidOperand;
571 : }
572 :
573 : // Get the current feature set.
574 0 : uint64_t AvailableFeatures = getAvailableFeatures();
575 :
576 : // Get the instruction mnemonic, which is the first token.
577 0 : StringRef Mnemonic = ((RISCVOperand&)*Operands[0]).getToken();
578 :
579 : // Some state to try to produce better error messages.
580 0 : bool HadMatchOtherThanFeatures = false;
581 0 : bool HadMatchOtherThanPredicate = false;
582 0 : unsigned RetCode = Match_InvalidOperand;
583 0 : uint64_t MissingFeatures = ~0ULL;
584 : // Set ErrorInfo to the operand that mismatches if it is
585 : // wrong for all instances of the instruction.
586 0 : ErrorInfo = ~0ULL;
587 : // Find the appropriate table for this asm variant.
588 : const MatchEntry *Start, *End;
589 0 : switch (VariantID) {
590 0 : default: llvm_unreachable("invalid variant!");
591 0 : case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
592 : }
593 : // Search the table.
594 0 : auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
595 :
596 : // Return a more specific error code if no mnemonics match.
597 0 : if (MnemonicRange.first == MnemonicRange.second)
598 : return Match_MnemonicFail;
599 :
600 0 : for (const MatchEntry *it = MnemonicRange.first, *ie = MnemonicRange.second;
601 0 : it != ie; ++it) {
602 : // equal_range guarantees that instruction mnemonic matches.
603 : assert(Mnemonic == it->getMnemonic());
604 : bool OperandsValid = true;
605 0 : for (unsigned FormalIdx = 0, ActualIdx = 1; FormalIdx != 3; ++FormalIdx) {
606 0 : auto Formal = static_cast<MatchClassKind>(it->Classes[FormalIdx]);
607 0 : if (ActualIdx >= Operands.size()) {
608 0 : OperandsValid = (Formal == InvalidMatchClass) || isSubclass(Formal, OptionalMatchClass);
609 0 : if (!OperandsValid) ErrorInfo = ActualIdx;
610 : break;
611 : }
612 0 : MCParsedAsmOperand &Actual = *Operands[ActualIdx];
613 0 : unsigned Diag = validateOperandClass(Actual, Formal);
614 0 : if (Diag == Match_Success) {
615 0 : ++ActualIdx;
616 0 : continue;
617 : }
618 : // If the generic handler indicates an invalid operand
619 : // failure, check for a special case.
620 0 : if (Diag == Match_InvalidOperand) {
621 0 : Diag = validateTargetOperandClass(Actual, Formal);
622 0 : if (Diag == Match_Success) {
623 0 : ++ActualIdx;
624 0 : continue;
625 : }
626 : }
627 : // If current formal operand wasn't matched and it is optional
628 : // then try to match next formal operand
629 0 : if (Diag == Match_InvalidOperand && isSubclass(Formal, OptionalMatchClass)) {
630 : continue;
631 : }
632 : // If this operand is broken for all of the instances of this
633 : // mnemonic, keep track of it so we can report loc info.
634 : // If we already had a match that only failed due to a
635 : // target predicate, that diagnostic is preferred.
636 0 : if (!HadMatchOtherThanPredicate &&
637 0 : (it == MnemonicRange.first || ErrorInfo <= ActualIdx)) {
638 0 : ErrorInfo = ActualIdx;
639 : // InvalidOperand is the default. Prefer specificity.
640 0 : if (Diag != Match_InvalidOperand)
641 0 : RetCode = Diag;
642 : }
643 : // Otherwise, just reject this instance of the mnemonic.
644 : OperandsValid = false;
645 : break;
646 : }
647 :
648 0 : if (!OperandsValid) continue;
649 0 : if ((AvailableFeatures & it->RequiredFeatures) != it->RequiredFeatures) {
650 0 : HadMatchOtherThanFeatures = true;
651 0 : uint64_t NewMissingFeatures = it->RequiredFeatures & ~AvailableFeatures;
652 0 : if (countPopulation(NewMissingFeatures) <=
653 0 : countPopulation(MissingFeatures))
654 0 : MissingFeatures = NewMissingFeatures;
655 : continue;
656 : }
657 :
658 0 : Inst.clear();
659 :
660 0 : Inst.setOpcode(it->Opcode);
661 : // We have a potential match but have not rendered the operands.
662 : // Check the target predicate to handle any context sensitive
663 : // constraints.
664 : // For example, Ties that are referenced multiple times must be
665 : // checked here to ensure the input is the same for each match
666 : // constraints. If we leave it any later the ties will have been
667 : // canonicalized
668 : unsigned MatchResult;
669 0 : if ((MatchResult = checkEarlyTargetMatchPredicate(Inst, Operands)) != Match_Success) {
670 : Inst.clear();
671 : RetCode = MatchResult;
672 : HadMatchOtherThanPredicate = true;
673 : continue;
674 : }
675 :
676 0 : if (matchingInlineAsm) {
677 0 : convertToMapAndConstraints(it->ConvertFn, Operands);
678 0 : return Match_Success;
679 : }
680 :
681 : // We have selected a definite instruction, convert the parsed
682 : // operands into the appropriate MCInst.
683 0 : convertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);
684 :
685 : // We have a potential match. Check the target predicate to
686 : // handle any context sensitive constraints.
687 0 : if ((MatchResult = checkTargetMatchPredicate(Inst)) != Match_Success) {
688 0 : Inst.clear();
689 0 : RetCode = MatchResult;
690 0 : HadMatchOtherThanPredicate = true;
691 0 : continue;
692 : }
693 :
694 : return Match_Success;
695 : }
696 :
697 : // Okay, we had no match. Try to return a useful error code.
698 0 : if (HadMatchOtherThanPredicate || !HadMatchOtherThanFeatures)
699 : return RetCode;
700 :
701 : // Missing feature matches return which features were missing
702 0 : ErrorInfo = MissingFeatures;
703 0 : return Match_MissingFeature;
704 : }
705 :
706 : #endif // GET_MATCHER_IMPLEMENTATION
707 :
|