1 //===---- CSKYAsmParser.cpp - Parse CSKY assembly to MCInst instructions --===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "MCTargetDesc/CSKYInstPrinter.h"
10 #include "MCTargetDesc/CSKYMCExpr.h"
11 #include "MCTargetDesc/CSKYMCTargetDesc.h"
12 #include "TargetInfo/CSKYTargetInfo.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/ADT/Statistic.h"
15 #include "llvm/ADT/StringSwitch.h"
16 #include "llvm/BinaryFormat/ELF.h"
17 #include "llvm/CodeGen/Register.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCInstrInfo.h"
22 #include "llvm/MC/MCParser/MCAsmLexer.h"
23 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
24 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
25 #include "llvm/MC/MCRegisterInfo.h"
26 #include "llvm/MC/MCSectionELF.h"
27 #include "llvm/MC/MCStreamer.h"
28 #include "llvm/MC/MCSubtargetInfo.h"
29 #include "llvm/MC/TargetRegistry.h"
30 #include "llvm/Support/Casting.h"
31 #include "llvm/Support/CommandLine.h"
32 #include "llvm/Support/Debug.h"
33 
34 using namespace llvm;
35 
36 #define DEBUG_TYPE "csky-asm-parser"
37 
38 // Include the auto-generated portion of the compress emitter.
39 #define GEN_COMPRESS_INSTR
40 #include "CSKYGenCompressInstEmitter.inc"
41 
42 STATISTIC(CSKYNumInstrsCompressed,
43           "Number of C-SKY Compressed instructions emitted");
44 
45 static cl::opt<bool>
46     EnableCompressedInst("enable-csky-asm-compressed-inst", cl::Hidden,
47                          cl::init(false),
48                          cl::desc("Enable C-SKY asm compressed instruction"));
49 
50 namespace {
51 struct CSKYOperand;
52 
53 class CSKYAsmParser : public MCTargetAsmParser {
54 
55   const MCRegisterInfo *MRI;
56 
57   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
58                                       unsigned Kind) override;
59 
60   bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,
61                                   int64_t Lower, int64_t Upper, Twine Msg);
62 
63   SMLoc getLoc() const { return getParser().getTok().getLoc(); }
64 
65   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
66                                OperandVector &Operands, MCStreamer &Out,
67                                uint64_t &ErrorInfo,
68                                bool MatchingInlineAsm) override;
69 
70   bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
71 
72   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
73                         SMLoc NameLoc, OperandVector &Operands) override;
74 
75   bool ParseDirective(AsmToken DirectiveID) override;
76 
77   // Helper to actually emit an instruction to the MCStreamer. Also, when
78   // possible, compression of the instruction is performed.
79   void emitToStreamer(MCStreamer &S, const MCInst &Inst);
80 
81   OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc,
82                                         SMLoc &EndLoc) override;
83 
84   bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands,
85                           MCStreamer &Out);
86 
87 // Auto-generated instruction matching functions
88 #define GET_ASSEMBLER_HEADER
89 #include "CSKYGenAsmMatcher.inc"
90 
91   OperandMatchResultTy parseImmediate(OperandVector &Operands);
92   OperandMatchResultTy parseRegister(OperandVector &Operands);
93   OperandMatchResultTy parseBaseRegImm(OperandVector &Operands);
94   OperandMatchResultTy parseCSKYSymbol(OperandVector &Operands);
95   OperandMatchResultTy parseConstpoolSymbol(OperandVector &Operands);
96   OperandMatchResultTy parseDataSymbol(OperandVector &Operands);
97   OperandMatchResultTy parsePSRFlag(OperandVector &Operands);
98   OperandMatchResultTy parseRegSeq(OperandVector &Operands);
99   OperandMatchResultTy parseRegList(OperandVector &Operands);
100 
101   bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
102 
103 public:
104   enum CSKYMatchResultTy {
105     Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
106     Match_RequiresSameSrcAndDst,
107     Match_InvalidRegOutOfRange,
108 #define GET_OPERAND_DIAGNOSTIC_TYPES
109 #include "CSKYGenAsmMatcher.inc"
110 #undef GET_OPERAND_DIAGNOSTIC_TYPES
111   };
112 
113   CSKYAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
114                 const MCInstrInfo &MII, const MCTargetOptions &Options)
115       : MCTargetAsmParser(Options, STI, MII) {
116     setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
117   }
118 };
119 
120 /// Instances of this class represent a parsed machine instruction.
121 struct CSKYOperand : public MCParsedAsmOperand {
122 
123   enum KindTy {
124     Token,
125     Register,
126     Immediate,
127     RegisterSeq,
128     CPOP,
129     RegisterList
130   } Kind;
131 
132   struct RegOp {
133     unsigned RegNum;
134   };
135 
136   struct ImmOp {
137     const MCExpr *Val;
138   };
139 
140   struct ConstpoolOp {
141     const MCExpr *Val;
142   };
143 
144   struct RegSeqOp {
145     unsigned RegNumFrom;
146     unsigned RegNumTo;
147   };
148 
149   struct RegListOp {
150     unsigned List1From = 0;
151     unsigned List1To = 0;
152     unsigned List2From = 0;
153     unsigned List2To = 0;
154     unsigned List3From = 0;
155     unsigned List3To = 0;
156     unsigned List4From = 0;
157     unsigned List4To = 0;
158   };
159 
160   SMLoc StartLoc, EndLoc;
161   union {
162     StringRef Tok;
163     RegOp Reg;
164     ImmOp Imm;
165     ConstpoolOp CPool;
166     RegSeqOp RegSeq;
167     RegListOp RegList;
168   };
169 
170   CSKYOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
171 
172 public:
173   CSKYOperand(const CSKYOperand &o) : MCParsedAsmOperand() {
174     Kind = o.Kind;
175     StartLoc = o.StartLoc;
176     EndLoc = o.EndLoc;
177     switch (Kind) {
178     case Register:
179       Reg = o.Reg;
180       break;
181     case RegisterSeq:
182       RegSeq = o.RegSeq;
183       break;
184     case CPOP:
185       CPool = o.CPool;
186       break;
187     case Immediate:
188       Imm = o.Imm;
189       break;
190     case Token:
191       Tok = o.Tok;
192       break;
193     case RegisterList:
194       RegList = o.RegList;
195       break;
196     }
197   }
198 
199   bool isToken() const override { return Kind == Token; }
200   bool isReg() const override { return Kind == Register; }
201   bool isImm() const override { return Kind == Immediate; }
202   bool isRegisterSeq() const { return Kind == RegisterSeq; }
203   bool isRegisterList() const { return Kind == RegisterList; }
204   bool isConstPoolOp() const { return Kind == CPOP; }
205 
206   bool isMem() const override { return false; }
207 
208   static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm) {
209     if (auto CE = dyn_cast<MCConstantExpr>(Expr)) {
210       Imm = CE->getValue();
211       return true;
212     }
213 
214     return false;
215   }
216 
217   template <unsigned num, unsigned shift = 0> bool isUImm() const {
218     if (!isImm())
219       return false;
220 
221     int64_t Imm;
222     bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
223     return IsConstantImm && isShiftedUInt<num, shift>(Imm);
224   }
225 
226   template <unsigned num> bool isOImm() const {
227     if (!isImm())
228       return false;
229 
230     int64_t Imm;
231     bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
232     return IsConstantImm && isUInt<num>(Imm - 1);
233   }
234 
235   template <unsigned num, unsigned shift = 0> bool isSImm() const {
236     if (!isImm())
237       return false;
238 
239     int64_t Imm;
240     bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
241     return IsConstantImm && isShiftedInt<num, shift>(Imm);
242   }
243 
244   bool isUImm1() const { return isUImm<1>(); }
245   bool isUImm2() const { return isUImm<2>(); }
246   bool isUImm3() const { return isUImm<3>(); }
247   bool isUImm4() const { return isUImm<4>(); }
248   bool isUImm5() const { return isUImm<5>(); }
249   bool isUImm6() const { return isUImm<6>(); }
250   bool isUImm7() const { return isUImm<7>(); }
251   bool isUImm8() const { return isUImm<8>(); }
252   bool isUImm12() const { return isUImm<12>(); }
253   bool isUImm16() const { return isUImm<16>(); }
254   bool isUImm20() const { return isUImm<20>(); }
255   bool isUImm24() const { return isUImm<24>(); }
256 
257   bool isOImm3() const { return isOImm<3>(); }
258   bool isOImm4() const { return isOImm<4>(); }
259   bool isOImm5() const { return isOImm<5>(); }
260   bool isOImm6() const { return isOImm<6>(); }
261   bool isOImm8() const { return isOImm<8>(); }
262   bool isOImm12() const { return isOImm<12>(); }
263   bool isOImm16() const { return isOImm<16>(); }
264 
265   bool isSImm8() const { return isSImm<8>(); }
266 
267   bool isUImm5Shift1() { return isUImm<5, 1>(); }
268   bool isUImm5Shift2() { return isUImm<5, 2>(); }
269   bool isUImm7Shift1() { return isUImm<7, 1>(); }
270   bool isUImm7Shift2() { return isUImm<7, 2>(); }
271   bool isUImm7Shift3() { return isUImm<7, 3>(); }
272   bool isUImm8Shift2() { return isUImm<8, 2>(); }
273   bool isUImm8Shift3() { return isUImm<8, 3>(); }
274   bool isUImm8Shift8() { return isUImm<8, 8>(); }
275   bool isUImm8Shift16() { return isUImm<8, 16>(); }
276   bool isUImm8Shift24() { return isUImm<8, 24>(); }
277   bool isUImm12Shift1() { return isUImm<12, 1>(); }
278   bool isUImm12Shift2() { return isUImm<12, 2>(); }
279   bool isUImm16Shift8() { return isUImm<16, 8>(); }
280   bool isUImm16Shift16() { return isUImm<16, 16>(); }
281   bool isUImm24Shift8() { return isUImm<24, 8>(); }
282 
283   bool isSImm16Shift1() { return isSImm<16, 1>(); }
284 
285   bool isCSKYSymbol() const { return isImm(); }
286 
287   bool isConstpool() const { return isConstPoolOp(); }
288   bool isDataSymbol() const { return isConstPoolOp(); }
289 
290   bool isPSRFlag() const {
291     int64_t Imm;
292     // Must be of 'immediate' type and a constant.
293     if (!isImm() || !evaluateConstantImm(getImm(), Imm))
294       return false;
295 
296     return isUInt<5>(Imm);
297   }
298 
299   template <unsigned MIN, unsigned MAX> bool isRegSeqTemplate() const {
300     if (!isRegisterSeq())
301       return false;
302 
303     std::pair<unsigned, unsigned> regSeq = getRegSeq();
304 
305     return MIN <= regSeq.first && regSeq.first <= regSeq.second &&
306            regSeq.second <= MAX;
307   }
308 
309   bool isRegSeq() const { return isRegSeqTemplate<CSKY::R0, CSKY::R31>(); }
310 
311   bool isRegSeqV1() const {
312     return isRegSeqTemplate<CSKY::F0_32, CSKY::F15_32>();
313   }
314 
315   bool isRegSeqV2() const {
316     return isRegSeqTemplate<CSKY::F0_32, CSKY::F31_32>();
317   }
318 
319   static bool isLegalRegList(unsigned from, unsigned to) {
320     if (from == 0 && to == 0)
321       return true;
322 
323     if (from == to) {
324       if (from != CSKY::R4 && from != CSKY::R15 && from != CSKY::R16 &&
325           from != CSKY::R28)
326         return false;
327 
328       return true;
329     } else {
330       if (from != CSKY::R4 && from != CSKY::R16)
331         return false;
332 
333       if (from == CSKY::R4 && to > CSKY::R4 && to < CSKY::R12)
334         return true;
335       else if (from == CSKY::R16 && to > CSKY::R16 && to < CSKY::R18)
336         return true;
337       else
338         return false;
339     }
340   }
341 
342   bool isRegList() const {
343     if (!isRegisterList())
344       return false;
345 
346     auto regList = getRegList();
347 
348     if (!isLegalRegList(regList.List1From, regList.List1To))
349       return false;
350     if (!isLegalRegList(regList.List2From, regList.List2To))
351       return false;
352     if (!isLegalRegList(regList.List3From, regList.List3To))
353       return false;
354     if (!isLegalRegList(regList.List4From, regList.List4To))
355       return false;
356 
357     return true;
358   }
359 
360   bool isExtImm6() {
361     if (!isImm())
362       return false;
363 
364     int64_t Imm;
365     bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
366     if (!IsConstantImm)
367       return false;
368 
369     int uimm4 = Imm & 0xf;
370 
371     return isShiftedUInt<6, 0>(Imm) && uimm4 >= 0 && uimm4 <= 14;
372   }
373 
374   /// Gets location of the first token of this operand.
375   SMLoc getStartLoc() const override { return StartLoc; }
376   /// Gets location of the last token of this operand.
377   SMLoc getEndLoc() const override { return EndLoc; }
378 
379   unsigned getReg() const override {
380     assert(Kind == Register && "Invalid type access!");
381     return Reg.RegNum;
382   }
383 
384   std::pair<unsigned, unsigned> getRegSeq() const {
385     assert(Kind == RegisterSeq && "Invalid type access!");
386     return std::pair<unsigned, unsigned>(RegSeq.RegNumFrom, RegSeq.RegNumTo);
387   }
388 
389   RegListOp getRegList() const {
390     assert(Kind == RegisterList && "Invalid type access!");
391     return RegList;
392   }
393 
394   const MCExpr *getImm() const {
395     assert(Kind == Immediate && "Invalid type access!");
396     return Imm.Val;
397   }
398 
399   const MCExpr *getConstpoolOp() const {
400     assert(Kind == CPOP && "Invalid type access!");
401     return CPool.Val;
402   }
403 
404   StringRef getToken() const {
405     assert(Kind == Token && "Invalid type access!");
406     return Tok;
407   }
408 
409   void print(raw_ostream &OS) const override {
410     auto RegName = [](unsigned Reg) {
411       if (Reg)
412         return CSKYInstPrinter::getRegisterName(Reg);
413       else
414         return "noreg";
415     };
416 
417     switch (Kind) {
418     case CPOP:
419       OS << *getConstpoolOp();
420       break;
421     case Immediate:
422       OS << *getImm();
423       break;
424     case KindTy::Register:
425       OS << "<register " << RegName(getReg()) << ">";
426       break;
427     case RegisterSeq:
428       OS << "<register-seq ";
429       OS << RegName(getRegSeq().first) << "-" << RegName(getRegSeq().second)
430          << ">";
431       break;
432     case RegisterList:
433       OS << "<register-list ";
434       OS << RegName(getRegList().List1From) << "-"
435          << RegName(getRegList().List1To) << ",";
436       OS << RegName(getRegList().List2From) << "-"
437          << RegName(getRegList().List2To) << ",";
438       OS << RegName(getRegList().List3From) << "-"
439          << RegName(getRegList().List3To) << ",";
440       OS << RegName(getRegList().List4From) << "-"
441          << RegName(getRegList().List4To);
442       break;
443     case Token:
444       OS << "'" << getToken() << "'";
445       break;
446     }
447   }
448 
449   static std::unique_ptr<CSKYOperand> createToken(StringRef Str, SMLoc S) {
450     auto Op = std::make_unique<CSKYOperand>(Token);
451     Op->Tok = Str;
452     Op->StartLoc = S;
453     Op->EndLoc = S;
454     return Op;
455   }
456 
457   static std::unique_ptr<CSKYOperand> createReg(unsigned RegNo, SMLoc S,
458                                                 SMLoc E) {
459     auto Op = std::make_unique<CSKYOperand>(Register);
460     Op->Reg.RegNum = RegNo;
461     Op->StartLoc = S;
462     Op->EndLoc = E;
463     return Op;
464   }
465 
466   static std::unique_ptr<CSKYOperand> createRegSeq(unsigned RegNoFrom,
467                                                    unsigned RegNoTo, SMLoc S) {
468     auto Op = std::make_unique<CSKYOperand>(RegisterSeq);
469     Op->RegSeq.RegNumFrom = RegNoFrom;
470     Op->RegSeq.RegNumTo = RegNoTo;
471     Op->StartLoc = S;
472     Op->EndLoc = S;
473     return Op;
474   }
475 
476   static std::unique_ptr<CSKYOperand>
477   createRegList(SmallVector<unsigned, 4> reglist, SMLoc S) {
478     auto Op = std::make_unique<CSKYOperand>(RegisterList);
479     Op->RegList.List1From = 0;
480     Op->RegList.List1To = 0;
481     Op->RegList.List2From = 0;
482     Op->RegList.List2To = 0;
483     Op->RegList.List3From = 0;
484     Op->RegList.List3To = 0;
485     Op->RegList.List4From = 0;
486     Op->RegList.List4To = 0;
487 
488     for (unsigned i = 0; i < reglist.size(); i += 2) {
489       if (Op->RegList.List1From == 0) {
490         Op->RegList.List1From = reglist[i];
491         Op->RegList.List1To = reglist[i + 1];
492       } else if (Op->RegList.List2From == 0) {
493         Op->RegList.List2From = reglist[i];
494         Op->RegList.List2To = reglist[i + 1];
495       } else if (Op->RegList.List3From == 0) {
496         Op->RegList.List3From = reglist[i];
497         Op->RegList.List3To = reglist[i + 1];
498       } else if (Op->RegList.List4From == 0) {
499         Op->RegList.List4From = reglist[i];
500         Op->RegList.List4To = reglist[i + 1];
501       } else {
502         assert(0);
503       }
504     }
505 
506     Op->StartLoc = S;
507     Op->EndLoc = S;
508     return Op;
509   }
510 
511   static std::unique_ptr<CSKYOperand> createImm(const MCExpr *Val, SMLoc S,
512                                                 SMLoc E) {
513     auto Op = std::make_unique<CSKYOperand>(Immediate);
514     Op->Imm.Val = Val;
515     Op->StartLoc = S;
516     Op->EndLoc = E;
517     return Op;
518   }
519 
520   static std::unique_ptr<CSKYOperand> createConstpoolOp(const MCExpr *Val,
521                                                         SMLoc S, SMLoc E) {
522     auto Op = std::make_unique<CSKYOperand>(CPOP);
523     Op->CPool.Val = Val;
524     Op->StartLoc = S;
525     Op->EndLoc = E;
526     return Op;
527   }
528 
529   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
530     assert(Expr && "Expr shouldn't be null!");
531     if (auto *CE = dyn_cast<MCConstantExpr>(Expr))
532       Inst.addOperand(MCOperand::createImm(CE->getValue()));
533     else
534       Inst.addOperand(MCOperand::createExpr(Expr));
535   }
536 
537   // Used by the TableGen Code.
538   void addRegOperands(MCInst &Inst, unsigned N) const {
539     assert(N == 1 && "Invalid number of operands!");
540     Inst.addOperand(MCOperand::createReg(getReg()));
541   }
542 
543   void addImmOperands(MCInst &Inst, unsigned N) const {
544     assert(N == 1 && "Invalid number of operands!");
545     addExpr(Inst, getImm());
546   }
547 
548   void addConstpoolOperands(MCInst &Inst, unsigned N) const {
549     assert(N == 1 && "Invalid number of operands!");
550     Inst.addOperand(MCOperand::createExpr(getConstpoolOp()));
551   }
552 
553   void addRegSeqOperands(MCInst &Inst, unsigned N) const {
554     assert(N == 2 && "Invalid number of operands!");
555     auto regSeq = getRegSeq();
556 
557     Inst.addOperand(MCOperand::createReg(regSeq.first));
558     Inst.addOperand(MCOperand::createReg(regSeq.second));
559   }
560 
561   static unsigned getListValue(unsigned ListFrom, unsigned ListTo) {
562     if (ListFrom == ListTo && ListFrom == CSKY::R15)
563       return (1 << 4);
564     else if (ListFrom == ListTo && ListFrom == CSKY::R28)
565       return (1 << 8);
566     else if (ListFrom == CSKY::R4)
567       return ListTo - ListFrom + 1;
568     else if (ListFrom == CSKY::R16)
569       return ((ListTo - ListFrom + 1) << 5);
570     else
571       return 0;
572   }
573 
574   void addRegListOperands(MCInst &Inst, unsigned N) const {
575     assert(N == 1 && "Invalid number of operands!");
576     auto regList = getRegList();
577 
578     unsigned V = 0;
579 
580     unsigned T = getListValue(regList.List1From, regList.List1To);
581     if (T != 0)
582       V = V | T;
583 
584     T = getListValue(regList.List2From, regList.List2To);
585     if (T != 0)
586       V = V | T;
587 
588     T = getListValue(regList.List3From, regList.List3To);
589     if (T != 0)
590       V = V | T;
591 
592     T = getListValue(regList.List4From, regList.List4To);
593     if (T != 0)
594       V = V | T;
595 
596     Inst.addOperand(MCOperand::createImm(V));
597   }
598 
599   bool isValidForTie(const CSKYOperand &Other) const {
600     if (Kind != Other.Kind)
601       return false;
602 
603     switch (Kind) {
604     default:
605       llvm_unreachable("Unexpected kind");
606       return false;
607     case Register:
608       return Reg.RegNum == Other.Reg.RegNum;
609     }
610   }
611 };
612 } // end anonymous namespace.
613 
614 #define GET_REGISTER_MATCHER
615 #define GET_SUBTARGET_FEATURE_NAME
616 #define GET_MATCHER_IMPLEMENTATION
617 #define GET_MNEMONIC_SPELL_CHECKER
618 #include "CSKYGenAsmMatcher.inc"
619 
620 static MCRegister convertFPR32ToFPR64(MCRegister Reg) {
621   assert(Reg >= CSKY::F0_32 && Reg <= CSKY::F31_32 && "Invalid register");
622   return Reg - CSKY::F0_32 + CSKY::F0_64;
623 }
624 
625 static std::string CSKYMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
626                                           unsigned VariantID = 0);
627 
628 bool CSKYAsmParser::generateImmOutOfRangeError(
629     OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,
630     Twine Msg = "immediate must be an integer in the range") {
631   SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
632   return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
633 }
634 
635 bool CSKYAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
636                                             OperandVector &Operands,
637                                             MCStreamer &Out,
638                                             uint64_t &ErrorInfo,
639                                             bool MatchingInlineAsm) {
640   MCInst Inst;
641   FeatureBitset MissingFeatures;
642 
643   auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
644                                      MatchingInlineAsm);
645   switch (Result) {
646   default:
647     break;
648   case Match_Success:
649     return processInstruction(Inst, IDLoc, Operands, Out);
650   case Match_MissingFeature: {
651     assert(MissingFeatures.any() && "Unknown missing features!");
652     ListSeparator LS;
653     std::string Msg = "instruction requires the following: ";
654     for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {
655       if (MissingFeatures[i]) {
656         Msg += LS;
657         Msg += getSubtargetFeatureName(i);
658       }
659     }
660     return Error(IDLoc, Msg);
661   }
662   case Match_MnemonicFail: {
663     FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
664     std::string Suggestion =
665         CSKYMnemonicSpellCheck(((CSKYOperand &)*Operands[0]).getToken(), FBS);
666     return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion);
667   }
668   case Match_InvalidTiedOperand:
669   case Match_InvalidOperand: {
670     SMLoc ErrorLoc = IDLoc;
671     if (ErrorInfo != ~0U) {
672       if (ErrorInfo >= Operands.size())
673         return Error(ErrorLoc, "too few operands for instruction");
674 
675       ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
676       if (ErrorLoc == SMLoc())
677         ErrorLoc = IDLoc;
678     }
679     return Error(ErrorLoc, "invalid operand for instruction");
680   }
681   }
682 
683   // Handle the case when the error message is of specific type
684   // other than the generic Match_InvalidOperand, and the
685   // corresponding operand is missing.
686   if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
687     SMLoc ErrorLoc = IDLoc;
688     if (ErrorInfo != ~0U && ErrorInfo >= Operands.size())
689       return Error(ErrorLoc, "too few operands for instruction");
690   }
691 
692   switch (Result) {
693   default:
694     break;
695   case Match_InvalidSImm8:
696     return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),
697                                       (1 << 7) - 1);
698   case Match_InvalidOImm3:
699     return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 3));
700   case Match_InvalidOImm4:
701     return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4));
702   case Match_InvalidOImm5:
703     return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5));
704   case Match_InvalidOImm6:
705     return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6));
706   case Match_InvalidOImm8:
707     return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 8));
708   case Match_InvalidOImm12:
709     return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 12));
710   case Match_InvalidOImm16:
711     return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16));
712   case Match_InvalidUImm1:
713     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);
714   case Match_InvalidUImm2:
715     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);
716   case Match_InvalidUImm3:
717     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);
718   case Match_InvalidUImm4:
719     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
720   case Match_InvalidUImm5:
721     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
722   case Match_InvalidUImm6:
723     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
724   case Match_InvalidUImm7:
725     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);
726   case Match_InvalidUImm8:
727     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);
728   case Match_InvalidUImm12:
729     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1);
730   case Match_InvalidUImm16:
731     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 16) - 1);
732   case Match_InvalidUImm5Shift1:
733     return generateImmOutOfRangeError(
734         Operands, ErrorInfo, 0, (1 << 5) - 2,
735         "immediate must be a multiple of 2 bytes in the range");
736   case Match_InvalidUImm12Shift1:
737     return generateImmOutOfRangeError(
738         Operands, ErrorInfo, 0, (1 << 12) - 2,
739         "immediate must be a multiple of 2 bytes in the range");
740   case Match_InvalidUImm5Shift2:
741     return generateImmOutOfRangeError(
742         Operands, ErrorInfo, 0, (1 << 5) - 4,
743         "immediate must be a multiple of 4 bytes in the range");
744   case Match_InvalidUImm7Shift1:
745     return generateImmOutOfRangeError(
746         Operands, ErrorInfo, 0, (1 << 7) - 2,
747         "immediate must be a multiple of 2 bytes in the range");
748   case Match_InvalidUImm7Shift2:
749     return generateImmOutOfRangeError(
750         Operands, ErrorInfo, 0, (1 << 7) - 4,
751         "immediate must be a multiple of 4 bytes in the range");
752   case Match_InvalidUImm8Shift2:
753     return generateImmOutOfRangeError(
754         Operands, ErrorInfo, 0, (1 << 8) - 4,
755         "immediate must be a multiple of 4 bytes in the range");
756   case Match_InvalidUImm8Shift3:
757     return generateImmOutOfRangeError(
758         Operands, ErrorInfo, 0, (1 << 8) - 8,
759         "immediate must be a multiple of 8 bytes in the range");
760   case Match_InvalidUImm8Shift8:
761     return generateImmOutOfRangeError(
762         Operands, ErrorInfo, 0, (1 << 8) - 256,
763         "immediate must be a multiple of 256 bytes in the range");
764   case Match_InvalidUImm12Shift2:
765     return generateImmOutOfRangeError(
766         Operands, ErrorInfo, 0, (1 << 12) - 4,
767         "immediate must be a multiple of 4 bytes in the range");
768   case Match_InvalidCSKYSymbol: {
769     SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
770     return Error(ErrorLoc, "operand must be a symbol name");
771   }
772   case Match_InvalidConstpool: {
773     SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
774     return Error(ErrorLoc, "operand must be a constpool symbol name");
775   }
776   case Match_InvalidPSRFlag: {
777     SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
778     return Error(ErrorLoc, "psrset operand is not valid");
779   }
780   case Match_InvalidRegSeq: {
781     SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
782     return Error(ErrorLoc, "Register sequence is not valid");
783   }
784   case Match_InvalidRegOutOfRange: {
785     SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
786     return Error(ErrorLoc, "register is out of range");
787   }
788   case Match_RequiresSameSrcAndDst: {
789     SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
790     return Error(ErrorLoc, "src and dst operand must be same");
791   }
792   case Match_InvalidRegList: {
793     SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
794     return Error(ErrorLoc, "invalid register list");
795   }
796   }
797   LLVM_DEBUG(dbgs() << "Result = " << Result);
798   llvm_unreachable("Unknown match type detected!");
799 }
800 
801 bool CSKYAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
802                                        OperandVector &Operands,
803                                        MCStreamer &Out) {
804 
805   switch (Inst.getOpcode()) {
806   default:
807     break;
808   case CSKY::LDQ32:
809   case CSKY::STQ32:
810     if (Inst.getOperand(1).getReg() != CSKY::R4 ||
811         Inst.getOperand(2).getReg() != CSKY::R7) {
812       return Error(IDLoc, "Register sequence is not valid. 'r4-r7' expected");
813     }
814     Inst.setOpcode(Inst.getOpcode() == CSKY::LDQ32 ? CSKY::LDM32 : CSKY::STM32);
815     break;
816   case CSKY::SEXT32:
817   case CSKY::ZEXT32:
818     if (Inst.getOperand(2).getImm() < Inst.getOperand(3).getImm())
819       return Error(IDLoc, "msb must be greater or equal to lsb");
820     break;
821   case CSKY::INS32:
822     if (Inst.getOperand(3).getImm() < Inst.getOperand(4).getImm())
823       return Error(IDLoc, "msb must be greater or equal to lsb");
824     break;
825   case CSKY::IDLY32:
826     if (Inst.getOperand(0).getImm() > 32 || Inst.getOperand(0).getImm() < 0)
827       return Error(IDLoc, "n must be in range [0,32]");
828     break;
829   case CSKY::ADDC32:
830   case CSKY::SUBC32:
831   case CSKY::ADDC16:
832   case CSKY::SUBC16:
833     Inst.erase(std::next(Inst.begin()));
834     Inst.erase(std::prev(Inst.end()));
835     Inst.insert(std::next(Inst.begin()), MCOperand::createReg(CSKY::C));
836     Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C));
837     break;
838   case CSKY::CMPNEI32:
839   case CSKY::CMPNEI16:
840   case CSKY::CMPNE32:
841   case CSKY::CMPNE16:
842   case CSKY::CMPHSI32:
843   case CSKY::CMPHSI16:
844   case CSKY::CMPHS32:
845   case CSKY::CMPHS16:
846   case CSKY::CMPLTI32:
847   case CSKY::CMPLTI16:
848   case CSKY::CMPLT32:
849   case CSKY::CMPLT16:
850   case CSKY::BTSTI32:
851     Inst.erase(Inst.begin());
852     Inst.insert(Inst.begin(), MCOperand::createReg(CSKY::C));
853     break;
854   case CSKY::MVCV32:
855     Inst.erase(std::next(Inst.begin()));
856     Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C));
857     break;
858   }
859 
860   emitToStreamer(Out, Inst);
861   return false;
862 }
863 
864 // Attempts to match Name as a register (either using the default name or
865 // alternative ABI names), setting RegNo to the matching register. Upon
866 // failure, returns true and sets RegNo to 0.
867 static bool matchRegisterNameHelper(const MCSubtargetInfo &STI,
868                                     MCRegister &RegNo, StringRef Name) {
869   RegNo = MatchRegisterName(Name);
870 
871   if (RegNo == CSKY::NoRegister)
872     RegNo = MatchRegisterAltName(Name);
873 
874   return RegNo == CSKY::NoRegister;
875 }
876 
877 bool CSKYAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
878                                   SMLoc &EndLoc) {
879   const AsmToken &Tok = getParser().getTok();
880   StartLoc = Tok.getLoc();
881   EndLoc = Tok.getEndLoc();
882   StringRef Name = getLexer().getTok().getIdentifier();
883 
884   if (!matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) {
885     getParser().Lex(); // Eat identifier token.
886     return false;
887   }
888 
889   return MatchOperand_NoMatch;
890 }
891 
892 OperandMatchResultTy CSKYAsmParser::parseRegister(OperandVector &Operands) {
893   SMLoc S = getLoc();
894   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
895 
896   switch (getLexer().getKind()) {
897   default:
898     return MatchOperand_NoMatch;
899   case AsmToken::Identifier: {
900     StringRef Name = getLexer().getTok().getIdentifier();
901     MCRegister RegNo;
902 
903     if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name))
904       return MatchOperand_NoMatch;
905 
906     getLexer().Lex();
907     Operands.push_back(CSKYOperand::createReg(RegNo, S, E));
908 
909     return MatchOperand_Success;
910   }
911   }
912 }
913 
914 OperandMatchResultTy CSKYAsmParser::parseBaseRegImm(OperandVector &Operands) {
915   assert(getLexer().is(AsmToken::LParen));
916 
917   Operands.push_back(CSKYOperand::createToken("(", getLoc()));
918 
919   auto Tok = getParser().Lex(); // Eat '('
920 
921   if (parseRegister(Operands) != MatchOperand_Success) {
922     getLexer().UnLex(Tok);
923     Operands.pop_back();
924     return MatchOperand_NoMatch;
925   }
926 
927   if (getLexer().is(AsmToken::RParen)) {
928     Operands.push_back(CSKYOperand::createToken(")", getLoc()));
929     getParser().Lex(); // Eat ')'
930     return MatchOperand_Success;
931   }
932 
933   if (getLexer().isNot(AsmToken::Comma)) {
934     Error(getLoc(), "expected ','");
935     return MatchOperand_ParseFail;
936   }
937 
938   getParser().Lex(); // Eat ','
939 
940   if (parseRegister(Operands) == MatchOperand_Success) {
941     if (getLexer().isNot(AsmToken::LessLess)) {
942       Error(getLoc(), "expected '<<'");
943       return MatchOperand_ParseFail;
944     }
945 
946     Operands.push_back(CSKYOperand::createToken("<<", getLoc()));
947 
948     getParser().Lex(); // Eat '<<'
949 
950     if (parseImmediate(Operands) != MatchOperand_Success) {
951       Error(getLoc(), "expected imm");
952       return MatchOperand_ParseFail;
953     }
954 
955   } else if (parseImmediate(Operands) != MatchOperand_Success) {
956     Error(getLoc(), "expected imm");
957     return MatchOperand_ParseFail;
958   }
959 
960   if (getLexer().isNot(AsmToken::RParen)) {
961     Error(getLoc(), "expected ')'");
962     return MatchOperand_ParseFail;
963   }
964 
965   Operands.push_back(CSKYOperand::createToken(")", getLoc()));
966 
967   getParser().Lex(); // Eat ')'
968 
969   return MatchOperand_Success;
970 }
971 
972 OperandMatchResultTy CSKYAsmParser::parseImmediate(OperandVector &Operands) {
973   switch (getLexer().getKind()) {
974   default:
975     return MatchOperand_NoMatch;
976   case AsmToken::LParen:
977   case AsmToken::Minus:
978   case AsmToken::Plus:
979   case AsmToken::Integer:
980   case AsmToken::String:
981     break;
982   }
983 
984   const MCExpr *IdVal;
985   SMLoc S = getLoc();
986   if (getParser().parseExpression(IdVal)) {
987     Error(getLoc(), "unknown expression");
988     return MatchOperand_ParseFail;
989   }
990 
991   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
992   Operands.push_back(CSKYOperand::createImm(IdVal, S, E));
993   return MatchOperand_Success;
994 }
995 
996 /// Looks at a token type and creates the relevant operand from this
997 /// information, adding to Operands. If operand was parsed, returns false, else
998 /// true.
999 bool CSKYAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1000   // Check if the current operand has a custom associated parser, if so, try to
1001   // custom parse the operand, or fallback to the general approach.
1002   OperandMatchResultTy Result =
1003       MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true);
1004   if (Result == MatchOperand_Success)
1005     return false;
1006   if (Result == MatchOperand_ParseFail)
1007     return true;
1008 
1009   // Attempt to parse token as register
1010   auto Res = parseRegister(Operands);
1011   if (Res == MatchOperand_Success)
1012     return false;
1013   else if (Res == MatchOperand_ParseFail)
1014     return true;
1015 
1016   // Attempt to parse token as (register, imm)
1017   if (getLexer().is(AsmToken::LParen)) {
1018     Res = parseBaseRegImm(Operands);
1019     if (Res == MatchOperand_Success)
1020       return false;
1021     else if (Res == MatchOperand_ParseFail)
1022       return true;
1023   }
1024 
1025   Res = parseImmediate(Operands);
1026   if (Res == MatchOperand_Success)
1027     return false;
1028   else if (Res == MatchOperand_ParseFail)
1029     return true;
1030 
1031   // Finally we have exhausted all options and must declare defeat.
1032   Error(getLoc(), "unknown operand");
1033   return true;
1034 }
1035 
1036 OperandMatchResultTy CSKYAsmParser::parseCSKYSymbol(OperandVector &Operands) {
1037   SMLoc S = getLoc();
1038   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1039   const MCExpr *Res;
1040 
1041   if (getLexer().getKind() != AsmToken::Identifier)
1042     return MatchOperand_NoMatch;
1043 
1044   StringRef Identifier;
1045   AsmToken Tok = getLexer().getTok();
1046 
1047   if (getParser().parseIdentifier(Identifier)) {
1048     Error(getLoc(), "unknown identifier");
1049     return MatchOperand_ParseFail;
1050   }
1051 
1052   CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None;
1053   if (Identifier.consume_back("@GOT"))
1054     Kind = CSKYMCExpr::VK_CSKY_GOT;
1055   else if (Identifier.consume_back("@GOTOFF"))
1056     Kind = CSKYMCExpr::VK_CSKY_GOTOFF;
1057   else if (Identifier.consume_back("@PLT"))
1058     Kind = CSKYMCExpr::VK_CSKY_PLT;
1059   else if (Identifier.consume_back("@GOTPC"))
1060     Kind = CSKYMCExpr::VK_CSKY_GOTPC;
1061   else if (Identifier.consume_back("@TLSGD32"))
1062     Kind = CSKYMCExpr::VK_CSKY_TLSGD;
1063   else if (Identifier.consume_back("@GOTTPOFF"))
1064     Kind = CSKYMCExpr::VK_CSKY_TLSIE;
1065   else if (Identifier.consume_back("@TPOFF"))
1066     Kind = CSKYMCExpr::VK_CSKY_TLSLE;
1067   else if (Identifier.consume_back("@TLSLDM32"))
1068     Kind = CSKYMCExpr::VK_CSKY_TLSLDM;
1069   else if (Identifier.consume_back("@TLSLDO32"))
1070     Kind = CSKYMCExpr::VK_CSKY_TLSLDO;
1071 
1072   MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);
1073 
1074   if (!Sym)
1075     Sym = getContext().getOrCreateSymbol(Identifier);
1076 
1077   if (Sym->isVariable()) {
1078     const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
1079     if (!isa<MCSymbolRefExpr>(V)) {
1080       getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
1081       Error(getLoc(), "unknown symbol");
1082       return MatchOperand_ParseFail;
1083     }
1084     Res = V;
1085   } else
1086     Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1087 
1088   MCBinaryExpr::Opcode Opcode;
1089   switch (getLexer().getKind()) {
1090   default:
1091     if (Kind != CSKYMCExpr::VK_CSKY_None)
1092       Res = CSKYMCExpr::create(Res, Kind, getContext());
1093 
1094     Operands.push_back(CSKYOperand::createImm(Res, S, E));
1095     return MatchOperand_Success;
1096   case AsmToken::Plus:
1097     Opcode = MCBinaryExpr::Add;
1098     break;
1099   case AsmToken::Minus:
1100     Opcode = MCBinaryExpr::Sub;
1101     break;
1102   }
1103 
1104   getLexer().Lex(); // eat + or -
1105 
1106   const MCExpr *Expr;
1107   if (getParser().parseExpression(Expr)) {
1108     Error(getLoc(), "unknown expression");
1109     return MatchOperand_ParseFail;
1110   }
1111   Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
1112   Operands.push_back(CSKYOperand::createImm(Res, S, E));
1113   return MatchOperand_Success;
1114 }
1115 
1116 OperandMatchResultTy CSKYAsmParser::parseDataSymbol(OperandVector &Operands) {
1117   SMLoc S = getLoc();
1118   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1119   const MCExpr *Res;
1120 
1121   if (getLexer().getKind() != AsmToken::LBrac)
1122     return MatchOperand_NoMatch;
1123 
1124   getLexer().Lex(); // Eat '['.
1125 
1126   if (getLexer().getKind() != AsmToken::Identifier) {
1127     const MCExpr *Expr;
1128     if (getParser().parseExpression(Expr)) {
1129       Error(getLoc(), "unknown expression");
1130       return MatchOperand_ParseFail;
1131     }
1132 
1133     if (getLexer().getKind() != AsmToken::RBrac) {
1134       Error(getLoc(), "expected ]");
1135       return MatchOperand_ParseFail;
1136     }
1137 
1138     getLexer().Lex(); // Eat ']'.
1139 
1140     Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E));
1141     return MatchOperand_Success;
1142   }
1143 
1144   AsmToken Tok = getLexer().getTok();
1145   StringRef Identifier;
1146 
1147   if (getParser().parseIdentifier(Identifier)) {
1148     Error(getLoc(), "unknown identifier " + Identifier);
1149     return MatchOperand_ParseFail;
1150   }
1151 
1152   CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None;
1153   if (Identifier.consume_back("@GOT"))
1154     Kind = CSKYMCExpr::VK_CSKY_GOT_IMM18_BY4;
1155   else if (Identifier.consume_back("@PLT"))
1156     Kind = CSKYMCExpr::VK_CSKY_PLT_IMM18_BY4;
1157 
1158   MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);
1159 
1160   if (!Sym)
1161     Sym = getContext().getOrCreateSymbol(Identifier);
1162 
1163   if (Sym->isVariable()) {
1164     const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
1165     if (!isa<MCSymbolRefExpr>(V)) {
1166       getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
1167       Error(getLoc(), "unknown symbol");
1168       return MatchOperand_ParseFail;
1169     }
1170     Res = V;
1171   } else {
1172     Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1173   }
1174 
1175   MCBinaryExpr::Opcode Opcode;
1176   switch (getLexer().getKind()) {
1177   default:
1178     Error(getLoc(), "unknown symbol");
1179     return MatchOperand_ParseFail;
1180   case AsmToken::RBrac:
1181 
1182     getLexer().Lex(); // Eat ']'.
1183 
1184     if (Kind != CSKYMCExpr::VK_CSKY_None)
1185       Res = CSKYMCExpr::create(Res, Kind, getContext());
1186 
1187     Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
1188     return MatchOperand_Success;
1189   case AsmToken::Plus:
1190     Opcode = MCBinaryExpr::Add;
1191     break;
1192   case AsmToken::Minus:
1193     Opcode = MCBinaryExpr::Sub;
1194     break;
1195   }
1196 
1197   getLexer().Lex(); // eat + or -
1198 
1199   const MCExpr *Expr;
1200   if (getParser().parseExpression(Expr)) {
1201     Error(getLoc(), "unknown expression");
1202     return MatchOperand_ParseFail;
1203   }
1204 
1205   if (getLexer().getKind() != AsmToken::RBrac) {
1206     Error(getLoc(), "expected ']'");
1207     return MatchOperand_ParseFail;
1208   }
1209 
1210   getLexer().Lex(); // Eat ']'.
1211 
1212   Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
1213   Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
1214   return MatchOperand_Success;
1215 }
1216 
1217 OperandMatchResultTy
1218 CSKYAsmParser::parseConstpoolSymbol(OperandVector &Operands) {
1219   SMLoc S = getLoc();
1220   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1221   const MCExpr *Res;
1222 
1223   if (getLexer().getKind() != AsmToken::LBrac)
1224     return MatchOperand_NoMatch;
1225 
1226   getLexer().Lex(); // Eat '['.
1227 
1228   if (getLexer().getKind() != AsmToken::Identifier) {
1229     const MCExpr *Expr;
1230     if (getParser().parseExpression(Expr)) {
1231       Error(getLoc(), "unknown expression");
1232       return MatchOperand_ParseFail;
1233     }
1234 
1235     if (getLexer().getKind() != AsmToken::RBrac) {
1236       Error(getLoc(), "expected ']'");
1237       return MatchOperand_ParseFail;
1238     }
1239 
1240     getLexer().Lex(); // Eat ']'.
1241 
1242     Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E));
1243     return MatchOperand_Success;
1244   }
1245 
1246   AsmToken Tok = getLexer().getTok();
1247   StringRef Identifier;
1248 
1249   if (getParser().parseIdentifier(Identifier)) {
1250     Error(getLoc(), "unknown identifier");
1251     return MatchOperand_ParseFail;
1252   }
1253 
1254   MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);
1255 
1256   if (!Sym)
1257     Sym = getContext().getOrCreateSymbol(Identifier);
1258 
1259   if (Sym->isVariable()) {
1260     const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
1261     if (!isa<MCSymbolRefExpr>(V)) {
1262       getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
1263       Error(getLoc(), "unknown symbol");
1264       return MatchOperand_ParseFail;
1265     }
1266     Res = V;
1267   } else {
1268     Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1269   }
1270 
1271   MCBinaryExpr::Opcode Opcode;
1272   switch (getLexer().getKind()) {
1273   default:
1274     Error(getLoc(), "unknown symbol");
1275     return MatchOperand_ParseFail;
1276   case AsmToken::RBrac:
1277 
1278     getLexer().Lex(); // Eat ']'.
1279 
1280     Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
1281     return MatchOperand_Success;
1282   case AsmToken::Plus:
1283     Opcode = MCBinaryExpr::Add;
1284     break;
1285   case AsmToken::Minus:
1286     Opcode = MCBinaryExpr::Sub;
1287     break;
1288   }
1289 
1290   getLexer().Lex(); // eat + or -
1291 
1292   const MCExpr *Expr;
1293   if (getParser().parseExpression(Expr)) {
1294     Error(getLoc(), "unknown expression");
1295     return MatchOperand_ParseFail;
1296   }
1297 
1298   if (getLexer().getKind() != AsmToken::RBrac) {
1299     Error(getLoc(), "expected ']'");
1300     return MatchOperand_ParseFail;
1301   }
1302 
1303   getLexer().Lex(); // Eat ']'.
1304 
1305   Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
1306   Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
1307   return MatchOperand_Success;
1308 }
1309 
1310 OperandMatchResultTy CSKYAsmParser::parsePSRFlag(OperandVector &Operands) {
1311   SMLoc S = getLoc();
1312   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1313 
1314   unsigned Flag = 0;
1315 
1316   while (getLexer().isNot(AsmToken::EndOfStatement)) {
1317     StringRef Identifier;
1318     if (getParser().parseIdentifier(Identifier)) {
1319       Error(getLoc(), "unknown identifier " + Identifier);
1320       return MatchOperand_ParseFail;
1321     }
1322 
1323     if (Identifier == "sie")
1324       Flag = (1 << 4) | Flag;
1325     else if (Identifier == "ee")
1326       Flag = (1 << 3) | Flag;
1327     else if (Identifier == "ie")
1328       Flag = (1 << 2) | Flag;
1329     else if (Identifier == "fe")
1330       Flag = (1 << 1) | Flag;
1331     else if (Identifier == "af")
1332       Flag = (1 << 0) | Flag;
1333     else {
1334       Error(getLoc(), "expected " + Identifier);
1335       return MatchOperand_ParseFail;
1336     }
1337 
1338     if (getLexer().is(AsmToken::EndOfStatement))
1339       break;
1340 
1341     if (getLexer().is(AsmToken::Comma)) {
1342       getLexer().Lex(); // eat ','
1343     } else {
1344       Error(getLoc(), "expected ,");
1345       return MatchOperand_ParseFail;
1346     }
1347   }
1348 
1349   Operands.push_back(
1350       CSKYOperand::createImm(MCConstantExpr::create(Flag, getContext()), S, E));
1351   return MatchOperand_Success;
1352 }
1353 
1354 OperandMatchResultTy CSKYAsmParser::parseRegSeq(OperandVector &Operands) {
1355   SMLoc S = getLoc();
1356 
1357   if (parseRegister(Operands) != MatchOperand_Success)
1358     return MatchOperand_NoMatch;
1359 
1360   auto Ry = Operands.back()->getReg();
1361   Operands.pop_back();
1362 
1363   if (getLexer().isNot(AsmToken::Minus)) {
1364     Error(getLoc(), "expected '-'");
1365     return MatchOperand_ParseFail;
1366   }
1367 
1368   getLexer().Lex(); // eat '-'
1369 
1370   if (parseRegister(Operands) != MatchOperand_Success) {
1371     Error(getLoc(), "invalid register");
1372     return MatchOperand_ParseFail;
1373   }
1374 
1375   auto Rz = Operands.back()->getReg();
1376   Operands.pop_back();
1377 
1378   Operands.push_back(CSKYOperand::createRegSeq(Ry, Rz, S));
1379   return MatchOperand_Success;
1380 }
1381 
1382 OperandMatchResultTy CSKYAsmParser::parseRegList(OperandVector &Operands) {
1383   SMLoc S = getLoc();
1384 
1385   SmallVector<unsigned, 4> reglist;
1386 
1387   while (true) {
1388 
1389     if (parseRegister(Operands) != MatchOperand_Success) {
1390       Error(getLoc(), "invalid register");
1391       return MatchOperand_ParseFail;
1392     }
1393 
1394     auto Ry = Operands.back()->getReg();
1395     Operands.pop_back();
1396 
1397     if (getLexer().is(AsmToken::Minus)) {
1398       getLexer().Lex(); // eat '-'
1399 
1400       if (parseRegister(Operands) != MatchOperand_Success) {
1401         Error(getLoc(), "invalid register");
1402         return MatchOperand_ParseFail;
1403       }
1404 
1405       auto Rz = Operands.back()->getReg();
1406       Operands.pop_back();
1407 
1408       reglist.push_back(Ry);
1409       reglist.push_back(Rz);
1410 
1411       if (getLexer().is(AsmToken::Comma))
1412         getLexer().Lex(); // eat ','
1413       else if (getLexer().is(AsmToken::EndOfStatement))
1414         break;
1415 
1416     } else if (getLexer().is(AsmToken::Comma)) {
1417       reglist.push_back(Ry);
1418       reglist.push_back(Ry);
1419 
1420       getLexer().Lex(); // eat ','
1421     } else if (getLexer().is(AsmToken::EndOfStatement)) {
1422       reglist.push_back(Ry);
1423       reglist.push_back(Ry);
1424       break;
1425     } else {
1426       Error(getLoc(), "invalid register list");
1427       return MatchOperand_ParseFail;
1428     }
1429   }
1430 
1431   Operands.push_back(CSKYOperand::createRegList(reglist, S));
1432   return MatchOperand_Success;
1433 }
1434 
1435 bool CSKYAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
1436                                      SMLoc NameLoc, OperandVector &Operands) {
1437   // First operand is token for instruction.
1438   Operands.push_back(CSKYOperand::createToken(Name, NameLoc));
1439 
1440   // If there are no more operands, then finish.
1441   if (getLexer().is(AsmToken::EndOfStatement))
1442     return false;
1443 
1444   // Parse first operand.
1445   if (parseOperand(Operands, Name))
1446     return true;
1447 
1448   // Parse until end of statement, consuming commas between operands.
1449   while (getLexer().is(AsmToken::Comma)) {
1450     // Consume comma token.
1451     getLexer().Lex();
1452 
1453     // Parse next operand.
1454     if (parseOperand(Operands, Name))
1455       return true;
1456   }
1457 
1458   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1459     SMLoc Loc = getLexer().getLoc();
1460     getParser().eatToEndOfStatement();
1461     return Error(Loc, "unexpected token");
1462   }
1463 
1464   getParser().Lex(); // Consume the EndOfStatement.
1465   return false;
1466 }
1467 
1468 OperandMatchResultTy CSKYAsmParser::tryParseRegister(unsigned &RegNo,
1469                                                      SMLoc &StartLoc,
1470                                                      SMLoc &EndLoc) {
1471   const AsmToken &Tok = getParser().getTok();
1472   StartLoc = Tok.getLoc();
1473   EndLoc = Tok.getEndLoc();
1474 
1475   StringRef Name = getLexer().getTok().getIdentifier();
1476 
1477   if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name))
1478     return MatchOperand_NoMatch;
1479 
1480   getParser().Lex(); // Eat identifier token.
1481   return MatchOperand_Success;
1482 }
1483 
1484 bool CSKYAsmParser::ParseDirective(AsmToken DirectiveID) { return true; }
1485 
1486 unsigned CSKYAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1487                                                    unsigned Kind) {
1488   CSKYOperand &Op = static_cast<CSKYOperand &>(AsmOp);
1489 
1490   if (!Op.isReg())
1491     return Match_InvalidOperand;
1492 
1493   MCRegister Reg = Op.getReg();
1494 
1495   if (CSKYMCRegisterClasses[CSKY::FPR32RegClassID].contains(Reg)) {
1496     // As the parser couldn't differentiate an FPR64 from an FPR32, coerce the
1497     // register from FPR32 to FPR64 if necessary.
1498     if (Kind == MCK_FPR64 || Kind == MCK_sFPR64_V) {
1499       Op.Reg.RegNum = convertFPR32ToFPR64(Reg);
1500       if (Kind == MCK_sFPR64_V &&
1501           (Op.Reg.RegNum < CSKY::F0_64 || Op.Reg.RegNum > CSKY::F15_64))
1502         return Match_InvalidRegOutOfRange;
1503       if (Kind == MCK_FPR64 &&
1504           (Op.Reg.RegNum < CSKY::F0_64 || Op.Reg.RegNum > CSKY::F31_64))
1505         return Match_InvalidRegOutOfRange;
1506       return Match_Success;
1507     }
1508   }
1509 
1510   if (CSKYMCRegisterClasses[CSKY::GPRRegClassID].contains(Reg)) {
1511     if (Kind == MCK_GPRPair) {
1512       Op.Reg.RegNum = MRI->getEncodingValue(Reg) + CSKY::R0_R1;
1513       return Match_Success;
1514     }
1515   }
1516 
1517   return Match_InvalidOperand;
1518 }
1519 
1520 void CSKYAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) {
1521   MCInst CInst;
1522   bool Res = false;
1523   if (EnableCompressedInst)
1524     Res = compressInst(CInst, Inst, getSTI(), S.getContext());
1525   if (Res)
1526     ++CSKYNumInstrsCompressed;
1527   S.emitInstruction((Res ? CInst : Inst), getSTI());
1528 }
1529 
1530 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYAsmParser() {
1531   RegisterMCAsmParser<CSKYAsmParser> X(getTheCSKYTarget());
1532 }
1533