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