1de10a02fSZi Xuan Wu //===---- CSKYAsmParser.cpp - Parse CSKY assembly to MCInst instructions --===//
28ba622baSZi Xuan Wu //
3c874dd53SChristopher Di Bella // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c874dd53SChristopher Di Bella // See https://llvm.org/LICENSE.txt for license information.
5c874dd53SChristopher Di Bella // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
68ba622baSZi Xuan Wu //
78ba622baSZi Xuan Wu //===----------------------------------------------------------------------===//
88ba622baSZi Xuan Wu 
9de10a02fSZi Xuan Wu #include "MCTargetDesc/CSKYInstPrinter.h"
104bb60c28SZi Xuan Wu #include "MCTargetDesc/CSKYMCExpr.h"
118ba622baSZi Xuan Wu #include "MCTargetDesc/CSKYMCTargetDesc.h"
1232977589SZi Xuan Wu #include "MCTargetDesc/CSKYTargetStreamer.h"
138ba622baSZi Xuan Wu #include "TargetInfo/CSKYTargetInfo.h"
148ba622baSZi Xuan Wu #include "llvm/ADT/STLExtras.h"
15bdd7c53dSZi Xuan Wu #include "llvm/ADT/Statistic.h"
168ba622baSZi Xuan Wu #include "llvm/ADT/StringSwitch.h"
17e8b30371SZi Xuan Wu #include "llvm/BinaryFormat/ELF.h"
188ba622baSZi Xuan Wu #include "llvm/CodeGen/Register.h"
198ba622baSZi Xuan Wu #include "llvm/MC/MCContext.h"
208ba622baSZi Xuan Wu #include "llvm/MC/MCExpr.h"
218ba622baSZi Xuan Wu #include "llvm/MC/MCInst.h"
2221bce900SZi Xuan Wu #include "llvm/MC/MCInstrInfo.h"
238ba622baSZi Xuan Wu #include "llvm/MC/MCParser/MCAsmLexer.h"
248ba622baSZi Xuan Wu #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
258ba622baSZi Xuan Wu #include "llvm/MC/MCParser/MCTargetAsmParser.h"
268ba622baSZi Xuan Wu #include "llvm/MC/MCRegisterInfo.h"
27de10a02fSZi Xuan Wu #include "llvm/MC/MCSectionELF.h"
288ba622baSZi Xuan Wu #include "llvm/MC/MCStreamer.h"
298ba622baSZi Xuan Wu #include "llvm/MC/MCSubtargetInfo.h"
3089b57061SReid Kleckner #include "llvm/MC/TargetRegistry.h"
3132977589SZi Xuan Wu #include "llvm/Support/CSKYAttributes.h"
3232977589SZi Xuan Wu #include "llvm/Support/CSKYTargetParser.h"
338ba622baSZi Xuan Wu #include "llvm/Support/Casting.h"
34bdd7c53dSZi Xuan Wu #include "llvm/Support/CommandLine.h"
35de10a02fSZi Xuan Wu #include "llvm/Support/Debug.h"
36de10a02fSZi Xuan Wu 
37bdd7c53dSZi Xuan Wu using namespace llvm;
38bdd7c53dSZi Xuan Wu 
39de10a02fSZi Xuan Wu #define DEBUG_TYPE "csky-asm-parser"
408ba622baSZi Xuan Wu 
41bdd7c53dSZi Xuan Wu // Include the auto-generated portion of the compress emitter.
42bdd7c53dSZi Xuan Wu #define GEN_COMPRESS_INSTR
43bdd7c53dSZi Xuan Wu #include "CSKYGenCompressInstEmitter.inc"
44bdd7c53dSZi Xuan Wu 
45bdd7c53dSZi Xuan Wu STATISTIC(CSKYNumInstrsCompressed,
46bdd7c53dSZi Xuan Wu           "Number of C-SKY Compressed instructions emitted");
47bdd7c53dSZi Xuan Wu 
48bdd7c53dSZi Xuan Wu static cl::opt<bool>
49bdd7c53dSZi Xuan Wu     EnableCompressedInst("enable-csky-asm-compressed-inst", cl::Hidden,
50bdd7c53dSZi Xuan Wu                          cl::init(false),
51bdd7c53dSZi Xuan Wu                          cl::desc("Enable C-SKY asm compressed instruction"));
528ba622baSZi Xuan Wu 
538ba622baSZi Xuan Wu namespace {
548ba622baSZi Xuan Wu struct CSKYOperand;
558ba622baSZi Xuan Wu 
568ba622baSZi Xuan Wu class CSKYAsmParser : public MCTargetAsmParser {
578ba622baSZi Xuan Wu 
58de10a02fSZi Xuan Wu   const MCRegisterInfo *MRI;
59de10a02fSZi Xuan Wu 
60a190fcdfSZi Xuan Wu   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
61a190fcdfSZi Xuan Wu                                       unsigned Kind) override;
62a190fcdfSZi Xuan Wu 
638ba622baSZi Xuan Wu   bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,
648ba622baSZi Xuan Wu                                   int64_t Lower, int64_t Upper, Twine Msg);
658ba622baSZi Xuan Wu 
getLoc() const668ba622baSZi Xuan Wu   SMLoc getLoc() const { return getParser().getTok().getLoc(); }
678ba622baSZi Xuan Wu 
688ba622baSZi Xuan Wu   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
698ba622baSZi Xuan Wu                                OperandVector &Operands, MCStreamer &Out,
708ba622baSZi Xuan Wu                                uint64_t &ErrorInfo,
718ba622baSZi Xuan Wu                                bool MatchingInlineAsm) override;
728ba622baSZi Xuan Wu 
738ba622baSZi Xuan Wu   bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
748ba622baSZi Xuan Wu 
758ba622baSZi Xuan Wu   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
768ba622baSZi Xuan Wu                         SMLoc NameLoc, OperandVector &Operands) override;
778ba622baSZi Xuan Wu 
788ba622baSZi Xuan Wu   bool ParseDirective(AsmToken DirectiveID) override;
798ba622baSZi Xuan Wu 
80bdd7c53dSZi Xuan Wu   // Helper to actually emit an instruction to the MCStreamer. Also, when
81bdd7c53dSZi Xuan Wu   // possible, compression of the instruction is performed.
82bdd7c53dSZi Xuan Wu   void emitToStreamer(MCStreamer &S, const MCInst &Inst);
83bdd7c53dSZi Xuan Wu 
848ba622baSZi Xuan Wu   OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc,
858ba622baSZi Xuan Wu                                         SMLoc &EndLoc) override;
868ba622baSZi Xuan Wu 
87de10a02fSZi Xuan Wu   bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands,
88de10a02fSZi Xuan Wu                           MCStreamer &Out);
89582836faSZi Xuan Wu   bool processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
90582836faSZi Xuan Wu   bool processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
91582836faSZi Xuan Wu   bool processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
92de10a02fSZi Xuan Wu 
getTargetStreamer()9332977589SZi Xuan Wu   CSKYTargetStreamer &getTargetStreamer() {
9432977589SZi Xuan Wu     assert(getParser().getStreamer().getTargetStreamer() &&
9532977589SZi Xuan Wu            "do not have a target streamer");
9632977589SZi Xuan Wu     MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
9732977589SZi Xuan Wu     return static_cast<CSKYTargetStreamer &>(TS);
9832977589SZi Xuan Wu   }
9932977589SZi Xuan Wu 
1008ba622baSZi Xuan Wu // Auto-generated instruction matching functions
1018ba622baSZi Xuan Wu #define GET_ASSEMBLER_HEADER
1028ba622baSZi Xuan Wu #include "CSKYGenAsmMatcher.inc"
1038ba622baSZi Xuan Wu 
1048ba622baSZi Xuan Wu   OperandMatchResultTy parseImmediate(OperandVector &Operands);
1058ba622baSZi Xuan Wu   OperandMatchResultTy parseRegister(OperandVector &Operands);
1064216389cSZi Xuan Wu   OperandMatchResultTy parseBaseRegImm(OperandVector &Operands);
1074bb60c28SZi Xuan Wu   OperandMatchResultTy parseCSKYSymbol(OperandVector &Operands);
1084bb60c28SZi Xuan Wu   OperandMatchResultTy parseConstpoolSymbol(OperandVector &Operands);
109de10a02fSZi Xuan Wu   OperandMatchResultTy parseDataSymbol(OperandVector &Operands);
110de10a02fSZi Xuan Wu   OperandMatchResultTy parsePSRFlag(OperandVector &Operands);
111de10a02fSZi Xuan Wu   OperandMatchResultTy parseRegSeq(OperandVector &Operands);
112de10a02fSZi Xuan Wu   OperandMatchResultTy parseRegList(OperandVector &Operands);
1138ba622baSZi Xuan Wu 
1148ba622baSZi Xuan Wu   bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
1158ba622baSZi Xuan Wu 
11632977589SZi Xuan Wu   bool parseDirectiveAttribute();
11732977589SZi Xuan Wu 
1188ba622baSZi Xuan Wu public:
1198ba622baSZi Xuan Wu   enum CSKYMatchResultTy {
1208ba622baSZi Xuan Wu     Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
121de10a02fSZi Xuan Wu     Match_RequiresSameSrcAndDst,
122de10a02fSZi Xuan Wu     Match_InvalidRegOutOfRange,
1238ba622baSZi Xuan Wu #define GET_OPERAND_DIAGNOSTIC_TYPES
1248ba622baSZi Xuan Wu #include "CSKYGenAsmMatcher.inc"
1258ba622baSZi Xuan Wu #undef GET_OPERAND_DIAGNOSTIC_TYPES
1268ba622baSZi Xuan Wu   };
1278ba622baSZi Xuan Wu 
CSKYAsmParser(const MCSubtargetInfo & STI,MCAsmParser & Parser,const MCInstrInfo & MII,const MCTargetOptions & Options)1288ba622baSZi Xuan Wu   CSKYAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
1298ba622baSZi Xuan Wu                 const MCInstrInfo &MII, const MCTargetOptions &Options)
1308ba622baSZi Xuan Wu       : MCTargetAsmParser(Options, STI, MII) {
13132977589SZi Xuan Wu 
13232977589SZi Xuan Wu     MCAsmParserExtension::Initialize(Parser);
13332977589SZi Xuan Wu 
134582836faSZi Xuan Wu     // Cache the MCRegisterInfo.
135582836faSZi Xuan Wu     MRI = getContext().getRegisterInfo();
136582836faSZi Xuan Wu 
1378ba622baSZi Xuan Wu     setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
138582836faSZi Xuan Wu     getTargetStreamer().emitTargetAttributes(STI);
1398ba622baSZi Xuan Wu   }
1408ba622baSZi Xuan Wu };
1418ba622baSZi Xuan Wu 
1428ba622baSZi Xuan Wu /// Instances of this class represent a parsed machine instruction.
1438ba622baSZi Xuan Wu struct CSKYOperand : public MCParsedAsmOperand {
144de10a02fSZi Xuan Wu 
1458ba622baSZi Xuan Wu   enum KindTy {
1468ba622baSZi Xuan Wu     Token,
1478ba622baSZi Xuan Wu     Register,
1488ba622baSZi Xuan Wu     Immediate,
149de10a02fSZi Xuan Wu     RegisterSeq,
150de10a02fSZi Xuan Wu     CPOP,
151de10a02fSZi Xuan Wu     RegisterList
1528ba622baSZi Xuan Wu   } Kind;
1538ba622baSZi Xuan Wu 
1548ba622baSZi Xuan Wu   struct RegOp {
1558ba622baSZi Xuan Wu     unsigned RegNum;
1568ba622baSZi Xuan Wu   };
1578ba622baSZi Xuan Wu 
1588ba622baSZi Xuan Wu   struct ImmOp {
1598ba622baSZi Xuan Wu     const MCExpr *Val;
1608ba622baSZi Xuan Wu   };
1618ba622baSZi Xuan Wu 
162de10a02fSZi Xuan Wu   struct ConstpoolOp {
163de10a02fSZi Xuan Wu     const MCExpr *Val;
164de10a02fSZi Xuan Wu   };
165de10a02fSZi Xuan Wu 
166de10a02fSZi Xuan Wu   struct RegSeqOp {
167de10a02fSZi Xuan Wu     unsigned RegNumFrom;
168de10a02fSZi Xuan Wu     unsigned RegNumTo;
169de10a02fSZi Xuan Wu   };
170de10a02fSZi Xuan Wu 
171de10a02fSZi Xuan Wu   struct RegListOp {
172de10a02fSZi Xuan Wu     unsigned List1From = 0;
173de10a02fSZi Xuan Wu     unsigned List1To = 0;
174de10a02fSZi Xuan Wu     unsigned List2From = 0;
175de10a02fSZi Xuan Wu     unsigned List2To = 0;
176de10a02fSZi Xuan Wu     unsigned List3From = 0;
177de10a02fSZi Xuan Wu     unsigned List3To = 0;
178de10a02fSZi Xuan Wu     unsigned List4From = 0;
179de10a02fSZi Xuan Wu     unsigned List4To = 0;
180de10a02fSZi Xuan Wu   };
181de10a02fSZi Xuan Wu 
1828ba622baSZi Xuan Wu   SMLoc StartLoc, EndLoc;
1838ba622baSZi Xuan Wu   union {
1848ba622baSZi Xuan Wu     StringRef Tok;
1858ba622baSZi Xuan Wu     RegOp Reg;
1868ba622baSZi Xuan Wu     ImmOp Imm;
187de10a02fSZi Xuan Wu     ConstpoolOp CPool;
188de10a02fSZi Xuan Wu     RegSeqOp RegSeq;
189de10a02fSZi Xuan Wu     RegListOp RegList;
1908ba622baSZi Xuan Wu   };
1918ba622baSZi Xuan Wu 
CSKYOperand__anon1c3a35040111::CSKYOperand1928ba622baSZi Xuan Wu   CSKYOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
1938ba622baSZi Xuan Wu 
1948ba622baSZi Xuan Wu public:
CSKYOperand__anon1c3a35040111::CSKYOperand1958ba622baSZi Xuan Wu   CSKYOperand(const CSKYOperand &o) : MCParsedAsmOperand() {
1968ba622baSZi Xuan Wu     Kind = o.Kind;
1978ba622baSZi Xuan Wu     StartLoc = o.StartLoc;
1988ba622baSZi Xuan Wu     EndLoc = o.EndLoc;
1998ba622baSZi Xuan Wu     switch (Kind) {
2008ba622baSZi Xuan Wu     case Register:
2018ba622baSZi Xuan Wu       Reg = o.Reg;
2028ba622baSZi Xuan Wu       break;
203de10a02fSZi Xuan Wu     case RegisterSeq:
204de10a02fSZi Xuan Wu       RegSeq = o.RegSeq;
205de10a02fSZi Xuan Wu       break;
206de10a02fSZi Xuan Wu     case CPOP:
207de10a02fSZi Xuan Wu       CPool = o.CPool;
208de10a02fSZi Xuan Wu       break;
2098ba622baSZi Xuan Wu     case Immediate:
2108ba622baSZi Xuan Wu       Imm = o.Imm;
2118ba622baSZi Xuan Wu       break;
2128ba622baSZi Xuan Wu     case Token:
2138ba622baSZi Xuan Wu       Tok = o.Tok;
2148ba622baSZi Xuan Wu       break;
215de10a02fSZi Xuan Wu     case RegisterList:
216de10a02fSZi Xuan Wu       RegList = o.RegList;
217de10a02fSZi Xuan Wu       break;
2188ba622baSZi Xuan Wu     }
2198ba622baSZi Xuan Wu   }
2208ba622baSZi Xuan Wu 
isToken__anon1c3a35040111::CSKYOperand2218ba622baSZi Xuan Wu   bool isToken() const override { return Kind == Token; }
isReg__anon1c3a35040111::CSKYOperand2228ba622baSZi Xuan Wu   bool isReg() const override { return Kind == Register; }
isImm__anon1c3a35040111::CSKYOperand2238ba622baSZi Xuan Wu   bool isImm() const override { return Kind == Immediate; }
isRegisterSeq__anon1c3a35040111::CSKYOperand224de10a02fSZi Xuan Wu   bool isRegisterSeq() const { return Kind == RegisterSeq; }
isRegisterList__anon1c3a35040111::CSKYOperand225de10a02fSZi Xuan Wu   bool isRegisterList() const { return Kind == RegisterList; }
isConstPoolOp__anon1c3a35040111::CSKYOperand226de10a02fSZi Xuan Wu   bool isConstPoolOp() const { return Kind == CPOP; }
227de10a02fSZi Xuan Wu 
isMem__anon1c3a35040111::CSKYOperand2288ba622baSZi Xuan Wu   bool isMem() const override { return false; }
2298ba622baSZi Xuan Wu 
evaluateConstantImm__anon1c3a35040111::CSKYOperand2308ba622baSZi Xuan Wu   static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm) {
2318ba622baSZi Xuan Wu     if (auto CE = dyn_cast<MCConstantExpr>(Expr)) {
2328ba622baSZi Xuan Wu       Imm = CE->getValue();
2338ba622baSZi Xuan Wu       return true;
2348ba622baSZi Xuan Wu     }
2358ba622baSZi Xuan Wu 
2368ba622baSZi Xuan Wu     return false;
2378ba622baSZi Xuan Wu   }
2388ba622baSZi Xuan Wu 
isUImm__anon1c3a35040111::CSKYOperand2394216389cSZi Xuan Wu   template <unsigned num, unsigned shift = 0> bool isUImm() const {
2408ba622baSZi Xuan Wu     if (!isImm())
2418ba622baSZi Xuan Wu       return false;
2428ba622baSZi Xuan Wu 
2438ba622baSZi Xuan Wu     int64_t Imm;
2448ba622baSZi Xuan Wu     bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
2454216389cSZi Xuan Wu     return IsConstantImm && isShiftedUInt<num, shift>(Imm);
2468ba622baSZi Xuan Wu   }
2478ba622baSZi Xuan Wu 
isOImm__anon1c3a35040111::CSKYOperand2488ba622baSZi Xuan Wu   template <unsigned num> bool isOImm() const {
2498ba622baSZi Xuan Wu     if (!isImm())
2508ba622baSZi Xuan Wu       return false;
2518ba622baSZi Xuan Wu 
2528ba622baSZi Xuan Wu     int64_t Imm;
2538ba622baSZi Xuan Wu     bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
2548ba622baSZi Xuan Wu     return IsConstantImm && isUInt<num>(Imm - 1);
2558ba622baSZi Xuan Wu   }
2568ba622baSZi Xuan Wu 
isSImm__anon1c3a35040111::CSKYOperand2574216389cSZi Xuan Wu   template <unsigned num, unsigned shift = 0> bool isSImm() const {
2588ba622baSZi Xuan Wu     if (!isImm())
2598ba622baSZi Xuan Wu       return false;
2608ba622baSZi Xuan Wu 
2618ba622baSZi Xuan Wu     int64_t Imm;
2628ba622baSZi Xuan Wu     bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
2634216389cSZi Xuan Wu     return IsConstantImm && isShiftedInt<num, shift>(Imm);
2648ba622baSZi Xuan Wu   }
2658ba622baSZi Xuan Wu 
isUImm1__anon1c3a35040111::CSKYOperand266de10a02fSZi Xuan Wu   bool isUImm1() const { return isUImm<1>(); }
isUImm2__anon1c3a35040111::CSKYOperand2674216389cSZi Xuan Wu   bool isUImm2() const { return isUImm<2>(); }
isUImm3__anon1c3a35040111::CSKYOperand268de10a02fSZi Xuan Wu   bool isUImm3() const { return isUImm<3>(); }
isUImm4__anon1c3a35040111::CSKYOperand269de10a02fSZi Xuan Wu   bool isUImm4() const { return isUImm<4>(); }
isUImm5__anon1c3a35040111::CSKYOperand2708ba622baSZi Xuan Wu   bool isUImm5() const { return isUImm<5>(); }
isUImm6__anon1c3a35040111::CSKYOperand271de10a02fSZi Xuan Wu   bool isUImm6() const { return isUImm<6>(); }
isUImm7__anon1c3a35040111::CSKYOperand272de10a02fSZi Xuan Wu   bool isUImm7() const { return isUImm<7>(); }
isUImm8__anon1c3a35040111::CSKYOperand273de10a02fSZi Xuan Wu   bool isUImm8() const { return isUImm<8>(); }
isUImm12__anon1c3a35040111::CSKYOperand2748ba622baSZi Xuan Wu   bool isUImm12() const { return isUImm<12>(); }
isUImm16__anon1c3a35040111::CSKYOperand2754216389cSZi Xuan Wu   bool isUImm16() const { return isUImm<16>(); }
isUImm20__anon1c3a35040111::CSKYOperand276de10a02fSZi Xuan Wu   bool isUImm20() const { return isUImm<20>(); }
isUImm24__anon1c3a35040111::CSKYOperand277de10a02fSZi Xuan Wu   bool isUImm24() const { return isUImm<24>(); }
2784216389cSZi Xuan Wu 
isOImm3__anon1c3a35040111::CSKYOperand279de10a02fSZi Xuan Wu   bool isOImm3() const { return isOImm<3>(); }
isOImm4__anon1c3a35040111::CSKYOperand280de10a02fSZi Xuan Wu   bool isOImm4() const { return isOImm<4>(); }
isOImm5__anon1c3a35040111::CSKYOperand281de10a02fSZi Xuan Wu   bool isOImm5() const { return isOImm<5>(); }
isOImm6__anon1c3a35040111::CSKYOperand282de10a02fSZi Xuan Wu   bool isOImm6() const { return isOImm<6>(); }
isOImm8__anon1c3a35040111::CSKYOperand283de10a02fSZi Xuan Wu   bool isOImm8() const { return isOImm<8>(); }
isOImm12__anon1c3a35040111::CSKYOperand2848ba622baSZi Xuan Wu   bool isOImm12() const { return isOImm<12>(); }
isOImm16__anon1c3a35040111::CSKYOperand2854216389cSZi Xuan Wu   bool isOImm16() const { return isOImm<16>(); }
2864216389cSZi Xuan Wu 
isSImm8__anon1c3a35040111::CSKYOperand287de10a02fSZi Xuan Wu   bool isSImm8() const { return isSImm<8>(); }
288de10a02fSZi Xuan Wu 
isUImm5Shift1__anon1c3a35040111::CSKYOperand289de10a02fSZi Xuan Wu   bool isUImm5Shift1() { return isUImm<5, 1>(); }
isUImm5Shift2__anon1c3a35040111::CSKYOperand290de10a02fSZi Xuan Wu   bool isUImm5Shift2() { return isUImm<5, 2>(); }
isUImm7Shift1__anon1c3a35040111::CSKYOperand291de10a02fSZi Xuan Wu   bool isUImm7Shift1() { return isUImm<7, 1>(); }
isUImm7Shift2__anon1c3a35040111::CSKYOperand292de10a02fSZi Xuan Wu   bool isUImm7Shift2() { return isUImm<7, 2>(); }
isUImm7Shift3__anon1c3a35040111::CSKYOperand293de10a02fSZi Xuan Wu   bool isUImm7Shift3() { return isUImm<7, 3>(); }
isUImm8Shift2__anon1c3a35040111::CSKYOperand294de10a02fSZi Xuan Wu   bool isUImm8Shift2() { return isUImm<8, 2>(); }
isUImm8Shift3__anon1c3a35040111::CSKYOperand295de10a02fSZi Xuan Wu   bool isUImm8Shift3() { return isUImm<8, 3>(); }
isUImm8Shift8__anon1c3a35040111::CSKYOperand296de10a02fSZi Xuan Wu   bool isUImm8Shift8() { return isUImm<8, 8>(); }
isUImm8Shift16__anon1c3a35040111::CSKYOperand297de10a02fSZi Xuan Wu   bool isUImm8Shift16() { return isUImm<8, 16>(); }
isUImm8Shift24__anon1c3a35040111::CSKYOperand298de10a02fSZi Xuan Wu   bool isUImm8Shift24() { return isUImm<8, 24>(); }
isUImm12Shift1__anon1c3a35040111::CSKYOperand2994216389cSZi Xuan Wu   bool isUImm12Shift1() { return isUImm<12, 1>(); }
isUImm12Shift2__anon1c3a35040111::CSKYOperand3004216389cSZi Xuan Wu   bool isUImm12Shift2() { return isUImm<12, 2>(); }
isUImm16Shift8__anon1c3a35040111::CSKYOperand301de10a02fSZi Xuan Wu   bool isUImm16Shift8() { return isUImm<16, 8>(); }
isUImm16Shift16__anon1c3a35040111::CSKYOperand302de10a02fSZi Xuan Wu   bool isUImm16Shift16() { return isUImm<16, 16>(); }
isUImm24Shift8__anon1c3a35040111::CSKYOperand303de10a02fSZi Xuan Wu   bool isUImm24Shift8() { return isUImm<24, 8>(); }
3048ba622baSZi Xuan Wu 
isSImm16Shift1__anon1c3a35040111::CSKYOperand3054bb60c28SZi Xuan Wu   bool isSImm16Shift1() { return isSImm<16, 1>(); }
3064bb60c28SZi Xuan Wu 
isCSKYSymbol__anon1c3a35040111::CSKYOperand307de10a02fSZi Xuan Wu   bool isCSKYSymbol() const { return isImm(); }
308de10a02fSZi Xuan Wu 
isConstpool__anon1c3a35040111::CSKYOperand309de10a02fSZi Xuan Wu   bool isConstpool() const { return isConstPoolOp(); }
isDataSymbol__anon1c3a35040111::CSKYOperand310de10a02fSZi Xuan Wu   bool isDataSymbol() const { return isConstPoolOp(); }
311de10a02fSZi Xuan Wu 
isPSRFlag__anon1c3a35040111::CSKYOperand312de10a02fSZi Xuan Wu   bool isPSRFlag() const {
3134bb60c28SZi Xuan Wu     int64_t Imm;
314de10a02fSZi Xuan Wu     // Must be of 'immediate' type and a constant.
315de10a02fSZi Xuan Wu     if (!isImm() || !evaluateConstantImm(getImm(), Imm))
316de10a02fSZi Xuan Wu       return false;
317de10a02fSZi Xuan Wu 
318de10a02fSZi Xuan Wu     return isUInt<5>(Imm);
319de10a02fSZi Xuan Wu   }
320de10a02fSZi Xuan Wu 
isRegSeqTemplate__anon1c3a35040111::CSKYOperand321de10a02fSZi Xuan Wu   template <unsigned MIN, unsigned MAX> bool isRegSeqTemplate() const {
322de10a02fSZi Xuan Wu     if (!isRegisterSeq())
323de10a02fSZi Xuan Wu       return false;
324de10a02fSZi Xuan Wu 
325de10a02fSZi Xuan Wu     std::pair<unsigned, unsigned> regSeq = getRegSeq();
326de10a02fSZi Xuan Wu 
327de10a02fSZi Xuan Wu     return MIN <= regSeq.first && regSeq.first <= regSeq.second &&
328de10a02fSZi Xuan Wu            regSeq.second <= MAX;
329de10a02fSZi Xuan Wu   }
330de10a02fSZi Xuan Wu 
isRegSeq__anon1c3a35040111::CSKYOperand331de10a02fSZi Xuan Wu   bool isRegSeq() const { return isRegSeqTemplate<CSKY::R0, CSKY::R31>(); }
332de10a02fSZi Xuan Wu 
isRegSeqV1__anon1c3a35040111::CSKYOperand3334ad517e6SZi Xuan Wu   bool isRegSeqV1() const {
3344ad517e6SZi Xuan Wu     return isRegSeqTemplate<CSKY::F0_32, CSKY::F15_32>();
3354ad517e6SZi Xuan Wu   }
3364ad517e6SZi Xuan Wu 
isRegSeqV2__anon1c3a35040111::CSKYOperand3374ad517e6SZi Xuan Wu   bool isRegSeqV2() const {
3384ad517e6SZi Xuan Wu     return isRegSeqTemplate<CSKY::F0_32, CSKY::F31_32>();
3394ad517e6SZi Xuan Wu   }
3404ad517e6SZi Xuan Wu 
isLegalRegList__anon1c3a35040111::CSKYOperand341de10a02fSZi Xuan Wu   static bool isLegalRegList(unsigned from, unsigned to) {
342de10a02fSZi Xuan Wu     if (from == 0 && to == 0)
343de10a02fSZi Xuan Wu       return true;
344de10a02fSZi Xuan Wu 
345de10a02fSZi Xuan Wu     if (from == to) {
346de10a02fSZi Xuan Wu       if (from != CSKY::R4 && from != CSKY::R15 && from != CSKY::R16 &&
347de10a02fSZi Xuan Wu           from != CSKY::R28)
348de10a02fSZi Xuan Wu         return false;
349de10a02fSZi Xuan Wu 
350de10a02fSZi Xuan Wu       return true;
351de10a02fSZi Xuan Wu     } else {
352de10a02fSZi Xuan Wu       if (from != CSKY::R4 && from != CSKY::R16)
353de10a02fSZi Xuan Wu         return false;
354de10a02fSZi Xuan Wu 
355de10a02fSZi Xuan Wu       if (from == CSKY::R4 && to > CSKY::R4 && to < CSKY::R12)
356de10a02fSZi Xuan Wu         return true;
357de10a02fSZi Xuan Wu       else if (from == CSKY::R16 && to > CSKY::R16 && to < CSKY::R18)
358de10a02fSZi Xuan Wu         return true;
359de10a02fSZi Xuan Wu       else
360de10a02fSZi Xuan Wu         return false;
361de10a02fSZi Xuan Wu     }
362de10a02fSZi Xuan Wu   }
363de10a02fSZi Xuan Wu 
isRegList__anon1c3a35040111::CSKYOperand364de10a02fSZi Xuan Wu   bool isRegList() const {
365de10a02fSZi Xuan Wu     if (!isRegisterList())
366de10a02fSZi Xuan Wu       return false;
367de10a02fSZi Xuan Wu 
368de10a02fSZi Xuan Wu     auto regList = getRegList();
369de10a02fSZi Xuan Wu 
370de10a02fSZi Xuan Wu     if (!isLegalRegList(regList.List1From, regList.List1To))
371de10a02fSZi Xuan Wu       return false;
372de10a02fSZi Xuan Wu     if (!isLegalRegList(regList.List2From, regList.List2To))
373de10a02fSZi Xuan Wu       return false;
374de10a02fSZi Xuan Wu     if (!isLegalRegList(regList.List3From, regList.List3To))
375de10a02fSZi Xuan Wu       return false;
376de10a02fSZi Xuan Wu     if (!isLegalRegList(regList.List4From, regList.List4To))
377de10a02fSZi Xuan Wu       return false;
378de10a02fSZi Xuan Wu 
379de10a02fSZi Xuan Wu     return true;
380de10a02fSZi Xuan Wu   }
381de10a02fSZi Xuan Wu 
isExtImm6__anon1c3a35040111::CSKYOperand382de10a02fSZi Xuan Wu   bool isExtImm6() {
383de10a02fSZi Xuan Wu     if (!isImm())
384de10a02fSZi Xuan Wu       return false;
385de10a02fSZi Xuan Wu 
386de10a02fSZi Xuan Wu     int64_t Imm;
387de10a02fSZi Xuan Wu     bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
388de10a02fSZi Xuan Wu     if (!IsConstantImm)
389de10a02fSZi Xuan Wu       return false;
390de10a02fSZi Xuan Wu 
391de10a02fSZi Xuan Wu     int uimm4 = Imm & 0xf;
392de10a02fSZi Xuan Wu 
393de10a02fSZi Xuan Wu     return isShiftedUInt<6, 0>(Imm) && uimm4 >= 0 && uimm4 <= 14;
3944bb60c28SZi Xuan Wu   }
3954bb60c28SZi Xuan Wu 
3968ba622baSZi Xuan Wu   /// Gets location of the first token of this operand.
getStartLoc__anon1c3a35040111::CSKYOperand3978ba622baSZi Xuan Wu   SMLoc getStartLoc() const override { return StartLoc; }
3988ba622baSZi Xuan Wu   /// Gets location of the last token of this operand.
getEndLoc__anon1c3a35040111::CSKYOperand3998ba622baSZi Xuan Wu   SMLoc getEndLoc() const override { return EndLoc; }
4008ba622baSZi Xuan Wu 
getReg__anon1c3a35040111::CSKYOperand4018ba622baSZi Xuan Wu   unsigned getReg() const override {
4028ba622baSZi Xuan Wu     assert(Kind == Register && "Invalid type access!");
4038ba622baSZi Xuan Wu     return Reg.RegNum;
4048ba622baSZi Xuan Wu   }
4058ba622baSZi Xuan Wu 
getRegSeq__anon1c3a35040111::CSKYOperand406de10a02fSZi Xuan Wu   std::pair<unsigned, unsigned> getRegSeq() const {
407de10a02fSZi Xuan Wu     assert(Kind == RegisterSeq && "Invalid type access!");
408de10a02fSZi Xuan Wu     return std::pair<unsigned, unsigned>(RegSeq.RegNumFrom, RegSeq.RegNumTo);
409de10a02fSZi Xuan Wu   }
410de10a02fSZi Xuan Wu 
getRegList__anon1c3a35040111::CSKYOperand411de10a02fSZi Xuan Wu   RegListOp getRegList() const {
412de10a02fSZi Xuan Wu     assert(Kind == RegisterList && "Invalid type access!");
413de10a02fSZi Xuan Wu     return RegList;
414de10a02fSZi Xuan Wu   }
415de10a02fSZi Xuan Wu 
getImm__anon1c3a35040111::CSKYOperand4168ba622baSZi Xuan Wu   const MCExpr *getImm() const {
4178ba622baSZi Xuan Wu     assert(Kind == Immediate && "Invalid type access!");
4188ba622baSZi Xuan Wu     return Imm.Val;
4198ba622baSZi Xuan Wu   }
4208ba622baSZi Xuan Wu 
getConstpoolOp__anon1c3a35040111::CSKYOperand421de10a02fSZi Xuan Wu   const MCExpr *getConstpoolOp() const {
422de10a02fSZi Xuan Wu     assert(Kind == CPOP && "Invalid type access!");
423de10a02fSZi Xuan Wu     return CPool.Val;
424de10a02fSZi Xuan Wu   }
425de10a02fSZi Xuan Wu 
getToken__anon1c3a35040111::CSKYOperand4268ba622baSZi Xuan Wu   StringRef getToken() const {
4278ba622baSZi Xuan Wu     assert(Kind == Token && "Invalid type access!");
4288ba622baSZi Xuan Wu     return Tok;
4298ba622baSZi Xuan Wu   }
4308ba622baSZi Xuan Wu 
print__anon1c3a35040111::CSKYOperand4318ba622baSZi Xuan Wu   void print(raw_ostream &OS) const override {
432de10a02fSZi Xuan Wu     auto RegName = [](unsigned Reg) {
433de10a02fSZi Xuan Wu       if (Reg)
434de10a02fSZi Xuan Wu         return CSKYInstPrinter::getRegisterName(Reg);
435de10a02fSZi Xuan Wu       else
436de10a02fSZi Xuan Wu         return "noreg";
437de10a02fSZi Xuan Wu     };
438de10a02fSZi Xuan Wu 
4398ba622baSZi Xuan Wu     switch (Kind) {
440de10a02fSZi Xuan Wu     case CPOP:
441de10a02fSZi Xuan Wu       OS << *getConstpoolOp();
442de10a02fSZi Xuan Wu       break;
4438ba622baSZi Xuan Wu     case Immediate:
4448ba622baSZi Xuan Wu       OS << *getImm();
4458ba622baSZi Xuan Wu       break;
446de10a02fSZi Xuan Wu     case KindTy::Register:
447de10a02fSZi Xuan Wu       OS << "<register " << RegName(getReg()) << ">";
448de10a02fSZi Xuan Wu       break;
449de10a02fSZi Xuan Wu     case RegisterSeq:
450de10a02fSZi Xuan Wu       OS << "<register-seq ";
451de10a02fSZi Xuan Wu       OS << RegName(getRegSeq().first) << "-" << RegName(getRegSeq().second)
452de10a02fSZi Xuan Wu          << ">";
453de10a02fSZi Xuan Wu       break;
454de10a02fSZi Xuan Wu     case RegisterList:
455de10a02fSZi Xuan Wu       OS << "<register-list ";
456de10a02fSZi Xuan Wu       OS << RegName(getRegList().List1From) << "-"
457de10a02fSZi Xuan Wu          << RegName(getRegList().List1To) << ",";
458de10a02fSZi Xuan Wu       OS << RegName(getRegList().List2From) << "-"
459de10a02fSZi Xuan Wu          << RegName(getRegList().List2To) << ",";
460de10a02fSZi Xuan Wu       OS << RegName(getRegList().List3From) << "-"
461de10a02fSZi Xuan Wu          << RegName(getRegList().List3To) << ",";
462de10a02fSZi Xuan Wu       OS << RegName(getRegList().List4From) << "-"
463de10a02fSZi Xuan Wu          << RegName(getRegList().List4To);
4648ba622baSZi Xuan Wu       break;
4658ba622baSZi Xuan Wu     case Token:
4668ba622baSZi Xuan Wu       OS << "'" << getToken() << "'";
4678ba622baSZi Xuan Wu       break;
4688ba622baSZi Xuan Wu     }
4698ba622baSZi Xuan Wu   }
4708ba622baSZi Xuan Wu 
createToken__anon1c3a35040111::CSKYOperand4718ba622baSZi Xuan Wu   static std::unique_ptr<CSKYOperand> createToken(StringRef Str, SMLoc S) {
4728ba622baSZi Xuan Wu     auto Op = std::make_unique<CSKYOperand>(Token);
4738ba622baSZi Xuan Wu     Op->Tok = Str;
4748ba622baSZi Xuan Wu     Op->StartLoc = S;
4758ba622baSZi Xuan Wu     Op->EndLoc = S;
4768ba622baSZi Xuan Wu     return Op;
4778ba622baSZi Xuan Wu   }
4788ba622baSZi Xuan Wu 
createReg__anon1c3a35040111::CSKYOperand4798ba622baSZi Xuan Wu   static std::unique_ptr<CSKYOperand> createReg(unsigned RegNo, SMLoc S,
4808ba622baSZi Xuan Wu                                                 SMLoc E) {
4818ba622baSZi Xuan Wu     auto Op = std::make_unique<CSKYOperand>(Register);
4828ba622baSZi Xuan Wu     Op->Reg.RegNum = RegNo;
4838ba622baSZi Xuan Wu     Op->StartLoc = S;
4848ba622baSZi Xuan Wu     Op->EndLoc = E;
4858ba622baSZi Xuan Wu     return Op;
4868ba622baSZi Xuan Wu   }
4878ba622baSZi Xuan Wu 
createRegSeq__anon1c3a35040111::CSKYOperand488de10a02fSZi Xuan Wu   static std::unique_ptr<CSKYOperand> createRegSeq(unsigned RegNoFrom,
489de10a02fSZi Xuan Wu                                                    unsigned RegNoTo, SMLoc S) {
490de10a02fSZi Xuan Wu     auto Op = std::make_unique<CSKYOperand>(RegisterSeq);
491de10a02fSZi Xuan Wu     Op->RegSeq.RegNumFrom = RegNoFrom;
492de10a02fSZi Xuan Wu     Op->RegSeq.RegNumTo = RegNoTo;
493de10a02fSZi Xuan Wu     Op->StartLoc = S;
494de10a02fSZi Xuan Wu     Op->EndLoc = S;
495de10a02fSZi Xuan Wu     return Op;
496de10a02fSZi Xuan Wu   }
497de10a02fSZi Xuan Wu 
498de10a02fSZi Xuan Wu   static std::unique_ptr<CSKYOperand>
createRegList__anon1c3a35040111::CSKYOperand499de10a02fSZi Xuan Wu   createRegList(SmallVector<unsigned, 4> reglist, SMLoc S) {
500de10a02fSZi Xuan Wu     auto Op = std::make_unique<CSKYOperand>(RegisterList);
501de10a02fSZi Xuan Wu     Op->RegList.List1From = 0;
502de10a02fSZi Xuan Wu     Op->RegList.List1To = 0;
503de10a02fSZi Xuan Wu     Op->RegList.List2From = 0;
504de10a02fSZi Xuan Wu     Op->RegList.List2To = 0;
505de10a02fSZi Xuan Wu     Op->RegList.List3From = 0;
506de10a02fSZi Xuan Wu     Op->RegList.List3To = 0;
507de10a02fSZi Xuan Wu     Op->RegList.List4From = 0;
508de10a02fSZi Xuan Wu     Op->RegList.List4To = 0;
509de10a02fSZi Xuan Wu 
510de10a02fSZi Xuan Wu     for (unsigned i = 0; i < reglist.size(); i += 2) {
511de10a02fSZi Xuan Wu       if (Op->RegList.List1From == 0) {
512de10a02fSZi Xuan Wu         Op->RegList.List1From = reglist[i];
513de10a02fSZi Xuan Wu         Op->RegList.List1To = reglist[i + 1];
514de10a02fSZi Xuan Wu       } else if (Op->RegList.List2From == 0) {
515de10a02fSZi Xuan Wu         Op->RegList.List2From = reglist[i];
516de10a02fSZi Xuan Wu         Op->RegList.List2To = reglist[i + 1];
517de10a02fSZi Xuan Wu       } else if (Op->RegList.List3From == 0) {
518de10a02fSZi Xuan Wu         Op->RegList.List3From = reglist[i];
519de10a02fSZi Xuan Wu         Op->RegList.List3To = reglist[i + 1];
520de10a02fSZi Xuan Wu       } else if (Op->RegList.List4From == 0) {
521de10a02fSZi Xuan Wu         Op->RegList.List4From = reglist[i];
522de10a02fSZi Xuan Wu         Op->RegList.List4To = reglist[i + 1];
523de10a02fSZi Xuan Wu       } else {
524de10a02fSZi Xuan Wu         assert(0);
525de10a02fSZi Xuan Wu       }
526de10a02fSZi Xuan Wu     }
527de10a02fSZi Xuan Wu 
528de10a02fSZi Xuan Wu     Op->StartLoc = S;
529de10a02fSZi Xuan Wu     Op->EndLoc = S;
530de10a02fSZi Xuan Wu     return Op;
531de10a02fSZi Xuan Wu   }
532de10a02fSZi Xuan Wu 
createImm__anon1c3a35040111::CSKYOperand5338ba622baSZi Xuan Wu   static std::unique_ptr<CSKYOperand> createImm(const MCExpr *Val, SMLoc S,
5348ba622baSZi Xuan Wu                                                 SMLoc E) {
5358ba622baSZi Xuan Wu     auto Op = std::make_unique<CSKYOperand>(Immediate);
5368ba622baSZi Xuan Wu     Op->Imm.Val = Val;
5378ba622baSZi Xuan Wu     Op->StartLoc = S;
5388ba622baSZi Xuan Wu     Op->EndLoc = E;
5398ba622baSZi Xuan Wu     return Op;
5408ba622baSZi Xuan Wu   }
5418ba622baSZi Xuan Wu 
createConstpoolOp__anon1c3a35040111::CSKYOperand542de10a02fSZi Xuan Wu   static std::unique_ptr<CSKYOperand> createConstpoolOp(const MCExpr *Val,
543de10a02fSZi Xuan Wu                                                         SMLoc S, SMLoc E) {
544de10a02fSZi Xuan Wu     auto Op = std::make_unique<CSKYOperand>(CPOP);
545de10a02fSZi Xuan Wu     Op->CPool.Val = Val;
546de10a02fSZi Xuan Wu     Op->StartLoc = S;
547de10a02fSZi Xuan Wu     Op->EndLoc = E;
548de10a02fSZi Xuan Wu     return Op;
549de10a02fSZi Xuan Wu   }
550de10a02fSZi Xuan Wu 
addExpr__anon1c3a35040111::CSKYOperand5518ba622baSZi Xuan Wu   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
5528ba622baSZi Xuan Wu     assert(Expr && "Expr shouldn't be null!");
5538ba622baSZi Xuan Wu     if (auto *CE = dyn_cast<MCConstantExpr>(Expr))
5548ba622baSZi Xuan Wu       Inst.addOperand(MCOperand::createImm(CE->getValue()));
5558ba622baSZi Xuan Wu     else
5568ba622baSZi Xuan Wu       Inst.addOperand(MCOperand::createExpr(Expr));
5578ba622baSZi Xuan Wu   }
5588ba622baSZi Xuan Wu 
5598ba622baSZi Xuan Wu   // Used by the TableGen Code.
addRegOperands__anon1c3a35040111::CSKYOperand5608ba622baSZi Xuan Wu   void addRegOperands(MCInst &Inst, unsigned N) const {
5618ba622baSZi Xuan Wu     assert(N == 1 && "Invalid number of operands!");
5628ba622baSZi Xuan Wu     Inst.addOperand(MCOperand::createReg(getReg()));
5638ba622baSZi Xuan Wu   }
5648ba622baSZi Xuan Wu 
addImmOperands__anon1c3a35040111::CSKYOperand5658ba622baSZi Xuan Wu   void addImmOperands(MCInst &Inst, unsigned N) const {
5668ba622baSZi Xuan Wu     assert(N == 1 && "Invalid number of operands!");
5678ba622baSZi Xuan Wu     addExpr(Inst, getImm());
5688ba622baSZi Xuan Wu   }
569de10a02fSZi Xuan Wu 
addConstpoolOperands__anon1c3a35040111::CSKYOperand570de10a02fSZi Xuan Wu   void addConstpoolOperands(MCInst &Inst, unsigned N) const {
571de10a02fSZi Xuan Wu     assert(N == 1 && "Invalid number of operands!");
572de10a02fSZi Xuan Wu     Inst.addOperand(MCOperand::createExpr(getConstpoolOp()));
573de10a02fSZi Xuan Wu   }
574de10a02fSZi Xuan Wu 
addRegSeqOperands__anon1c3a35040111::CSKYOperand575de10a02fSZi Xuan Wu   void addRegSeqOperands(MCInst &Inst, unsigned N) const {
576de10a02fSZi Xuan Wu     assert(N == 2 && "Invalid number of operands!");
577de10a02fSZi Xuan Wu     auto regSeq = getRegSeq();
578de10a02fSZi Xuan Wu 
579de10a02fSZi Xuan Wu     Inst.addOperand(MCOperand::createReg(regSeq.first));
580de10a02fSZi Xuan Wu     Inst.addOperand(MCOperand::createReg(regSeq.second));
581de10a02fSZi Xuan Wu   }
582de10a02fSZi Xuan Wu 
getListValue__anon1c3a35040111::CSKYOperand583de10a02fSZi Xuan Wu   static unsigned getListValue(unsigned ListFrom, unsigned ListTo) {
584de10a02fSZi Xuan Wu     if (ListFrom == ListTo && ListFrom == CSKY::R15)
585de10a02fSZi Xuan Wu       return (1 << 4);
586de10a02fSZi Xuan Wu     else if (ListFrom == ListTo && ListFrom == CSKY::R28)
587de10a02fSZi Xuan Wu       return (1 << 8);
588de10a02fSZi Xuan Wu     else if (ListFrom == CSKY::R4)
589de10a02fSZi Xuan Wu       return ListTo - ListFrom + 1;
590de10a02fSZi Xuan Wu     else if (ListFrom == CSKY::R16)
591de10a02fSZi Xuan Wu       return ((ListTo - ListFrom + 1) << 5);
592de10a02fSZi Xuan Wu     else
593de10a02fSZi Xuan Wu       return 0;
594de10a02fSZi Xuan Wu   }
595de10a02fSZi Xuan Wu 
addRegListOperands__anon1c3a35040111::CSKYOperand596de10a02fSZi Xuan Wu   void addRegListOperands(MCInst &Inst, unsigned N) const {
597de10a02fSZi Xuan Wu     assert(N == 1 && "Invalid number of operands!");
598de10a02fSZi Xuan Wu     auto regList = getRegList();
599de10a02fSZi Xuan Wu 
600de10a02fSZi Xuan Wu     unsigned V = 0;
601de10a02fSZi Xuan Wu 
602de10a02fSZi Xuan Wu     unsigned T = getListValue(regList.List1From, regList.List1To);
603de10a02fSZi Xuan Wu     if (T != 0)
604de10a02fSZi Xuan Wu       V = V | T;
605de10a02fSZi Xuan Wu 
606de10a02fSZi Xuan Wu     T = getListValue(regList.List2From, regList.List2To);
607de10a02fSZi Xuan Wu     if (T != 0)
608de10a02fSZi Xuan Wu       V = V | T;
609de10a02fSZi Xuan Wu 
610de10a02fSZi Xuan Wu     T = getListValue(regList.List3From, regList.List3To);
611de10a02fSZi Xuan Wu     if (T != 0)
612de10a02fSZi Xuan Wu       V = V | T;
613de10a02fSZi Xuan Wu 
614de10a02fSZi Xuan Wu     T = getListValue(regList.List4From, regList.List4To);
615de10a02fSZi Xuan Wu     if (T != 0)
616de10a02fSZi Xuan Wu       V = V | T;
617de10a02fSZi Xuan Wu 
618de10a02fSZi Xuan Wu     Inst.addOperand(MCOperand::createImm(V));
619de10a02fSZi Xuan Wu   }
620de10a02fSZi Xuan Wu 
isValidForTie__anon1c3a35040111::CSKYOperand621de10a02fSZi Xuan Wu   bool isValidForTie(const CSKYOperand &Other) const {
622de10a02fSZi Xuan Wu     if (Kind != Other.Kind)
623de10a02fSZi Xuan Wu       return false;
624de10a02fSZi Xuan Wu 
625de10a02fSZi Xuan Wu     switch (Kind) {
626de10a02fSZi Xuan Wu     default:
627de10a02fSZi Xuan Wu       llvm_unreachable("Unexpected kind");
628de10a02fSZi Xuan Wu       return false;
629de10a02fSZi Xuan Wu     case Register:
630de10a02fSZi Xuan Wu       return Reg.RegNum == Other.Reg.RegNum;
631de10a02fSZi Xuan Wu     }
632de10a02fSZi Xuan Wu   }
6338ba622baSZi Xuan Wu };
6348ba622baSZi Xuan Wu } // end anonymous namespace.
6358ba622baSZi Xuan Wu 
6368ba622baSZi Xuan Wu #define GET_REGISTER_MATCHER
6378ba622baSZi Xuan Wu #define GET_SUBTARGET_FEATURE_NAME
6388ba622baSZi Xuan Wu #define GET_MATCHER_IMPLEMENTATION
6398ba622baSZi Xuan Wu #define GET_MNEMONIC_SPELL_CHECKER
6408ba622baSZi Xuan Wu #include "CSKYGenAsmMatcher.inc"
6418ba622baSZi Xuan Wu 
convertFPR32ToFPR64(MCRegister Reg)642a190fcdfSZi Xuan Wu static MCRegister convertFPR32ToFPR64(MCRegister Reg) {
643a190fcdfSZi Xuan Wu   assert(Reg >= CSKY::F0_32 && Reg <= CSKY::F31_32 && "Invalid register");
644a190fcdfSZi Xuan Wu   return Reg - CSKY::F0_32 + CSKY::F0_64;
645a190fcdfSZi Xuan Wu }
646a190fcdfSZi Xuan Wu 
6478ba622baSZi Xuan Wu static std::string CSKYMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
6488ba622baSZi Xuan Wu                                           unsigned VariantID = 0);
6498ba622baSZi Xuan Wu 
generateImmOutOfRangeError(OperandVector & Operands,uint64_t ErrorInfo,int64_t Lower,int64_t Upper,Twine Msg="immediate must be an integer in the range")6508ba622baSZi Xuan Wu bool CSKYAsmParser::generateImmOutOfRangeError(
6518ba622baSZi Xuan Wu     OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,
6528ba622baSZi Xuan Wu     Twine Msg = "immediate must be an integer in the range") {
6538ba622baSZi Xuan Wu   SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
6548ba622baSZi Xuan Wu   return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
6558ba622baSZi Xuan Wu }
6568ba622baSZi Xuan Wu 
MatchAndEmitInstruction(SMLoc IDLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)6578ba622baSZi Xuan Wu bool CSKYAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
6588ba622baSZi Xuan Wu                                             OperandVector &Operands,
6598ba622baSZi Xuan Wu                                             MCStreamer &Out,
6608ba622baSZi Xuan Wu                                             uint64_t &ErrorInfo,
6618ba622baSZi Xuan Wu                                             bool MatchingInlineAsm) {
6628ba622baSZi Xuan Wu   MCInst Inst;
6638ba622baSZi Xuan Wu   FeatureBitset MissingFeatures;
6648ba622baSZi Xuan Wu 
6658ba622baSZi Xuan Wu   auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
6668ba622baSZi Xuan Wu                                      MatchingInlineAsm);
6678ba622baSZi Xuan Wu   switch (Result) {
6688ba622baSZi Xuan Wu   default:
6698ba622baSZi Xuan Wu     break;
6708ba622baSZi Xuan Wu   case Match_Success:
671de10a02fSZi Xuan Wu     return processInstruction(Inst, IDLoc, Operands, Out);
6728ba622baSZi Xuan Wu   case Match_MissingFeature: {
6738ba622baSZi Xuan Wu     assert(MissingFeatures.any() && "Unknown missing features!");
6748ba622baSZi Xuan Wu     ListSeparator LS;
6758ba622baSZi Xuan Wu     std::string Msg = "instruction requires the following: ";
6768ba622baSZi Xuan Wu     for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {
6778ba622baSZi Xuan Wu       if (MissingFeatures[i]) {
6788ba622baSZi Xuan Wu         Msg += LS;
6798ba622baSZi Xuan Wu         Msg += getSubtargetFeatureName(i);
6808ba622baSZi Xuan Wu       }
6818ba622baSZi Xuan Wu     }
6828ba622baSZi Xuan Wu     return Error(IDLoc, Msg);
6838ba622baSZi Xuan Wu   }
6848ba622baSZi Xuan Wu   case Match_MnemonicFail: {
6858ba622baSZi Xuan Wu     FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6868ba622baSZi Xuan Wu     std::string Suggestion =
6878ba622baSZi Xuan Wu         CSKYMnemonicSpellCheck(((CSKYOperand &)*Operands[0]).getToken(), FBS);
6888ba622baSZi Xuan Wu     return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion);
6898ba622baSZi Xuan Wu   }
6904216389cSZi Xuan Wu   case Match_InvalidTiedOperand:
6918ba622baSZi Xuan Wu   case Match_InvalidOperand: {
6928ba622baSZi Xuan Wu     SMLoc ErrorLoc = IDLoc;
6938ba622baSZi Xuan Wu     if (ErrorInfo != ~0U) {
6948ba622baSZi Xuan Wu       if (ErrorInfo >= Operands.size())
6958ba622baSZi Xuan Wu         return Error(ErrorLoc, "too few operands for instruction");
6968ba622baSZi Xuan Wu 
6978ba622baSZi Xuan Wu       ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
6988ba622baSZi Xuan Wu       if (ErrorLoc == SMLoc())
6998ba622baSZi Xuan Wu         ErrorLoc = IDLoc;
7008ba622baSZi Xuan Wu     }
7018ba622baSZi Xuan Wu     return Error(ErrorLoc, "invalid operand for instruction");
7028ba622baSZi Xuan Wu   }
7038ba622baSZi Xuan Wu   }
7048ba622baSZi Xuan Wu 
7058ba622baSZi Xuan Wu   // Handle the case when the error message is of specific type
7068ba622baSZi Xuan Wu   // other than the generic Match_InvalidOperand, and the
7078ba622baSZi Xuan Wu   // corresponding operand is missing.
7088ba622baSZi Xuan Wu   if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
7098ba622baSZi Xuan Wu     SMLoc ErrorLoc = IDLoc;
7108ba622baSZi Xuan Wu     if (ErrorInfo != ~0U && ErrorInfo >= Operands.size())
7118ba622baSZi Xuan Wu       return Error(ErrorLoc, "too few operands for instruction");
7128ba622baSZi Xuan Wu   }
7138ba622baSZi Xuan Wu 
7148ba622baSZi Xuan Wu   switch (Result) {
7158ba622baSZi Xuan Wu   default:
7168ba622baSZi Xuan Wu     break;
717de10a02fSZi Xuan Wu   case Match_InvalidSImm8:
718de10a02fSZi Xuan Wu     return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),
719de10a02fSZi Xuan Wu                                       (1 << 7) - 1);
720de10a02fSZi Xuan Wu   case Match_InvalidOImm3:
721de10a02fSZi Xuan Wu     return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 3));
722de10a02fSZi Xuan Wu   case Match_InvalidOImm4:
723de10a02fSZi Xuan Wu     return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4));
724de10a02fSZi Xuan Wu   case Match_InvalidOImm5:
725de10a02fSZi Xuan Wu     return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5));
726de10a02fSZi Xuan Wu   case Match_InvalidOImm6:
727de10a02fSZi Xuan Wu     return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6));
728de10a02fSZi Xuan Wu   case Match_InvalidOImm8:
729de10a02fSZi Xuan Wu     return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 8));
7308ba622baSZi Xuan Wu   case Match_InvalidOImm12:
7318ba622baSZi Xuan Wu     return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 12));
7324216389cSZi Xuan Wu   case Match_InvalidOImm16:
7334216389cSZi Xuan Wu     return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16));
734de10a02fSZi Xuan Wu   case Match_InvalidUImm1:
735de10a02fSZi Xuan Wu     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);
7364216389cSZi Xuan Wu   case Match_InvalidUImm2:
7374216389cSZi Xuan Wu     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);
738de10a02fSZi Xuan Wu   case Match_InvalidUImm3:
739de10a02fSZi Xuan Wu     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);
740de10a02fSZi Xuan Wu   case Match_InvalidUImm4:
741de10a02fSZi Xuan Wu     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
7428ba622baSZi Xuan Wu   case Match_InvalidUImm5:
7438ba622baSZi Xuan Wu     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
744de10a02fSZi Xuan Wu   case Match_InvalidUImm6:
745de10a02fSZi Xuan Wu     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
746de10a02fSZi Xuan Wu   case Match_InvalidUImm7:
747de10a02fSZi Xuan Wu     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);
748de10a02fSZi Xuan Wu   case Match_InvalidUImm8:
749de10a02fSZi Xuan Wu     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);
7504216389cSZi Xuan Wu   case Match_InvalidUImm12:
7514216389cSZi Xuan Wu     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1);
752de10a02fSZi Xuan Wu   case Match_InvalidUImm16:
753de10a02fSZi Xuan Wu     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 16) - 1);
754de10a02fSZi Xuan Wu   case Match_InvalidUImm5Shift1:
755de10a02fSZi Xuan Wu     return generateImmOutOfRangeError(
756de10a02fSZi Xuan Wu         Operands, ErrorInfo, 0, (1 << 5) - 2,
757de10a02fSZi Xuan Wu         "immediate must be a multiple of 2 bytes in the range");
7584216389cSZi Xuan Wu   case Match_InvalidUImm12Shift1:
7594216389cSZi Xuan Wu     return generateImmOutOfRangeError(
7604216389cSZi Xuan Wu         Operands, ErrorInfo, 0, (1 << 12) - 2,
7614216389cSZi Xuan Wu         "immediate must be a multiple of 2 bytes in the range");
762de10a02fSZi Xuan Wu   case Match_InvalidUImm5Shift2:
763de10a02fSZi Xuan Wu     return generateImmOutOfRangeError(
764de10a02fSZi Xuan Wu         Operands, ErrorInfo, 0, (1 << 5) - 4,
765de10a02fSZi Xuan Wu         "immediate must be a multiple of 4 bytes in the range");
766de10a02fSZi Xuan Wu   case Match_InvalidUImm7Shift1:
767de10a02fSZi Xuan Wu     return generateImmOutOfRangeError(
768de10a02fSZi Xuan Wu         Operands, ErrorInfo, 0, (1 << 7) - 2,
769de10a02fSZi Xuan Wu         "immediate must be a multiple of 2 bytes in the range");
770de10a02fSZi Xuan Wu   case Match_InvalidUImm7Shift2:
771de10a02fSZi Xuan Wu     return generateImmOutOfRangeError(
772de10a02fSZi Xuan Wu         Operands, ErrorInfo, 0, (1 << 7) - 4,
773de10a02fSZi Xuan Wu         "immediate must be a multiple of 4 bytes in the range");
774de10a02fSZi Xuan Wu   case Match_InvalidUImm8Shift2:
775de10a02fSZi Xuan Wu     return generateImmOutOfRangeError(
776de10a02fSZi Xuan Wu         Operands, ErrorInfo, 0, (1 << 8) - 4,
777de10a02fSZi Xuan Wu         "immediate must be a multiple of 4 bytes in the range");
778de10a02fSZi Xuan Wu   case Match_InvalidUImm8Shift3:
779de10a02fSZi Xuan Wu     return generateImmOutOfRangeError(
780de10a02fSZi Xuan Wu         Operands, ErrorInfo, 0, (1 << 8) - 8,
781de10a02fSZi Xuan Wu         "immediate must be a multiple of 8 bytes in the range");
782de10a02fSZi Xuan Wu   case Match_InvalidUImm8Shift8:
783de10a02fSZi Xuan Wu     return generateImmOutOfRangeError(
784de10a02fSZi Xuan Wu         Operands, ErrorInfo, 0, (1 << 8) - 256,
785de10a02fSZi Xuan Wu         "immediate must be a multiple of 256 bytes in the range");
7864216389cSZi Xuan Wu   case Match_InvalidUImm12Shift2:
7874216389cSZi Xuan Wu     return generateImmOutOfRangeError(
7884216389cSZi Xuan Wu         Operands, ErrorInfo, 0, (1 << 12) - 4,
7894216389cSZi Xuan Wu         "immediate must be a multiple of 4 bytes in the range");
7904bb60c28SZi Xuan Wu   case Match_InvalidCSKYSymbol: {
7914bb60c28SZi Xuan Wu     SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
7924bb60c28SZi Xuan Wu     return Error(ErrorLoc, "operand must be a symbol name");
7934bb60c28SZi Xuan Wu   }
7944bb60c28SZi Xuan Wu   case Match_InvalidConstpool: {
7954bb60c28SZi Xuan Wu     SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
7964bb60c28SZi Xuan Wu     return Error(ErrorLoc, "operand must be a constpool symbol name");
7974bb60c28SZi Xuan Wu   }
798de10a02fSZi Xuan Wu   case Match_InvalidPSRFlag: {
799de10a02fSZi Xuan Wu     SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
800de10a02fSZi Xuan Wu     return Error(ErrorLoc, "psrset operand is not valid");
801de10a02fSZi Xuan Wu   }
802de10a02fSZi Xuan Wu   case Match_InvalidRegSeq: {
803de10a02fSZi Xuan Wu     SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
804de10a02fSZi Xuan Wu     return Error(ErrorLoc, "Register sequence is not valid");
805de10a02fSZi Xuan Wu   }
806de10a02fSZi Xuan Wu   case Match_InvalidRegOutOfRange: {
807de10a02fSZi Xuan Wu     SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
808de10a02fSZi Xuan Wu     return Error(ErrorLoc, "register is out of range");
809de10a02fSZi Xuan Wu   }
810de10a02fSZi Xuan Wu   case Match_RequiresSameSrcAndDst: {
811de10a02fSZi Xuan Wu     SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
812de10a02fSZi Xuan Wu     return Error(ErrorLoc, "src and dst operand must be same");
813de10a02fSZi Xuan Wu   }
814de10a02fSZi Xuan Wu   case Match_InvalidRegList: {
815de10a02fSZi Xuan Wu     SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
816de10a02fSZi Xuan Wu     return Error(ErrorLoc, "invalid register list");
817de10a02fSZi Xuan Wu   }
818de10a02fSZi Xuan Wu   }
819de10a02fSZi Xuan Wu   LLVM_DEBUG(dbgs() << "Result = " << Result);
820de10a02fSZi Xuan Wu   llvm_unreachable("Unknown match type detected!");
8218ba622baSZi Xuan Wu }
8228ba622baSZi Xuan Wu 
processLRW(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out)823582836faSZi Xuan Wu bool CSKYAsmParser::processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
824582836faSZi Xuan Wu   Inst.setLoc(IDLoc);
825582836faSZi Xuan Wu 
826582836faSZi Xuan Wu   unsigned Opcode;
827582836faSZi Xuan Wu   MCOperand Op;
828582836faSZi Xuan Wu   if (Inst.getOpcode() == CSKY::PseudoLRW16)
829582836faSZi Xuan Wu     Opcode = CSKY::LRW16;
830582836faSZi Xuan Wu   else
831582836faSZi Xuan Wu     Opcode = CSKY::LRW32;
832582836faSZi Xuan Wu 
833582836faSZi Xuan Wu   if (Inst.getOperand(1).isImm()) {
834582836faSZi Xuan Wu     if (isUInt<8>(Inst.getOperand(1).getImm()) &&
835582836faSZi Xuan Wu         Inst.getOperand(0).getReg() <= CSKY::R7) {
836582836faSZi Xuan Wu       Opcode = CSKY::MOVI16;
837582836faSZi Xuan Wu     } else if (getSTI().getFeatureBits()[CSKY::HasE2] &&
838582836faSZi Xuan Wu                isUInt<16>(Inst.getOperand(1).getImm())) {
839582836faSZi Xuan Wu       Opcode = CSKY::MOVI32;
840582836faSZi Xuan Wu     } else {
841582836faSZi Xuan Wu       auto *Expr = getTargetStreamer().addConstantPoolEntry(
842582836faSZi Xuan Wu           MCConstantExpr::create(Inst.getOperand(1).getImm(), getContext()),
843582836faSZi Xuan Wu           Inst.getLoc());
844582836faSZi Xuan Wu       Inst.erase(std::prev(Inst.end()));
845582836faSZi Xuan Wu       Inst.addOperand(MCOperand::createExpr(Expr));
846582836faSZi Xuan Wu     }
847582836faSZi Xuan Wu   } else {
848582836faSZi Xuan Wu     const MCExpr *AdjustExpr = nullptr;
849582836faSZi Xuan Wu     if (const CSKYMCExpr *CSKYExpr =
850582836faSZi Xuan Wu             dyn_cast<CSKYMCExpr>(Inst.getOperand(1).getExpr())) {
851582836faSZi Xuan Wu       if (CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSGD ||
852582836faSZi Xuan Wu           CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSIE ||
853582836faSZi Xuan Wu           CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSLDM) {
854582836faSZi Xuan Wu         MCSymbol *Dot = getContext().createNamedTempSymbol();
855582836faSZi Xuan Wu         Out.emitLabel(Dot);
856582836faSZi Xuan Wu         AdjustExpr = MCSymbolRefExpr::create(Dot, getContext());
857582836faSZi Xuan Wu       }
858582836faSZi Xuan Wu     }
859582836faSZi Xuan Wu     auto *Expr = getTargetStreamer().addConstantPoolEntry(
860582836faSZi Xuan Wu         Inst.getOperand(1).getExpr(), Inst.getLoc(), AdjustExpr);
861582836faSZi Xuan Wu     Inst.erase(std::prev(Inst.end()));
862582836faSZi Xuan Wu     Inst.addOperand(MCOperand::createExpr(Expr));
863582836faSZi Xuan Wu   }
864582836faSZi Xuan Wu 
865582836faSZi Xuan Wu   Inst.setOpcode(Opcode);
866582836faSZi Xuan Wu 
867582836faSZi Xuan Wu   Out.emitInstruction(Inst, getSTI());
868582836faSZi Xuan Wu   return false;
869582836faSZi Xuan Wu }
870582836faSZi Xuan Wu 
processJSRI(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out)871582836faSZi Xuan Wu bool CSKYAsmParser::processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
872582836faSZi Xuan Wu   Inst.setLoc(IDLoc);
873582836faSZi Xuan Wu 
874582836faSZi Xuan Wu   if (Inst.getOperand(0).isImm()) {
875582836faSZi Xuan Wu     const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
876582836faSZi Xuan Wu         MCConstantExpr::create(Inst.getOperand(0).getImm(), getContext()),
877582836faSZi Xuan Wu         Inst.getLoc());
878582836faSZi Xuan Wu     Inst.setOpcode(CSKY::JSRI32);
879582836faSZi Xuan Wu     Inst.erase(std::prev(Inst.end()));
880582836faSZi Xuan Wu     Inst.addOperand(MCOperand::createExpr(Expr));
881582836faSZi Xuan Wu   } else {
882582836faSZi Xuan Wu     const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
883582836faSZi Xuan Wu         Inst.getOperand(0).getExpr(), Inst.getLoc());
884582836faSZi Xuan Wu     Inst.setOpcode(CSKY::JBSR32);
885582836faSZi Xuan Wu     Inst.addOperand(MCOperand::createExpr(Expr));
886582836faSZi Xuan Wu   }
887582836faSZi Xuan Wu 
888582836faSZi Xuan Wu   Out.emitInstruction(Inst, getSTI());
889582836faSZi Xuan Wu   return false;
890582836faSZi Xuan Wu }
891582836faSZi Xuan Wu 
processJMPI(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out)892582836faSZi Xuan Wu bool CSKYAsmParser::processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
893582836faSZi Xuan Wu   Inst.setLoc(IDLoc);
894582836faSZi Xuan Wu 
895582836faSZi Xuan Wu   if (Inst.getOperand(0).isImm()) {
896582836faSZi Xuan Wu     const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
897582836faSZi Xuan Wu         MCConstantExpr::create(Inst.getOperand(0).getImm(), getContext()),
898582836faSZi Xuan Wu         Inst.getLoc());
899582836faSZi Xuan Wu     Inst.setOpcode(CSKY::JMPI32);
900582836faSZi Xuan Wu     Inst.erase(std::prev(Inst.end()));
901582836faSZi Xuan Wu     Inst.addOperand(MCOperand::createExpr(Expr));
902582836faSZi Xuan Wu   } else {
903582836faSZi Xuan Wu     const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
904582836faSZi Xuan Wu         Inst.getOperand(0).getExpr(), Inst.getLoc());
905582836faSZi Xuan Wu     Inst.setOpcode(CSKY::JBR32);
906582836faSZi Xuan Wu     Inst.addOperand(MCOperand::createExpr(Expr));
907582836faSZi Xuan Wu   }
908582836faSZi Xuan Wu 
909582836faSZi Xuan Wu   Out.emitInstruction(Inst, getSTI());
910582836faSZi Xuan Wu   return false;
911582836faSZi Xuan Wu }
912582836faSZi Xuan Wu 
processInstruction(MCInst & Inst,SMLoc IDLoc,OperandVector & Operands,MCStreamer & Out)913de10a02fSZi Xuan Wu bool CSKYAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
914de10a02fSZi Xuan Wu                                        OperandVector &Operands,
915de10a02fSZi Xuan Wu                                        MCStreamer &Out) {
916de10a02fSZi Xuan Wu 
917bdd7c53dSZi Xuan Wu   switch (Inst.getOpcode()) {
918bdd7c53dSZi Xuan Wu   default:
919bdd7c53dSZi Xuan Wu     break;
920bdd7c53dSZi Xuan Wu   case CSKY::LDQ32:
921bdd7c53dSZi Xuan Wu   case CSKY::STQ32:
922de10a02fSZi Xuan Wu     if (Inst.getOperand(1).getReg() != CSKY::R4 ||
923de10a02fSZi Xuan Wu         Inst.getOperand(2).getReg() != CSKY::R7) {
924de10a02fSZi Xuan Wu       return Error(IDLoc, "Register sequence is not valid. 'r4-r7' expected");
925de10a02fSZi Xuan Wu     }
926de10a02fSZi Xuan Wu     Inst.setOpcode(Inst.getOpcode() == CSKY::LDQ32 ? CSKY::LDM32 : CSKY::STM32);
927bdd7c53dSZi Xuan Wu     break;
928bdd7c53dSZi Xuan Wu   case CSKY::SEXT32:
929bdd7c53dSZi Xuan Wu   case CSKY::ZEXT32:
930de10a02fSZi Xuan Wu     if (Inst.getOperand(2).getImm() < Inst.getOperand(3).getImm())
931de10a02fSZi Xuan Wu       return Error(IDLoc, "msb must be greater or equal to lsb");
932bdd7c53dSZi Xuan Wu     break;
933bdd7c53dSZi Xuan Wu   case CSKY::INS32:
934de10a02fSZi Xuan Wu     if (Inst.getOperand(3).getImm() < Inst.getOperand(4).getImm())
935de10a02fSZi Xuan Wu       return Error(IDLoc, "msb must be greater or equal to lsb");
936bdd7c53dSZi Xuan Wu     break;
937bdd7c53dSZi Xuan Wu   case CSKY::IDLY32:
938de10a02fSZi Xuan Wu     if (Inst.getOperand(0).getImm() > 32 || Inst.getOperand(0).getImm() < 0)
939de10a02fSZi Xuan Wu       return Error(IDLoc, "n must be in range [0,32]");
940bdd7c53dSZi Xuan Wu     break;
941bdd7c53dSZi Xuan Wu   case CSKY::ADDC32:
942bdd7c53dSZi Xuan Wu   case CSKY::SUBC32:
943bdd7c53dSZi Xuan Wu   case CSKY::ADDC16:
944bdd7c53dSZi Xuan Wu   case CSKY::SUBC16:
945bdd7c53dSZi Xuan Wu     Inst.erase(std::next(Inst.begin()));
946bdd7c53dSZi Xuan Wu     Inst.erase(std::prev(Inst.end()));
947bdd7c53dSZi Xuan Wu     Inst.insert(std::next(Inst.begin()), MCOperand::createReg(CSKY::C));
948bdd7c53dSZi Xuan Wu     Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C));
949bdd7c53dSZi Xuan Wu     break;
950bdd7c53dSZi Xuan Wu   case CSKY::CMPNEI32:
951bdd7c53dSZi Xuan Wu   case CSKY::CMPNEI16:
952bdd7c53dSZi Xuan Wu   case CSKY::CMPNE32:
953bdd7c53dSZi Xuan Wu   case CSKY::CMPNE16:
954bdd7c53dSZi Xuan Wu   case CSKY::CMPHSI32:
955bdd7c53dSZi Xuan Wu   case CSKY::CMPHSI16:
956bdd7c53dSZi Xuan Wu   case CSKY::CMPHS32:
957bdd7c53dSZi Xuan Wu   case CSKY::CMPHS16:
958bdd7c53dSZi Xuan Wu   case CSKY::CMPLTI32:
959bdd7c53dSZi Xuan Wu   case CSKY::CMPLTI16:
960bdd7c53dSZi Xuan Wu   case CSKY::CMPLT32:
961bdd7c53dSZi Xuan Wu   case CSKY::CMPLT16:
962bdd7c53dSZi Xuan Wu   case CSKY::BTSTI32:
963bdd7c53dSZi Xuan Wu     Inst.erase(Inst.begin());
964bdd7c53dSZi Xuan Wu     Inst.insert(Inst.begin(), MCOperand::createReg(CSKY::C));
965bdd7c53dSZi Xuan Wu     break;
966bdd7c53dSZi Xuan Wu   case CSKY::MVCV32:
967bdd7c53dSZi Xuan Wu     Inst.erase(std::next(Inst.begin()));
968bdd7c53dSZi Xuan Wu     Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C));
969bdd7c53dSZi Xuan Wu     break;
970582836faSZi Xuan Wu   case CSKY::PseudoLRW16:
971582836faSZi Xuan Wu   case CSKY::PseudoLRW32:
972582836faSZi Xuan Wu     return processLRW(Inst, IDLoc, Out);
973582836faSZi Xuan Wu   case CSKY::PseudoJSRI32:
974582836faSZi Xuan Wu     return processJSRI(Inst, IDLoc, Out);
975582836faSZi Xuan Wu   case CSKY::PseudoJMPI32:
976582836faSZi Xuan Wu     return processJMPI(Inst, IDLoc, Out);
977582836faSZi Xuan Wu   case CSKY::JBSR32:
978582836faSZi Xuan Wu   case CSKY::JBR16:
979582836faSZi Xuan Wu   case CSKY::JBT16:
980582836faSZi Xuan Wu   case CSKY::JBF16:
981582836faSZi Xuan Wu   case CSKY::JBR32:
982582836faSZi Xuan Wu   case CSKY::JBT32:
983582836faSZi Xuan Wu   case CSKY::JBF32:
984582836faSZi Xuan Wu     unsigned Num = Inst.getNumOperands() - 1;
985582836faSZi Xuan Wu     assert(Inst.getOperand(Num).isExpr());
986582836faSZi Xuan Wu 
987582836faSZi Xuan Wu     const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
988582836faSZi Xuan Wu         Inst.getOperand(Num).getExpr(), Inst.getLoc());
989582836faSZi Xuan Wu 
990582836faSZi Xuan Wu     Inst.addOperand(MCOperand::createExpr(Expr));
991582836faSZi Xuan Wu     break;
992de10a02fSZi Xuan Wu   }
993de10a02fSZi Xuan Wu 
994bdd7c53dSZi Xuan Wu   emitToStreamer(Out, Inst);
995de10a02fSZi Xuan Wu   return false;
9968ba622baSZi Xuan Wu }
9978ba622baSZi Xuan Wu 
9988ba622baSZi Xuan Wu // Attempts to match Name as a register (either using the default name or
9998ba622baSZi Xuan Wu // alternative ABI names), setting RegNo to the matching register. Upon
10008ba622baSZi Xuan Wu // failure, returns true and sets RegNo to 0.
matchRegisterNameHelper(const MCSubtargetInfo & STI,MCRegister & RegNo,StringRef Name)1001de10a02fSZi Xuan Wu static bool matchRegisterNameHelper(const MCSubtargetInfo &STI,
1002de10a02fSZi Xuan Wu                                     MCRegister &RegNo, StringRef Name) {
10038ba622baSZi Xuan Wu   RegNo = MatchRegisterName(Name);
10048ba622baSZi Xuan Wu 
10058ba622baSZi Xuan Wu   if (RegNo == CSKY::NoRegister)
10068ba622baSZi Xuan Wu     RegNo = MatchRegisterAltName(Name);
10078ba622baSZi Xuan Wu 
10088ba622baSZi Xuan Wu   return RegNo == CSKY::NoRegister;
10098ba622baSZi Xuan Wu }
10108ba622baSZi Xuan Wu 
ParseRegister(unsigned & RegNo,SMLoc & StartLoc,SMLoc & EndLoc)10118ba622baSZi Xuan Wu bool CSKYAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
10128ba622baSZi Xuan Wu                                   SMLoc &EndLoc) {
10138ba622baSZi Xuan Wu   const AsmToken &Tok = getParser().getTok();
10148ba622baSZi Xuan Wu   StartLoc = Tok.getLoc();
10158ba622baSZi Xuan Wu   EndLoc = Tok.getEndLoc();
10168ba622baSZi Xuan Wu   StringRef Name = getLexer().getTok().getIdentifier();
10178ba622baSZi Xuan Wu 
1018de10a02fSZi Xuan Wu   if (!matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) {
10198ba622baSZi Xuan Wu     getParser().Lex(); // Eat identifier token.
10208ba622baSZi Xuan Wu     return false;
10218ba622baSZi Xuan Wu   }
10228ba622baSZi Xuan Wu 
1023de10a02fSZi Xuan Wu   return MatchOperand_NoMatch;
10248ba622baSZi Xuan Wu }
10258ba622baSZi Xuan Wu 
parseRegister(OperandVector & Operands)10268ba622baSZi Xuan Wu OperandMatchResultTy CSKYAsmParser::parseRegister(OperandVector &Operands) {
10278ba622baSZi Xuan Wu   SMLoc S = getLoc();
10288ba622baSZi Xuan Wu   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
10298ba622baSZi Xuan Wu 
10308ba622baSZi Xuan Wu   switch (getLexer().getKind()) {
10318ba622baSZi Xuan Wu   default:
10328ba622baSZi Xuan Wu     return MatchOperand_NoMatch;
10338ba622baSZi Xuan Wu   case AsmToken::Identifier: {
10348ba622baSZi Xuan Wu     StringRef Name = getLexer().getTok().getIdentifier();
10358ba622baSZi Xuan Wu     MCRegister RegNo;
10368ba622baSZi Xuan Wu 
1037de10a02fSZi Xuan Wu     if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name))
10388ba622baSZi Xuan Wu       return MatchOperand_NoMatch;
10398ba622baSZi Xuan Wu 
10408ba622baSZi Xuan Wu     getLexer().Lex();
10418ba622baSZi Xuan Wu     Operands.push_back(CSKYOperand::createReg(RegNo, S, E));
10428ba622baSZi Xuan Wu 
10438ba622baSZi Xuan Wu     return MatchOperand_Success;
10448ba622baSZi Xuan Wu   }
10458ba622baSZi Xuan Wu   }
10468ba622baSZi Xuan Wu }
10478ba622baSZi Xuan Wu 
parseBaseRegImm(OperandVector & Operands)10484216389cSZi Xuan Wu OperandMatchResultTy CSKYAsmParser::parseBaseRegImm(OperandVector &Operands) {
10494216389cSZi Xuan Wu   assert(getLexer().is(AsmToken::LParen));
10504216389cSZi Xuan Wu 
10514216389cSZi Xuan Wu   Operands.push_back(CSKYOperand::createToken("(", getLoc()));
10524216389cSZi Xuan Wu 
10534216389cSZi Xuan Wu   auto Tok = getParser().Lex(); // Eat '('
10544216389cSZi Xuan Wu 
10554216389cSZi Xuan Wu   if (parseRegister(Operands) != MatchOperand_Success) {
10564216389cSZi Xuan Wu     getLexer().UnLex(Tok);
10574216389cSZi Xuan Wu     Operands.pop_back();
1058de10a02fSZi Xuan Wu     return MatchOperand_NoMatch;
1059de10a02fSZi Xuan Wu   }
1060de10a02fSZi Xuan Wu 
1061de10a02fSZi Xuan Wu   if (getLexer().is(AsmToken::RParen)) {
1062de10a02fSZi Xuan Wu     Operands.push_back(CSKYOperand::createToken(")", getLoc()));
1063de10a02fSZi Xuan Wu     getParser().Lex(); // Eat ')'
1064de10a02fSZi Xuan Wu     return MatchOperand_Success;
10654216389cSZi Xuan Wu   }
10664216389cSZi Xuan Wu 
10674216389cSZi Xuan Wu   if (getLexer().isNot(AsmToken::Comma)) {
10684216389cSZi Xuan Wu     Error(getLoc(), "expected ','");
10694216389cSZi Xuan Wu     return MatchOperand_ParseFail;
10704216389cSZi Xuan Wu   }
10714216389cSZi Xuan Wu 
10724216389cSZi Xuan Wu   getParser().Lex(); // Eat ','
10734216389cSZi Xuan Wu 
10744216389cSZi Xuan Wu   if (parseRegister(Operands) == MatchOperand_Success) {
10754216389cSZi Xuan Wu     if (getLexer().isNot(AsmToken::LessLess)) {
10764216389cSZi Xuan Wu       Error(getLoc(), "expected '<<'");
10774216389cSZi Xuan Wu       return MatchOperand_ParseFail;
10784216389cSZi Xuan Wu     }
10794216389cSZi Xuan Wu 
10804216389cSZi Xuan Wu     Operands.push_back(CSKYOperand::createToken("<<", getLoc()));
10814216389cSZi Xuan Wu 
10824216389cSZi Xuan Wu     getParser().Lex(); // Eat '<<'
10834216389cSZi Xuan Wu 
10844216389cSZi Xuan Wu     if (parseImmediate(Operands) != MatchOperand_Success) {
10854216389cSZi Xuan Wu       Error(getLoc(), "expected imm");
10864216389cSZi Xuan Wu       return MatchOperand_ParseFail;
10874216389cSZi Xuan Wu     }
10884216389cSZi Xuan Wu 
10894216389cSZi Xuan Wu   } else if (parseImmediate(Operands) != MatchOperand_Success) {
10904216389cSZi Xuan Wu     Error(getLoc(), "expected imm");
10914216389cSZi Xuan Wu     return MatchOperand_ParseFail;
10924216389cSZi Xuan Wu   }
10934216389cSZi Xuan Wu 
10944216389cSZi Xuan Wu   if (getLexer().isNot(AsmToken::RParen)) {
10954216389cSZi Xuan Wu     Error(getLoc(), "expected ')'");
10964216389cSZi Xuan Wu     return MatchOperand_ParseFail;
10974216389cSZi Xuan Wu   }
10984216389cSZi Xuan Wu 
10994216389cSZi Xuan Wu   Operands.push_back(CSKYOperand::createToken(")", getLoc()));
11004216389cSZi Xuan Wu 
11014216389cSZi Xuan Wu   getParser().Lex(); // Eat ')'
11024216389cSZi Xuan Wu 
11034216389cSZi Xuan Wu   return MatchOperand_Success;
11044216389cSZi Xuan Wu }
11054216389cSZi Xuan Wu 
parseImmediate(OperandVector & Operands)11068ba622baSZi Xuan Wu OperandMatchResultTy CSKYAsmParser::parseImmediate(OperandVector &Operands) {
11078ba622baSZi Xuan Wu   switch (getLexer().getKind()) {
11088ba622baSZi Xuan Wu   default:
11098ba622baSZi Xuan Wu     return MatchOperand_NoMatch;
11108ba622baSZi Xuan Wu   case AsmToken::LParen:
11118ba622baSZi Xuan Wu   case AsmToken::Minus:
11128ba622baSZi Xuan Wu   case AsmToken::Plus:
11138ba622baSZi Xuan Wu   case AsmToken::Integer:
11148ba622baSZi Xuan Wu   case AsmToken::String:
11158ba622baSZi Xuan Wu     break;
11168ba622baSZi Xuan Wu   }
11178ba622baSZi Xuan Wu 
11188ba622baSZi Xuan Wu   const MCExpr *IdVal;
11198ba622baSZi Xuan Wu   SMLoc S = getLoc();
1120de10a02fSZi Xuan Wu   if (getParser().parseExpression(IdVal)) {
1121de10a02fSZi Xuan Wu     Error(getLoc(), "unknown expression");
11228ba622baSZi Xuan Wu     return MatchOperand_ParseFail;
1123de10a02fSZi Xuan Wu   }
11248ba622baSZi Xuan Wu 
11258ba622baSZi Xuan Wu   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
11268ba622baSZi Xuan Wu   Operands.push_back(CSKYOperand::createImm(IdVal, S, E));
11278ba622baSZi Xuan Wu   return MatchOperand_Success;
11288ba622baSZi Xuan Wu }
11298ba622baSZi Xuan Wu 
11308ba622baSZi Xuan Wu /// Looks at a token type and creates the relevant operand from this
11318ba622baSZi Xuan Wu /// information, adding to Operands. If operand was parsed, returns false, else
11328ba622baSZi Xuan Wu /// true.
parseOperand(OperandVector & Operands,StringRef Mnemonic)11338ba622baSZi Xuan Wu bool CSKYAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
11344bb60c28SZi Xuan Wu   // Check if the current operand has a custom associated parser, if so, try to
11354bb60c28SZi Xuan Wu   // custom parse the operand, or fallback to the general approach.
11364bb60c28SZi Xuan Wu   OperandMatchResultTy Result =
11374bb60c28SZi Xuan Wu       MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true);
11384bb60c28SZi Xuan Wu   if (Result == MatchOperand_Success)
11394bb60c28SZi Xuan Wu     return false;
11404bb60c28SZi Xuan Wu   if (Result == MatchOperand_ParseFail)
11414bb60c28SZi Xuan Wu     return true;
11424bb60c28SZi Xuan Wu 
11438ba622baSZi Xuan Wu   // Attempt to parse token as register
1144de10a02fSZi Xuan Wu   auto Res = parseRegister(Operands);
1145de10a02fSZi Xuan Wu   if (Res == MatchOperand_Success)
11468ba622baSZi Xuan Wu     return false;
1147de10a02fSZi Xuan Wu   else if (Res == MatchOperand_ParseFail)
1148de10a02fSZi Xuan Wu     return true;
11498ba622baSZi Xuan Wu 
11504216389cSZi Xuan Wu   // Attempt to parse token as (register, imm)
1151de10a02fSZi Xuan Wu   if (getLexer().is(AsmToken::LParen)) {
1152de10a02fSZi Xuan Wu     Res = parseBaseRegImm(Operands);
1153de10a02fSZi Xuan Wu     if (Res == MatchOperand_Success)
11544216389cSZi Xuan Wu       return false;
1155de10a02fSZi Xuan Wu     else if (Res == MatchOperand_ParseFail)
1156de10a02fSZi Xuan Wu       return true;
1157de10a02fSZi Xuan Wu   }
11584216389cSZi Xuan Wu 
1159de10a02fSZi Xuan Wu   Res = parseImmediate(Operands);
1160de10a02fSZi Xuan Wu   if (Res == MatchOperand_Success)
11618ba622baSZi Xuan Wu     return false;
1162de10a02fSZi Xuan Wu   else if (Res == MatchOperand_ParseFail)
1163de10a02fSZi Xuan Wu     return true;
11648ba622baSZi Xuan Wu 
11658ba622baSZi Xuan Wu   // Finally we have exhausted all options and must declare defeat.
11668ba622baSZi Xuan Wu   Error(getLoc(), "unknown operand");
11678ba622baSZi Xuan Wu   return true;
11688ba622baSZi Xuan Wu }
11698ba622baSZi Xuan Wu 
parseCSKYSymbol(OperandVector & Operands)11704bb60c28SZi Xuan Wu OperandMatchResultTy CSKYAsmParser::parseCSKYSymbol(OperandVector &Operands) {
11714bb60c28SZi Xuan Wu   SMLoc S = getLoc();
11724bb60c28SZi Xuan Wu   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1173de10a02fSZi Xuan Wu   const MCExpr *Res;
11744bb60c28SZi Xuan Wu 
11754bb60c28SZi Xuan Wu   if (getLexer().getKind() != AsmToken::Identifier)
11764bb60c28SZi Xuan Wu     return MatchOperand_NoMatch;
11774bb60c28SZi Xuan Wu 
11784bb60c28SZi Xuan Wu   StringRef Identifier;
1179de10a02fSZi Xuan Wu   AsmToken Tok = getLexer().getTok();
1180de10a02fSZi Xuan Wu 
1181de10a02fSZi Xuan Wu   if (getParser().parseIdentifier(Identifier)) {
1182de10a02fSZi Xuan Wu     Error(getLoc(), "unknown identifier");
11834bb60c28SZi Xuan Wu     return MatchOperand_ParseFail;
1184de10a02fSZi Xuan Wu   }
11854bb60c28SZi Xuan Wu 
11864bb60c28SZi Xuan Wu   CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None;
11874bb60c28SZi Xuan Wu   if (Identifier.consume_back("@GOT"))
11884bb60c28SZi Xuan Wu     Kind = CSKYMCExpr::VK_CSKY_GOT;
11894bb60c28SZi Xuan Wu   else if (Identifier.consume_back("@GOTOFF"))
11904bb60c28SZi Xuan Wu     Kind = CSKYMCExpr::VK_CSKY_GOTOFF;
11914bb60c28SZi Xuan Wu   else if (Identifier.consume_back("@PLT"))
11924bb60c28SZi Xuan Wu     Kind = CSKYMCExpr::VK_CSKY_PLT;
11934bb60c28SZi Xuan Wu   else if (Identifier.consume_back("@GOTPC"))
11944bb60c28SZi Xuan Wu     Kind = CSKYMCExpr::VK_CSKY_GOTPC;
1195de10a02fSZi Xuan Wu   else if (Identifier.consume_back("@TLSGD32"))
1196de10a02fSZi Xuan Wu     Kind = CSKYMCExpr::VK_CSKY_TLSGD;
1197de10a02fSZi Xuan Wu   else if (Identifier.consume_back("@GOTTPOFF"))
1198de10a02fSZi Xuan Wu     Kind = CSKYMCExpr::VK_CSKY_TLSIE;
1199de10a02fSZi Xuan Wu   else if (Identifier.consume_back("@TPOFF"))
1200de10a02fSZi Xuan Wu     Kind = CSKYMCExpr::VK_CSKY_TLSLE;
1201de10a02fSZi Xuan Wu   else if (Identifier.consume_back("@TLSLDM32"))
1202de10a02fSZi Xuan Wu     Kind = CSKYMCExpr::VK_CSKY_TLSLDM;
1203de10a02fSZi Xuan Wu   else if (Identifier.consume_back("@TLSLDO32"))
1204de10a02fSZi Xuan Wu     Kind = CSKYMCExpr::VK_CSKY_TLSLDO;
12054bb60c28SZi Xuan Wu 
1206de10a02fSZi Xuan Wu   MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);
12074bb60c28SZi Xuan Wu 
1208de10a02fSZi Xuan Wu   if (!Sym)
1209de10a02fSZi Xuan Wu     Sym = getContext().getOrCreateSymbol(Identifier);
1210de10a02fSZi Xuan Wu 
1211de10a02fSZi Xuan Wu   if (Sym->isVariable()) {
1212de10a02fSZi Xuan Wu     const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
1213de10a02fSZi Xuan Wu     if (!isa<MCSymbolRefExpr>(V)) {
1214de10a02fSZi Xuan Wu       getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
1215de10a02fSZi Xuan Wu       Error(getLoc(), "unknown symbol");
1216de10a02fSZi Xuan Wu       return MatchOperand_ParseFail;
1217de10a02fSZi Xuan Wu     }
1218de10a02fSZi Xuan Wu     Res = V;
1219de10a02fSZi Xuan Wu   } else
1220de10a02fSZi Xuan Wu     Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1221de10a02fSZi Xuan Wu 
1222de10a02fSZi Xuan Wu   MCBinaryExpr::Opcode Opcode;
1223de10a02fSZi Xuan Wu   switch (getLexer().getKind()) {
1224de10a02fSZi Xuan Wu   default:
12254bb60c28SZi Xuan Wu     if (Kind != CSKYMCExpr::VK_CSKY_None)
12264bb60c28SZi Xuan Wu       Res = CSKYMCExpr::create(Res, Kind, getContext());
12274bb60c28SZi Xuan Wu 
12284bb60c28SZi Xuan Wu     Operands.push_back(CSKYOperand::createImm(Res, S, E));
12294bb60c28SZi Xuan Wu     return MatchOperand_Success;
1230de10a02fSZi Xuan Wu   case AsmToken::Plus:
1231de10a02fSZi Xuan Wu     Opcode = MCBinaryExpr::Add;
1232de10a02fSZi Xuan Wu     break;
1233de10a02fSZi Xuan Wu   case AsmToken::Minus:
1234de10a02fSZi Xuan Wu     Opcode = MCBinaryExpr::Sub;
1235de10a02fSZi Xuan Wu     break;
1236de10a02fSZi Xuan Wu   }
1237de10a02fSZi Xuan Wu 
1238de10a02fSZi Xuan Wu   getLexer().Lex(); // eat + or -
1239de10a02fSZi Xuan Wu 
1240de10a02fSZi Xuan Wu   const MCExpr *Expr;
1241de10a02fSZi Xuan Wu   if (getParser().parseExpression(Expr)) {
1242de10a02fSZi Xuan Wu     Error(getLoc(), "unknown expression");
1243de10a02fSZi Xuan Wu     return MatchOperand_ParseFail;
1244de10a02fSZi Xuan Wu   }
1245de10a02fSZi Xuan Wu   Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
1246de10a02fSZi Xuan Wu   Operands.push_back(CSKYOperand::createImm(Res, S, E));
1247de10a02fSZi Xuan Wu   return MatchOperand_Success;
1248de10a02fSZi Xuan Wu }
1249de10a02fSZi Xuan Wu 
parseDataSymbol(OperandVector & Operands)1250de10a02fSZi Xuan Wu OperandMatchResultTy CSKYAsmParser::parseDataSymbol(OperandVector &Operands) {
1251de10a02fSZi Xuan Wu   SMLoc S = getLoc();
1252de10a02fSZi Xuan Wu   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1253de10a02fSZi Xuan Wu   const MCExpr *Res;
1254de10a02fSZi Xuan Wu 
1255de10a02fSZi Xuan Wu   if (getLexer().getKind() != AsmToken::LBrac)
1256de10a02fSZi Xuan Wu     return MatchOperand_NoMatch;
1257de10a02fSZi Xuan Wu 
1258de10a02fSZi Xuan Wu   getLexer().Lex(); // Eat '['.
1259de10a02fSZi Xuan Wu 
1260de10a02fSZi Xuan Wu   if (getLexer().getKind() != AsmToken::Identifier) {
1261de10a02fSZi Xuan Wu     const MCExpr *Expr;
1262de10a02fSZi Xuan Wu     if (getParser().parseExpression(Expr)) {
1263de10a02fSZi Xuan Wu       Error(getLoc(), "unknown expression");
1264de10a02fSZi Xuan Wu       return MatchOperand_ParseFail;
1265de10a02fSZi Xuan Wu     }
1266de10a02fSZi Xuan Wu 
1267de10a02fSZi Xuan Wu     if (getLexer().getKind() != AsmToken::RBrac) {
1268de10a02fSZi Xuan Wu       Error(getLoc(), "expected ]");
1269de10a02fSZi Xuan Wu       return MatchOperand_ParseFail;
1270de10a02fSZi Xuan Wu     }
1271de10a02fSZi Xuan Wu 
1272de10a02fSZi Xuan Wu     getLexer().Lex(); // Eat ']'.
1273de10a02fSZi Xuan Wu 
1274de10a02fSZi Xuan Wu     Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E));
1275de10a02fSZi Xuan Wu     return MatchOperand_Success;
1276de10a02fSZi Xuan Wu   }
1277de10a02fSZi Xuan Wu 
1278de10a02fSZi Xuan Wu   AsmToken Tok = getLexer().getTok();
1279de10a02fSZi Xuan Wu   StringRef Identifier;
1280de10a02fSZi Xuan Wu 
1281de10a02fSZi Xuan Wu   if (getParser().parseIdentifier(Identifier)) {
1282de10a02fSZi Xuan Wu     Error(getLoc(), "unknown identifier " + Identifier);
1283de10a02fSZi Xuan Wu     return MatchOperand_ParseFail;
1284de10a02fSZi Xuan Wu   }
1285de10a02fSZi Xuan Wu 
1286de10a02fSZi Xuan Wu   CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None;
1287de10a02fSZi Xuan Wu   if (Identifier.consume_back("@GOT"))
1288de10a02fSZi Xuan Wu     Kind = CSKYMCExpr::VK_CSKY_GOT_IMM18_BY4;
1289de10a02fSZi Xuan Wu   else if (Identifier.consume_back("@PLT"))
1290de10a02fSZi Xuan Wu     Kind = CSKYMCExpr::VK_CSKY_PLT_IMM18_BY4;
1291de10a02fSZi Xuan Wu 
1292de10a02fSZi Xuan Wu   MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);
1293de10a02fSZi Xuan Wu 
1294de10a02fSZi Xuan Wu   if (!Sym)
1295de10a02fSZi Xuan Wu     Sym = getContext().getOrCreateSymbol(Identifier);
1296de10a02fSZi Xuan Wu 
1297de10a02fSZi Xuan Wu   if (Sym->isVariable()) {
1298de10a02fSZi Xuan Wu     const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
1299de10a02fSZi Xuan Wu     if (!isa<MCSymbolRefExpr>(V)) {
1300de10a02fSZi Xuan Wu       getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
1301de10a02fSZi Xuan Wu       Error(getLoc(), "unknown symbol");
1302de10a02fSZi Xuan Wu       return MatchOperand_ParseFail;
1303de10a02fSZi Xuan Wu     }
1304de10a02fSZi Xuan Wu     Res = V;
1305de10a02fSZi Xuan Wu   } else {
1306de10a02fSZi Xuan Wu     Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1307de10a02fSZi Xuan Wu   }
1308de10a02fSZi Xuan Wu 
1309de10a02fSZi Xuan Wu   MCBinaryExpr::Opcode Opcode;
1310de10a02fSZi Xuan Wu   switch (getLexer().getKind()) {
1311de10a02fSZi Xuan Wu   default:
1312de10a02fSZi Xuan Wu     Error(getLoc(), "unknown symbol");
1313de10a02fSZi Xuan Wu     return MatchOperand_ParseFail;
1314de10a02fSZi Xuan Wu   case AsmToken::RBrac:
1315de10a02fSZi Xuan Wu 
1316de10a02fSZi Xuan Wu     getLexer().Lex(); // Eat ']'.
1317de10a02fSZi Xuan Wu 
1318de10a02fSZi Xuan Wu     if (Kind != CSKYMCExpr::VK_CSKY_None)
1319de10a02fSZi Xuan Wu       Res = CSKYMCExpr::create(Res, Kind, getContext());
1320de10a02fSZi Xuan Wu 
1321de10a02fSZi Xuan Wu     Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
1322de10a02fSZi Xuan Wu     return MatchOperand_Success;
1323de10a02fSZi Xuan Wu   case AsmToken::Plus:
1324de10a02fSZi Xuan Wu     Opcode = MCBinaryExpr::Add;
1325de10a02fSZi Xuan Wu     break;
1326de10a02fSZi Xuan Wu   case AsmToken::Minus:
1327de10a02fSZi Xuan Wu     Opcode = MCBinaryExpr::Sub;
1328de10a02fSZi Xuan Wu     break;
1329de10a02fSZi Xuan Wu   }
1330de10a02fSZi Xuan Wu 
1331de10a02fSZi Xuan Wu   getLexer().Lex(); // eat + or -
1332de10a02fSZi Xuan Wu 
1333de10a02fSZi Xuan Wu   const MCExpr *Expr;
1334de10a02fSZi Xuan Wu   if (getParser().parseExpression(Expr)) {
1335de10a02fSZi Xuan Wu     Error(getLoc(), "unknown expression");
1336de10a02fSZi Xuan Wu     return MatchOperand_ParseFail;
1337de10a02fSZi Xuan Wu   }
1338de10a02fSZi Xuan Wu 
1339de10a02fSZi Xuan Wu   if (getLexer().getKind() != AsmToken::RBrac) {
1340de10a02fSZi Xuan Wu     Error(getLoc(), "expected ']'");
1341de10a02fSZi Xuan Wu     return MatchOperand_ParseFail;
1342de10a02fSZi Xuan Wu   }
1343de10a02fSZi Xuan Wu 
1344de10a02fSZi Xuan Wu   getLexer().Lex(); // Eat ']'.
1345de10a02fSZi Xuan Wu 
1346de10a02fSZi Xuan Wu   Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
1347de10a02fSZi Xuan Wu   Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
1348de10a02fSZi Xuan Wu   return MatchOperand_Success;
13494bb60c28SZi Xuan Wu }
13504bb60c28SZi Xuan Wu 
13514bb60c28SZi Xuan Wu OperandMatchResultTy
parseConstpoolSymbol(OperandVector & Operands)13524bb60c28SZi Xuan Wu CSKYAsmParser::parseConstpoolSymbol(OperandVector &Operands) {
13534bb60c28SZi Xuan Wu   SMLoc S = getLoc();
13544bb60c28SZi Xuan Wu   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1355de10a02fSZi Xuan Wu   const MCExpr *Res;
13564bb60c28SZi Xuan Wu 
13574bb60c28SZi Xuan Wu   if (getLexer().getKind() != AsmToken::LBrac)
13584bb60c28SZi Xuan Wu     return MatchOperand_NoMatch;
13594bb60c28SZi Xuan Wu 
13604bb60c28SZi Xuan Wu   getLexer().Lex(); // Eat '['.
13614bb60c28SZi Xuan Wu 
1362de10a02fSZi Xuan Wu   if (getLexer().getKind() != AsmToken::Identifier) {
1363de10a02fSZi Xuan Wu     const MCExpr *Expr;
1364de10a02fSZi Xuan Wu     if (getParser().parseExpression(Expr)) {
1365de10a02fSZi Xuan Wu       Error(getLoc(), "unknown expression");
13664bb60c28SZi Xuan Wu       return MatchOperand_ParseFail;
1367de10a02fSZi Xuan Wu     }
13684bb60c28SZi Xuan Wu 
1369de10a02fSZi Xuan Wu     if (getLexer().getKind() != AsmToken::RBrac) {
1370de10a02fSZi Xuan Wu       Error(getLoc(), "expected ']'");
1371de10a02fSZi Xuan Wu       return MatchOperand_ParseFail;
1372de10a02fSZi Xuan Wu     }
13734bb60c28SZi Xuan Wu 
13744bb60c28SZi Xuan Wu     getLexer().Lex(); // Eat ']'.
13754bb60c28SZi Xuan Wu 
1376de10a02fSZi Xuan Wu     Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E));
1377de10a02fSZi Xuan Wu     return MatchOperand_Success;
1378de10a02fSZi Xuan Wu   }
1379de10a02fSZi Xuan Wu 
1380de10a02fSZi Xuan Wu   AsmToken Tok = getLexer().getTok();
1381de10a02fSZi Xuan Wu   StringRef Identifier;
1382de10a02fSZi Xuan Wu 
1383de10a02fSZi Xuan Wu   if (getParser().parseIdentifier(Identifier)) {
1384de10a02fSZi Xuan Wu     Error(getLoc(), "unknown identifier");
1385de10a02fSZi Xuan Wu     return MatchOperand_ParseFail;
1386de10a02fSZi Xuan Wu   }
1387de10a02fSZi Xuan Wu 
1388de10a02fSZi Xuan Wu   MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);
1389de10a02fSZi Xuan Wu 
1390de10a02fSZi Xuan Wu   if (!Sym)
1391de10a02fSZi Xuan Wu     Sym = getContext().getOrCreateSymbol(Identifier);
1392de10a02fSZi Xuan Wu 
1393de10a02fSZi Xuan Wu   if (Sym->isVariable()) {
1394de10a02fSZi Xuan Wu     const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
1395de10a02fSZi Xuan Wu     if (!isa<MCSymbolRefExpr>(V)) {
1396de10a02fSZi Xuan Wu       getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
1397de10a02fSZi Xuan Wu       Error(getLoc(), "unknown symbol");
1398de10a02fSZi Xuan Wu       return MatchOperand_ParseFail;
1399de10a02fSZi Xuan Wu     }
1400de10a02fSZi Xuan Wu     Res = V;
1401de10a02fSZi Xuan Wu   } else {
1402de10a02fSZi Xuan Wu     Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1403de10a02fSZi Xuan Wu   }
1404de10a02fSZi Xuan Wu 
1405de10a02fSZi Xuan Wu   MCBinaryExpr::Opcode Opcode;
1406de10a02fSZi Xuan Wu   switch (getLexer().getKind()) {
1407de10a02fSZi Xuan Wu   default:
1408de10a02fSZi Xuan Wu     Error(getLoc(), "unknown symbol");
1409de10a02fSZi Xuan Wu     return MatchOperand_ParseFail;
1410de10a02fSZi Xuan Wu   case AsmToken::RBrac:
1411de10a02fSZi Xuan Wu 
1412de10a02fSZi Xuan Wu     getLexer().Lex(); // Eat ']'.
1413de10a02fSZi Xuan Wu 
1414de10a02fSZi Xuan Wu     Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
1415de10a02fSZi Xuan Wu     return MatchOperand_Success;
1416de10a02fSZi Xuan Wu   case AsmToken::Plus:
1417de10a02fSZi Xuan Wu     Opcode = MCBinaryExpr::Add;
1418de10a02fSZi Xuan Wu     break;
1419de10a02fSZi Xuan Wu   case AsmToken::Minus:
1420de10a02fSZi Xuan Wu     Opcode = MCBinaryExpr::Sub;
1421de10a02fSZi Xuan Wu     break;
1422de10a02fSZi Xuan Wu   }
1423de10a02fSZi Xuan Wu 
1424de10a02fSZi Xuan Wu   getLexer().Lex(); // eat + or -
1425de10a02fSZi Xuan Wu 
1426de10a02fSZi Xuan Wu   const MCExpr *Expr;
1427de10a02fSZi Xuan Wu   if (getParser().parseExpression(Expr)) {
1428de10a02fSZi Xuan Wu     Error(getLoc(), "unknown expression");
1429de10a02fSZi Xuan Wu     return MatchOperand_ParseFail;
1430de10a02fSZi Xuan Wu   }
1431de10a02fSZi Xuan Wu 
1432de10a02fSZi Xuan Wu   if (getLexer().getKind() != AsmToken::RBrac) {
1433de10a02fSZi Xuan Wu     Error(getLoc(), "expected ']'");
1434de10a02fSZi Xuan Wu     return MatchOperand_ParseFail;
1435de10a02fSZi Xuan Wu   }
1436de10a02fSZi Xuan Wu 
1437de10a02fSZi Xuan Wu   getLexer().Lex(); // Eat ']'.
1438de10a02fSZi Xuan Wu 
1439de10a02fSZi Xuan Wu   Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
1440de10a02fSZi Xuan Wu   Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
1441de10a02fSZi Xuan Wu   return MatchOperand_Success;
1442de10a02fSZi Xuan Wu }
1443de10a02fSZi Xuan Wu 
parsePSRFlag(OperandVector & Operands)1444de10a02fSZi Xuan Wu OperandMatchResultTy CSKYAsmParser::parsePSRFlag(OperandVector &Operands) {
1445de10a02fSZi Xuan Wu   SMLoc S = getLoc();
1446de10a02fSZi Xuan Wu   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1447de10a02fSZi Xuan Wu 
1448de10a02fSZi Xuan Wu   unsigned Flag = 0;
1449de10a02fSZi Xuan Wu 
1450de10a02fSZi Xuan Wu   while (getLexer().isNot(AsmToken::EndOfStatement)) {
1451de10a02fSZi Xuan Wu     StringRef Identifier;
1452de10a02fSZi Xuan Wu     if (getParser().parseIdentifier(Identifier)) {
1453de10a02fSZi Xuan Wu       Error(getLoc(), "unknown identifier " + Identifier);
1454de10a02fSZi Xuan Wu       return MatchOperand_ParseFail;
1455de10a02fSZi Xuan Wu     }
1456de10a02fSZi Xuan Wu 
1457de10a02fSZi Xuan Wu     if (Identifier == "sie")
1458de10a02fSZi Xuan Wu       Flag = (1 << 4) | Flag;
1459de10a02fSZi Xuan Wu     else if (Identifier == "ee")
1460de10a02fSZi Xuan Wu       Flag = (1 << 3) | Flag;
1461de10a02fSZi Xuan Wu     else if (Identifier == "ie")
1462de10a02fSZi Xuan Wu       Flag = (1 << 2) | Flag;
1463de10a02fSZi Xuan Wu     else if (Identifier == "fe")
1464de10a02fSZi Xuan Wu       Flag = (1 << 1) | Flag;
1465de10a02fSZi Xuan Wu     else if (Identifier == "af")
1466de10a02fSZi Xuan Wu       Flag = (1 << 0) | Flag;
1467de10a02fSZi Xuan Wu     else {
1468de10a02fSZi Xuan Wu       Error(getLoc(), "expected " + Identifier);
1469de10a02fSZi Xuan Wu       return MatchOperand_ParseFail;
1470de10a02fSZi Xuan Wu     }
1471de10a02fSZi Xuan Wu 
1472de10a02fSZi Xuan Wu     if (getLexer().is(AsmToken::EndOfStatement))
1473de10a02fSZi Xuan Wu       break;
1474de10a02fSZi Xuan Wu 
1475de10a02fSZi Xuan Wu     if (getLexer().is(AsmToken::Comma)) {
1476de10a02fSZi Xuan Wu       getLexer().Lex(); // eat ','
1477de10a02fSZi Xuan Wu     } else {
1478de10a02fSZi Xuan Wu       Error(getLoc(), "expected ,");
1479de10a02fSZi Xuan Wu       return MatchOperand_ParseFail;
1480de10a02fSZi Xuan Wu     }
1481de10a02fSZi Xuan Wu   }
1482de10a02fSZi Xuan Wu 
1483de10a02fSZi Xuan Wu   Operands.push_back(
1484de10a02fSZi Xuan Wu       CSKYOperand::createImm(MCConstantExpr::create(Flag, getContext()), S, E));
1485de10a02fSZi Xuan Wu   return MatchOperand_Success;
1486de10a02fSZi Xuan Wu }
1487de10a02fSZi Xuan Wu 
parseRegSeq(OperandVector & Operands)1488de10a02fSZi Xuan Wu OperandMatchResultTy CSKYAsmParser::parseRegSeq(OperandVector &Operands) {
1489de10a02fSZi Xuan Wu   SMLoc S = getLoc();
1490de10a02fSZi Xuan Wu 
1491de10a02fSZi Xuan Wu   if (parseRegister(Operands) != MatchOperand_Success)
1492de10a02fSZi Xuan Wu     return MatchOperand_NoMatch;
1493de10a02fSZi Xuan Wu 
1494de10a02fSZi Xuan Wu   auto Ry = Operands.back()->getReg();
1495de10a02fSZi Xuan Wu   Operands.pop_back();
1496de10a02fSZi Xuan Wu 
1497de10a02fSZi Xuan Wu   if (getLexer().isNot(AsmToken::Minus)) {
1498de10a02fSZi Xuan Wu     Error(getLoc(), "expected '-'");
1499de10a02fSZi Xuan Wu     return MatchOperand_ParseFail;
1500de10a02fSZi Xuan Wu   }
1501de10a02fSZi Xuan Wu 
1502de10a02fSZi Xuan Wu   getLexer().Lex(); // eat '-'
1503de10a02fSZi Xuan Wu 
1504de10a02fSZi Xuan Wu   if (parseRegister(Operands) != MatchOperand_Success) {
1505de10a02fSZi Xuan Wu     Error(getLoc(), "invalid register");
1506de10a02fSZi Xuan Wu     return MatchOperand_ParseFail;
1507de10a02fSZi Xuan Wu   }
1508de10a02fSZi Xuan Wu 
1509de10a02fSZi Xuan Wu   auto Rz = Operands.back()->getReg();
1510de10a02fSZi Xuan Wu   Operands.pop_back();
1511de10a02fSZi Xuan Wu 
1512de10a02fSZi Xuan Wu   Operands.push_back(CSKYOperand::createRegSeq(Ry, Rz, S));
1513de10a02fSZi Xuan Wu   return MatchOperand_Success;
1514de10a02fSZi Xuan Wu }
1515de10a02fSZi Xuan Wu 
parseRegList(OperandVector & Operands)1516de10a02fSZi Xuan Wu OperandMatchResultTy CSKYAsmParser::parseRegList(OperandVector &Operands) {
1517de10a02fSZi Xuan Wu   SMLoc S = getLoc();
1518de10a02fSZi Xuan Wu 
1519de10a02fSZi Xuan Wu   SmallVector<unsigned, 4> reglist;
1520de10a02fSZi Xuan Wu 
1521de10a02fSZi Xuan Wu   while (true) {
1522de10a02fSZi Xuan Wu 
1523de10a02fSZi Xuan Wu     if (parseRegister(Operands) != MatchOperand_Success) {
1524de10a02fSZi Xuan Wu       Error(getLoc(), "invalid register");
1525de10a02fSZi Xuan Wu       return MatchOperand_ParseFail;
1526de10a02fSZi Xuan Wu     }
1527de10a02fSZi Xuan Wu 
1528de10a02fSZi Xuan Wu     auto Ry = Operands.back()->getReg();
1529de10a02fSZi Xuan Wu     Operands.pop_back();
1530de10a02fSZi Xuan Wu 
1531de10a02fSZi Xuan Wu     if (getLexer().is(AsmToken::Minus)) {
1532de10a02fSZi Xuan Wu       getLexer().Lex(); // eat '-'
1533de10a02fSZi Xuan Wu 
1534de10a02fSZi Xuan Wu       if (parseRegister(Operands) != MatchOperand_Success) {
1535de10a02fSZi Xuan Wu         Error(getLoc(), "invalid register");
1536de10a02fSZi Xuan Wu         return MatchOperand_ParseFail;
1537de10a02fSZi Xuan Wu       }
1538de10a02fSZi Xuan Wu 
1539de10a02fSZi Xuan Wu       auto Rz = Operands.back()->getReg();
1540de10a02fSZi Xuan Wu       Operands.pop_back();
1541de10a02fSZi Xuan Wu 
1542de10a02fSZi Xuan Wu       reglist.push_back(Ry);
1543de10a02fSZi Xuan Wu       reglist.push_back(Rz);
1544de10a02fSZi Xuan Wu 
1545de10a02fSZi Xuan Wu       if (getLexer().is(AsmToken::Comma))
1546de10a02fSZi Xuan Wu         getLexer().Lex(); // eat ','
1547de10a02fSZi Xuan Wu       else if (getLexer().is(AsmToken::EndOfStatement))
1548de10a02fSZi Xuan Wu         break;
1549de10a02fSZi Xuan Wu 
1550de10a02fSZi Xuan Wu     } else if (getLexer().is(AsmToken::Comma)) {
1551de10a02fSZi Xuan Wu       reglist.push_back(Ry);
1552de10a02fSZi Xuan Wu       reglist.push_back(Ry);
1553de10a02fSZi Xuan Wu 
1554de10a02fSZi Xuan Wu       getLexer().Lex(); // eat ','
1555de10a02fSZi Xuan Wu     } else if (getLexer().is(AsmToken::EndOfStatement)) {
1556de10a02fSZi Xuan Wu       reglist.push_back(Ry);
1557de10a02fSZi Xuan Wu       reglist.push_back(Ry);
1558de10a02fSZi Xuan Wu       break;
1559de10a02fSZi Xuan Wu     } else {
1560de10a02fSZi Xuan Wu       Error(getLoc(), "invalid register list");
1561de10a02fSZi Xuan Wu       return MatchOperand_ParseFail;
1562de10a02fSZi Xuan Wu     }
1563de10a02fSZi Xuan Wu   }
1564de10a02fSZi Xuan Wu 
1565de10a02fSZi Xuan Wu   Operands.push_back(CSKYOperand::createRegList(reglist, S));
15664bb60c28SZi Xuan Wu   return MatchOperand_Success;
15674bb60c28SZi Xuan Wu }
15684bb60c28SZi Xuan Wu 
ParseInstruction(ParseInstructionInfo & Info,StringRef Name,SMLoc NameLoc,OperandVector & Operands)15698ba622baSZi Xuan Wu bool CSKYAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
15708ba622baSZi Xuan Wu                                      SMLoc NameLoc, OperandVector &Operands) {
15718ba622baSZi Xuan Wu   // First operand is token for instruction.
15728ba622baSZi Xuan Wu   Operands.push_back(CSKYOperand::createToken(Name, NameLoc));
15738ba622baSZi Xuan Wu 
15748ba622baSZi Xuan Wu   // If there are no more operands, then finish.
15758ba622baSZi Xuan Wu   if (getLexer().is(AsmToken::EndOfStatement))
15768ba622baSZi Xuan Wu     return false;
15778ba622baSZi Xuan Wu 
15788ba622baSZi Xuan Wu   // Parse first operand.
15798ba622baSZi Xuan Wu   if (parseOperand(Operands, Name))
15808ba622baSZi Xuan Wu     return true;
15818ba622baSZi Xuan Wu 
15828ba622baSZi Xuan Wu   // Parse until end of statement, consuming commas between operands.
15838ba622baSZi Xuan Wu   while (getLexer().is(AsmToken::Comma)) {
15848ba622baSZi Xuan Wu     // Consume comma token.
15858ba622baSZi Xuan Wu     getLexer().Lex();
15868ba622baSZi Xuan Wu 
15878ba622baSZi Xuan Wu     // Parse next operand.
15888ba622baSZi Xuan Wu     if (parseOperand(Operands, Name))
15898ba622baSZi Xuan Wu       return true;
15908ba622baSZi Xuan Wu   }
15918ba622baSZi Xuan Wu 
15928ba622baSZi Xuan Wu   if (getLexer().isNot(AsmToken::EndOfStatement)) {
15938ba622baSZi Xuan Wu     SMLoc Loc = getLexer().getLoc();
15948ba622baSZi Xuan Wu     getParser().eatToEndOfStatement();
15958ba622baSZi Xuan Wu     return Error(Loc, "unexpected token");
15968ba622baSZi Xuan Wu   }
15978ba622baSZi Xuan Wu 
15988ba622baSZi Xuan Wu   getParser().Lex(); // Consume the EndOfStatement.
15998ba622baSZi Xuan Wu   return false;
16008ba622baSZi Xuan Wu }
16018ba622baSZi Xuan Wu 
tryParseRegister(unsigned & RegNo,SMLoc & StartLoc,SMLoc & EndLoc)16028ba622baSZi Xuan Wu OperandMatchResultTy CSKYAsmParser::tryParseRegister(unsigned &RegNo,
16038ba622baSZi Xuan Wu                                                      SMLoc &StartLoc,
16048ba622baSZi Xuan Wu                                                      SMLoc &EndLoc) {
16058ba622baSZi Xuan Wu   const AsmToken &Tok = getParser().getTok();
16068ba622baSZi Xuan Wu   StartLoc = Tok.getLoc();
16078ba622baSZi Xuan Wu   EndLoc = Tok.getEndLoc();
16088ba622baSZi Xuan Wu 
16098ba622baSZi Xuan Wu   StringRef Name = getLexer().getTok().getIdentifier();
16108ba622baSZi Xuan Wu 
1611de10a02fSZi Xuan Wu   if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name))
16128ba622baSZi Xuan Wu     return MatchOperand_NoMatch;
16138ba622baSZi Xuan Wu 
16148ba622baSZi Xuan Wu   getParser().Lex(); // Eat identifier token.
16158ba622baSZi Xuan Wu   return MatchOperand_Success;
16168ba622baSZi Xuan Wu }
16178ba622baSZi Xuan Wu 
ParseDirective(AsmToken DirectiveID)161832977589SZi Xuan Wu bool CSKYAsmParser::ParseDirective(AsmToken DirectiveID) {
161932977589SZi Xuan Wu   // This returns false if this function recognizes the directive
162032977589SZi Xuan Wu   // regardless of whether it is successfully handles or reports an
162132977589SZi Xuan Wu   // error. Otherwise it returns true to give the generic parser a
162232977589SZi Xuan Wu   // chance at recognizing it.
162332977589SZi Xuan Wu   StringRef IDVal = DirectiveID.getString();
162432977589SZi Xuan Wu 
162532977589SZi Xuan Wu   if (IDVal == ".csky_attribute")
162632977589SZi Xuan Wu     return parseDirectiveAttribute();
162732977589SZi Xuan Wu 
162832977589SZi Xuan Wu   return true;
162932977589SZi Xuan Wu }
163032977589SZi Xuan Wu 
163132977589SZi Xuan Wu /// parseDirectiveAttribute
163232977589SZi Xuan Wu ///  ::= .attribute expression ',' ( expression | "string" )
parseDirectiveAttribute()163332977589SZi Xuan Wu bool CSKYAsmParser::parseDirectiveAttribute() {
163432977589SZi Xuan Wu   MCAsmParser &Parser = getParser();
163532977589SZi Xuan Wu   int64_t Tag;
163632977589SZi Xuan Wu   SMLoc TagLoc;
163732977589SZi Xuan Wu   TagLoc = Parser.getTok().getLoc();
163832977589SZi Xuan Wu   if (Parser.getTok().is(AsmToken::Identifier)) {
163932977589SZi Xuan Wu     StringRef Name = Parser.getTok().getIdentifier();
164032977589SZi Xuan Wu     Optional<unsigned> Ret =
164132977589SZi Xuan Wu         ELFAttrs::attrTypeFromString(Name, CSKYAttrs::getCSKYAttributeTags());
164232977589SZi Xuan Wu     if (!Ret.hasValue()) {
164332977589SZi Xuan Wu       Error(TagLoc, "attribute name not recognised: " + Name);
164432977589SZi Xuan Wu       return false;
164532977589SZi Xuan Wu     }
164632977589SZi Xuan Wu     Tag = Ret.getValue();
164732977589SZi Xuan Wu     Parser.Lex();
164832977589SZi Xuan Wu   } else {
164932977589SZi Xuan Wu     const MCExpr *AttrExpr;
165032977589SZi Xuan Wu 
165132977589SZi Xuan Wu     TagLoc = Parser.getTok().getLoc();
165232977589SZi Xuan Wu     if (Parser.parseExpression(AttrExpr))
165332977589SZi Xuan Wu       return true;
165432977589SZi Xuan Wu 
165532977589SZi Xuan Wu     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr);
165632977589SZi Xuan Wu     if (check(!CE, TagLoc, "expected numeric constant"))
165732977589SZi Xuan Wu       return true;
165832977589SZi Xuan Wu 
165932977589SZi Xuan Wu     Tag = CE->getValue();
166032977589SZi Xuan Wu   }
166132977589SZi Xuan Wu 
166232977589SZi Xuan Wu   if (Parser.parseToken(AsmToken::Comma, "comma expected"))
166332977589SZi Xuan Wu     return true;
166432977589SZi Xuan Wu 
166532977589SZi Xuan Wu   StringRef StringValue;
166632977589SZi Xuan Wu   int64_t IntegerValue = 0;
166732977589SZi Xuan Wu   bool IsIntegerValue = ((Tag != CSKYAttrs::CSKY_ARCH_NAME) &&
166832977589SZi Xuan Wu                          (Tag != CSKYAttrs::CSKY_CPU_NAME) &&
166932977589SZi Xuan Wu                          (Tag != CSKYAttrs::CSKY_FPU_NUMBER_MODULE));
167032977589SZi Xuan Wu 
167132977589SZi Xuan Wu   SMLoc ValueExprLoc = Parser.getTok().getLoc();
167232977589SZi Xuan Wu   if (IsIntegerValue) {
167332977589SZi Xuan Wu     const MCExpr *ValueExpr;
167432977589SZi Xuan Wu     if (Parser.parseExpression(ValueExpr))
167532977589SZi Xuan Wu       return true;
167632977589SZi Xuan Wu 
167732977589SZi Xuan Wu     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr);
167832977589SZi Xuan Wu     if (!CE)
167932977589SZi Xuan Wu       return Error(ValueExprLoc, "expected numeric constant");
168032977589SZi Xuan Wu     IntegerValue = CE->getValue();
168132977589SZi Xuan Wu   } else {
168232977589SZi Xuan Wu     if (Parser.getTok().isNot(AsmToken::String))
168332977589SZi Xuan Wu       return Error(Parser.getTok().getLoc(), "expected string constant");
168432977589SZi Xuan Wu 
168532977589SZi Xuan Wu     StringValue = Parser.getTok().getStringContents();
168632977589SZi Xuan Wu     Parser.Lex();
168732977589SZi Xuan Wu   }
168832977589SZi Xuan Wu 
1689*77e300ffSFangrui Song   if (Parser.parseEOL())
169032977589SZi Xuan Wu     return true;
169132977589SZi Xuan Wu 
169232977589SZi Xuan Wu   if (IsIntegerValue)
169332977589SZi Xuan Wu     getTargetStreamer().emitAttribute(Tag, IntegerValue);
169432977589SZi Xuan Wu   else if (Tag != CSKYAttrs::CSKY_ARCH_NAME && Tag != CSKYAttrs::CSKY_CPU_NAME)
169532977589SZi Xuan Wu     getTargetStreamer().emitTextAttribute(Tag, StringValue);
169632977589SZi Xuan Wu   else {
169732977589SZi Xuan Wu     CSKY::ArchKind ID = (Tag == CSKYAttrs::CSKY_ARCH_NAME)
169832977589SZi Xuan Wu                             ? CSKY::parseArch(StringValue)
169932977589SZi Xuan Wu                             : CSKY::parseCPUArch(StringValue);
170032977589SZi Xuan Wu     if (ID == CSKY::ArchKind::INVALID)
170132977589SZi Xuan Wu       return Error(ValueExprLoc, (Tag == CSKYAttrs::CSKY_ARCH_NAME)
170232977589SZi Xuan Wu                                      ? "unknown arch name"
170332977589SZi Xuan Wu                                      : "unknown cpu name");
170432977589SZi Xuan Wu 
170532977589SZi Xuan Wu     getTargetStreamer().emitTextAttribute(Tag, StringValue);
170632977589SZi Xuan Wu   }
170732977589SZi Xuan Wu 
170832977589SZi Xuan Wu   return false;
170932977589SZi Xuan Wu }
17108ba622baSZi Xuan Wu 
validateTargetOperandClass(MCParsedAsmOperand & AsmOp,unsigned Kind)1711a190fcdfSZi Xuan Wu unsigned CSKYAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1712a190fcdfSZi Xuan Wu                                                    unsigned Kind) {
1713a190fcdfSZi Xuan Wu   CSKYOperand &Op = static_cast<CSKYOperand &>(AsmOp);
1714a190fcdfSZi Xuan Wu 
1715a190fcdfSZi Xuan Wu   if (!Op.isReg())
1716a190fcdfSZi Xuan Wu     return Match_InvalidOperand;
1717a190fcdfSZi Xuan Wu 
1718a190fcdfSZi Xuan Wu   MCRegister Reg = Op.getReg();
1719a190fcdfSZi Xuan Wu 
1720a190fcdfSZi Xuan Wu   if (CSKYMCRegisterClasses[CSKY::FPR32RegClassID].contains(Reg)) {
1721a190fcdfSZi Xuan Wu     // As the parser couldn't differentiate an FPR64 from an FPR32, coerce the
1722a190fcdfSZi Xuan Wu     // register from FPR32 to FPR64 if necessary.
17233d4ca8a8SZi Xuan Wu     if (Kind == MCK_FPR64 || Kind == MCK_sFPR64) {
1724a190fcdfSZi Xuan Wu       Op.Reg.RegNum = convertFPR32ToFPR64(Reg);
17253d4ca8a8SZi Xuan Wu       if (Kind == MCK_sFPR64 &&
1726a190fcdfSZi Xuan Wu           (Op.Reg.RegNum < CSKY::F0_64 || Op.Reg.RegNum > CSKY::F15_64))
1727a190fcdfSZi Xuan Wu         return Match_InvalidRegOutOfRange;
1728a190fcdfSZi Xuan Wu       if (Kind == MCK_FPR64 &&
1729a190fcdfSZi Xuan Wu           (Op.Reg.RegNum < CSKY::F0_64 || Op.Reg.RegNum > CSKY::F31_64))
1730a190fcdfSZi Xuan Wu         return Match_InvalidRegOutOfRange;
1731a190fcdfSZi Xuan Wu       return Match_Success;
1732a190fcdfSZi Xuan Wu     }
1733a190fcdfSZi Xuan Wu   }
1734a190fcdfSZi Xuan Wu 
1735a190fcdfSZi Xuan Wu   if (CSKYMCRegisterClasses[CSKY::GPRRegClassID].contains(Reg)) {
1736a190fcdfSZi Xuan Wu     if (Kind == MCK_GPRPair) {
1737a190fcdfSZi Xuan Wu       Op.Reg.RegNum = MRI->getEncodingValue(Reg) + CSKY::R0_R1;
1738a190fcdfSZi Xuan Wu       return Match_Success;
1739a190fcdfSZi Xuan Wu     }
1740a190fcdfSZi Xuan Wu   }
1741a190fcdfSZi Xuan Wu 
1742a190fcdfSZi Xuan Wu   return Match_InvalidOperand;
1743a190fcdfSZi Xuan Wu }
1744a190fcdfSZi Xuan Wu 
emitToStreamer(MCStreamer & S,const MCInst & Inst)1745bdd7c53dSZi Xuan Wu void CSKYAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) {
1746bdd7c53dSZi Xuan Wu   MCInst CInst;
1747bdd7c53dSZi Xuan Wu   bool Res = false;
1748bdd7c53dSZi Xuan Wu   if (EnableCompressedInst)
1749bdd7c53dSZi Xuan Wu     Res = compressInst(CInst, Inst, getSTI(), S.getContext());
1750bdd7c53dSZi Xuan Wu   if (Res)
1751bdd7c53dSZi Xuan Wu     ++CSKYNumInstrsCompressed;
1752bdd7c53dSZi Xuan Wu   S.emitInstruction((Res ? CInst : Inst), getSTI());
1753bdd7c53dSZi Xuan Wu }
1754bdd7c53dSZi Xuan Wu 
LLVMInitializeCSKYAsmParser()17558ba622baSZi Xuan Wu extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYAsmParser() {
17568ba622baSZi Xuan Wu   RegisterMCAsmParser<CSKYAsmParser> X(getTheCSKYTarget());
17578ba622baSZi Xuan Wu }
1758