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