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