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