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