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