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