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