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