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