1349cc55cSDimitry Andric //===---- CSKYAsmParser.cpp - Parse CSKY assembly to MCInst instructions --===// 2fe6060f1SDimitry Andric // 3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fe6060f1SDimitry Andric // 7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 8fe6060f1SDimitry Andric 9349cc55cSDimitry Andric #include "MCTargetDesc/CSKYInstPrinter.h" 10fe6060f1SDimitry Andric #include "MCTargetDesc/CSKYMCExpr.h" 11fe6060f1SDimitry Andric #include "MCTargetDesc/CSKYMCTargetDesc.h" 1281ad6265SDimitry Andric #include "MCTargetDesc/CSKYTargetStreamer.h" 13fe6060f1SDimitry Andric #include "TargetInfo/CSKYTargetInfo.h" 14fe6060f1SDimitry Andric #include "llvm/ADT/STLExtras.h" 150eae32dcSDimitry Andric #include "llvm/ADT/Statistic.h" 16*06c3fb27SDimitry Andric #include "llvm/ADT/StringExtras.h" 17fe6060f1SDimitry Andric #include "llvm/ADT/StringSwitch.h" 1881ad6265SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 19fe6060f1SDimitry Andric #include "llvm/CodeGen/Register.h" 20fe6060f1SDimitry Andric #include "llvm/MC/MCContext.h" 21fe6060f1SDimitry Andric #include "llvm/MC/MCExpr.h" 22fe6060f1SDimitry Andric #include "llvm/MC/MCInst.h" 2381ad6265SDimitry Andric #include "llvm/MC/MCInstrInfo.h" 24fe6060f1SDimitry Andric #include "llvm/MC/MCParser/MCAsmLexer.h" 25fe6060f1SDimitry Andric #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 26fe6060f1SDimitry Andric #include "llvm/MC/MCParser/MCTargetAsmParser.h" 27fe6060f1SDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 28349cc55cSDimitry Andric #include "llvm/MC/MCSectionELF.h" 29fe6060f1SDimitry Andric #include "llvm/MC/MCStreamer.h" 30fe6060f1SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 31349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h" 3281ad6265SDimitry Andric #include "llvm/Support/CSKYAttributes.h" 33fe6060f1SDimitry Andric #include "llvm/Support/Casting.h" 340eae32dcSDimitry Andric #include "llvm/Support/CommandLine.h" 35349cc55cSDimitry Andric #include "llvm/Support/Debug.h" 36*06c3fb27SDimitry Andric #include "llvm/TargetParser/CSKYTargetParser.h" 37349cc55cSDimitry Andric 380eae32dcSDimitry Andric using namespace llvm; 390eae32dcSDimitry Andric 40349cc55cSDimitry Andric #define DEBUG_TYPE "csky-asm-parser" 41fe6060f1SDimitry Andric 420eae32dcSDimitry Andric // Include the auto-generated portion of the compress emitter. 430eae32dcSDimitry Andric #define GEN_COMPRESS_INSTR 440eae32dcSDimitry Andric #include "CSKYGenCompressInstEmitter.inc" 450eae32dcSDimitry Andric 460eae32dcSDimitry Andric STATISTIC(CSKYNumInstrsCompressed, 470eae32dcSDimitry Andric "Number of C-SKY Compressed instructions emitted"); 480eae32dcSDimitry Andric 490eae32dcSDimitry Andric static cl::opt<bool> 500eae32dcSDimitry Andric EnableCompressedInst("enable-csky-asm-compressed-inst", cl::Hidden, 510eae32dcSDimitry Andric cl::init(false), 520eae32dcSDimitry Andric cl::desc("Enable C-SKY asm compressed instruction")); 53fe6060f1SDimitry Andric 54fe6060f1SDimitry Andric namespace { 55fe6060f1SDimitry Andric struct CSKYOperand; 56fe6060f1SDimitry Andric 57fe6060f1SDimitry Andric class CSKYAsmParser : public MCTargetAsmParser { 58fe6060f1SDimitry Andric 59349cc55cSDimitry Andric const MCRegisterInfo *MRI; 60349cc55cSDimitry Andric 6181ad6265SDimitry Andric unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 6281ad6265SDimitry Andric unsigned Kind) override; 6381ad6265SDimitry Andric 64fe6060f1SDimitry Andric bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo, 65*06c3fb27SDimitry Andric int64_t Lower, int64_t Upper, 66*06c3fb27SDimitry Andric const Twine &Msg); 67fe6060f1SDimitry Andric 68fe6060f1SDimitry Andric SMLoc getLoc() const { return getParser().getTok().getLoc(); } 69fe6060f1SDimitry Andric 70fe6060f1SDimitry Andric bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 71fe6060f1SDimitry Andric OperandVector &Operands, MCStreamer &Out, 72fe6060f1SDimitry Andric uint64_t &ErrorInfo, 73fe6060f1SDimitry Andric bool MatchingInlineAsm) override; 74fe6060f1SDimitry Andric 75bdd1243dSDimitry Andric bool parseRegister(MCRegister &RegNo, SMLoc &StartLoc, 76bdd1243dSDimitry Andric SMLoc &EndLoc) override; 77fe6060f1SDimitry Andric 78fe6060f1SDimitry Andric bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 79fe6060f1SDimitry Andric SMLoc NameLoc, OperandVector &Operands) override; 80fe6060f1SDimitry Andric 81*06c3fb27SDimitry Andric ParseStatus parseDirective(AsmToken DirectiveID) override; 82fe6060f1SDimitry Andric 830eae32dcSDimitry Andric // Helper to actually emit an instruction to the MCStreamer. Also, when 840eae32dcSDimitry Andric // possible, compression of the instruction is performed. 850eae32dcSDimitry Andric void emitToStreamer(MCStreamer &S, const MCInst &Inst); 860eae32dcSDimitry Andric 87bdd1243dSDimitry Andric OperandMatchResultTy tryParseRegister(MCRegister &RegNo, SMLoc &StartLoc, 88fe6060f1SDimitry Andric SMLoc &EndLoc) override; 89fe6060f1SDimitry Andric 90349cc55cSDimitry Andric bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands, 91349cc55cSDimitry Andric MCStreamer &Out); 9281ad6265SDimitry Andric bool processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 9381ad6265SDimitry Andric bool processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 9481ad6265SDimitry Andric bool processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 9581ad6265SDimitry Andric 9681ad6265SDimitry Andric CSKYTargetStreamer &getTargetStreamer() { 9781ad6265SDimitry Andric assert(getParser().getStreamer().getTargetStreamer() && 9881ad6265SDimitry Andric "do not have a target streamer"); 9981ad6265SDimitry Andric MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); 10081ad6265SDimitry Andric return static_cast<CSKYTargetStreamer &>(TS); 10181ad6265SDimitry Andric } 102349cc55cSDimitry Andric 103fe6060f1SDimitry Andric // Auto-generated instruction matching functions 104fe6060f1SDimitry Andric #define GET_ASSEMBLER_HEADER 105fe6060f1SDimitry Andric #include "CSKYGenAsmMatcher.inc" 106fe6060f1SDimitry Andric 107*06c3fb27SDimitry Andric ParseStatus parseImmediate(OperandVector &Operands); 108*06c3fb27SDimitry Andric ParseStatus parseRegister(OperandVector &Operands); 109*06c3fb27SDimitry Andric ParseStatus parseBaseRegImm(OperandVector &Operands); 110*06c3fb27SDimitry Andric ParseStatus parseCSKYSymbol(OperandVector &Operands); 111*06c3fb27SDimitry Andric ParseStatus parseConstpoolSymbol(OperandVector &Operands); 112*06c3fb27SDimitry Andric ParseStatus parseDataSymbol(OperandVector &Operands); 113*06c3fb27SDimitry Andric ParseStatus parsePSRFlag(OperandVector &Operands); 114*06c3fb27SDimitry Andric ParseStatus parseRegSeq(OperandVector &Operands); 115*06c3fb27SDimitry Andric ParseStatus parseRegList(OperandVector &Operands); 116fe6060f1SDimitry Andric 117fe6060f1SDimitry Andric bool parseOperand(OperandVector &Operands, StringRef Mnemonic); 118fe6060f1SDimitry Andric 11981ad6265SDimitry Andric bool parseDirectiveAttribute(); 12081ad6265SDimitry Andric 121fe6060f1SDimitry Andric public: 122fe6060f1SDimitry Andric enum CSKYMatchResultTy { 123fe6060f1SDimitry Andric Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY, 124349cc55cSDimitry Andric Match_RequiresSameSrcAndDst, 125349cc55cSDimitry Andric Match_InvalidRegOutOfRange, 126fe6060f1SDimitry Andric #define GET_OPERAND_DIAGNOSTIC_TYPES 127fe6060f1SDimitry Andric #include "CSKYGenAsmMatcher.inc" 128fe6060f1SDimitry Andric #undef GET_OPERAND_DIAGNOSTIC_TYPES 129fe6060f1SDimitry Andric }; 130fe6060f1SDimitry Andric 131fe6060f1SDimitry Andric CSKYAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, 132fe6060f1SDimitry Andric const MCInstrInfo &MII, const MCTargetOptions &Options) 133fe6060f1SDimitry Andric : MCTargetAsmParser(Options, STI, MII) { 13481ad6265SDimitry Andric 13581ad6265SDimitry Andric MCAsmParserExtension::Initialize(Parser); 13681ad6265SDimitry Andric 13781ad6265SDimitry Andric // Cache the MCRegisterInfo. 13881ad6265SDimitry Andric MRI = getContext().getRegisterInfo(); 13981ad6265SDimitry Andric 140fe6060f1SDimitry Andric setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 14181ad6265SDimitry Andric getTargetStreamer().emitTargetAttributes(STI); 142fe6060f1SDimitry Andric } 143fe6060f1SDimitry Andric }; 144fe6060f1SDimitry Andric 145fe6060f1SDimitry Andric /// Instances of this class represent a parsed machine instruction. 146fe6060f1SDimitry Andric struct CSKYOperand : public MCParsedAsmOperand { 147349cc55cSDimitry Andric 148fe6060f1SDimitry Andric enum KindTy { 149fe6060f1SDimitry Andric Token, 150fe6060f1SDimitry Andric Register, 151fe6060f1SDimitry Andric Immediate, 152349cc55cSDimitry Andric RegisterSeq, 153349cc55cSDimitry Andric CPOP, 154349cc55cSDimitry Andric RegisterList 155fe6060f1SDimitry Andric } Kind; 156fe6060f1SDimitry Andric 157fe6060f1SDimitry Andric struct RegOp { 158fe6060f1SDimitry Andric unsigned RegNum; 159fe6060f1SDimitry Andric }; 160fe6060f1SDimitry Andric 161fe6060f1SDimitry Andric struct ImmOp { 162fe6060f1SDimitry Andric const MCExpr *Val; 163fe6060f1SDimitry Andric }; 164fe6060f1SDimitry Andric 165349cc55cSDimitry Andric struct ConstpoolOp { 166349cc55cSDimitry Andric const MCExpr *Val; 167349cc55cSDimitry Andric }; 168349cc55cSDimitry Andric 169349cc55cSDimitry Andric struct RegSeqOp { 170349cc55cSDimitry Andric unsigned RegNumFrom; 171349cc55cSDimitry Andric unsigned RegNumTo; 172349cc55cSDimitry Andric }; 173349cc55cSDimitry Andric 174349cc55cSDimitry Andric struct RegListOp { 175349cc55cSDimitry Andric unsigned List1From = 0; 176349cc55cSDimitry Andric unsigned List1To = 0; 177349cc55cSDimitry Andric unsigned List2From = 0; 178349cc55cSDimitry Andric unsigned List2To = 0; 179349cc55cSDimitry Andric unsigned List3From = 0; 180349cc55cSDimitry Andric unsigned List3To = 0; 181349cc55cSDimitry Andric unsigned List4From = 0; 182349cc55cSDimitry Andric unsigned List4To = 0; 183349cc55cSDimitry Andric }; 184349cc55cSDimitry Andric 185fe6060f1SDimitry Andric SMLoc StartLoc, EndLoc; 186fe6060f1SDimitry Andric union { 187fe6060f1SDimitry Andric StringRef Tok; 188fe6060f1SDimitry Andric RegOp Reg; 189fe6060f1SDimitry Andric ImmOp Imm; 190349cc55cSDimitry Andric ConstpoolOp CPool; 191349cc55cSDimitry Andric RegSeqOp RegSeq; 192349cc55cSDimitry Andric RegListOp RegList; 193fe6060f1SDimitry Andric }; 194fe6060f1SDimitry Andric 195fe6060f1SDimitry Andric CSKYOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 196fe6060f1SDimitry Andric 197fe6060f1SDimitry Andric public: 198fe6060f1SDimitry Andric CSKYOperand(const CSKYOperand &o) : MCParsedAsmOperand() { 199fe6060f1SDimitry Andric Kind = o.Kind; 200fe6060f1SDimitry Andric StartLoc = o.StartLoc; 201fe6060f1SDimitry Andric EndLoc = o.EndLoc; 202fe6060f1SDimitry Andric switch (Kind) { 203fe6060f1SDimitry Andric case Register: 204fe6060f1SDimitry Andric Reg = o.Reg; 205fe6060f1SDimitry Andric break; 206349cc55cSDimitry Andric case RegisterSeq: 207349cc55cSDimitry Andric RegSeq = o.RegSeq; 208349cc55cSDimitry Andric break; 209349cc55cSDimitry Andric case CPOP: 210349cc55cSDimitry Andric CPool = o.CPool; 211349cc55cSDimitry Andric break; 212fe6060f1SDimitry Andric case Immediate: 213fe6060f1SDimitry Andric Imm = o.Imm; 214fe6060f1SDimitry Andric break; 215fe6060f1SDimitry Andric case Token: 216fe6060f1SDimitry Andric Tok = o.Tok; 217fe6060f1SDimitry Andric break; 218349cc55cSDimitry Andric case RegisterList: 219349cc55cSDimitry Andric RegList = o.RegList; 220349cc55cSDimitry Andric break; 221fe6060f1SDimitry Andric } 222fe6060f1SDimitry Andric } 223fe6060f1SDimitry Andric 224fe6060f1SDimitry Andric bool isToken() const override { return Kind == Token; } 225fe6060f1SDimitry Andric bool isReg() const override { return Kind == Register; } 226fe6060f1SDimitry Andric bool isImm() const override { return Kind == Immediate; } 227349cc55cSDimitry Andric bool isRegisterSeq() const { return Kind == RegisterSeq; } 228349cc55cSDimitry Andric bool isRegisterList() const { return Kind == RegisterList; } 229349cc55cSDimitry Andric bool isConstPoolOp() const { return Kind == CPOP; } 230349cc55cSDimitry Andric 231fe6060f1SDimitry Andric bool isMem() const override { return false; } 232fe6060f1SDimitry Andric 233fe6060f1SDimitry Andric static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm) { 234fe6060f1SDimitry Andric if (auto CE = dyn_cast<MCConstantExpr>(Expr)) { 235fe6060f1SDimitry Andric Imm = CE->getValue(); 236fe6060f1SDimitry Andric return true; 237fe6060f1SDimitry Andric } 238fe6060f1SDimitry Andric 239fe6060f1SDimitry Andric return false; 240fe6060f1SDimitry Andric } 241fe6060f1SDimitry Andric 242fe6060f1SDimitry Andric template <unsigned num, unsigned shift = 0> bool isUImm() const { 243fe6060f1SDimitry Andric if (!isImm()) 244fe6060f1SDimitry Andric return false; 245fe6060f1SDimitry Andric 246fe6060f1SDimitry Andric int64_t Imm; 247fe6060f1SDimitry Andric bool IsConstantImm = evaluateConstantImm(getImm(), Imm); 248fe6060f1SDimitry Andric return IsConstantImm && isShiftedUInt<num, shift>(Imm); 249fe6060f1SDimitry Andric } 250fe6060f1SDimitry Andric 251fe6060f1SDimitry Andric template <unsigned num> bool isOImm() const { 252fe6060f1SDimitry Andric if (!isImm()) 253fe6060f1SDimitry Andric return false; 254fe6060f1SDimitry Andric 255fe6060f1SDimitry Andric int64_t Imm; 256fe6060f1SDimitry Andric bool IsConstantImm = evaluateConstantImm(getImm(), Imm); 257fe6060f1SDimitry Andric return IsConstantImm && isUInt<num>(Imm - 1); 258fe6060f1SDimitry Andric } 259fe6060f1SDimitry Andric 260fe6060f1SDimitry Andric template <unsigned num, unsigned shift = 0> bool isSImm() const { 261fe6060f1SDimitry Andric if (!isImm()) 262fe6060f1SDimitry Andric return false; 263fe6060f1SDimitry Andric 264fe6060f1SDimitry Andric int64_t Imm; 265fe6060f1SDimitry Andric bool IsConstantImm = evaluateConstantImm(getImm(), Imm); 266fe6060f1SDimitry Andric return IsConstantImm && isShiftedInt<num, shift>(Imm); 267fe6060f1SDimitry Andric } 268fe6060f1SDimitry Andric 269349cc55cSDimitry Andric bool isUImm1() const { return isUImm<1>(); } 270fe6060f1SDimitry Andric bool isUImm2() const { return isUImm<2>(); } 271349cc55cSDimitry Andric bool isUImm3() const { return isUImm<3>(); } 272349cc55cSDimitry Andric bool isUImm4() const { return isUImm<4>(); } 273fe6060f1SDimitry Andric bool isUImm5() const { return isUImm<5>(); } 274349cc55cSDimitry Andric bool isUImm6() const { return isUImm<6>(); } 275349cc55cSDimitry Andric bool isUImm7() const { return isUImm<7>(); } 276349cc55cSDimitry Andric bool isUImm8() const { return isUImm<8>(); } 277fe6060f1SDimitry Andric bool isUImm12() const { return isUImm<12>(); } 278fe6060f1SDimitry Andric bool isUImm16() const { return isUImm<16>(); } 279349cc55cSDimitry Andric bool isUImm20() const { return isUImm<20>(); } 280349cc55cSDimitry Andric bool isUImm24() const { return isUImm<24>(); } 281fe6060f1SDimitry Andric 282349cc55cSDimitry Andric bool isOImm3() const { return isOImm<3>(); } 283349cc55cSDimitry Andric bool isOImm4() const { return isOImm<4>(); } 284349cc55cSDimitry Andric bool isOImm5() const { return isOImm<5>(); } 285349cc55cSDimitry Andric bool isOImm6() const { return isOImm<6>(); } 286349cc55cSDimitry Andric bool isOImm8() const { return isOImm<8>(); } 287fe6060f1SDimitry Andric bool isOImm12() const { return isOImm<12>(); } 288fe6060f1SDimitry Andric bool isOImm16() const { return isOImm<16>(); } 289fe6060f1SDimitry Andric 290349cc55cSDimitry Andric bool isSImm8() const { return isSImm<8>(); } 291349cc55cSDimitry Andric 292349cc55cSDimitry Andric bool isUImm5Shift1() { return isUImm<5, 1>(); } 293349cc55cSDimitry Andric bool isUImm5Shift2() { return isUImm<5, 2>(); } 294349cc55cSDimitry Andric bool isUImm7Shift1() { return isUImm<7, 1>(); } 295349cc55cSDimitry Andric bool isUImm7Shift2() { return isUImm<7, 2>(); } 296349cc55cSDimitry Andric bool isUImm7Shift3() { return isUImm<7, 3>(); } 297349cc55cSDimitry Andric bool isUImm8Shift2() { return isUImm<8, 2>(); } 298349cc55cSDimitry Andric bool isUImm8Shift3() { return isUImm<8, 3>(); } 299349cc55cSDimitry Andric bool isUImm8Shift8() { return isUImm<8, 8>(); } 300349cc55cSDimitry Andric bool isUImm8Shift16() { return isUImm<8, 16>(); } 301349cc55cSDimitry Andric bool isUImm8Shift24() { return isUImm<8, 24>(); } 302fe6060f1SDimitry Andric bool isUImm12Shift1() { return isUImm<12, 1>(); } 303fe6060f1SDimitry Andric bool isUImm12Shift2() { return isUImm<12, 2>(); } 304349cc55cSDimitry Andric bool isUImm16Shift8() { return isUImm<16, 8>(); } 305349cc55cSDimitry Andric bool isUImm16Shift16() { return isUImm<16, 16>(); } 306349cc55cSDimitry Andric bool isUImm24Shift8() { return isUImm<24, 8>(); } 307fe6060f1SDimitry Andric 308fe6060f1SDimitry Andric bool isSImm16Shift1() { return isSImm<16, 1>(); } 309fe6060f1SDimitry Andric 310349cc55cSDimitry Andric bool isCSKYSymbol() const { return isImm(); } 311349cc55cSDimitry Andric 312349cc55cSDimitry Andric bool isConstpool() const { return isConstPoolOp(); } 313349cc55cSDimitry Andric bool isDataSymbol() const { return isConstPoolOp(); } 314349cc55cSDimitry Andric 315349cc55cSDimitry Andric bool isPSRFlag() const { 316fe6060f1SDimitry Andric int64_t Imm; 317349cc55cSDimitry Andric // Must be of 'immediate' type and a constant. 318349cc55cSDimitry Andric if (!isImm() || !evaluateConstantImm(getImm(), Imm)) 319349cc55cSDimitry Andric return false; 320349cc55cSDimitry Andric 321349cc55cSDimitry Andric return isUInt<5>(Imm); 322349cc55cSDimitry Andric } 323349cc55cSDimitry Andric 324349cc55cSDimitry Andric template <unsigned MIN, unsigned MAX> bool isRegSeqTemplate() const { 325349cc55cSDimitry Andric if (!isRegisterSeq()) 326349cc55cSDimitry Andric return false; 327349cc55cSDimitry Andric 328349cc55cSDimitry Andric std::pair<unsigned, unsigned> regSeq = getRegSeq(); 329349cc55cSDimitry Andric 330349cc55cSDimitry Andric return MIN <= regSeq.first && regSeq.first <= regSeq.second && 331349cc55cSDimitry Andric regSeq.second <= MAX; 332349cc55cSDimitry Andric } 333349cc55cSDimitry Andric 334349cc55cSDimitry Andric bool isRegSeq() const { return isRegSeqTemplate<CSKY::R0, CSKY::R31>(); } 335349cc55cSDimitry Andric 33604eeddc0SDimitry Andric bool isRegSeqV1() const { 33704eeddc0SDimitry Andric return isRegSeqTemplate<CSKY::F0_32, CSKY::F15_32>(); 33804eeddc0SDimitry Andric } 33904eeddc0SDimitry Andric 34004eeddc0SDimitry Andric bool isRegSeqV2() const { 34104eeddc0SDimitry Andric return isRegSeqTemplate<CSKY::F0_32, CSKY::F31_32>(); 34204eeddc0SDimitry Andric } 34304eeddc0SDimitry Andric 344349cc55cSDimitry Andric static bool isLegalRegList(unsigned from, unsigned to) { 345349cc55cSDimitry Andric if (from == 0 && to == 0) 346349cc55cSDimitry Andric return true; 347349cc55cSDimitry Andric 348349cc55cSDimitry Andric if (from == to) { 349349cc55cSDimitry Andric if (from != CSKY::R4 && from != CSKY::R15 && from != CSKY::R16 && 350349cc55cSDimitry Andric from != CSKY::R28) 351349cc55cSDimitry Andric return false; 352349cc55cSDimitry Andric 353349cc55cSDimitry Andric return true; 354349cc55cSDimitry Andric } else { 355349cc55cSDimitry Andric if (from != CSKY::R4 && from != CSKY::R16) 356349cc55cSDimitry Andric return false; 357349cc55cSDimitry Andric 358349cc55cSDimitry Andric if (from == CSKY::R4 && to > CSKY::R4 && to < CSKY::R12) 359349cc55cSDimitry Andric return true; 360349cc55cSDimitry Andric else if (from == CSKY::R16 && to > CSKY::R16 && to < CSKY::R18) 361349cc55cSDimitry Andric return true; 362349cc55cSDimitry Andric else 363349cc55cSDimitry Andric return false; 364349cc55cSDimitry Andric } 365349cc55cSDimitry Andric } 366349cc55cSDimitry Andric 367349cc55cSDimitry Andric bool isRegList() const { 368349cc55cSDimitry Andric if (!isRegisterList()) 369349cc55cSDimitry Andric return false; 370349cc55cSDimitry Andric 371349cc55cSDimitry Andric auto regList = getRegList(); 372349cc55cSDimitry Andric 373349cc55cSDimitry Andric if (!isLegalRegList(regList.List1From, regList.List1To)) 374349cc55cSDimitry Andric return false; 375349cc55cSDimitry Andric if (!isLegalRegList(regList.List2From, regList.List2To)) 376349cc55cSDimitry Andric return false; 377349cc55cSDimitry Andric if (!isLegalRegList(regList.List3From, regList.List3To)) 378349cc55cSDimitry Andric return false; 379349cc55cSDimitry Andric if (!isLegalRegList(regList.List4From, regList.List4To)) 380349cc55cSDimitry Andric return false; 381349cc55cSDimitry Andric 382349cc55cSDimitry Andric return true; 383349cc55cSDimitry Andric } 384349cc55cSDimitry Andric 385349cc55cSDimitry Andric bool isExtImm6() { 386349cc55cSDimitry Andric if (!isImm()) 387349cc55cSDimitry Andric return false; 388349cc55cSDimitry Andric 389349cc55cSDimitry Andric int64_t Imm; 390349cc55cSDimitry Andric bool IsConstantImm = evaluateConstantImm(getImm(), Imm); 391349cc55cSDimitry Andric if (!IsConstantImm) 392349cc55cSDimitry Andric return false; 393349cc55cSDimitry Andric 394349cc55cSDimitry Andric int uimm4 = Imm & 0xf; 395349cc55cSDimitry Andric 396349cc55cSDimitry Andric return isShiftedUInt<6, 0>(Imm) && uimm4 >= 0 && uimm4 <= 14; 397fe6060f1SDimitry Andric } 398fe6060f1SDimitry Andric 399fe6060f1SDimitry Andric /// Gets location of the first token of this operand. 400fe6060f1SDimitry Andric SMLoc getStartLoc() const override { return StartLoc; } 401fe6060f1SDimitry Andric /// Gets location of the last token of this operand. 402fe6060f1SDimitry Andric SMLoc getEndLoc() const override { return EndLoc; } 403fe6060f1SDimitry Andric 404fe6060f1SDimitry Andric unsigned getReg() const override { 405fe6060f1SDimitry Andric assert(Kind == Register && "Invalid type access!"); 406fe6060f1SDimitry Andric return Reg.RegNum; 407fe6060f1SDimitry Andric } 408fe6060f1SDimitry Andric 409349cc55cSDimitry Andric std::pair<unsigned, unsigned> getRegSeq() const { 410349cc55cSDimitry Andric assert(Kind == RegisterSeq && "Invalid type access!"); 411349cc55cSDimitry Andric return std::pair<unsigned, unsigned>(RegSeq.RegNumFrom, RegSeq.RegNumTo); 412349cc55cSDimitry Andric } 413349cc55cSDimitry Andric 414349cc55cSDimitry Andric RegListOp getRegList() const { 415349cc55cSDimitry Andric assert(Kind == RegisterList && "Invalid type access!"); 416349cc55cSDimitry Andric return RegList; 417349cc55cSDimitry Andric } 418349cc55cSDimitry Andric 419fe6060f1SDimitry Andric const MCExpr *getImm() const { 420fe6060f1SDimitry Andric assert(Kind == Immediate && "Invalid type access!"); 421fe6060f1SDimitry Andric return Imm.Val; 422fe6060f1SDimitry Andric } 423fe6060f1SDimitry Andric 424349cc55cSDimitry Andric const MCExpr *getConstpoolOp() const { 425349cc55cSDimitry Andric assert(Kind == CPOP && "Invalid type access!"); 426349cc55cSDimitry Andric return CPool.Val; 427349cc55cSDimitry Andric } 428349cc55cSDimitry Andric 429fe6060f1SDimitry Andric StringRef getToken() const { 430fe6060f1SDimitry Andric assert(Kind == Token && "Invalid type access!"); 431fe6060f1SDimitry Andric return Tok; 432fe6060f1SDimitry Andric } 433fe6060f1SDimitry Andric 434fe6060f1SDimitry Andric void print(raw_ostream &OS) const override { 435bdd1243dSDimitry Andric auto RegName = [](MCRegister Reg) { 436349cc55cSDimitry Andric if (Reg) 437349cc55cSDimitry Andric return CSKYInstPrinter::getRegisterName(Reg); 438349cc55cSDimitry Andric else 439349cc55cSDimitry Andric return "noreg"; 440349cc55cSDimitry Andric }; 441349cc55cSDimitry Andric 442fe6060f1SDimitry Andric switch (Kind) { 443349cc55cSDimitry Andric case CPOP: 444349cc55cSDimitry Andric OS << *getConstpoolOp(); 445349cc55cSDimitry Andric break; 446fe6060f1SDimitry Andric case Immediate: 447fe6060f1SDimitry Andric OS << *getImm(); 448fe6060f1SDimitry Andric break; 449349cc55cSDimitry Andric case KindTy::Register: 450349cc55cSDimitry Andric OS << "<register " << RegName(getReg()) << ">"; 451349cc55cSDimitry Andric break; 452349cc55cSDimitry Andric case RegisterSeq: 453349cc55cSDimitry Andric OS << "<register-seq "; 454349cc55cSDimitry Andric OS << RegName(getRegSeq().first) << "-" << RegName(getRegSeq().second) 455349cc55cSDimitry Andric << ">"; 456349cc55cSDimitry Andric break; 457349cc55cSDimitry Andric case RegisterList: 458349cc55cSDimitry Andric OS << "<register-list "; 459349cc55cSDimitry Andric OS << RegName(getRegList().List1From) << "-" 460349cc55cSDimitry Andric << RegName(getRegList().List1To) << ","; 461349cc55cSDimitry Andric OS << RegName(getRegList().List2From) << "-" 462349cc55cSDimitry Andric << RegName(getRegList().List2To) << ","; 463349cc55cSDimitry Andric OS << RegName(getRegList().List3From) << "-" 464349cc55cSDimitry Andric << RegName(getRegList().List3To) << ","; 465349cc55cSDimitry Andric OS << RegName(getRegList().List4From) << "-" 466349cc55cSDimitry Andric << RegName(getRegList().List4To); 467fe6060f1SDimitry Andric break; 468fe6060f1SDimitry Andric case Token: 469fe6060f1SDimitry Andric OS << "'" << getToken() << "'"; 470fe6060f1SDimitry Andric break; 471fe6060f1SDimitry Andric } 472fe6060f1SDimitry Andric } 473fe6060f1SDimitry Andric 474fe6060f1SDimitry Andric static std::unique_ptr<CSKYOperand> createToken(StringRef Str, SMLoc S) { 475fe6060f1SDimitry Andric auto Op = std::make_unique<CSKYOperand>(Token); 476fe6060f1SDimitry Andric Op->Tok = Str; 477fe6060f1SDimitry Andric Op->StartLoc = S; 478fe6060f1SDimitry Andric Op->EndLoc = S; 479fe6060f1SDimitry Andric return Op; 480fe6060f1SDimitry Andric } 481fe6060f1SDimitry Andric 482fe6060f1SDimitry Andric static std::unique_ptr<CSKYOperand> createReg(unsigned RegNo, SMLoc S, 483fe6060f1SDimitry Andric SMLoc E) { 484fe6060f1SDimitry Andric auto Op = std::make_unique<CSKYOperand>(Register); 485fe6060f1SDimitry Andric Op->Reg.RegNum = RegNo; 486fe6060f1SDimitry Andric Op->StartLoc = S; 487fe6060f1SDimitry Andric Op->EndLoc = E; 488fe6060f1SDimitry Andric return Op; 489fe6060f1SDimitry Andric } 490fe6060f1SDimitry Andric 491349cc55cSDimitry Andric static std::unique_ptr<CSKYOperand> createRegSeq(unsigned RegNoFrom, 492349cc55cSDimitry Andric unsigned RegNoTo, SMLoc S) { 493349cc55cSDimitry Andric auto Op = std::make_unique<CSKYOperand>(RegisterSeq); 494349cc55cSDimitry Andric Op->RegSeq.RegNumFrom = RegNoFrom; 495349cc55cSDimitry Andric Op->RegSeq.RegNumTo = RegNoTo; 496349cc55cSDimitry Andric Op->StartLoc = S; 497349cc55cSDimitry Andric Op->EndLoc = S; 498349cc55cSDimitry Andric return Op; 499349cc55cSDimitry Andric } 500349cc55cSDimitry Andric 501349cc55cSDimitry Andric static std::unique_ptr<CSKYOperand> 502349cc55cSDimitry Andric createRegList(SmallVector<unsigned, 4> reglist, SMLoc S) { 503349cc55cSDimitry Andric auto Op = std::make_unique<CSKYOperand>(RegisterList); 504349cc55cSDimitry Andric Op->RegList.List1From = 0; 505349cc55cSDimitry Andric Op->RegList.List1To = 0; 506349cc55cSDimitry Andric Op->RegList.List2From = 0; 507349cc55cSDimitry Andric Op->RegList.List2To = 0; 508349cc55cSDimitry Andric Op->RegList.List3From = 0; 509349cc55cSDimitry Andric Op->RegList.List3To = 0; 510349cc55cSDimitry Andric Op->RegList.List4From = 0; 511349cc55cSDimitry Andric Op->RegList.List4To = 0; 512349cc55cSDimitry Andric 513349cc55cSDimitry Andric for (unsigned i = 0; i < reglist.size(); i += 2) { 514349cc55cSDimitry Andric if (Op->RegList.List1From == 0) { 515349cc55cSDimitry Andric Op->RegList.List1From = reglist[i]; 516349cc55cSDimitry Andric Op->RegList.List1To = reglist[i + 1]; 517349cc55cSDimitry Andric } else if (Op->RegList.List2From == 0) { 518349cc55cSDimitry Andric Op->RegList.List2From = reglist[i]; 519349cc55cSDimitry Andric Op->RegList.List2To = reglist[i + 1]; 520349cc55cSDimitry Andric } else if (Op->RegList.List3From == 0) { 521349cc55cSDimitry Andric Op->RegList.List3From = reglist[i]; 522349cc55cSDimitry Andric Op->RegList.List3To = reglist[i + 1]; 523349cc55cSDimitry Andric } else if (Op->RegList.List4From == 0) { 524349cc55cSDimitry Andric Op->RegList.List4From = reglist[i]; 525349cc55cSDimitry Andric Op->RegList.List4To = reglist[i + 1]; 526349cc55cSDimitry Andric } else { 527349cc55cSDimitry Andric assert(0); 528349cc55cSDimitry Andric } 529349cc55cSDimitry Andric } 530349cc55cSDimitry Andric 531349cc55cSDimitry Andric Op->StartLoc = S; 532349cc55cSDimitry Andric Op->EndLoc = S; 533349cc55cSDimitry Andric return Op; 534349cc55cSDimitry Andric } 535349cc55cSDimitry Andric 536fe6060f1SDimitry Andric static std::unique_ptr<CSKYOperand> createImm(const MCExpr *Val, SMLoc S, 537fe6060f1SDimitry Andric SMLoc E) { 538fe6060f1SDimitry Andric auto Op = std::make_unique<CSKYOperand>(Immediate); 539fe6060f1SDimitry Andric Op->Imm.Val = Val; 540fe6060f1SDimitry Andric Op->StartLoc = S; 541fe6060f1SDimitry Andric Op->EndLoc = E; 542fe6060f1SDimitry Andric return Op; 543fe6060f1SDimitry Andric } 544fe6060f1SDimitry Andric 545349cc55cSDimitry Andric static std::unique_ptr<CSKYOperand> createConstpoolOp(const MCExpr *Val, 546349cc55cSDimitry Andric SMLoc S, SMLoc E) { 547349cc55cSDimitry Andric auto Op = std::make_unique<CSKYOperand>(CPOP); 548349cc55cSDimitry Andric Op->CPool.Val = Val; 549349cc55cSDimitry Andric Op->StartLoc = S; 550349cc55cSDimitry Andric Op->EndLoc = E; 551349cc55cSDimitry Andric return Op; 552349cc55cSDimitry Andric } 553349cc55cSDimitry Andric 554fe6060f1SDimitry Andric void addExpr(MCInst &Inst, const MCExpr *Expr) const { 555fe6060f1SDimitry Andric assert(Expr && "Expr shouldn't be null!"); 556fe6060f1SDimitry Andric if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) 557fe6060f1SDimitry Andric Inst.addOperand(MCOperand::createImm(CE->getValue())); 558fe6060f1SDimitry Andric else 559fe6060f1SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr)); 560fe6060f1SDimitry Andric } 561fe6060f1SDimitry Andric 562fe6060f1SDimitry Andric // Used by the TableGen Code. 563fe6060f1SDimitry Andric void addRegOperands(MCInst &Inst, unsigned N) const { 564fe6060f1SDimitry Andric assert(N == 1 && "Invalid number of operands!"); 565fe6060f1SDimitry Andric Inst.addOperand(MCOperand::createReg(getReg())); 566fe6060f1SDimitry Andric } 567fe6060f1SDimitry Andric 568fe6060f1SDimitry Andric void addImmOperands(MCInst &Inst, unsigned N) const { 569fe6060f1SDimitry Andric assert(N == 1 && "Invalid number of operands!"); 570fe6060f1SDimitry Andric addExpr(Inst, getImm()); 571fe6060f1SDimitry Andric } 572349cc55cSDimitry Andric 573349cc55cSDimitry Andric void addConstpoolOperands(MCInst &Inst, unsigned N) const { 574349cc55cSDimitry Andric assert(N == 1 && "Invalid number of operands!"); 575349cc55cSDimitry Andric Inst.addOperand(MCOperand::createExpr(getConstpoolOp())); 576349cc55cSDimitry Andric } 577349cc55cSDimitry Andric 578349cc55cSDimitry Andric void addRegSeqOperands(MCInst &Inst, unsigned N) const { 579349cc55cSDimitry Andric assert(N == 2 && "Invalid number of operands!"); 580349cc55cSDimitry Andric auto regSeq = getRegSeq(); 581349cc55cSDimitry Andric 582349cc55cSDimitry Andric Inst.addOperand(MCOperand::createReg(regSeq.first)); 583349cc55cSDimitry Andric Inst.addOperand(MCOperand::createReg(regSeq.second)); 584349cc55cSDimitry Andric } 585349cc55cSDimitry Andric 586349cc55cSDimitry Andric static unsigned getListValue(unsigned ListFrom, unsigned ListTo) { 587349cc55cSDimitry Andric if (ListFrom == ListTo && ListFrom == CSKY::R15) 588349cc55cSDimitry Andric return (1 << 4); 589349cc55cSDimitry Andric else if (ListFrom == ListTo && ListFrom == CSKY::R28) 590349cc55cSDimitry Andric return (1 << 8); 591349cc55cSDimitry Andric else if (ListFrom == CSKY::R4) 592349cc55cSDimitry Andric return ListTo - ListFrom + 1; 593349cc55cSDimitry Andric else if (ListFrom == CSKY::R16) 594349cc55cSDimitry Andric return ((ListTo - ListFrom + 1) << 5); 595349cc55cSDimitry Andric else 596349cc55cSDimitry Andric return 0; 597349cc55cSDimitry Andric } 598349cc55cSDimitry Andric 599349cc55cSDimitry Andric void addRegListOperands(MCInst &Inst, unsigned N) const { 600349cc55cSDimitry Andric assert(N == 1 && "Invalid number of operands!"); 601349cc55cSDimitry Andric auto regList = getRegList(); 602349cc55cSDimitry Andric 603349cc55cSDimitry Andric unsigned V = 0; 604349cc55cSDimitry Andric 605349cc55cSDimitry Andric unsigned T = getListValue(regList.List1From, regList.List1To); 606349cc55cSDimitry Andric if (T != 0) 607349cc55cSDimitry Andric V = V | T; 608349cc55cSDimitry Andric 609349cc55cSDimitry Andric T = getListValue(regList.List2From, regList.List2To); 610349cc55cSDimitry Andric if (T != 0) 611349cc55cSDimitry Andric V = V | T; 612349cc55cSDimitry Andric 613349cc55cSDimitry Andric T = getListValue(regList.List3From, regList.List3To); 614349cc55cSDimitry Andric if (T != 0) 615349cc55cSDimitry Andric V = V | T; 616349cc55cSDimitry Andric 617349cc55cSDimitry Andric T = getListValue(regList.List4From, regList.List4To); 618349cc55cSDimitry Andric if (T != 0) 619349cc55cSDimitry Andric V = V | T; 620349cc55cSDimitry Andric 621349cc55cSDimitry Andric Inst.addOperand(MCOperand::createImm(V)); 622349cc55cSDimitry Andric } 623349cc55cSDimitry Andric 624349cc55cSDimitry Andric bool isValidForTie(const CSKYOperand &Other) const { 625349cc55cSDimitry Andric if (Kind != Other.Kind) 626349cc55cSDimitry Andric return false; 627349cc55cSDimitry Andric 628349cc55cSDimitry Andric switch (Kind) { 629349cc55cSDimitry Andric default: 630349cc55cSDimitry Andric llvm_unreachable("Unexpected kind"); 631349cc55cSDimitry Andric return false; 632349cc55cSDimitry Andric case Register: 633349cc55cSDimitry Andric return Reg.RegNum == Other.Reg.RegNum; 634349cc55cSDimitry Andric } 635349cc55cSDimitry Andric } 636fe6060f1SDimitry Andric }; 637fe6060f1SDimitry Andric } // end anonymous namespace. 638fe6060f1SDimitry Andric 639fe6060f1SDimitry Andric #define GET_REGISTER_MATCHER 640fe6060f1SDimitry Andric #define GET_SUBTARGET_FEATURE_NAME 641fe6060f1SDimitry Andric #define GET_MATCHER_IMPLEMENTATION 642fe6060f1SDimitry Andric #define GET_MNEMONIC_SPELL_CHECKER 643fe6060f1SDimitry Andric #include "CSKYGenAsmMatcher.inc" 644fe6060f1SDimitry Andric 64581ad6265SDimitry Andric static MCRegister convertFPR32ToFPR64(MCRegister Reg) { 64681ad6265SDimitry Andric assert(Reg >= CSKY::F0_32 && Reg <= CSKY::F31_32 && "Invalid register"); 64781ad6265SDimitry Andric return Reg - CSKY::F0_32 + CSKY::F0_64; 64881ad6265SDimitry Andric } 64981ad6265SDimitry Andric 650fe6060f1SDimitry Andric static std::string CSKYMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, 651fe6060f1SDimitry Andric unsigned VariantID = 0); 652fe6060f1SDimitry Andric 653fe6060f1SDimitry Andric bool CSKYAsmParser::generateImmOutOfRangeError( 654fe6060f1SDimitry Andric OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper, 655*06c3fb27SDimitry Andric const Twine &Msg = "immediate must be an integer in the range") { 656fe6060f1SDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 657fe6060f1SDimitry Andric return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]"); 658fe6060f1SDimitry Andric } 659fe6060f1SDimitry Andric 660fe6060f1SDimitry Andric bool CSKYAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 661fe6060f1SDimitry Andric OperandVector &Operands, 662fe6060f1SDimitry Andric MCStreamer &Out, 663fe6060f1SDimitry Andric uint64_t &ErrorInfo, 664fe6060f1SDimitry Andric bool MatchingInlineAsm) { 665fe6060f1SDimitry Andric MCInst Inst; 666fe6060f1SDimitry Andric FeatureBitset MissingFeatures; 667fe6060f1SDimitry Andric 668fe6060f1SDimitry Andric auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures, 669fe6060f1SDimitry Andric MatchingInlineAsm); 670fe6060f1SDimitry Andric switch (Result) { 671fe6060f1SDimitry Andric default: 672fe6060f1SDimitry Andric break; 673fe6060f1SDimitry Andric case Match_Success: 674349cc55cSDimitry Andric return processInstruction(Inst, IDLoc, Operands, Out); 675fe6060f1SDimitry Andric case Match_MissingFeature: { 676fe6060f1SDimitry Andric assert(MissingFeatures.any() && "Unknown missing features!"); 677fe6060f1SDimitry Andric ListSeparator LS; 678fe6060f1SDimitry Andric std::string Msg = "instruction requires the following: "; 679fe6060f1SDimitry Andric for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) { 680fe6060f1SDimitry Andric if (MissingFeatures[i]) { 681fe6060f1SDimitry Andric Msg += LS; 682fe6060f1SDimitry Andric Msg += getSubtargetFeatureName(i); 683fe6060f1SDimitry Andric } 684fe6060f1SDimitry Andric } 685fe6060f1SDimitry Andric return Error(IDLoc, Msg); 686fe6060f1SDimitry Andric } 687fe6060f1SDimitry Andric case Match_MnemonicFail: { 688fe6060f1SDimitry Andric FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits()); 689fe6060f1SDimitry Andric std::string Suggestion = 690fe6060f1SDimitry Andric CSKYMnemonicSpellCheck(((CSKYOperand &)*Operands[0]).getToken(), FBS); 691fe6060f1SDimitry Andric return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion); 692fe6060f1SDimitry Andric } 693fe6060f1SDimitry Andric case Match_InvalidTiedOperand: 694fe6060f1SDimitry Andric case Match_InvalidOperand: { 695fe6060f1SDimitry Andric SMLoc ErrorLoc = IDLoc; 696fe6060f1SDimitry Andric if (ErrorInfo != ~0U) { 697fe6060f1SDimitry Andric if (ErrorInfo >= Operands.size()) 698fe6060f1SDimitry Andric return Error(ErrorLoc, "too few operands for instruction"); 699fe6060f1SDimitry Andric 700fe6060f1SDimitry Andric ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 701fe6060f1SDimitry Andric if (ErrorLoc == SMLoc()) 702fe6060f1SDimitry Andric ErrorLoc = IDLoc; 703fe6060f1SDimitry Andric } 704fe6060f1SDimitry Andric return Error(ErrorLoc, "invalid operand for instruction"); 705fe6060f1SDimitry Andric } 706fe6060f1SDimitry Andric } 707fe6060f1SDimitry Andric 708fe6060f1SDimitry Andric // Handle the case when the error message is of specific type 709fe6060f1SDimitry Andric // other than the generic Match_InvalidOperand, and the 710fe6060f1SDimitry Andric // corresponding operand is missing. 711fe6060f1SDimitry Andric if (Result > FIRST_TARGET_MATCH_RESULT_TY) { 712fe6060f1SDimitry Andric SMLoc ErrorLoc = IDLoc; 713fe6060f1SDimitry Andric if (ErrorInfo != ~0U && ErrorInfo >= Operands.size()) 714fe6060f1SDimitry Andric return Error(ErrorLoc, "too few operands for instruction"); 715fe6060f1SDimitry Andric } 716fe6060f1SDimitry Andric 717fe6060f1SDimitry Andric switch (Result) { 718fe6060f1SDimitry Andric default: 719fe6060f1SDimitry Andric break; 720349cc55cSDimitry Andric case Match_InvalidSImm8: 721349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7), 722349cc55cSDimitry Andric (1 << 7) - 1); 723349cc55cSDimitry Andric case Match_InvalidOImm3: 724349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 3)); 725349cc55cSDimitry Andric case Match_InvalidOImm4: 726349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4)); 727349cc55cSDimitry Andric case Match_InvalidOImm5: 728349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5)); 729349cc55cSDimitry Andric case Match_InvalidOImm6: 730349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6)); 731349cc55cSDimitry Andric case Match_InvalidOImm8: 732349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 8)); 733fe6060f1SDimitry Andric case Match_InvalidOImm12: 734fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 12)); 735fe6060f1SDimitry Andric case Match_InvalidOImm16: 736fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16)); 737349cc55cSDimitry Andric case Match_InvalidUImm1: 738349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1); 739fe6060f1SDimitry Andric case Match_InvalidUImm2: 740fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1); 741349cc55cSDimitry Andric case Match_InvalidUImm3: 742349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1); 743349cc55cSDimitry Andric case Match_InvalidUImm4: 744349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1); 745fe6060f1SDimitry Andric case Match_InvalidUImm5: 746fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 747349cc55cSDimitry Andric case Match_InvalidUImm6: 748349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); 749349cc55cSDimitry Andric case Match_InvalidUImm7: 750349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1); 751349cc55cSDimitry Andric case Match_InvalidUImm8: 752349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1); 753fe6060f1SDimitry Andric case Match_InvalidUImm12: 754fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1); 755349cc55cSDimitry Andric case Match_InvalidUImm16: 756349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 16) - 1); 757349cc55cSDimitry Andric case Match_InvalidUImm5Shift1: 758349cc55cSDimitry Andric return generateImmOutOfRangeError( 759349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 5) - 2, 760349cc55cSDimitry Andric "immediate must be a multiple of 2 bytes in the range"); 761fe6060f1SDimitry Andric case Match_InvalidUImm12Shift1: 762fe6060f1SDimitry Andric return generateImmOutOfRangeError( 763fe6060f1SDimitry Andric Operands, ErrorInfo, 0, (1 << 12) - 2, 764fe6060f1SDimitry Andric "immediate must be a multiple of 2 bytes in the range"); 765349cc55cSDimitry Andric case Match_InvalidUImm5Shift2: 766349cc55cSDimitry Andric return generateImmOutOfRangeError( 767349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 5) - 4, 768349cc55cSDimitry Andric "immediate must be a multiple of 4 bytes in the range"); 769349cc55cSDimitry Andric case Match_InvalidUImm7Shift1: 770349cc55cSDimitry Andric return generateImmOutOfRangeError( 771349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 7) - 2, 772349cc55cSDimitry Andric "immediate must be a multiple of 2 bytes in the range"); 773349cc55cSDimitry Andric case Match_InvalidUImm7Shift2: 774349cc55cSDimitry Andric return generateImmOutOfRangeError( 775349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 7) - 4, 776349cc55cSDimitry Andric "immediate must be a multiple of 4 bytes in the range"); 777349cc55cSDimitry Andric case Match_InvalidUImm8Shift2: 778349cc55cSDimitry Andric return generateImmOutOfRangeError( 779349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 8) - 4, 780349cc55cSDimitry Andric "immediate must be a multiple of 4 bytes in the range"); 781349cc55cSDimitry Andric case Match_InvalidUImm8Shift3: 782349cc55cSDimitry Andric return generateImmOutOfRangeError( 783349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 8) - 8, 784349cc55cSDimitry Andric "immediate must be a multiple of 8 bytes in the range"); 785349cc55cSDimitry Andric case Match_InvalidUImm8Shift8: 786349cc55cSDimitry Andric return generateImmOutOfRangeError( 787349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 8) - 256, 788349cc55cSDimitry Andric "immediate must be a multiple of 256 bytes in the range"); 789fe6060f1SDimitry Andric case Match_InvalidUImm12Shift2: 790fe6060f1SDimitry Andric return generateImmOutOfRangeError( 791fe6060f1SDimitry Andric Operands, ErrorInfo, 0, (1 << 12) - 4, 792fe6060f1SDimitry Andric "immediate must be a multiple of 4 bytes in the range"); 793fe6060f1SDimitry Andric case Match_InvalidCSKYSymbol: { 794fe6060f1SDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 795fe6060f1SDimitry Andric return Error(ErrorLoc, "operand must be a symbol name"); 796fe6060f1SDimitry Andric } 797fe6060f1SDimitry Andric case Match_InvalidConstpool: { 798fe6060f1SDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 799fe6060f1SDimitry Andric return Error(ErrorLoc, "operand must be a constpool symbol name"); 800fe6060f1SDimitry Andric } 801349cc55cSDimitry Andric case Match_InvalidPSRFlag: { 802349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 803349cc55cSDimitry Andric return Error(ErrorLoc, "psrset operand is not valid"); 804349cc55cSDimitry Andric } 805349cc55cSDimitry Andric case Match_InvalidRegSeq: { 806349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 807349cc55cSDimitry Andric return Error(ErrorLoc, "Register sequence is not valid"); 808349cc55cSDimitry Andric } 809349cc55cSDimitry Andric case Match_InvalidRegOutOfRange: { 810349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 811349cc55cSDimitry Andric return Error(ErrorLoc, "register is out of range"); 812349cc55cSDimitry Andric } 813349cc55cSDimitry Andric case Match_RequiresSameSrcAndDst: { 814349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 815349cc55cSDimitry Andric return Error(ErrorLoc, "src and dst operand must be same"); 816349cc55cSDimitry Andric } 817349cc55cSDimitry Andric case Match_InvalidRegList: { 818349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 819349cc55cSDimitry Andric return Error(ErrorLoc, "invalid register list"); 820349cc55cSDimitry Andric } 821349cc55cSDimitry Andric } 822349cc55cSDimitry Andric LLVM_DEBUG(dbgs() << "Result = " << Result); 823349cc55cSDimitry Andric llvm_unreachable("Unknown match type detected!"); 824fe6060f1SDimitry Andric } 825fe6060f1SDimitry Andric 82681ad6265SDimitry Andric bool CSKYAsmParser::processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) { 82781ad6265SDimitry Andric Inst.setLoc(IDLoc); 82881ad6265SDimitry Andric 82981ad6265SDimitry Andric unsigned Opcode; 83081ad6265SDimitry Andric MCOperand Op; 83181ad6265SDimitry Andric if (Inst.getOpcode() == CSKY::PseudoLRW16) 83281ad6265SDimitry Andric Opcode = CSKY::LRW16; 83381ad6265SDimitry Andric else 83481ad6265SDimitry Andric Opcode = CSKY::LRW32; 83581ad6265SDimitry Andric 83681ad6265SDimitry Andric if (Inst.getOperand(1).isImm()) { 83781ad6265SDimitry Andric if (isUInt<8>(Inst.getOperand(1).getImm()) && 83881ad6265SDimitry Andric Inst.getOperand(0).getReg() <= CSKY::R7) { 83981ad6265SDimitry Andric Opcode = CSKY::MOVI16; 840*06c3fb27SDimitry Andric } else if (getSTI().hasFeature(CSKY::HasE2) && 84181ad6265SDimitry Andric isUInt<16>(Inst.getOperand(1).getImm())) { 84281ad6265SDimitry Andric Opcode = CSKY::MOVI32; 84381ad6265SDimitry Andric } else { 84481ad6265SDimitry Andric auto *Expr = getTargetStreamer().addConstantPoolEntry( 84581ad6265SDimitry Andric MCConstantExpr::create(Inst.getOperand(1).getImm(), getContext()), 84681ad6265SDimitry Andric Inst.getLoc()); 84781ad6265SDimitry Andric Inst.erase(std::prev(Inst.end())); 84881ad6265SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr)); 84981ad6265SDimitry Andric } 85081ad6265SDimitry Andric } else { 85181ad6265SDimitry Andric const MCExpr *AdjustExpr = nullptr; 85281ad6265SDimitry Andric if (const CSKYMCExpr *CSKYExpr = 85381ad6265SDimitry Andric dyn_cast<CSKYMCExpr>(Inst.getOperand(1).getExpr())) { 85481ad6265SDimitry Andric if (CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSGD || 85581ad6265SDimitry Andric CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSIE || 85681ad6265SDimitry Andric CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSLDM) { 85781ad6265SDimitry Andric MCSymbol *Dot = getContext().createNamedTempSymbol(); 85881ad6265SDimitry Andric Out.emitLabel(Dot); 85981ad6265SDimitry Andric AdjustExpr = MCSymbolRefExpr::create(Dot, getContext()); 86081ad6265SDimitry Andric } 86181ad6265SDimitry Andric } 86281ad6265SDimitry Andric auto *Expr = getTargetStreamer().addConstantPoolEntry( 86381ad6265SDimitry Andric Inst.getOperand(1).getExpr(), Inst.getLoc(), AdjustExpr); 86481ad6265SDimitry Andric Inst.erase(std::prev(Inst.end())); 86581ad6265SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr)); 86681ad6265SDimitry Andric } 86781ad6265SDimitry Andric 86881ad6265SDimitry Andric Inst.setOpcode(Opcode); 86981ad6265SDimitry Andric 87081ad6265SDimitry Andric Out.emitInstruction(Inst, getSTI()); 87181ad6265SDimitry Andric return false; 87281ad6265SDimitry Andric } 87381ad6265SDimitry Andric 87481ad6265SDimitry Andric bool CSKYAsmParser::processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) { 87581ad6265SDimitry Andric Inst.setLoc(IDLoc); 87681ad6265SDimitry Andric 87781ad6265SDimitry Andric if (Inst.getOperand(0).isImm()) { 87881ad6265SDimitry Andric const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry( 87981ad6265SDimitry Andric MCConstantExpr::create(Inst.getOperand(0).getImm(), getContext()), 88081ad6265SDimitry Andric Inst.getLoc()); 88181ad6265SDimitry Andric Inst.setOpcode(CSKY::JSRI32); 88281ad6265SDimitry Andric Inst.erase(std::prev(Inst.end())); 88381ad6265SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr)); 88481ad6265SDimitry Andric } else { 88581ad6265SDimitry Andric const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry( 88681ad6265SDimitry Andric Inst.getOperand(0).getExpr(), Inst.getLoc()); 88781ad6265SDimitry Andric Inst.setOpcode(CSKY::JBSR32); 88881ad6265SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr)); 88981ad6265SDimitry Andric } 89081ad6265SDimitry Andric 89181ad6265SDimitry Andric Out.emitInstruction(Inst, getSTI()); 89281ad6265SDimitry Andric return false; 89381ad6265SDimitry Andric } 89481ad6265SDimitry Andric 89581ad6265SDimitry Andric bool CSKYAsmParser::processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) { 89681ad6265SDimitry Andric Inst.setLoc(IDLoc); 89781ad6265SDimitry Andric 89881ad6265SDimitry Andric if (Inst.getOperand(0).isImm()) { 89981ad6265SDimitry Andric const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry( 90081ad6265SDimitry Andric MCConstantExpr::create(Inst.getOperand(0).getImm(), getContext()), 90181ad6265SDimitry Andric Inst.getLoc()); 90281ad6265SDimitry Andric Inst.setOpcode(CSKY::JMPI32); 90381ad6265SDimitry Andric Inst.erase(std::prev(Inst.end())); 90481ad6265SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr)); 90581ad6265SDimitry Andric } else { 90681ad6265SDimitry Andric const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry( 90781ad6265SDimitry Andric Inst.getOperand(0).getExpr(), Inst.getLoc()); 90881ad6265SDimitry Andric Inst.setOpcode(CSKY::JBR32); 90981ad6265SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr)); 91081ad6265SDimitry Andric } 91181ad6265SDimitry Andric 91281ad6265SDimitry Andric Out.emitInstruction(Inst, getSTI()); 91381ad6265SDimitry Andric return false; 91481ad6265SDimitry Andric } 91581ad6265SDimitry Andric 916349cc55cSDimitry Andric bool CSKYAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 917349cc55cSDimitry Andric OperandVector &Operands, 918349cc55cSDimitry Andric MCStreamer &Out) { 919349cc55cSDimitry Andric 9200eae32dcSDimitry Andric switch (Inst.getOpcode()) { 9210eae32dcSDimitry Andric default: 9220eae32dcSDimitry Andric break; 9230eae32dcSDimitry Andric case CSKY::LDQ32: 9240eae32dcSDimitry Andric case CSKY::STQ32: 925349cc55cSDimitry Andric if (Inst.getOperand(1).getReg() != CSKY::R4 || 926349cc55cSDimitry Andric Inst.getOperand(2).getReg() != CSKY::R7) { 927349cc55cSDimitry Andric return Error(IDLoc, "Register sequence is not valid. 'r4-r7' expected"); 928349cc55cSDimitry Andric } 929349cc55cSDimitry Andric Inst.setOpcode(Inst.getOpcode() == CSKY::LDQ32 ? CSKY::LDM32 : CSKY::STM32); 9300eae32dcSDimitry Andric break; 9310eae32dcSDimitry Andric case CSKY::SEXT32: 9320eae32dcSDimitry Andric case CSKY::ZEXT32: 933349cc55cSDimitry Andric if (Inst.getOperand(2).getImm() < Inst.getOperand(3).getImm()) 934349cc55cSDimitry Andric return Error(IDLoc, "msb must be greater or equal to lsb"); 9350eae32dcSDimitry Andric break; 9360eae32dcSDimitry Andric case CSKY::INS32: 937349cc55cSDimitry Andric if (Inst.getOperand(3).getImm() < Inst.getOperand(4).getImm()) 938349cc55cSDimitry Andric return Error(IDLoc, "msb must be greater or equal to lsb"); 9390eae32dcSDimitry Andric break; 9400eae32dcSDimitry Andric case CSKY::IDLY32: 941349cc55cSDimitry Andric if (Inst.getOperand(0).getImm() > 32 || Inst.getOperand(0).getImm() < 0) 942349cc55cSDimitry Andric return Error(IDLoc, "n must be in range [0,32]"); 9430eae32dcSDimitry Andric break; 9440eae32dcSDimitry Andric case CSKY::ADDC32: 9450eae32dcSDimitry Andric case CSKY::SUBC32: 9460eae32dcSDimitry Andric case CSKY::ADDC16: 9470eae32dcSDimitry Andric case CSKY::SUBC16: 9480eae32dcSDimitry Andric Inst.erase(std::next(Inst.begin())); 9490eae32dcSDimitry Andric Inst.erase(std::prev(Inst.end())); 9500eae32dcSDimitry Andric Inst.insert(std::next(Inst.begin()), MCOperand::createReg(CSKY::C)); 9510eae32dcSDimitry Andric Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C)); 9520eae32dcSDimitry Andric break; 9530eae32dcSDimitry Andric case CSKY::CMPNEI32: 9540eae32dcSDimitry Andric case CSKY::CMPNEI16: 9550eae32dcSDimitry Andric case CSKY::CMPNE32: 9560eae32dcSDimitry Andric case CSKY::CMPNE16: 9570eae32dcSDimitry Andric case CSKY::CMPHSI32: 9580eae32dcSDimitry Andric case CSKY::CMPHSI16: 9590eae32dcSDimitry Andric case CSKY::CMPHS32: 9600eae32dcSDimitry Andric case CSKY::CMPHS16: 9610eae32dcSDimitry Andric case CSKY::CMPLTI32: 9620eae32dcSDimitry Andric case CSKY::CMPLTI16: 9630eae32dcSDimitry Andric case CSKY::CMPLT32: 9640eae32dcSDimitry Andric case CSKY::CMPLT16: 9650eae32dcSDimitry Andric case CSKY::BTSTI32: 9660eae32dcSDimitry Andric Inst.erase(Inst.begin()); 9670eae32dcSDimitry Andric Inst.insert(Inst.begin(), MCOperand::createReg(CSKY::C)); 9680eae32dcSDimitry Andric break; 9690eae32dcSDimitry Andric case CSKY::MVCV32: 9700eae32dcSDimitry Andric Inst.erase(std::next(Inst.begin())); 9710eae32dcSDimitry Andric Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C)); 9720eae32dcSDimitry Andric break; 97381ad6265SDimitry Andric case CSKY::PseudoLRW16: 97481ad6265SDimitry Andric case CSKY::PseudoLRW32: 97581ad6265SDimitry Andric return processLRW(Inst, IDLoc, Out); 97681ad6265SDimitry Andric case CSKY::PseudoJSRI32: 97781ad6265SDimitry Andric return processJSRI(Inst, IDLoc, Out); 97881ad6265SDimitry Andric case CSKY::PseudoJMPI32: 97981ad6265SDimitry Andric return processJMPI(Inst, IDLoc, Out); 98081ad6265SDimitry Andric case CSKY::JBSR32: 98181ad6265SDimitry Andric case CSKY::JBR16: 98281ad6265SDimitry Andric case CSKY::JBT16: 98381ad6265SDimitry Andric case CSKY::JBF16: 98481ad6265SDimitry Andric case CSKY::JBR32: 98581ad6265SDimitry Andric case CSKY::JBT32: 98681ad6265SDimitry Andric case CSKY::JBF32: 98781ad6265SDimitry Andric unsigned Num = Inst.getNumOperands() - 1; 98881ad6265SDimitry Andric assert(Inst.getOperand(Num).isExpr()); 98981ad6265SDimitry Andric 99081ad6265SDimitry Andric const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry( 99181ad6265SDimitry Andric Inst.getOperand(Num).getExpr(), Inst.getLoc()); 99281ad6265SDimitry Andric 99381ad6265SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr)); 99481ad6265SDimitry Andric break; 995349cc55cSDimitry Andric } 996349cc55cSDimitry Andric 9970eae32dcSDimitry Andric emitToStreamer(Out, Inst); 998349cc55cSDimitry Andric return false; 999fe6060f1SDimitry Andric } 1000fe6060f1SDimitry Andric 1001fe6060f1SDimitry Andric // Attempts to match Name as a register (either using the default name or 1002fe6060f1SDimitry Andric // alternative ABI names), setting RegNo to the matching register. Upon 1003fe6060f1SDimitry Andric // failure, returns true and sets RegNo to 0. 1004349cc55cSDimitry Andric static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, 1005349cc55cSDimitry Andric MCRegister &RegNo, StringRef Name) { 1006fe6060f1SDimitry Andric RegNo = MatchRegisterName(Name); 1007fe6060f1SDimitry Andric 1008fe6060f1SDimitry Andric if (RegNo == CSKY::NoRegister) 1009fe6060f1SDimitry Andric RegNo = MatchRegisterAltName(Name); 1010fe6060f1SDimitry Andric 1011fe6060f1SDimitry Andric return RegNo == CSKY::NoRegister; 1012fe6060f1SDimitry Andric } 1013fe6060f1SDimitry Andric 1014bdd1243dSDimitry Andric bool CSKYAsmParser::parseRegister(MCRegister &RegNo, SMLoc &StartLoc, 1015fe6060f1SDimitry Andric SMLoc &EndLoc) { 1016fe6060f1SDimitry Andric const AsmToken &Tok = getParser().getTok(); 1017fe6060f1SDimitry Andric StartLoc = Tok.getLoc(); 1018fe6060f1SDimitry Andric EndLoc = Tok.getEndLoc(); 1019fe6060f1SDimitry Andric StringRef Name = getLexer().getTok().getIdentifier(); 1020fe6060f1SDimitry Andric 1021349cc55cSDimitry Andric if (!matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) { 1022fe6060f1SDimitry Andric getParser().Lex(); // Eat identifier token. 1023fe6060f1SDimitry Andric return false; 1024fe6060f1SDimitry Andric } 1025fe6060f1SDimitry Andric 1026*06c3fb27SDimitry Andric return true; 1027fe6060f1SDimitry Andric } 1028fe6060f1SDimitry Andric 1029*06c3fb27SDimitry Andric ParseStatus CSKYAsmParser::parseRegister(OperandVector &Operands) { 1030fe6060f1SDimitry Andric SMLoc S = getLoc(); 1031fe6060f1SDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1032fe6060f1SDimitry Andric 1033fe6060f1SDimitry Andric switch (getLexer().getKind()) { 1034fe6060f1SDimitry Andric default: 1035*06c3fb27SDimitry Andric return ParseStatus::NoMatch; 1036fe6060f1SDimitry Andric case AsmToken::Identifier: { 1037fe6060f1SDimitry Andric StringRef Name = getLexer().getTok().getIdentifier(); 1038fe6060f1SDimitry Andric MCRegister RegNo; 1039fe6060f1SDimitry Andric 1040349cc55cSDimitry Andric if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) 1041*06c3fb27SDimitry Andric return ParseStatus::NoMatch; 1042fe6060f1SDimitry Andric 1043fe6060f1SDimitry Andric getLexer().Lex(); 1044fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createReg(RegNo, S, E)); 1045fe6060f1SDimitry Andric 1046*06c3fb27SDimitry Andric return ParseStatus::Success; 1047fe6060f1SDimitry Andric } 1048fe6060f1SDimitry Andric } 1049fe6060f1SDimitry Andric } 1050fe6060f1SDimitry Andric 1051*06c3fb27SDimitry Andric ParseStatus CSKYAsmParser::parseBaseRegImm(OperandVector &Operands) { 1052fe6060f1SDimitry Andric assert(getLexer().is(AsmToken::LParen)); 1053fe6060f1SDimitry Andric 1054fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createToken("(", getLoc())); 1055fe6060f1SDimitry Andric 1056fe6060f1SDimitry Andric auto Tok = getParser().Lex(); // Eat '(' 1057fe6060f1SDimitry Andric 1058*06c3fb27SDimitry Andric if (!parseRegister(Operands).isSuccess()) { 1059fe6060f1SDimitry Andric getLexer().UnLex(Tok); 1060fe6060f1SDimitry Andric Operands.pop_back(); 1061*06c3fb27SDimitry Andric return ParseStatus::NoMatch; 1062349cc55cSDimitry Andric } 1063349cc55cSDimitry Andric 1064349cc55cSDimitry Andric if (getLexer().is(AsmToken::RParen)) { 1065349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createToken(")", getLoc())); 1066349cc55cSDimitry Andric getParser().Lex(); // Eat ')' 1067*06c3fb27SDimitry Andric return ParseStatus::Success; 1068fe6060f1SDimitry Andric } 1069fe6060f1SDimitry Andric 1070*06c3fb27SDimitry Andric if (getLexer().isNot(AsmToken::Comma)) 1071*06c3fb27SDimitry Andric return Error(getLoc(), "expected ','"); 1072fe6060f1SDimitry Andric 1073fe6060f1SDimitry Andric getParser().Lex(); // Eat ',' 1074fe6060f1SDimitry Andric 1075*06c3fb27SDimitry Andric if (parseRegister(Operands).isSuccess()) { 1076*06c3fb27SDimitry Andric if (getLexer().isNot(AsmToken::LessLess)) 1077*06c3fb27SDimitry Andric return Error(getLoc(), "expected '<<'"); 1078fe6060f1SDimitry Andric 1079fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createToken("<<", getLoc())); 1080fe6060f1SDimitry Andric 1081fe6060f1SDimitry Andric getParser().Lex(); // Eat '<<' 1082fe6060f1SDimitry Andric 1083*06c3fb27SDimitry Andric if (!parseImmediate(Operands).isSuccess()) 1084*06c3fb27SDimitry Andric return Error(getLoc(), "expected imm"); 1085*06c3fb27SDimitry Andric 1086*06c3fb27SDimitry Andric } else if (!parseImmediate(Operands).isSuccess()) { 1087*06c3fb27SDimitry Andric return Error(getLoc(), "expected imm"); 1088fe6060f1SDimitry Andric } 1089fe6060f1SDimitry Andric 1090*06c3fb27SDimitry Andric if (getLexer().isNot(AsmToken::RParen)) 1091*06c3fb27SDimitry Andric return Error(getLoc(), "expected ')'"); 1092fe6060f1SDimitry Andric 1093fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createToken(")", getLoc())); 1094fe6060f1SDimitry Andric 1095fe6060f1SDimitry Andric getParser().Lex(); // Eat ')' 1096fe6060f1SDimitry Andric 1097*06c3fb27SDimitry Andric return ParseStatus::Success; 1098fe6060f1SDimitry Andric } 1099fe6060f1SDimitry Andric 1100*06c3fb27SDimitry Andric ParseStatus CSKYAsmParser::parseImmediate(OperandVector &Operands) { 1101fe6060f1SDimitry Andric switch (getLexer().getKind()) { 1102fe6060f1SDimitry Andric default: 1103*06c3fb27SDimitry Andric return ParseStatus::NoMatch; 1104fe6060f1SDimitry Andric case AsmToken::LParen: 1105fe6060f1SDimitry Andric case AsmToken::Minus: 1106fe6060f1SDimitry Andric case AsmToken::Plus: 1107fe6060f1SDimitry Andric case AsmToken::Integer: 1108fe6060f1SDimitry Andric case AsmToken::String: 1109fe6060f1SDimitry Andric break; 1110fe6060f1SDimitry Andric } 1111fe6060f1SDimitry Andric 1112fe6060f1SDimitry Andric const MCExpr *IdVal; 1113fe6060f1SDimitry Andric SMLoc S = getLoc(); 1114*06c3fb27SDimitry Andric if (getParser().parseExpression(IdVal)) 1115*06c3fb27SDimitry Andric return Error(getLoc(), "unknown expression"); 1116fe6060f1SDimitry Andric 1117fe6060f1SDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1118fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createImm(IdVal, S, E)); 1119*06c3fb27SDimitry Andric return ParseStatus::Success; 1120fe6060f1SDimitry Andric } 1121fe6060f1SDimitry Andric 1122fe6060f1SDimitry Andric /// Looks at a token type and creates the relevant operand from this 1123fe6060f1SDimitry Andric /// information, adding to Operands. If operand was parsed, returns false, else 1124fe6060f1SDimitry Andric /// true. 1125fe6060f1SDimitry Andric bool CSKYAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 1126fe6060f1SDimitry Andric // Check if the current operand has a custom associated parser, if so, try to 1127fe6060f1SDimitry Andric // custom parse the operand, or fallback to the general approach. 1128*06c3fb27SDimitry Andric ParseStatus Result = 1129fe6060f1SDimitry Andric MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true); 1130*06c3fb27SDimitry Andric if (Result.isSuccess()) 1131fe6060f1SDimitry Andric return false; 1132*06c3fb27SDimitry Andric if (Result.isFailure()) 1133fe6060f1SDimitry Andric return true; 1134fe6060f1SDimitry Andric 1135fe6060f1SDimitry Andric // Attempt to parse token as register 1136349cc55cSDimitry Andric auto Res = parseRegister(Operands); 1137*06c3fb27SDimitry Andric if (Res.isSuccess()) 1138fe6060f1SDimitry Andric return false; 1139*06c3fb27SDimitry Andric if (Res.isFailure()) 1140349cc55cSDimitry Andric return true; 1141fe6060f1SDimitry Andric 1142fe6060f1SDimitry Andric // Attempt to parse token as (register, imm) 1143349cc55cSDimitry Andric if (getLexer().is(AsmToken::LParen)) { 1144349cc55cSDimitry Andric Res = parseBaseRegImm(Operands); 1145*06c3fb27SDimitry Andric if (Res.isSuccess()) 1146fe6060f1SDimitry Andric return false; 1147*06c3fb27SDimitry Andric if (Res.isFailure()) 1148349cc55cSDimitry Andric return true; 1149349cc55cSDimitry Andric } 1150fe6060f1SDimitry Andric 1151349cc55cSDimitry Andric Res = parseImmediate(Operands); 1152*06c3fb27SDimitry Andric if (Res.isSuccess()) 1153fe6060f1SDimitry Andric return false; 1154*06c3fb27SDimitry Andric if (Res.isFailure()) 1155349cc55cSDimitry Andric return true; 1156fe6060f1SDimitry Andric 1157fe6060f1SDimitry Andric // Finally we have exhausted all options and must declare defeat. 1158fe6060f1SDimitry Andric Error(getLoc(), "unknown operand"); 1159fe6060f1SDimitry Andric return true; 1160fe6060f1SDimitry Andric } 1161fe6060f1SDimitry Andric 1162*06c3fb27SDimitry Andric ParseStatus CSKYAsmParser::parseCSKYSymbol(OperandVector &Operands) { 1163fe6060f1SDimitry Andric SMLoc S = getLoc(); 1164fe6060f1SDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1165349cc55cSDimitry Andric const MCExpr *Res; 1166fe6060f1SDimitry Andric 1167fe6060f1SDimitry Andric if (getLexer().getKind() != AsmToken::Identifier) 1168*06c3fb27SDimitry Andric return ParseStatus::NoMatch; 1169fe6060f1SDimitry Andric 1170fe6060f1SDimitry Andric StringRef Identifier; 1171349cc55cSDimitry Andric AsmToken Tok = getLexer().getTok(); 1172349cc55cSDimitry Andric 1173*06c3fb27SDimitry Andric if (getParser().parseIdentifier(Identifier)) 1174*06c3fb27SDimitry Andric return Error(getLoc(), "unknown identifier"); 1175fe6060f1SDimitry Andric 1176fe6060f1SDimitry Andric CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None; 1177fe6060f1SDimitry Andric if (Identifier.consume_back("@GOT")) 1178fe6060f1SDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOT; 1179fe6060f1SDimitry Andric else if (Identifier.consume_back("@GOTOFF")) 1180fe6060f1SDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOTOFF; 1181fe6060f1SDimitry Andric else if (Identifier.consume_back("@PLT")) 1182fe6060f1SDimitry Andric Kind = CSKYMCExpr::VK_CSKY_PLT; 1183fe6060f1SDimitry Andric else if (Identifier.consume_back("@GOTPC")) 1184fe6060f1SDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOTPC; 1185349cc55cSDimitry Andric else if (Identifier.consume_back("@TLSGD32")) 1186349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSGD; 1187349cc55cSDimitry Andric else if (Identifier.consume_back("@GOTTPOFF")) 1188349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSIE; 1189349cc55cSDimitry Andric else if (Identifier.consume_back("@TPOFF")) 1190349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSLE; 1191349cc55cSDimitry Andric else if (Identifier.consume_back("@TLSLDM32")) 1192349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSLDM; 1193349cc55cSDimitry Andric else if (Identifier.consume_back("@TLSLDO32")) 1194349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSLDO; 1195fe6060f1SDimitry Andric 1196349cc55cSDimitry Andric MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier); 1197fe6060f1SDimitry Andric 1198349cc55cSDimitry Andric if (!Sym) 1199349cc55cSDimitry Andric Sym = getContext().getOrCreateSymbol(Identifier); 1200349cc55cSDimitry Andric 1201349cc55cSDimitry Andric if (Sym->isVariable()) { 1202349cc55cSDimitry Andric const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1203349cc55cSDimitry Andric if (!isa<MCSymbolRefExpr>(V)) { 1204349cc55cSDimitry Andric getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1205*06c3fb27SDimitry Andric return Error(getLoc(), "unknown symbol"); 1206349cc55cSDimitry Andric } 1207349cc55cSDimitry Andric Res = V; 1208349cc55cSDimitry Andric } else 1209349cc55cSDimitry Andric Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1210349cc55cSDimitry Andric 1211349cc55cSDimitry Andric MCBinaryExpr::Opcode Opcode; 1212349cc55cSDimitry Andric switch (getLexer().getKind()) { 1213349cc55cSDimitry Andric default: 1214fe6060f1SDimitry Andric if (Kind != CSKYMCExpr::VK_CSKY_None) 1215fe6060f1SDimitry Andric Res = CSKYMCExpr::create(Res, Kind, getContext()); 1216fe6060f1SDimitry Andric 1217fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createImm(Res, S, E)); 1218*06c3fb27SDimitry Andric return ParseStatus::Success; 1219349cc55cSDimitry Andric case AsmToken::Plus: 1220349cc55cSDimitry Andric Opcode = MCBinaryExpr::Add; 1221349cc55cSDimitry Andric break; 1222349cc55cSDimitry Andric case AsmToken::Minus: 1223349cc55cSDimitry Andric Opcode = MCBinaryExpr::Sub; 1224349cc55cSDimitry Andric break; 1225349cc55cSDimitry Andric } 1226349cc55cSDimitry Andric 1227349cc55cSDimitry Andric getLexer().Lex(); // eat + or - 1228349cc55cSDimitry Andric 1229349cc55cSDimitry Andric const MCExpr *Expr; 1230*06c3fb27SDimitry Andric if (getParser().parseExpression(Expr)) 1231*06c3fb27SDimitry Andric return Error(getLoc(), "unknown expression"); 1232349cc55cSDimitry Andric Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1233349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createImm(Res, S, E)); 1234*06c3fb27SDimitry Andric return ParseStatus::Success; 1235349cc55cSDimitry Andric } 1236349cc55cSDimitry Andric 1237*06c3fb27SDimitry Andric ParseStatus CSKYAsmParser::parseDataSymbol(OperandVector &Operands) { 1238349cc55cSDimitry Andric SMLoc S = getLoc(); 1239349cc55cSDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1240349cc55cSDimitry Andric const MCExpr *Res; 1241349cc55cSDimitry Andric 1242*06c3fb27SDimitry Andric if (!parseOptionalToken(AsmToken::LBrac)) 1243*06c3fb27SDimitry Andric return ParseStatus::NoMatch; 1244349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::Identifier) { 1245349cc55cSDimitry Andric const MCExpr *Expr; 1246*06c3fb27SDimitry Andric if (getParser().parseExpression(Expr)) 1247*06c3fb27SDimitry Andric return Error(getLoc(), "unknown expression"); 1248349cc55cSDimitry Andric 1249*06c3fb27SDimitry Andric if (parseToken(AsmToken::RBrac, "expected ']'")) 1250*06c3fb27SDimitry Andric return ParseStatus::Failure; 1251349cc55cSDimitry Andric 1252349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E)); 1253*06c3fb27SDimitry Andric return ParseStatus::Success; 1254349cc55cSDimitry Andric } 1255349cc55cSDimitry Andric 1256349cc55cSDimitry Andric AsmToken Tok = getLexer().getTok(); 1257349cc55cSDimitry Andric StringRef Identifier; 1258349cc55cSDimitry Andric 1259*06c3fb27SDimitry Andric if (getParser().parseIdentifier(Identifier)) 1260*06c3fb27SDimitry Andric return Error(getLoc(), "unknown identifier " + Identifier); 1261349cc55cSDimitry Andric 1262349cc55cSDimitry Andric CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None; 1263349cc55cSDimitry Andric if (Identifier.consume_back("@GOT")) 1264349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOT_IMM18_BY4; 1265349cc55cSDimitry Andric else if (Identifier.consume_back("@PLT")) 1266349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_PLT_IMM18_BY4; 1267349cc55cSDimitry Andric 1268349cc55cSDimitry Andric MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier); 1269349cc55cSDimitry Andric 1270349cc55cSDimitry Andric if (!Sym) 1271349cc55cSDimitry Andric Sym = getContext().getOrCreateSymbol(Identifier); 1272349cc55cSDimitry Andric 1273349cc55cSDimitry Andric if (Sym->isVariable()) { 1274349cc55cSDimitry Andric const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1275349cc55cSDimitry Andric if (!isa<MCSymbolRefExpr>(V)) { 1276349cc55cSDimitry Andric getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1277*06c3fb27SDimitry Andric return Error(getLoc(), "unknown symbol"); 1278349cc55cSDimitry Andric } 1279349cc55cSDimitry Andric Res = V; 1280349cc55cSDimitry Andric } else { 1281349cc55cSDimitry Andric Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1282349cc55cSDimitry Andric } 1283349cc55cSDimitry Andric 1284349cc55cSDimitry Andric MCBinaryExpr::Opcode Opcode; 1285349cc55cSDimitry Andric switch (getLexer().getKind()) { 1286349cc55cSDimitry Andric default: 1287*06c3fb27SDimitry Andric return Error(getLoc(), "unknown symbol"); 1288349cc55cSDimitry Andric case AsmToken::RBrac: 1289349cc55cSDimitry Andric 1290349cc55cSDimitry Andric getLexer().Lex(); // Eat ']'. 1291349cc55cSDimitry Andric 1292349cc55cSDimitry Andric if (Kind != CSKYMCExpr::VK_CSKY_None) 1293349cc55cSDimitry Andric Res = CSKYMCExpr::create(Res, Kind, getContext()); 1294349cc55cSDimitry Andric 1295349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1296*06c3fb27SDimitry Andric return ParseStatus::Success; 1297349cc55cSDimitry Andric case AsmToken::Plus: 1298349cc55cSDimitry Andric Opcode = MCBinaryExpr::Add; 1299349cc55cSDimitry Andric break; 1300349cc55cSDimitry Andric case AsmToken::Minus: 1301349cc55cSDimitry Andric Opcode = MCBinaryExpr::Sub; 1302349cc55cSDimitry Andric break; 1303349cc55cSDimitry Andric } 1304349cc55cSDimitry Andric 1305349cc55cSDimitry Andric getLexer().Lex(); // eat + or - 1306349cc55cSDimitry Andric 1307349cc55cSDimitry Andric const MCExpr *Expr; 1308*06c3fb27SDimitry Andric if (getParser().parseExpression(Expr)) 1309*06c3fb27SDimitry Andric return Error(getLoc(), "unknown expression"); 1310*06c3fb27SDimitry Andric if (parseToken(AsmToken::RBrac, "expected ']'")) 1311*06c3fb27SDimitry Andric return ParseStatus::Failure; 1312349cc55cSDimitry Andric 1313349cc55cSDimitry Andric Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1314349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1315*06c3fb27SDimitry Andric return ParseStatus::Success; 1316fe6060f1SDimitry Andric } 1317fe6060f1SDimitry Andric 1318*06c3fb27SDimitry Andric ParseStatus CSKYAsmParser::parseConstpoolSymbol(OperandVector &Operands) { 1319fe6060f1SDimitry Andric SMLoc S = getLoc(); 1320fe6060f1SDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1321349cc55cSDimitry Andric const MCExpr *Res; 1322fe6060f1SDimitry Andric 1323*06c3fb27SDimitry Andric if (!parseOptionalToken(AsmToken::LBrac)) 1324*06c3fb27SDimitry Andric return ParseStatus::NoMatch; 1325fe6060f1SDimitry Andric 1326349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::Identifier) { 1327349cc55cSDimitry Andric const MCExpr *Expr; 1328*06c3fb27SDimitry Andric if (getParser().parseExpression(Expr)) 1329*06c3fb27SDimitry Andric return Error(getLoc(), "unknown expression"); 1330*06c3fb27SDimitry Andric if (parseToken(AsmToken::RBrac)) 1331*06c3fb27SDimitry Andric return ParseStatus::Failure; 1332fe6060f1SDimitry Andric 1333349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E)); 1334*06c3fb27SDimitry Andric return ParseStatus::Success; 1335349cc55cSDimitry Andric } 1336349cc55cSDimitry Andric 1337349cc55cSDimitry Andric AsmToken Tok = getLexer().getTok(); 1338349cc55cSDimitry Andric StringRef Identifier; 1339349cc55cSDimitry Andric 1340*06c3fb27SDimitry Andric if (getParser().parseIdentifier(Identifier)) 1341*06c3fb27SDimitry Andric return Error(getLoc(), "unknown identifier"); 1342349cc55cSDimitry Andric 1343349cc55cSDimitry Andric MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier); 1344349cc55cSDimitry Andric 1345349cc55cSDimitry Andric if (!Sym) 1346349cc55cSDimitry Andric Sym = getContext().getOrCreateSymbol(Identifier); 1347349cc55cSDimitry Andric 1348349cc55cSDimitry Andric if (Sym->isVariable()) { 1349349cc55cSDimitry Andric const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1350349cc55cSDimitry Andric if (!isa<MCSymbolRefExpr>(V)) { 1351349cc55cSDimitry Andric getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1352*06c3fb27SDimitry Andric return Error(getLoc(), "unknown symbol"); 1353349cc55cSDimitry Andric } 1354349cc55cSDimitry Andric Res = V; 1355349cc55cSDimitry Andric } else { 1356349cc55cSDimitry Andric Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1357349cc55cSDimitry Andric } 1358349cc55cSDimitry Andric 1359349cc55cSDimitry Andric MCBinaryExpr::Opcode Opcode; 1360349cc55cSDimitry Andric switch (getLexer().getKind()) { 1361349cc55cSDimitry Andric default: 1362*06c3fb27SDimitry Andric return Error(getLoc(), "unknown symbol"); 1363349cc55cSDimitry Andric case AsmToken::RBrac: 1364349cc55cSDimitry Andric 1365349cc55cSDimitry Andric getLexer().Lex(); // Eat ']'. 1366349cc55cSDimitry Andric 1367349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1368*06c3fb27SDimitry Andric return ParseStatus::Success; 1369349cc55cSDimitry Andric case AsmToken::Plus: 1370349cc55cSDimitry Andric Opcode = MCBinaryExpr::Add; 1371349cc55cSDimitry Andric break; 1372349cc55cSDimitry Andric case AsmToken::Minus: 1373349cc55cSDimitry Andric Opcode = MCBinaryExpr::Sub; 1374349cc55cSDimitry Andric break; 1375349cc55cSDimitry Andric } 1376349cc55cSDimitry Andric 1377349cc55cSDimitry Andric getLexer().Lex(); // eat + or - 1378349cc55cSDimitry Andric 1379349cc55cSDimitry Andric const MCExpr *Expr; 1380*06c3fb27SDimitry Andric if (getParser().parseExpression(Expr)) 1381*06c3fb27SDimitry Andric return Error(getLoc(), "unknown expression"); 1382*06c3fb27SDimitry Andric if (parseToken(AsmToken::RBrac, "expected ']'")) 1383*06c3fb27SDimitry Andric return ParseStatus::Failure; 1384349cc55cSDimitry Andric 1385349cc55cSDimitry Andric Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1386349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1387*06c3fb27SDimitry Andric return ParseStatus::Success; 1388349cc55cSDimitry Andric } 1389349cc55cSDimitry Andric 1390*06c3fb27SDimitry Andric ParseStatus CSKYAsmParser::parsePSRFlag(OperandVector &Operands) { 1391349cc55cSDimitry Andric SMLoc S = getLoc(); 1392349cc55cSDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1393349cc55cSDimitry Andric 1394349cc55cSDimitry Andric unsigned Flag = 0; 1395349cc55cSDimitry Andric 1396349cc55cSDimitry Andric while (getLexer().isNot(AsmToken::EndOfStatement)) { 1397349cc55cSDimitry Andric StringRef Identifier; 1398*06c3fb27SDimitry Andric if (getParser().parseIdentifier(Identifier)) 1399*06c3fb27SDimitry Andric return Error(getLoc(), "unknown identifier " + Identifier); 1400349cc55cSDimitry Andric 1401349cc55cSDimitry Andric if (Identifier == "sie") 1402349cc55cSDimitry Andric Flag = (1 << 4) | Flag; 1403349cc55cSDimitry Andric else if (Identifier == "ee") 1404349cc55cSDimitry Andric Flag = (1 << 3) | Flag; 1405349cc55cSDimitry Andric else if (Identifier == "ie") 1406349cc55cSDimitry Andric Flag = (1 << 2) | Flag; 1407349cc55cSDimitry Andric else if (Identifier == "fe") 1408349cc55cSDimitry Andric Flag = (1 << 1) | Flag; 1409349cc55cSDimitry Andric else if (Identifier == "af") 1410349cc55cSDimitry Andric Flag = (1 << 0) | Flag; 1411*06c3fb27SDimitry Andric else 1412*06c3fb27SDimitry Andric return Error(getLoc(), "expected " + Identifier); 1413349cc55cSDimitry Andric 1414349cc55cSDimitry Andric if (getLexer().is(AsmToken::EndOfStatement)) 1415349cc55cSDimitry Andric break; 1416349cc55cSDimitry Andric 1417*06c3fb27SDimitry Andric if (parseToken(AsmToken::Comma, "expected ','")) 1418*06c3fb27SDimitry Andric return ParseStatus::Failure; 1419349cc55cSDimitry Andric } 1420349cc55cSDimitry Andric 1421349cc55cSDimitry Andric Operands.push_back( 1422349cc55cSDimitry Andric CSKYOperand::createImm(MCConstantExpr::create(Flag, getContext()), S, E)); 1423*06c3fb27SDimitry Andric return ParseStatus::Success; 1424349cc55cSDimitry Andric } 1425349cc55cSDimitry Andric 1426*06c3fb27SDimitry Andric ParseStatus CSKYAsmParser::parseRegSeq(OperandVector &Operands) { 1427349cc55cSDimitry Andric SMLoc S = getLoc(); 1428349cc55cSDimitry Andric 1429*06c3fb27SDimitry Andric if (!parseRegister(Operands).isSuccess()) 1430*06c3fb27SDimitry Andric return ParseStatus::NoMatch; 1431349cc55cSDimitry Andric 1432349cc55cSDimitry Andric auto Ry = Operands.back()->getReg(); 1433349cc55cSDimitry Andric Operands.pop_back(); 1434349cc55cSDimitry Andric 1435*06c3fb27SDimitry Andric if (parseToken(AsmToken::Minus, "expected '-'")) 1436*06c3fb27SDimitry Andric return ParseStatus::Failure; 1437*06c3fb27SDimitry Andric if (!parseRegister(Operands).isSuccess()) 1438*06c3fb27SDimitry Andric return Error(getLoc(), "invalid register"); 1439349cc55cSDimitry Andric 1440349cc55cSDimitry Andric auto Rz = Operands.back()->getReg(); 1441349cc55cSDimitry Andric Operands.pop_back(); 1442349cc55cSDimitry Andric 1443349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createRegSeq(Ry, Rz, S)); 1444*06c3fb27SDimitry Andric return ParseStatus::Success; 1445349cc55cSDimitry Andric } 1446349cc55cSDimitry Andric 1447*06c3fb27SDimitry Andric ParseStatus CSKYAsmParser::parseRegList(OperandVector &Operands) { 1448349cc55cSDimitry Andric SMLoc S = getLoc(); 1449349cc55cSDimitry Andric 1450349cc55cSDimitry Andric SmallVector<unsigned, 4> reglist; 1451349cc55cSDimitry Andric 1452349cc55cSDimitry Andric while (true) { 1453349cc55cSDimitry Andric 1454*06c3fb27SDimitry Andric if (!parseRegister(Operands).isSuccess()) 1455*06c3fb27SDimitry Andric return Error(getLoc(), "invalid register"); 1456349cc55cSDimitry Andric 1457349cc55cSDimitry Andric auto Ry = Operands.back()->getReg(); 1458349cc55cSDimitry Andric Operands.pop_back(); 1459349cc55cSDimitry Andric 1460*06c3fb27SDimitry Andric if (parseOptionalToken(AsmToken::Minus)) { 1461*06c3fb27SDimitry Andric if (!parseRegister(Operands).isSuccess()) 1462*06c3fb27SDimitry Andric return Error(getLoc(), "invalid register"); 1463349cc55cSDimitry Andric 1464349cc55cSDimitry Andric auto Rz = Operands.back()->getReg(); 1465349cc55cSDimitry Andric Operands.pop_back(); 1466349cc55cSDimitry Andric 1467349cc55cSDimitry Andric reglist.push_back(Ry); 1468349cc55cSDimitry Andric reglist.push_back(Rz); 1469349cc55cSDimitry Andric 1470*06c3fb27SDimitry Andric if (getLexer().is(AsmToken::EndOfStatement)) 1471349cc55cSDimitry Andric break; 1472*06c3fb27SDimitry Andric (void)parseOptionalToken(AsmToken::Comma); 1473*06c3fb27SDimitry Andric } else if (parseOptionalToken(AsmToken::Comma)) { 1474349cc55cSDimitry Andric reglist.push_back(Ry); 1475349cc55cSDimitry Andric reglist.push_back(Ry); 1476349cc55cSDimitry Andric } else if (getLexer().is(AsmToken::EndOfStatement)) { 1477349cc55cSDimitry Andric reglist.push_back(Ry); 1478349cc55cSDimitry Andric reglist.push_back(Ry); 1479349cc55cSDimitry Andric break; 1480349cc55cSDimitry Andric } else { 1481*06c3fb27SDimitry Andric return Error(getLoc(), "invalid register list"); 1482349cc55cSDimitry Andric } 1483349cc55cSDimitry Andric } 1484349cc55cSDimitry Andric 1485349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createRegList(reglist, S)); 1486*06c3fb27SDimitry Andric return ParseStatus::Success; 1487fe6060f1SDimitry Andric } 1488fe6060f1SDimitry Andric 1489fe6060f1SDimitry Andric bool CSKYAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 1490fe6060f1SDimitry Andric SMLoc NameLoc, OperandVector &Operands) { 1491fe6060f1SDimitry Andric // First operand is token for instruction. 1492fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createToken(Name, NameLoc)); 1493fe6060f1SDimitry Andric 1494fe6060f1SDimitry Andric // If there are no more operands, then finish. 1495fe6060f1SDimitry Andric if (getLexer().is(AsmToken::EndOfStatement)) 1496fe6060f1SDimitry Andric return false; 1497fe6060f1SDimitry Andric 1498fe6060f1SDimitry Andric // Parse first operand. 1499fe6060f1SDimitry Andric if (parseOperand(Operands, Name)) 1500fe6060f1SDimitry Andric return true; 1501fe6060f1SDimitry Andric 1502fe6060f1SDimitry Andric // Parse until end of statement, consuming commas between operands. 1503*06c3fb27SDimitry Andric while (parseOptionalToken(AsmToken::Comma)) 1504fe6060f1SDimitry Andric if (parseOperand(Operands, Name)) 1505fe6060f1SDimitry Andric return true; 1506fe6060f1SDimitry Andric 1507fe6060f1SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) { 1508fe6060f1SDimitry Andric SMLoc Loc = getLexer().getLoc(); 1509fe6060f1SDimitry Andric getParser().eatToEndOfStatement(); 1510fe6060f1SDimitry Andric return Error(Loc, "unexpected token"); 1511fe6060f1SDimitry Andric } 1512fe6060f1SDimitry Andric 1513fe6060f1SDimitry Andric getParser().Lex(); // Consume the EndOfStatement. 1514fe6060f1SDimitry Andric return false; 1515fe6060f1SDimitry Andric } 1516fe6060f1SDimitry Andric 1517bdd1243dSDimitry Andric OperandMatchResultTy CSKYAsmParser::tryParseRegister(MCRegister &RegNo, 1518fe6060f1SDimitry Andric SMLoc &StartLoc, 1519fe6060f1SDimitry Andric SMLoc &EndLoc) { 1520fe6060f1SDimitry Andric const AsmToken &Tok = getParser().getTok(); 1521fe6060f1SDimitry Andric StartLoc = Tok.getLoc(); 1522fe6060f1SDimitry Andric EndLoc = Tok.getEndLoc(); 1523fe6060f1SDimitry Andric 1524fe6060f1SDimitry Andric StringRef Name = getLexer().getTok().getIdentifier(); 1525fe6060f1SDimitry Andric 1526349cc55cSDimitry Andric if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) 1527fe6060f1SDimitry Andric return MatchOperand_NoMatch; 1528fe6060f1SDimitry Andric 1529fe6060f1SDimitry Andric getParser().Lex(); // Eat identifier token. 1530fe6060f1SDimitry Andric return MatchOperand_Success; 1531fe6060f1SDimitry Andric } 1532fe6060f1SDimitry Andric 1533*06c3fb27SDimitry Andric ParseStatus CSKYAsmParser::parseDirective(AsmToken DirectiveID) { 153481ad6265SDimitry Andric StringRef IDVal = DirectiveID.getString(); 153581ad6265SDimitry Andric 153681ad6265SDimitry Andric if (IDVal == ".csky_attribute") 153781ad6265SDimitry Andric return parseDirectiveAttribute(); 153881ad6265SDimitry Andric 1539*06c3fb27SDimitry Andric return ParseStatus::NoMatch; 154081ad6265SDimitry Andric } 154181ad6265SDimitry Andric 154281ad6265SDimitry Andric /// parseDirectiveAttribute 154381ad6265SDimitry Andric /// ::= .attribute expression ',' ( expression | "string" ) 154481ad6265SDimitry Andric bool CSKYAsmParser::parseDirectiveAttribute() { 154581ad6265SDimitry Andric MCAsmParser &Parser = getParser(); 154681ad6265SDimitry Andric int64_t Tag; 154781ad6265SDimitry Andric SMLoc TagLoc; 154881ad6265SDimitry Andric TagLoc = Parser.getTok().getLoc(); 154981ad6265SDimitry Andric if (Parser.getTok().is(AsmToken::Identifier)) { 155081ad6265SDimitry Andric StringRef Name = Parser.getTok().getIdentifier(); 1551bdd1243dSDimitry Andric std::optional<unsigned> Ret = 155281ad6265SDimitry Andric ELFAttrs::attrTypeFromString(Name, CSKYAttrs::getCSKYAttributeTags()); 1553*06c3fb27SDimitry Andric if (!Ret) 1554*06c3fb27SDimitry Andric return Error(TagLoc, "attribute name not recognised: " + Name); 1555bdd1243dSDimitry Andric Tag = *Ret; 155681ad6265SDimitry Andric Parser.Lex(); 155781ad6265SDimitry Andric } else { 155881ad6265SDimitry Andric const MCExpr *AttrExpr; 155981ad6265SDimitry Andric 156081ad6265SDimitry Andric TagLoc = Parser.getTok().getLoc(); 156181ad6265SDimitry Andric if (Parser.parseExpression(AttrExpr)) 156281ad6265SDimitry Andric return true; 156381ad6265SDimitry Andric 156481ad6265SDimitry Andric const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr); 1565*06c3fb27SDimitry Andric if (!CE) 1566*06c3fb27SDimitry Andric return Error(TagLoc, "expected numeric constant"); 156781ad6265SDimitry Andric 156881ad6265SDimitry Andric Tag = CE->getValue(); 156981ad6265SDimitry Andric } 157081ad6265SDimitry Andric 1571*06c3fb27SDimitry Andric if (Parser.parseComma()) 157281ad6265SDimitry Andric return true; 157381ad6265SDimitry Andric 157481ad6265SDimitry Andric StringRef StringValue; 157581ad6265SDimitry Andric int64_t IntegerValue = 0; 157681ad6265SDimitry Andric bool IsIntegerValue = ((Tag != CSKYAttrs::CSKY_ARCH_NAME) && 157781ad6265SDimitry Andric (Tag != CSKYAttrs::CSKY_CPU_NAME) && 157881ad6265SDimitry Andric (Tag != CSKYAttrs::CSKY_FPU_NUMBER_MODULE)); 157981ad6265SDimitry Andric 158081ad6265SDimitry Andric SMLoc ValueExprLoc = Parser.getTok().getLoc(); 158181ad6265SDimitry Andric if (IsIntegerValue) { 158281ad6265SDimitry Andric const MCExpr *ValueExpr; 158381ad6265SDimitry Andric if (Parser.parseExpression(ValueExpr)) 158481ad6265SDimitry Andric return true; 158581ad6265SDimitry Andric 158681ad6265SDimitry Andric const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr); 158781ad6265SDimitry Andric if (!CE) 158881ad6265SDimitry Andric return Error(ValueExprLoc, "expected numeric constant"); 158981ad6265SDimitry Andric IntegerValue = CE->getValue(); 159081ad6265SDimitry Andric } else { 159181ad6265SDimitry Andric if (Parser.getTok().isNot(AsmToken::String)) 159281ad6265SDimitry Andric return Error(Parser.getTok().getLoc(), "expected string constant"); 159381ad6265SDimitry Andric 159481ad6265SDimitry Andric StringValue = Parser.getTok().getStringContents(); 159581ad6265SDimitry Andric Parser.Lex(); 159681ad6265SDimitry Andric } 159781ad6265SDimitry Andric 159881ad6265SDimitry Andric if (Parser.parseEOL()) 159981ad6265SDimitry Andric return true; 160081ad6265SDimitry Andric 160181ad6265SDimitry Andric if (IsIntegerValue) 160281ad6265SDimitry Andric getTargetStreamer().emitAttribute(Tag, IntegerValue); 160381ad6265SDimitry Andric else if (Tag != CSKYAttrs::CSKY_ARCH_NAME && Tag != CSKYAttrs::CSKY_CPU_NAME) 160481ad6265SDimitry Andric getTargetStreamer().emitTextAttribute(Tag, StringValue); 160581ad6265SDimitry Andric else { 160681ad6265SDimitry Andric CSKY::ArchKind ID = (Tag == CSKYAttrs::CSKY_ARCH_NAME) 160781ad6265SDimitry Andric ? CSKY::parseArch(StringValue) 160881ad6265SDimitry Andric : CSKY::parseCPUArch(StringValue); 160981ad6265SDimitry Andric if (ID == CSKY::ArchKind::INVALID) 161081ad6265SDimitry Andric return Error(ValueExprLoc, (Tag == CSKYAttrs::CSKY_ARCH_NAME) 161181ad6265SDimitry Andric ? "unknown arch name" 161281ad6265SDimitry Andric : "unknown cpu name"); 161381ad6265SDimitry Andric 161481ad6265SDimitry Andric getTargetStreamer().emitTextAttribute(Tag, StringValue); 161581ad6265SDimitry Andric } 161681ad6265SDimitry Andric 161781ad6265SDimitry Andric return false; 161881ad6265SDimitry Andric } 161981ad6265SDimitry Andric 162081ad6265SDimitry Andric unsigned CSKYAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, 162181ad6265SDimitry Andric unsigned Kind) { 162281ad6265SDimitry Andric CSKYOperand &Op = static_cast<CSKYOperand &>(AsmOp); 162381ad6265SDimitry Andric 162481ad6265SDimitry Andric if (!Op.isReg()) 162581ad6265SDimitry Andric return Match_InvalidOperand; 162681ad6265SDimitry Andric 162781ad6265SDimitry Andric MCRegister Reg = Op.getReg(); 162881ad6265SDimitry Andric 162981ad6265SDimitry Andric if (CSKYMCRegisterClasses[CSKY::FPR32RegClassID].contains(Reg)) { 163081ad6265SDimitry Andric // As the parser couldn't differentiate an FPR64 from an FPR32, coerce the 163181ad6265SDimitry Andric // register from FPR32 to FPR64 if necessary. 163281ad6265SDimitry Andric if (Kind == MCK_FPR64 || Kind == MCK_sFPR64) { 163381ad6265SDimitry Andric Op.Reg.RegNum = convertFPR32ToFPR64(Reg); 163481ad6265SDimitry Andric if (Kind == MCK_sFPR64 && 163581ad6265SDimitry Andric (Op.Reg.RegNum < CSKY::F0_64 || Op.Reg.RegNum > CSKY::F15_64)) 163681ad6265SDimitry Andric return Match_InvalidRegOutOfRange; 163781ad6265SDimitry Andric if (Kind == MCK_FPR64 && 163881ad6265SDimitry Andric (Op.Reg.RegNum < CSKY::F0_64 || Op.Reg.RegNum > CSKY::F31_64)) 163981ad6265SDimitry Andric return Match_InvalidRegOutOfRange; 164081ad6265SDimitry Andric return Match_Success; 164181ad6265SDimitry Andric } 164281ad6265SDimitry Andric } 164381ad6265SDimitry Andric 164481ad6265SDimitry Andric if (CSKYMCRegisterClasses[CSKY::GPRRegClassID].contains(Reg)) { 164581ad6265SDimitry Andric if (Kind == MCK_GPRPair) { 164681ad6265SDimitry Andric Op.Reg.RegNum = MRI->getEncodingValue(Reg) + CSKY::R0_R1; 164781ad6265SDimitry Andric return Match_Success; 164881ad6265SDimitry Andric } 164981ad6265SDimitry Andric } 165081ad6265SDimitry Andric 165181ad6265SDimitry Andric return Match_InvalidOperand; 165281ad6265SDimitry Andric } 1653fe6060f1SDimitry Andric 16540eae32dcSDimitry Andric void CSKYAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) { 16550eae32dcSDimitry Andric MCInst CInst; 16560eae32dcSDimitry Andric bool Res = false; 16570eae32dcSDimitry Andric if (EnableCompressedInst) 1658bdd1243dSDimitry Andric Res = compressInst(CInst, Inst, getSTI()); 16590eae32dcSDimitry Andric if (Res) 16600eae32dcSDimitry Andric ++CSKYNumInstrsCompressed; 16610eae32dcSDimitry Andric S.emitInstruction((Res ? CInst : Inst), getSTI()); 16620eae32dcSDimitry Andric } 16630eae32dcSDimitry Andric 1664fe6060f1SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYAsmParser() { 1665fe6060f1SDimitry Andric RegisterMCAsmParser<CSKYAsmParser> X(getTheCSKYTarget()); 1666fe6060f1SDimitry Andric } 1667