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