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