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" 16fe6060f1SDimitry Andric #include "llvm/ADT/StringSwitch.h" 1781ad6265SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 18fe6060f1SDimitry Andric #include "llvm/CodeGen/Register.h" 19fe6060f1SDimitry Andric #include "llvm/MC/MCContext.h" 20fe6060f1SDimitry Andric #include "llvm/MC/MCExpr.h" 21fe6060f1SDimitry Andric #include "llvm/MC/MCInst.h" 2281ad6265SDimitry Andric #include "llvm/MC/MCInstrInfo.h" 23fe6060f1SDimitry Andric #include "llvm/MC/MCParser/MCAsmLexer.h" 24fe6060f1SDimitry Andric #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 25fe6060f1SDimitry Andric #include "llvm/MC/MCParser/MCTargetAsmParser.h" 26fe6060f1SDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 27349cc55cSDimitry Andric #include "llvm/MC/MCSectionELF.h" 28fe6060f1SDimitry Andric #include "llvm/MC/MCStreamer.h" 29fe6060f1SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 30349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h" 3181ad6265SDimitry Andric #include "llvm/Support/CSKYAttributes.h" 3281ad6265SDimitry Andric #include "llvm/Support/CSKYTargetParser.h" 33fe6060f1SDimitry Andric #include "llvm/Support/Casting.h" 340eae32dcSDimitry Andric #include "llvm/Support/CommandLine.h" 35349cc55cSDimitry Andric #include "llvm/Support/Debug.h" 36349cc55cSDimitry Andric 370eae32dcSDimitry Andric using namespace llvm; 380eae32dcSDimitry Andric 39349cc55cSDimitry Andric #define DEBUG_TYPE "csky-asm-parser" 40fe6060f1SDimitry Andric 410eae32dcSDimitry Andric // Include the auto-generated portion of the compress emitter. 420eae32dcSDimitry Andric #define GEN_COMPRESS_INSTR 430eae32dcSDimitry Andric #include "CSKYGenCompressInstEmitter.inc" 440eae32dcSDimitry Andric 450eae32dcSDimitry Andric STATISTIC(CSKYNumInstrsCompressed, 460eae32dcSDimitry Andric "Number of C-SKY Compressed instructions emitted"); 470eae32dcSDimitry Andric 480eae32dcSDimitry Andric static cl::opt<bool> 490eae32dcSDimitry Andric EnableCompressedInst("enable-csky-asm-compressed-inst", cl::Hidden, 500eae32dcSDimitry Andric cl::init(false), 510eae32dcSDimitry Andric cl::desc("Enable C-SKY asm compressed instruction")); 52fe6060f1SDimitry Andric 53fe6060f1SDimitry Andric namespace { 54fe6060f1SDimitry Andric struct CSKYOperand; 55fe6060f1SDimitry Andric 56fe6060f1SDimitry Andric class CSKYAsmParser : public MCTargetAsmParser { 57fe6060f1SDimitry Andric 58349cc55cSDimitry Andric const MCRegisterInfo *MRI; 59349cc55cSDimitry Andric 6081ad6265SDimitry Andric unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 6181ad6265SDimitry Andric unsigned Kind) override; 6281ad6265SDimitry Andric 63fe6060f1SDimitry Andric bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo, 64fe6060f1SDimitry Andric int64_t Lower, int64_t Upper, Twine Msg); 65fe6060f1SDimitry Andric 66fe6060f1SDimitry Andric SMLoc getLoc() const { return getParser().getTok().getLoc(); } 67fe6060f1SDimitry Andric 68fe6060f1SDimitry Andric bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 69fe6060f1SDimitry Andric OperandVector &Operands, MCStreamer &Out, 70fe6060f1SDimitry Andric uint64_t &ErrorInfo, 71fe6060f1SDimitry Andric bool MatchingInlineAsm) override; 72fe6060f1SDimitry Andric 73*bdd1243dSDimitry Andric bool parseRegister(MCRegister &RegNo, SMLoc &StartLoc, 74*bdd1243dSDimitry Andric SMLoc &EndLoc) override; 75fe6060f1SDimitry Andric 76fe6060f1SDimitry Andric bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 77fe6060f1SDimitry Andric SMLoc NameLoc, OperandVector &Operands) override; 78fe6060f1SDimitry Andric 79fe6060f1SDimitry Andric bool ParseDirective(AsmToken DirectiveID) override; 80fe6060f1SDimitry Andric 810eae32dcSDimitry Andric // Helper to actually emit an instruction to the MCStreamer. Also, when 820eae32dcSDimitry Andric // possible, compression of the instruction is performed. 830eae32dcSDimitry Andric void emitToStreamer(MCStreamer &S, const MCInst &Inst); 840eae32dcSDimitry Andric 85*bdd1243dSDimitry Andric OperandMatchResultTy tryParseRegister(MCRegister &RegNo, SMLoc &StartLoc, 86fe6060f1SDimitry Andric SMLoc &EndLoc) override; 87fe6060f1SDimitry Andric 88349cc55cSDimitry Andric bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands, 89349cc55cSDimitry Andric MCStreamer &Out); 9081ad6265SDimitry Andric bool processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 9181ad6265SDimitry Andric bool processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 9281ad6265SDimitry Andric bool processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 9381ad6265SDimitry Andric 9481ad6265SDimitry Andric CSKYTargetStreamer &getTargetStreamer() { 9581ad6265SDimitry Andric assert(getParser().getStreamer().getTargetStreamer() && 9681ad6265SDimitry Andric "do not have a target streamer"); 9781ad6265SDimitry Andric MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); 9881ad6265SDimitry Andric return static_cast<CSKYTargetStreamer &>(TS); 9981ad6265SDimitry Andric } 100349cc55cSDimitry Andric 101fe6060f1SDimitry Andric // Auto-generated instruction matching functions 102fe6060f1SDimitry Andric #define GET_ASSEMBLER_HEADER 103fe6060f1SDimitry Andric #include "CSKYGenAsmMatcher.inc" 104fe6060f1SDimitry Andric 105fe6060f1SDimitry Andric OperandMatchResultTy parseImmediate(OperandVector &Operands); 106fe6060f1SDimitry Andric OperandMatchResultTy parseRegister(OperandVector &Operands); 107fe6060f1SDimitry Andric OperandMatchResultTy parseBaseRegImm(OperandVector &Operands); 108fe6060f1SDimitry Andric OperandMatchResultTy parseCSKYSymbol(OperandVector &Operands); 109fe6060f1SDimitry Andric OperandMatchResultTy parseConstpoolSymbol(OperandVector &Operands); 110349cc55cSDimitry Andric OperandMatchResultTy parseDataSymbol(OperandVector &Operands); 111349cc55cSDimitry Andric OperandMatchResultTy parsePSRFlag(OperandVector &Operands); 112349cc55cSDimitry Andric OperandMatchResultTy parseRegSeq(OperandVector &Operands); 113349cc55cSDimitry Andric OperandMatchResultTy parseRegList(OperandVector &Operands); 114fe6060f1SDimitry Andric 115fe6060f1SDimitry Andric bool parseOperand(OperandVector &Operands, StringRef Mnemonic); 116fe6060f1SDimitry Andric 11781ad6265SDimitry Andric bool parseDirectiveAttribute(); 11881ad6265SDimitry Andric 119fe6060f1SDimitry Andric public: 120fe6060f1SDimitry Andric enum CSKYMatchResultTy { 121fe6060f1SDimitry Andric Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY, 122349cc55cSDimitry Andric Match_RequiresSameSrcAndDst, 123349cc55cSDimitry Andric Match_InvalidRegOutOfRange, 124fe6060f1SDimitry Andric #define GET_OPERAND_DIAGNOSTIC_TYPES 125fe6060f1SDimitry Andric #include "CSKYGenAsmMatcher.inc" 126fe6060f1SDimitry Andric #undef GET_OPERAND_DIAGNOSTIC_TYPES 127fe6060f1SDimitry Andric }; 128fe6060f1SDimitry Andric 129fe6060f1SDimitry Andric CSKYAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, 130fe6060f1SDimitry Andric const MCInstrInfo &MII, const MCTargetOptions &Options) 131fe6060f1SDimitry Andric : MCTargetAsmParser(Options, STI, MII) { 13281ad6265SDimitry Andric 13381ad6265SDimitry Andric MCAsmParserExtension::Initialize(Parser); 13481ad6265SDimitry Andric 13581ad6265SDimitry Andric // Cache the MCRegisterInfo. 13681ad6265SDimitry Andric MRI = getContext().getRegisterInfo(); 13781ad6265SDimitry Andric 138fe6060f1SDimitry Andric setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 13981ad6265SDimitry Andric getTargetStreamer().emitTargetAttributes(STI); 140fe6060f1SDimitry Andric } 141fe6060f1SDimitry Andric }; 142fe6060f1SDimitry Andric 143fe6060f1SDimitry Andric /// Instances of this class represent a parsed machine instruction. 144fe6060f1SDimitry Andric struct CSKYOperand : public MCParsedAsmOperand { 145349cc55cSDimitry Andric 146fe6060f1SDimitry Andric enum KindTy { 147fe6060f1SDimitry Andric Token, 148fe6060f1SDimitry Andric Register, 149fe6060f1SDimitry Andric Immediate, 150349cc55cSDimitry Andric RegisterSeq, 151349cc55cSDimitry Andric CPOP, 152349cc55cSDimitry Andric RegisterList 153fe6060f1SDimitry Andric } Kind; 154fe6060f1SDimitry Andric 155fe6060f1SDimitry Andric struct RegOp { 156fe6060f1SDimitry Andric unsigned RegNum; 157fe6060f1SDimitry Andric }; 158fe6060f1SDimitry Andric 159fe6060f1SDimitry Andric struct ImmOp { 160fe6060f1SDimitry Andric const MCExpr *Val; 161fe6060f1SDimitry Andric }; 162fe6060f1SDimitry Andric 163349cc55cSDimitry Andric struct ConstpoolOp { 164349cc55cSDimitry Andric const MCExpr *Val; 165349cc55cSDimitry Andric }; 166349cc55cSDimitry Andric 167349cc55cSDimitry Andric struct RegSeqOp { 168349cc55cSDimitry Andric unsigned RegNumFrom; 169349cc55cSDimitry Andric unsigned RegNumTo; 170349cc55cSDimitry Andric }; 171349cc55cSDimitry Andric 172349cc55cSDimitry Andric struct RegListOp { 173349cc55cSDimitry Andric unsigned List1From = 0; 174349cc55cSDimitry Andric unsigned List1To = 0; 175349cc55cSDimitry Andric unsigned List2From = 0; 176349cc55cSDimitry Andric unsigned List2To = 0; 177349cc55cSDimitry Andric unsigned List3From = 0; 178349cc55cSDimitry Andric unsigned List3To = 0; 179349cc55cSDimitry Andric unsigned List4From = 0; 180349cc55cSDimitry Andric unsigned List4To = 0; 181349cc55cSDimitry Andric }; 182349cc55cSDimitry Andric 183fe6060f1SDimitry Andric SMLoc StartLoc, EndLoc; 184fe6060f1SDimitry Andric union { 185fe6060f1SDimitry Andric StringRef Tok; 186fe6060f1SDimitry Andric RegOp Reg; 187fe6060f1SDimitry Andric ImmOp Imm; 188349cc55cSDimitry Andric ConstpoolOp CPool; 189349cc55cSDimitry Andric RegSeqOp RegSeq; 190349cc55cSDimitry Andric RegListOp RegList; 191fe6060f1SDimitry Andric }; 192fe6060f1SDimitry Andric 193fe6060f1SDimitry Andric CSKYOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 194fe6060f1SDimitry Andric 195fe6060f1SDimitry Andric public: 196fe6060f1SDimitry Andric CSKYOperand(const CSKYOperand &o) : MCParsedAsmOperand() { 197fe6060f1SDimitry Andric Kind = o.Kind; 198fe6060f1SDimitry Andric StartLoc = o.StartLoc; 199fe6060f1SDimitry Andric EndLoc = o.EndLoc; 200fe6060f1SDimitry Andric switch (Kind) { 201fe6060f1SDimitry Andric case Register: 202fe6060f1SDimitry Andric Reg = o.Reg; 203fe6060f1SDimitry Andric break; 204349cc55cSDimitry Andric case RegisterSeq: 205349cc55cSDimitry Andric RegSeq = o.RegSeq; 206349cc55cSDimitry Andric break; 207349cc55cSDimitry Andric case CPOP: 208349cc55cSDimitry Andric CPool = o.CPool; 209349cc55cSDimitry Andric break; 210fe6060f1SDimitry Andric case Immediate: 211fe6060f1SDimitry Andric Imm = o.Imm; 212fe6060f1SDimitry Andric break; 213fe6060f1SDimitry Andric case Token: 214fe6060f1SDimitry Andric Tok = o.Tok; 215fe6060f1SDimitry Andric break; 216349cc55cSDimitry Andric case RegisterList: 217349cc55cSDimitry Andric RegList = o.RegList; 218349cc55cSDimitry Andric break; 219fe6060f1SDimitry Andric } 220fe6060f1SDimitry Andric } 221fe6060f1SDimitry Andric 222fe6060f1SDimitry Andric bool isToken() const override { return Kind == Token; } 223fe6060f1SDimitry Andric bool isReg() const override { return Kind == Register; } 224fe6060f1SDimitry Andric bool isImm() const override { return Kind == Immediate; } 225349cc55cSDimitry Andric bool isRegisterSeq() const { return Kind == RegisterSeq; } 226349cc55cSDimitry Andric bool isRegisterList() const { return Kind == RegisterList; } 227349cc55cSDimitry Andric bool isConstPoolOp() const { return Kind == CPOP; } 228349cc55cSDimitry Andric 229fe6060f1SDimitry Andric bool isMem() const override { return false; } 230fe6060f1SDimitry Andric 231fe6060f1SDimitry Andric static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm) { 232fe6060f1SDimitry Andric if (auto CE = dyn_cast<MCConstantExpr>(Expr)) { 233fe6060f1SDimitry Andric Imm = CE->getValue(); 234fe6060f1SDimitry Andric return true; 235fe6060f1SDimitry Andric } 236fe6060f1SDimitry Andric 237fe6060f1SDimitry Andric return false; 238fe6060f1SDimitry Andric } 239fe6060f1SDimitry Andric 240fe6060f1SDimitry Andric template <unsigned num, unsigned shift = 0> bool isUImm() const { 241fe6060f1SDimitry Andric if (!isImm()) 242fe6060f1SDimitry Andric return false; 243fe6060f1SDimitry Andric 244fe6060f1SDimitry Andric int64_t Imm; 245fe6060f1SDimitry Andric bool IsConstantImm = evaluateConstantImm(getImm(), Imm); 246fe6060f1SDimitry Andric return IsConstantImm && isShiftedUInt<num, shift>(Imm); 247fe6060f1SDimitry Andric } 248fe6060f1SDimitry Andric 249fe6060f1SDimitry Andric template <unsigned num> bool isOImm() const { 250fe6060f1SDimitry Andric if (!isImm()) 251fe6060f1SDimitry Andric return false; 252fe6060f1SDimitry Andric 253fe6060f1SDimitry Andric int64_t Imm; 254fe6060f1SDimitry Andric bool IsConstantImm = evaluateConstantImm(getImm(), Imm); 255fe6060f1SDimitry Andric return IsConstantImm && isUInt<num>(Imm - 1); 256fe6060f1SDimitry Andric } 257fe6060f1SDimitry Andric 258fe6060f1SDimitry Andric template <unsigned num, unsigned shift = 0> bool isSImm() const { 259fe6060f1SDimitry Andric if (!isImm()) 260fe6060f1SDimitry Andric return false; 261fe6060f1SDimitry Andric 262fe6060f1SDimitry Andric int64_t Imm; 263fe6060f1SDimitry Andric bool IsConstantImm = evaluateConstantImm(getImm(), Imm); 264fe6060f1SDimitry Andric return IsConstantImm && isShiftedInt<num, shift>(Imm); 265fe6060f1SDimitry Andric } 266fe6060f1SDimitry Andric 267349cc55cSDimitry Andric bool isUImm1() const { return isUImm<1>(); } 268fe6060f1SDimitry Andric bool isUImm2() const { return isUImm<2>(); } 269349cc55cSDimitry Andric bool isUImm3() const { return isUImm<3>(); } 270349cc55cSDimitry Andric bool isUImm4() const { return isUImm<4>(); } 271fe6060f1SDimitry Andric bool isUImm5() const { return isUImm<5>(); } 272349cc55cSDimitry Andric bool isUImm6() const { return isUImm<6>(); } 273349cc55cSDimitry Andric bool isUImm7() const { return isUImm<7>(); } 274349cc55cSDimitry Andric bool isUImm8() const { return isUImm<8>(); } 275fe6060f1SDimitry Andric bool isUImm12() const { return isUImm<12>(); } 276fe6060f1SDimitry Andric bool isUImm16() const { return isUImm<16>(); } 277349cc55cSDimitry Andric bool isUImm20() const { return isUImm<20>(); } 278349cc55cSDimitry Andric bool isUImm24() const { return isUImm<24>(); } 279fe6060f1SDimitry Andric 280349cc55cSDimitry Andric bool isOImm3() const { return isOImm<3>(); } 281349cc55cSDimitry Andric bool isOImm4() const { return isOImm<4>(); } 282349cc55cSDimitry Andric bool isOImm5() const { return isOImm<5>(); } 283349cc55cSDimitry Andric bool isOImm6() const { return isOImm<6>(); } 284349cc55cSDimitry Andric bool isOImm8() const { return isOImm<8>(); } 285fe6060f1SDimitry Andric bool isOImm12() const { return isOImm<12>(); } 286fe6060f1SDimitry Andric bool isOImm16() const { return isOImm<16>(); } 287fe6060f1SDimitry Andric 288349cc55cSDimitry Andric bool isSImm8() const { return isSImm<8>(); } 289349cc55cSDimitry Andric 290349cc55cSDimitry Andric bool isUImm5Shift1() { return isUImm<5, 1>(); } 291349cc55cSDimitry Andric bool isUImm5Shift2() { return isUImm<5, 2>(); } 292349cc55cSDimitry Andric bool isUImm7Shift1() { return isUImm<7, 1>(); } 293349cc55cSDimitry Andric bool isUImm7Shift2() { return isUImm<7, 2>(); } 294349cc55cSDimitry Andric bool isUImm7Shift3() { return isUImm<7, 3>(); } 295349cc55cSDimitry Andric bool isUImm8Shift2() { return isUImm<8, 2>(); } 296349cc55cSDimitry Andric bool isUImm8Shift3() { return isUImm<8, 3>(); } 297349cc55cSDimitry Andric bool isUImm8Shift8() { return isUImm<8, 8>(); } 298349cc55cSDimitry Andric bool isUImm8Shift16() { return isUImm<8, 16>(); } 299349cc55cSDimitry Andric bool isUImm8Shift24() { return isUImm<8, 24>(); } 300fe6060f1SDimitry Andric bool isUImm12Shift1() { return isUImm<12, 1>(); } 301fe6060f1SDimitry Andric bool isUImm12Shift2() { return isUImm<12, 2>(); } 302349cc55cSDimitry Andric bool isUImm16Shift8() { return isUImm<16, 8>(); } 303349cc55cSDimitry Andric bool isUImm16Shift16() { return isUImm<16, 16>(); } 304349cc55cSDimitry Andric bool isUImm24Shift8() { return isUImm<24, 8>(); } 305fe6060f1SDimitry Andric 306fe6060f1SDimitry Andric bool isSImm16Shift1() { return isSImm<16, 1>(); } 307fe6060f1SDimitry Andric 308349cc55cSDimitry Andric bool isCSKYSymbol() const { return isImm(); } 309349cc55cSDimitry Andric 310349cc55cSDimitry Andric bool isConstpool() const { return isConstPoolOp(); } 311349cc55cSDimitry Andric bool isDataSymbol() const { return isConstPoolOp(); } 312349cc55cSDimitry Andric 313349cc55cSDimitry Andric bool isPSRFlag() const { 314fe6060f1SDimitry Andric int64_t Imm; 315349cc55cSDimitry Andric // Must be of 'immediate' type and a constant. 316349cc55cSDimitry Andric if (!isImm() || !evaluateConstantImm(getImm(), Imm)) 317349cc55cSDimitry Andric return false; 318349cc55cSDimitry Andric 319349cc55cSDimitry Andric return isUInt<5>(Imm); 320349cc55cSDimitry Andric } 321349cc55cSDimitry Andric 322349cc55cSDimitry Andric template <unsigned MIN, unsigned MAX> bool isRegSeqTemplate() const { 323349cc55cSDimitry Andric if (!isRegisterSeq()) 324349cc55cSDimitry Andric return false; 325349cc55cSDimitry Andric 326349cc55cSDimitry Andric std::pair<unsigned, unsigned> regSeq = getRegSeq(); 327349cc55cSDimitry Andric 328349cc55cSDimitry Andric return MIN <= regSeq.first && regSeq.first <= regSeq.second && 329349cc55cSDimitry Andric regSeq.second <= MAX; 330349cc55cSDimitry Andric } 331349cc55cSDimitry Andric 332349cc55cSDimitry Andric bool isRegSeq() const { return isRegSeqTemplate<CSKY::R0, CSKY::R31>(); } 333349cc55cSDimitry Andric 33404eeddc0SDimitry Andric bool isRegSeqV1() const { 33504eeddc0SDimitry Andric return isRegSeqTemplate<CSKY::F0_32, CSKY::F15_32>(); 33604eeddc0SDimitry Andric } 33704eeddc0SDimitry Andric 33804eeddc0SDimitry Andric bool isRegSeqV2() const { 33904eeddc0SDimitry Andric return isRegSeqTemplate<CSKY::F0_32, CSKY::F31_32>(); 34004eeddc0SDimitry Andric } 34104eeddc0SDimitry Andric 342349cc55cSDimitry Andric static bool isLegalRegList(unsigned from, unsigned to) { 343349cc55cSDimitry Andric if (from == 0 && to == 0) 344349cc55cSDimitry Andric return true; 345349cc55cSDimitry Andric 346349cc55cSDimitry Andric if (from == to) { 347349cc55cSDimitry Andric if (from != CSKY::R4 && from != CSKY::R15 && from != CSKY::R16 && 348349cc55cSDimitry Andric from != CSKY::R28) 349349cc55cSDimitry Andric return false; 350349cc55cSDimitry Andric 351349cc55cSDimitry Andric return true; 352349cc55cSDimitry Andric } else { 353349cc55cSDimitry Andric if (from != CSKY::R4 && from != CSKY::R16) 354349cc55cSDimitry Andric return false; 355349cc55cSDimitry Andric 356349cc55cSDimitry Andric if (from == CSKY::R4 && to > CSKY::R4 && to < CSKY::R12) 357349cc55cSDimitry Andric return true; 358349cc55cSDimitry Andric else if (from == CSKY::R16 && to > CSKY::R16 && to < CSKY::R18) 359349cc55cSDimitry Andric return true; 360349cc55cSDimitry Andric else 361349cc55cSDimitry Andric return false; 362349cc55cSDimitry Andric } 363349cc55cSDimitry Andric } 364349cc55cSDimitry Andric 365349cc55cSDimitry Andric bool isRegList() const { 366349cc55cSDimitry Andric if (!isRegisterList()) 367349cc55cSDimitry Andric return false; 368349cc55cSDimitry Andric 369349cc55cSDimitry Andric auto regList = getRegList(); 370349cc55cSDimitry Andric 371349cc55cSDimitry Andric if (!isLegalRegList(regList.List1From, regList.List1To)) 372349cc55cSDimitry Andric return false; 373349cc55cSDimitry Andric if (!isLegalRegList(regList.List2From, regList.List2To)) 374349cc55cSDimitry Andric return false; 375349cc55cSDimitry Andric if (!isLegalRegList(regList.List3From, regList.List3To)) 376349cc55cSDimitry Andric return false; 377349cc55cSDimitry Andric if (!isLegalRegList(regList.List4From, regList.List4To)) 378349cc55cSDimitry Andric return false; 379349cc55cSDimitry Andric 380349cc55cSDimitry Andric return true; 381349cc55cSDimitry Andric } 382349cc55cSDimitry Andric 383349cc55cSDimitry Andric bool isExtImm6() { 384349cc55cSDimitry Andric if (!isImm()) 385349cc55cSDimitry Andric return false; 386349cc55cSDimitry Andric 387349cc55cSDimitry Andric int64_t Imm; 388349cc55cSDimitry Andric bool IsConstantImm = evaluateConstantImm(getImm(), Imm); 389349cc55cSDimitry Andric if (!IsConstantImm) 390349cc55cSDimitry Andric return false; 391349cc55cSDimitry Andric 392349cc55cSDimitry Andric int uimm4 = Imm & 0xf; 393349cc55cSDimitry Andric 394349cc55cSDimitry Andric return isShiftedUInt<6, 0>(Imm) && uimm4 >= 0 && uimm4 <= 14; 395fe6060f1SDimitry Andric } 396fe6060f1SDimitry Andric 397fe6060f1SDimitry Andric /// Gets location of the first token of this operand. 398fe6060f1SDimitry Andric SMLoc getStartLoc() const override { return StartLoc; } 399fe6060f1SDimitry Andric /// Gets location of the last token of this operand. 400fe6060f1SDimitry Andric SMLoc getEndLoc() const override { return EndLoc; } 401fe6060f1SDimitry Andric 402fe6060f1SDimitry Andric unsigned getReg() const override { 403fe6060f1SDimitry Andric assert(Kind == Register && "Invalid type access!"); 404fe6060f1SDimitry Andric return Reg.RegNum; 405fe6060f1SDimitry Andric } 406fe6060f1SDimitry Andric 407349cc55cSDimitry Andric std::pair<unsigned, unsigned> getRegSeq() const { 408349cc55cSDimitry Andric assert(Kind == RegisterSeq && "Invalid type access!"); 409349cc55cSDimitry Andric return std::pair<unsigned, unsigned>(RegSeq.RegNumFrom, RegSeq.RegNumTo); 410349cc55cSDimitry Andric } 411349cc55cSDimitry Andric 412349cc55cSDimitry Andric RegListOp getRegList() const { 413349cc55cSDimitry Andric assert(Kind == RegisterList && "Invalid type access!"); 414349cc55cSDimitry Andric return RegList; 415349cc55cSDimitry Andric } 416349cc55cSDimitry Andric 417fe6060f1SDimitry Andric const MCExpr *getImm() const { 418fe6060f1SDimitry Andric assert(Kind == Immediate && "Invalid type access!"); 419fe6060f1SDimitry Andric return Imm.Val; 420fe6060f1SDimitry Andric } 421fe6060f1SDimitry Andric 422349cc55cSDimitry Andric const MCExpr *getConstpoolOp() const { 423349cc55cSDimitry Andric assert(Kind == CPOP && "Invalid type access!"); 424349cc55cSDimitry Andric return CPool.Val; 425349cc55cSDimitry Andric } 426349cc55cSDimitry Andric 427fe6060f1SDimitry Andric StringRef getToken() const { 428fe6060f1SDimitry Andric assert(Kind == Token && "Invalid type access!"); 429fe6060f1SDimitry Andric return Tok; 430fe6060f1SDimitry Andric } 431fe6060f1SDimitry Andric 432fe6060f1SDimitry Andric void print(raw_ostream &OS) const override { 433*bdd1243dSDimitry Andric auto RegName = [](MCRegister Reg) { 434349cc55cSDimitry Andric if (Reg) 435349cc55cSDimitry Andric return CSKYInstPrinter::getRegisterName(Reg); 436349cc55cSDimitry Andric else 437349cc55cSDimitry Andric return "noreg"; 438349cc55cSDimitry Andric }; 439349cc55cSDimitry Andric 440fe6060f1SDimitry Andric switch (Kind) { 441349cc55cSDimitry Andric case CPOP: 442349cc55cSDimitry Andric OS << *getConstpoolOp(); 443349cc55cSDimitry Andric break; 444fe6060f1SDimitry Andric case Immediate: 445fe6060f1SDimitry Andric OS << *getImm(); 446fe6060f1SDimitry Andric break; 447349cc55cSDimitry Andric case KindTy::Register: 448349cc55cSDimitry Andric OS << "<register " << RegName(getReg()) << ">"; 449349cc55cSDimitry Andric break; 450349cc55cSDimitry Andric case RegisterSeq: 451349cc55cSDimitry Andric OS << "<register-seq "; 452349cc55cSDimitry Andric OS << RegName(getRegSeq().first) << "-" << RegName(getRegSeq().second) 453349cc55cSDimitry Andric << ">"; 454349cc55cSDimitry Andric break; 455349cc55cSDimitry Andric case RegisterList: 456349cc55cSDimitry Andric OS << "<register-list "; 457349cc55cSDimitry Andric OS << RegName(getRegList().List1From) << "-" 458349cc55cSDimitry Andric << RegName(getRegList().List1To) << ","; 459349cc55cSDimitry Andric OS << RegName(getRegList().List2From) << "-" 460349cc55cSDimitry Andric << RegName(getRegList().List2To) << ","; 461349cc55cSDimitry Andric OS << RegName(getRegList().List3From) << "-" 462349cc55cSDimitry Andric << RegName(getRegList().List3To) << ","; 463349cc55cSDimitry Andric OS << RegName(getRegList().List4From) << "-" 464349cc55cSDimitry Andric << RegName(getRegList().List4To); 465fe6060f1SDimitry Andric break; 466fe6060f1SDimitry Andric case Token: 467fe6060f1SDimitry Andric OS << "'" << getToken() << "'"; 468fe6060f1SDimitry Andric break; 469fe6060f1SDimitry Andric } 470fe6060f1SDimitry Andric } 471fe6060f1SDimitry Andric 472fe6060f1SDimitry Andric static std::unique_ptr<CSKYOperand> createToken(StringRef Str, SMLoc S) { 473fe6060f1SDimitry Andric auto Op = std::make_unique<CSKYOperand>(Token); 474fe6060f1SDimitry Andric Op->Tok = Str; 475fe6060f1SDimitry Andric Op->StartLoc = S; 476fe6060f1SDimitry Andric Op->EndLoc = S; 477fe6060f1SDimitry Andric return Op; 478fe6060f1SDimitry Andric } 479fe6060f1SDimitry Andric 480fe6060f1SDimitry Andric static std::unique_ptr<CSKYOperand> createReg(unsigned RegNo, SMLoc S, 481fe6060f1SDimitry Andric SMLoc E) { 482fe6060f1SDimitry Andric auto Op = std::make_unique<CSKYOperand>(Register); 483fe6060f1SDimitry Andric Op->Reg.RegNum = RegNo; 484fe6060f1SDimitry Andric Op->StartLoc = S; 485fe6060f1SDimitry Andric Op->EndLoc = E; 486fe6060f1SDimitry Andric return Op; 487fe6060f1SDimitry Andric } 488fe6060f1SDimitry Andric 489349cc55cSDimitry Andric static std::unique_ptr<CSKYOperand> createRegSeq(unsigned RegNoFrom, 490349cc55cSDimitry Andric unsigned RegNoTo, SMLoc S) { 491349cc55cSDimitry Andric auto Op = std::make_unique<CSKYOperand>(RegisterSeq); 492349cc55cSDimitry Andric Op->RegSeq.RegNumFrom = RegNoFrom; 493349cc55cSDimitry Andric Op->RegSeq.RegNumTo = RegNoTo; 494349cc55cSDimitry Andric Op->StartLoc = S; 495349cc55cSDimitry Andric Op->EndLoc = S; 496349cc55cSDimitry Andric return Op; 497349cc55cSDimitry Andric } 498349cc55cSDimitry Andric 499349cc55cSDimitry Andric static std::unique_ptr<CSKYOperand> 500349cc55cSDimitry Andric createRegList(SmallVector<unsigned, 4> reglist, SMLoc S) { 501349cc55cSDimitry Andric auto Op = std::make_unique<CSKYOperand>(RegisterList); 502349cc55cSDimitry Andric Op->RegList.List1From = 0; 503349cc55cSDimitry Andric Op->RegList.List1To = 0; 504349cc55cSDimitry Andric Op->RegList.List2From = 0; 505349cc55cSDimitry Andric Op->RegList.List2To = 0; 506349cc55cSDimitry Andric Op->RegList.List3From = 0; 507349cc55cSDimitry Andric Op->RegList.List3To = 0; 508349cc55cSDimitry Andric Op->RegList.List4From = 0; 509349cc55cSDimitry Andric Op->RegList.List4To = 0; 510349cc55cSDimitry Andric 511349cc55cSDimitry Andric for (unsigned i = 0; i < reglist.size(); i += 2) { 512349cc55cSDimitry Andric if (Op->RegList.List1From == 0) { 513349cc55cSDimitry Andric Op->RegList.List1From = reglist[i]; 514349cc55cSDimitry Andric Op->RegList.List1To = reglist[i + 1]; 515349cc55cSDimitry Andric } else if (Op->RegList.List2From == 0) { 516349cc55cSDimitry Andric Op->RegList.List2From = reglist[i]; 517349cc55cSDimitry Andric Op->RegList.List2To = reglist[i + 1]; 518349cc55cSDimitry Andric } else if (Op->RegList.List3From == 0) { 519349cc55cSDimitry Andric Op->RegList.List3From = reglist[i]; 520349cc55cSDimitry Andric Op->RegList.List3To = reglist[i + 1]; 521349cc55cSDimitry Andric } else if (Op->RegList.List4From == 0) { 522349cc55cSDimitry Andric Op->RegList.List4From = reglist[i]; 523349cc55cSDimitry Andric Op->RegList.List4To = reglist[i + 1]; 524349cc55cSDimitry Andric } else { 525349cc55cSDimitry Andric assert(0); 526349cc55cSDimitry Andric } 527349cc55cSDimitry Andric } 528349cc55cSDimitry Andric 529349cc55cSDimitry Andric Op->StartLoc = S; 530349cc55cSDimitry Andric Op->EndLoc = S; 531349cc55cSDimitry Andric return Op; 532349cc55cSDimitry Andric } 533349cc55cSDimitry Andric 534fe6060f1SDimitry Andric static std::unique_ptr<CSKYOperand> createImm(const MCExpr *Val, SMLoc S, 535fe6060f1SDimitry Andric SMLoc E) { 536fe6060f1SDimitry Andric auto Op = std::make_unique<CSKYOperand>(Immediate); 537fe6060f1SDimitry Andric Op->Imm.Val = Val; 538fe6060f1SDimitry Andric Op->StartLoc = S; 539fe6060f1SDimitry Andric Op->EndLoc = E; 540fe6060f1SDimitry Andric return Op; 541fe6060f1SDimitry Andric } 542fe6060f1SDimitry Andric 543349cc55cSDimitry Andric static std::unique_ptr<CSKYOperand> createConstpoolOp(const MCExpr *Val, 544349cc55cSDimitry Andric SMLoc S, SMLoc E) { 545349cc55cSDimitry Andric auto Op = std::make_unique<CSKYOperand>(CPOP); 546349cc55cSDimitry Andric Op->CPool.Val = Val; 547349cc55cSDimitry Andric Op->StartLoc = S; 548349cc55cSDimitry Andric Op->EndLoc = E; 549349cc55cSDimitry Andric return Op; 550349cc55cSDimitry Andric } 551349cc55cSDimitry Andric 552fe6060f1SDimitry Andric void addExpr(MCInst &Inst, const MCExpr *Expr) const { 553fe6060f1SDimitry Andric assert(Expr && "Expr shouldn't be null!"); 554fe6060f1SDimitry Andric if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) 555fe6060f1SDimitry Andric Inst.addOperand(MCOperand::createImm(CE->getValue())); 556fe6060f1SDimitry Andric else 557fe6060f1SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr)); 558fe6060f1SDimitry Andric } 559fe6060f1SDimitry Andric 560fe6060f1SDimitry Andric // Used by the TableGen Code. 561fe6060f1SDimitry Andric void addRegOperands(MCInst &Inst, unsigned N) const { 562fe6060f1SDimitry Andric assert(N == 1 && "Invalid number of operands!"); 563fe6060f1SDimitry Andric Inst.addOperand(MCOperand::createReg(getReg())); 564fe6060f1SDimitry Andric } 565fe6060f1SDimitry Andric 566fe6060f1SDimitry Andric void addImmOperands(MCInst &Inst, unsigned N) const { 567fe6060f1SDimitry Andric assert(N == 1 && "Invalid number of operands!"); 568fe6060f1SDimitry Andric addExpr(Inst, getImm()); 569fe6060f1SDimitry Andric } 570349cc55cSDimitry Andric 571349cc55cSDimitry Andric void addConstpoolOperands(MCInst &Inst, unsigned N) const { 572349cc55cSDimitry Andric assert(N == 1 && "Invalid number of operands!"); 573349cc55cSDimitry Andric Inst.addOperand(MCOperand::createExpr(getConstpoolOp())); 574349cc55cSDimitry Andric } 575349cc55cSDimitry Andric 576349cc55cSDimitry Andric void addRegSeqOperands(MCInst &Inst, unsigned N) const { 577349cc55cSDimitry Andric assert(N == 2 && "Invalid number of operands!"); 578349cc55cSDimitry Andric auto regSeq = getRegSeq(); 579349cc55cSDimitry Andric 580349cc55cSDimitry Andric Inst.addOperand(MCOperand::createReg(regSeq.first)); 581349cc55cSDimitry Andric Inst.addOperand(MCOperand::createReg(regSeq.second)); 582349cc55cSDimitry Andric } 583349cc55cSDimitry Andric 584349cc55cSDimitry Andric static unsigned getListValue(unsigned ListFrom, unsigned ListTo) { 585349cc55cSDimitry Andric if (ListFrom == ListTo && ListFrom == CSKY::R15) 586349cc55cSDimitry Andric return (1 << 4); 587349cc55cSDimitry Andric else if (ListFrom == ListTo && ListFrom == CSKY::R28) 588349cc55cSDimitry Andric return (1 << 8); 589349cc55cSDimitry Andric else if (ListFrom == CSKY::R4) 590349cc55cSDimitry Andric return ListTo - ListFrom + 1; 591349cc55cSDimitry Andric else if (ListFrom == CSKY::R16) 592349cc55cSDimitry Andric return ((ListTo - ListFrom + 1) << 5); 593349cc55cSDimitry Andric else 594349cc55cSDimitry Andric return 0; 595349cc55cSDimitry Andric } 596349cc55cSDimitry Andric 597349cc55cSDimitry Andric void addRegListOperands(MCInst &Inst, unsigned N) const { 598349cc55cSDimitry Andric assert(N == 1 && "Invalid number of operands!"); 599349cc55cSDimitry Andric auto regList = getRegList(); 600349cc55cSDimitry Andric 601349cc55cSDimitry Andric unsigned V = 0; 602349cc55cSDimitry Andric 603349cc55cSDimitry Andric unsigned T = getListValue(regList.List1From, regList.List1To); 604349cc55cSDimitry Andric if (T != 0) 605349cc55cSDimitry Andric V = V | T; 606349cc55cSDimitry Andric 607349cc55cSDimitry Andric T = getListValue(regList.List2From, regList.List2To); 608349cc55cSDimitry Andric if (T != 0) 609349cc55cSDimitry Andric V = V | T; 610349cc55cSDimitry Andric 611349cc55cSDimitry Andric T = getListValue(regList.List3From, regList.List3To); 612349cc55cSDimitry Andric if (T != 0) 613349cc55cSDimitry Andric V = V | T; 614349cc55cSDimitry Andric 615349cc55cSDimitry Andric T = getListValue(regList.List4From, regList.List4To); 616349cc55cSDimitry Andric if (T != 0) 617349cc55cSDimitry Andric V = V | T; 618349cc55cSDimitry Andric 619349cc55cSDimitry Andric Inst.addOperand(MCOperand::createImm(V)); 620349cc55cSDimitry Andric } 621349cc55cSDimitry Andric 622349cc55cSDimitry Andric bool isValidForTie(const CSKYOperand &Other) const { 623349cc55cSDimitry Andric if (Kind != Other.Kind) 624349cc55cSDimitry Andric return false; 625349cc55cSDimitry Andric 626349cc55cSDimitry Andric switch (Kind) { 627349cc55cSDimitry Andric default: 628349cc55cSDimitry Andric llvm_unreachable("Unexpected kind"); 629349cc55cSDimitry Andric return false; 630349cc55cSDimitry Andric case Register: 631349cc55cSDimitry Andric return Reg.RegNum == Other.Reg.RegNum; 632349cc55cSDimitry Andric } 633349cc55cSDimitry Andric } 634fe6060f1SDimitry Andric }; 635fe6060f1SDimitry Andric } // end anonymous namespace. 636fe6060f1SDimitry Andric 637fe6060f1SDimitry Andric #define GET_REGISTER_MATCHER 638fe6060f1SDimitry Andric #define GET_SUBTARGET_FEATURE_NAME 639fe6060f1SDimitry Andric #define GET_MATCHER_IMPLEMENTATION 640fe6060f1SDimitry Andric #define GET_MNEMONIC_SPELL_CHECKER 641fe6060f1SDimitry Andric #include "CSKYGenAsmMatcher.inc" 642fe6060f1SDimitry Andric 64381ad6265SDimitry Andric static MCRegister convertFPR32ToFPR64(MCRegister Reg) { 64481ad6265SDimitry Andric assert(Reg >= CSKY::F0_32 && Reg <= CSKY::F31_32 && "Invalid register"); 64581ad6265SDimitry Andric return Reg - CSKY::F0_32 + CSKY::F0_64; 64681ad6265SDimitry Andric } 64781ad6265SDimitry Andric 648fe6060f1SDimitry Andric static std::string CSKYMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, 649fe6060f1SDimitry Andric unsigned VariantID = 0); 650fe6060f1SDimitry Andric 651fe6060f1SDimitry Andric bool CSKYAsmParser::generateImmOutOfRangeError( 652fe6060f1SDimitry Andric OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper, 653fe6060f1SDimitry Andric Twine Msg = "immediate must be an integer in the range") { 654fe6060f1SDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 655fe6060f1SDimitry Andric return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]"); 656fe6060f1SDimitry Andric } 657fe6060f1SDimitry Andric 658fe6060f1SDimitry Andric bool CSKYAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 659fe6060f1SDimitry Andric OperandVector &Operands, 660fe6060f1SDimitry Andric MCStreamer &Out, 661fe6060f1SDimitry Andric uint64_t &ErrorInfo, 662fe6060f1SDimitry Andric bool MatchingInlineAsm) { 663fe6060f1SDimitry Andric MCInst Inst; 664fe6060f1SDimitry Andric FeatureBitset MissingFeatures; 665fe6060f1SDimitry Andric 666fe6060f1SDimitry Andric auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures, 667fe6060f1SDimitry Andric MatchingInlineAsm); 668fe6060f1SDimitry Andric switch (Result) { 669fe6060f1SDimitry Andric default: 670fe6060f1SDimitry Andric break; 671fe6060f1SDimitry Andric case Match_Success: 672349cc55cSDimitry Andric return processInstruction(Inst, IDLoc, Operands, Out); 673fe6060f1SDimitry Andric case Match_MissingFeature: { 674fe6060f1SDimitry Andric assert(MissingFeatures.any() && "Unknown missing features!"); 675fe6060f1SDimitry Andric ListSeparator LS; 676fe6060f1SDimitry Andric std::string Msg = "instruction requires the following: "; 677fe6060f1SDimitry Andric for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) { 678fe6060f1SDimitry Andric if (MissingFeatures[i]) { 679fe6060f1SDimitry Andric Msg += LS; 680fe6060f1SDimitry Andric Msg += getSubtargetFeatureName(i); 681fe6060f1SDimitry Andric } 682fe6060f1SDimitry Andric } 683fe6060f1SDimitry Andric return Error(IDLoc, Msg); 684fe6060f1SDimitry Andric } 685fe6060f1SDimitry Andric case Match_MnemonicFail: { 686fe6060f1SDimitry Andric FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits()); 687fe6060f1SDimitry Andric std::string Suggestion = 688fe6060f1SDimitry Andric CSKYMnemonicSpellCheck(((CSKYOperand &)*Operands[0]).getToken(), FBS); 689fe6060f1SDimitry Andric return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion); 690fe6060f1SDimitry Andric } 691fe6060f1SDimitry Andric case Match_InvalidTiedOperand: 692fe6060f1SDimitry Andric case Match_InvalidOperand: { 693fe6060f1SDimitry Andric SMLoc ErrorLoc = IDLoc; 694fe6060f1SDimitry Andric if (ErrorInfo != ~0U) { 695fe6060f1SDimitry Andric if (ErrorInfo >= Operands.size()) 696fe6060f1SDimitry Andric return Error(ErrorLoc, "too few operands for instruction"); 697fe6060f1SDimitry Andric 698fe6060f1SDimitry Andric ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 699fe6060f1SDimitry Andric if (ErrorLoc == SMLoc()) 700fe6060f1SDimitry Andric ErrorLoc = IDLoc; 701fe6060f1SDimitry Andric } 702fe6060f1SDimitry Andric return Error(ErrorLoc, "invalid operand for instruction"); 703fe6060f1SDimitry Andric } 704fe6060f1SDimitry Andric } 705fe6060f1SDimitry Andric 706fe6060f1SDimitry Andric // Handle the case when the error message is of specific type 707fe6060f1SDimitry Andric // other than the generic Match_InvalidOperand, and the 708fe6060f1SDimitry Andric // corresponding operand is missing. 709fe6060f1SDimitry Andric if (Result > FIRST_TARGET_MATCH_RESULT_TY) { 710fe6060f1SDimitry Andric SMLoc ErrorLoc = IDLoc; 711fe6060f1SDimitry Andric if (ErrorInfo != ~0U && ErrorInfo >= Operands.size()) 712fe6060f1SDimitry Andric return Error(ErrorLoc, "too few operands for instruction"); 713fe6060f1SDimitry Andric } 714fe6060f1SDimitry Andric 715fe6060f1SDimitry Andric switch (Result) { 716fe6060f1SDimitry Andric default: 717fe6060f1SDimitry Andric break; 718349cc55cSDimitry Andric case Match_InvalidSImm8: 719349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7), 720349cc55cSDimitry Andric (1 << 7) - 1); 721349cc55cSDimitry Andric case Match_InvalidOImm3: 722349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 3)); 723349cc55cSDimitry Andric case Match_InvalidOImm4: 724349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4)); 725349cc55cSDimitry Andric case Match_InvalidOImm5: 726349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5)); 727349cc55cSDimitry Andric case Match_InvalidOImm6: 728349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6)); 729349cc55cSDimitry Andric case Match_InvalidOImm8: 730349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 8)); 731fe6060f1SDimitry Andric case Match_InvalidOImm12: 732fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 12)); 733fe6060f1SDimitry Andric case Match_InvalidOImm16: 734fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16)); 735349cc55cSDimitry Andric case Match_InvalidUImm1: 736349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1); 737fe6060f1SDimitry Andric case Match_InvalidUImm2: 738fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1); 739349cc55cSDimitry Andric case Match_InvalidUImm3: 740349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1); 741349cc55cSDimitry Andric case Match_InvalidUImm4: 742349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1); 743fe6060f1SDimitry Andric case Match_InvalidUImm5: 744fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 745349cc55cSDimitry Andric case Match_InvalidUImm6: 746349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); 747349cc55cSDimitry Andric case Match_InvalidUImm7: 748349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1); 749349cc55cSDimitry Andric case Match_InvalidUImm8: 750349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1); 751fe6060f1SDimitry Andric case Match_InvalidUImm12: 752fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1); 753349cc55cSDimitry Andric case Match_InvalidUImm16: 754349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 16) - 1); 755349cc55cSDimitry Andric case Match_InvalidUImm5Shift1: 756349cc55cSDimitry Andric return generateImmOutOfRangeError( 757349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 5) - 2, 758349cc55cSDimitry Andric "immediate must be a multiple of 2 bytes in the range"); 759fe6060f1SDimitry Andric case Match_InvalidUImm12Shift1: 760fe6060f1SDimitry Andric return generateImmOutOfRangeError( 761fe6060f1SDimitry Andric Operands, ErrorInfo, 0, (1 << 12) - 2, 762fe6060f1SDimitry Andric "immediate must be a multiple of 2 bytes in the range"); 763349cc55cSDimitry Andric case Match_InvalidUImm5Shift2: 764349cc55cSDimitry Andric return generateImmOutOfRangeError( 765349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 5) - 4, 766349cc55cSDimitry Andric "immediate must be a multiple of 4 bytes in the range"); 767349cc55cSDimitry Andric case Match_InvalidUImm7Shift1: 768349cc55cSDimitry Andric return generateImmOutOfRangeError( 769349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 7) - 2, 770349cc55cSDimitry Andric "immediate must be a multiple of 2 bytes in the range"); 771349cc55cSDimitry Andric case Match_InvalidUImm7Shift2: 772349cc55cSDimitry Andric return generateImmOutOfRangeError( 773349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 7) - 4, 774349cc55cSDimitry Andric "immediate must be a multiple of 4 bytes in the range"); 775349cc55cSDimitry Andric case Match_InvalidUImm8Shift2: 776349cc55cSDimitry Andric return generateImmOutOfRangeError( 777349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 8) - 4, 778349cc55cSDimitry Andric "immediate must be a multiple of 4 bytes in the range"); 779349cc55cSDimitry Andric case Match_InvalidUImm8Shift3: 780349cc55cSDimitry Andric return generateImmOutOfRangeError( 781349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 8) - 8, 782349cc55cSDimitry Andric "immediate must be a multiple of 8 bytes in the range"); 783349cc55cSDimitry Andric case Match_InvalidUImm8Shift8: 784349cc55cSDimitry Andric return generateImmOutOfRangeError( 785349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 8) - 256, 786349cc55cSDimitry Andric "immediate must be a multiple of 256 bytes in the range"); 787fe6060f1SDimitry Andric case Match_InvalidUImm12Shift2: 788fe6060f1SDimitry Andric return generateImmOutOfRangeError( 789fe6060f1SDimitry Andric Operands, ErrorInfo, 0, (1 << 12) - 4, 790fe6060f1SDimitry Andric "immediate must be a multiple of 4 bytes in the range"); 791fe6060f1SDimitry Andric case Match_InvalidCSKYSymbol: { 792fe6060f1SDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 793fe6060f1SDimitry Andric return Error(ErrorLoc, "operand must be a symbol name"); 794fe6060f1SDimitry Andric } 795fe6060f1SDimitry Andric case Match_InvalidConstpool: { 796fe6060f1SDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 797fe6060f1SDimitry Andric return Error(ErrorLoc, "operand must be a constpool symbol name"); 798fe6060f1SDimitry Andric } 799349cc55cSDimitry Andric case Match_InvalidPSRFlag: { 800349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 801349cc55cSDimitry Andric return Error(ErrorLoc, "psrset operand is not valid"); 802349cc55cSDimitry Andric } 803349cc55cSDimitry Andric case Match_InvalidRegSeq: { 804349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 805349cc55cSDimitry Andric return Error(ErrorLoc, "Register sequence is not valid"); 806349cc55cSDimitry Andric } 807349cc55cSDimitry Andric case Match_InvalidRegOutOfRange: { 808349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 809349cc55cSDimitry Andric return Error(ErrorLoc, "register is out of range"); 810349cc55cSDimitry Andric } 811349cc55cSDimitry Andric case Match_RequiresSameSrcAndDst: { 812349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 813349cc55cSDimitry Andric return Error(ErrorLoc, "src and dst operand must be same"); 814349cc55cSDimitry Andric } 815349cc55cSDimitry Andric case Match_InvalidRegList: { 816349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 817349cc55cSDimitry Andric return Error(ErrorLoc, "invalid register list"); 818349cc55cSDimitry Andric } 819349cc55cSDimitry Andric } 820349cc55cSDimitry Andric LLVM_DEBUG(dbgs() << "Result = " << Result); 821349cc55cSDimitry Andric llvm_unreachable("Unknown match type detected!"); 822fe6060f1SDimitry Andric } 823fe6060f1SDimitry Andric 82481ad6265SDimitry Andric bool CSKYAsmParser::processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) { 82581ad6265SDimitry Andric Inst.setLoc(IDLoc); 82681ad6265SDimitry Andric 82781ad6265SDimitry Andric unsigned Opcode; 82881ad6265SDimitry Andric MCOperand Op; 82981ad6265SDimitry Andric if (Inst.getOpcode() == CSKY::PseudoLRW16) 83081ad6265SDimitry Andric Opcode = CSKY::LRW16; 83181ad6265SDimitry Andric else 83281ad6265SDimitry Andric Opcode = CSKY::LRW32; 83381ad6265SDimitry Andric 83481ad6265SDimitry Andric if (Inst.getOperand(1).isImm()) { 83581ad6265SDimitry Andric if (isUInt<8>(Inst.getOperand(1).getImm()) && 83681ad6265SDimitry Andric Inst.getOperand(0).getReg() <= CSKY::R7) { 83781ad6265SDimitry Andric Opcode = CSKY::MOVI16; 83881ad6265SDimitry Andric } else if (getSTI().getFeatureBits()[CSKY::HasE2] && 83981ad6265SDimitry Andric isUInt<16>(Inst.getOperand(1).getImm())) { 84081ad6265SDimitry Andric Opcode = CSKY::MOVI32; 84181ad6265SDimitry Andric } else { 84281ad6265SDimitry Andric auto *Expr = getTargetStreamer().addConstantPoolEntry( 84381ad6265SDimitry Andric MCConstantExpr::create(Inst.getOperand(1).getImm(), getContext()), 84481ad6265SDimitry Andric Inst.getLoc()); 84581ad6265SDimitry Andric Inst.erase(std::prev(Inst.end())); 84681ad6265SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr)); 84781ad6265SDimitry Andric } 84881ad6265SDimitry Andric } else { 84981ad6265SDimitry Andric const MCExpr *AdjustExpr = nullptr; 85081ad6265SDimitry Andric if (const CSKYMCExpr *CSKYExpr = 85181ad6265SDimitry Andric dyn_cast<CSKYMCExpr>(Inst.getOperand(1).getExpr())) { 85281ad6265SDimitry Andric if (CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSGD || 85381ad6265SDimitry Andric CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSIE || 85481ad6265SDimitry Andric CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSLDM) { 85581ad6265SDimitry Andric MCSymbol *Dot = getContext().createNamedTempSymbol(); 85681ad6265SDimitry Andric Out.emitLabel(Dot); 85781ad6265SDimitry Andric AdjustExpr = MCSymbolRefExpr::create(Dot, getContext()); 85881ad6265SDimitry Andric } 85981ad6265SDimitry Andric } 86081ad6265SDimitry Andric auto *Expr = getTargetStreamer().addConstantPoolEntry( 86181ad6265SDimitry Andric Inst.getOperand(1).getExpr(), Inst.getLoc(), AdjustExpr); 86281ad6265SDimitry Andric Inst.erase(std::prev(Inst.end())); 86381ad6265SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr)); 86481ad6265SDimitry Andric } 86581ad6265SDimitry Andric 86681ad6265SDimitry Andric Inst.setOpcode(Opcode); 86781ad6265SDimitry Andric 86881ad6265SDimitry Andric Out.emitInstruction(Inst, getSTI()); 86981ad6265SDimitry Andric return false; 87081ad6265SDimitry Andric } 87181ad6265SDimitry Andric 87281ad6265SDimitry Andric bool CSKYAsmParser::processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) { 87381ad6265SDimitry Andric Inst.setLoc(IDLoc); 87481ad6265SDimitry Andric 87581ad6265SDimitry Andric if (Inst.getOperand(0).isImm()) { 87681ad6265SDimitry Andric const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry( 87781ad6265SDimitry Andric MCConstantExpr::create(Inst.getOperand(0).getImm(), getContext()), 87881ad6265SDimitry Andric Inst.getLoc()); 87981ad6265SDimitry Andric Inst.setOpcode(CSKY::JSRI32); 88081ad6265SDimitry Andric Inst.erase(std::prev(Inst.end())); 88181ad6265SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr)); 88281ad6265SDimitry Andric } else { 88381ad6265SDimitry Andric const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry( 88481ad6265SDimitry Andric Inst.getOperand(0).getExpr(), Inst.getLoc()); 88581ad6265SDimitry Andric Inst.setOpcode(CSKY::JBSR32); 88681ad6265SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr)); 88781ad6265SDimitry Andric } 88881ad6265SDimitry Andric 88981ad6265SDimitry Andric Out.emitInstruction(Inst, getSTI()); 89081ad6265SDimitry Andric return false; 89181ad6265SDimitry Andric } 89281ad6265SDimitry Andric 89381ad6265SDimitry Andric bool CSKYAsmParser::processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) { 89481ad6265SDimitry Andric Inst.setLoc(IDLoc); 89581ad6265SDimitry Andric 89681ad6265SDimitry Andric if (Inst.getOperand(0).isImm()) { 89781ad6265SDimitry Andric const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry( 89881ad6265SDimitry Andric MCConstantExpr::create(Inst.getOperand(0).getImm(), getContext()), 89981ad6265SDimitry Andric Inst.getLoc()); 90081ad6265SDimitry Andric Inst.setOpcode(CSKY::JMPI32); 90181ad6265SDimitry Andric Inst.erase(std::prev(Inst.end())); 90281ad6265SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr)); 90381ad6265SDimitry Andric } else { 90481ad6265SDimitry Andric const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry( 90581ad6265SDimitry Andric Inst.getOperand(0).getExpr(), Inst.getLoc()); 90681ad6265SDimitry Andric Inst.setOpcode(CSKY::JBR32); 90781ad6265SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr)); 90881ad6265SDimitry Andric } 90981ad6265SDimitry Andric 91081ad6265SDimitry Andric Out.emitInstruction(Inst, getSTI()); 91181ad6265SDimitry Andric return false; 91281ad6265SDimitry Andric } 91381ad6265SDimitry Andric 914349cc55cSDimitry Andric bool CSKYAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 915349cc55cSDimitry Andric OperandVector &Operands, 916349cc55cSDimitry Andric MCStreamer &Out) { 917349cc55cSDimitry Andric 9180eae32dcSDimitry Andric switch (Inst.getOpcode()) { 9190eae32dcSDimitry Andric default: 9200eae32dcSDimitry Andric break; 9210eae32dcSDimitry Andric case CSKY::LDQ32: 9220eae32dcSDimitry Andric case CSKY::STQ32: 923349cc55cSDimitry Andric if (Inst.getOperand(1).getReg() != CSKY::R4 || 924349cc55cSDimitry Andric Inst.getOperand(2).getReg() != CSKY::R7) { 925349cc55cSDimitry Andric return Error(IDLoc, "Register sequence is not valid. 'r4-r7' expected"); 926349cc55cSDimitry Andric } 927349cc55cSDimitry Andric Inst.setOpcode(Inst.getOpcode() == CSKY::LDQ32 ? CSKY::LDM32 : CSKY::STM32); 9280eae32dcSDimitry Andric break; 9290eae32dcSDimitry Andric case CSKY::SEXT32: 9300eae32dcSDimitry Andric case CSKY::ZEXT32: 931349cc55cSDimitry Andric if (Inst.getOperand(2).getImm() < Inst.getOperand(3).getImm()) 932349cc55cSDimitry Andric return Error(IDLoc, "msb must be greater or equal to lsb"); 9330eae32dcSDimitry Andric break; 9340eae32dcSDimitry Andric case CSKY::INS32: 935349cc55cSDimitry Andric if (Inst.getOperand(3).getImm() < Inst.getOperand(4).getImm()) 936349cc55cSDimitry Andric return Error(IDLoc, "msb must be greater or equal to lsb"); 9370eae32dcSDimitry Andric break; 9380eae32dcSDimitry Andric case CSKY::IDLY32: 939349cc55cSDimitry Andric if (Inst.getOperand(0).getImm() > 32 || Inst.getOperand(0).getImm() < 0) 940349cc55cSDimitry Andric return Error(IDLoc, "n must be in range [0,32]"); 9410eae32dcSDimitry Andric break; 9420eae32dcSDimitry Andric case CSKY::ADDC32: 9430eae32dcSDimitry Andric case CSKY::SUBC32: 9440eae32dcSDimitry Andric case CSKY::ADDC16: 9450eae32dcSDimitry Andric case CSKY::SUBC16: 9460eae32dcSDimitry Andric Inst.erase(std::next(Inst.begin())); 9470eae32dcSDimitry Andric Inst.erase(std::prev(Inst.end())); 9480eae32dcSDimitry Andric Inst.insert(std::next(Inst.begin()), MCOperand::createReg(CSKY::C)); 9490eae32dcSDimitry Andric Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C)); 9500eae32dcSDimitry Andric break; 9510eae32dcSDimitry Andric case CSKY::CMPNEI32: 9520eae32dcSDimitry Andric case CSKY::CMPNEI16: 9530eae32dcSDimitry Andric case CSKY::CMPNE32: 9540eae32dcSDimitry Andric case CSKY::CMPNE16: 9550eae32dcSDimitry Andric case CSKY::CMPHSI32: 9560eae32dcSDimitry Andric case CSKY::CMPHSI16: 9570eae32dcSDimitry Andric case CSKY::CMPHS32: 9580eae32dcSDimitry Andric case CSKY::CMPHS16: 9590eae32dcSDimitry Andric case CSKY::CMPLTI32: 9600eae32dcSDimitry Andric case CSKY::CMPLTI16: 9610eae32dcSDimitry Andric case CSKY::CMPLT32: 9620eae32dcSDimitry Andric case CSKY::CMPLT16: 9630eae32dcSDimitry Andric case CSKY::BTSTI32: 9640eae32dcSDimitry Andric Inst.erase(Inst.begin()); 9650eae32dcSDimitry Andric Inst.insert(Inst.begin(), MCOperand::createReg(CSKY::C)); 9660eae32dcSDimitry Andric break; 9670eae32dcSDimitry Andric case CSKY::MVCV32: 9680eae32dcSDimitry Andric Inst.erase(std::next(Inst.begin())); 9690eae32dcSDimitry Andric Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C)); 9700eae32dcSDimitry Andric break; 97181ad6265SDimitry Andric case CSKY::PseudoLRW16: 97281ad6265SDimitry Andric case CSKY::PseudoLRW32: 97381ad6265SDimitry Andric return processLRW(Inst, IDLoc, Out); 97481ad6265SDimitry Andric case CSKY::PseudoJSRI32: 97581ad6265SDimitry Andric return processJSRI(Inst, IDLoc, Out); 97681ad6265SDimitry Andric case CSKY::PseudoJMPI32: 97781ad6265SDimitry Andric return processJMPI(Inst, IDLoc, Out); 97881ad6265SDimitry Andric case CSKY::JBSR32: 97981ad6265SDimitry Andric case CSKY::JBR16: 98081ad6265SDimitry Andric case CSKY::JBT16: 98181ad6265SDimitry Andric case CSKY::JBF16: 98281ad6265SDimitry Andric case CSKY::JBR32: 98381ad6265SDimitry Andric case CSKY::JBT32: 98481ad6265SDimitry Andric case CSKY::JBF32: 98581ad6265SDimitry Andric unsigned Num = Inst.getNumOperands() - 1; 98681ad6265SDimitry Andric assert(Inst.getOperand(Num).isExpr()); 98781ad6265SDimitry Andric 98881ad6265SDimitry Andric const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry( 98981ad6265SDimitry Andric Inst.getOperand(Num).getExpr(), Inst.getLoc()); 99081ad6265SDimitry Andric 99181ad6265SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr)); 99281ad6265SDimitry Andric break; 993349cc55cSDimitry Andric } 994349cc55cSDimitry Andric 9950eae32dcSDimitry Andric emitToStreamer(Out, Inst); 996349cc55cSDimitry Andric return false; 997fe6060f1SDimitry Andric } 998fe6060f1SDimitry Andric 999fe6060f1SDimitry Andric // Attempts to match Name as a register (either using the default name or 1000fe6060f1SDimitry Andric // alternative ABI names), setting RegNo to the matching register. Upon 1001fe6060f1SDimitry Andric // failure, returns true and sets RegNo to 0. 1002349cc55cSDimitry Andric static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, 1003349cc55cSDimitry Andric MCRegister &RegNo, StringRef Name) { 1004fe6060f1SDimitry Andric RegNo = MatchRegisterName(Name); 1005fe6060f1SDimitry Andric 1006fe6060f1SDimitry Andric if (RegNo == CSKY::NoRegister) 1007fe6060f1SDimitry Andric RegNo = MatchRegisterAltName(Name); 1008fe6060f1SDimitry Andric 1009fe6060f1SDimitry Andric return RegNo == CSKY::NoRegister; 1010fe6060f1SDimitry Andric } 1011fe6060f1SDimitry Andric 1012*bdd1243dSDimitry Andric bool CSKYAsmParser::parseRegister(MCRegister &RegNo, SMLoc &StartLoc, 1013fe6060f1SDimitry Andric SMLoc &EndLoc) { 1014fe6060f1SDimitry Andric const AsmToken &Tok = getParser().getTok(); 1015fe6060f1SDimitry Andric StartLoc = Tok.getLoc(); 1016fe6060f1SDimitry Andric EndLoc = Tok.getEndLoc(); 1017fe6060f1SDimitry Andric StringRef Name = getLexer().getTok().getIdentifier(); 1018fe6060f1SDimitry Andric 1019349cc55cSDimitry Andric if (!matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) { 1020fe6060f1SDimitry Andric getParser().Lex(); // Eat identifier token. 1021fe6060f1SDimitry Andric return false; 1022fe6060f1SDimitry Andric } 1023fe6060f1SDimitry Andric 1024349cc55cSDimitry Andric return MatchOperand_NoMatch; 1025fe6060f1SDimitry Andric } 1026fe6060f1SDimitry Andric 1027fe6060f1SDimitry Andric OperandMatchResultTy CSKYAsmParser::parseRegister(OperandVector &Operands) { 1028fe6060f1SDimitry Andric SMLoc S = getLoc(); 1029fe6060f1SDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1030fe6060f1SDimitry Andric 1031fe6060f1SDimitry Andric switch (getLexer().getKind()) { 1032fe6060f1SDimitry Andric default: 1033fe6060f1SDimitry Andric return MatchOperand_NoMatch; 1034fe6060f1SDimitry Andric case AsmToken::Identifier: { 1035fe6060f1SDimitry Andric StringRef Name = getLexer().getTok().getIdentifier(); 1036fe6060f1SDimitry Andric MCRegister RegNo; 1037fe6060f1SDimitry Andric 1038349cc55cSDimitry Andric if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) 1039fe6060f1SDimitry Andric return MatchOperand_NoMatch; 1040fe6060f1SDimitry Andric 1041fe6060f1SDimitry Andric getLexer().Lex(); 1042fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createReg(RegNo, S, E)); 1043fe6060f1SDimitry Andric 1044fe6060f1SDimitry Andric return MatchOperand_Success; 1045fe6060f1SDimitry Andric } 1046fe6060f1SDimitry Andric } 1047fe6060f1SDimitry Andric } 1048fe6060f1SDimitry Andric 1049fe6060f1SDimitry Andric OperandMatchResultTy CSKYAsmParser::parseBaseRegImm(OperandVector &Operands) { 1050fe6060f1SDimitry Andric assert(getLexer().is(AsmToken::LParen)); 1051fe6060f1SDimitry Andric 1052fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createToken("(", getLoc())); 1053fe6060f1SDimitry Andric 1054fe6060f1SDimitry Andric auto Tok = getParser().Lex(); // Eat '(' 1055fe6060f1SDimitry Andric 1056fe6060f1SDimitry Andric if (parseRegister(Operands) != MatchOperand_Success) { 1057fe6060f1SDimitry Andric getLexer().UnLex(Tok); 1058fe6060f1SDimitry Andric Operands.pop_back(); 1059349cc55cSDimitry Andric return MatchOperand_NoMatch; 1060349cc55cSDimitry Andric } 1061349cc55cSDimitry Andric 1062349cc55cSDimitry Andric if (getLexer().is(AsmToken::RParen)) { 1063349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createToken(")", getLoc())); 1064349cc55cSDimitry Andric getParser().Lex(); // Eat ')' 1065349cc55cSDimitry Andric return MatchOperand_Success; 1066fe6060f1SDimitry Andric } 1067fe6060f1SDimitry Andric 1068fe6060f1SDimitry Andric if (getLexer().isNot(AsmToken::Comma)) { 1069fe6060f1SDimitry Andric Error(getLoc(), "expected ','"); 1070fe6060f1SDimitry Andric return MatchOperand_ParseFail; 1071fe6060f1SDimitry Andric } 1072fe6060f1SDimitry Andric 1073fe6060f1SDimitry Andric getParser().Lex(); // Eat ',' 1074fe6060f1SDimitry Andric 1075fe6060f1SDimitry Andric if (parseRegister(Operands) == MatchOperand_Success) { 1076fe6060f1SDimitry Andric if (getLexer().isNot(AsmToken::LessLess)) { 1077fe6060f1SDimitry Andric Error(getLoc(), "expected '<<'"); 1078fe6060f1SDimitry Andric return MatchOperand_ParseFail; 1079fe6060f1SDimitry Andric } 1080fe6060f1SDimitry Andric 1081fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createToken("<<", getLoc())); 1082fe6060f1SDimitry Andric 1083fe6060f1SDimitry Andric getParser().Lex(); // Eat '<<' 1084fe6060f1SDimitry Andric 1085fe6060f1SDimitry Andric if (parseImmediate(Operands) != MatchOperand_Success) { 1086fe6060f1SDimitry Andric Error(getLoc(), "expected imm"); 1087fe6060f1SDimitry Andric return MatchOperand_ParseFail; 1088fe6060f1SDimitry Andric } 1089fe6060f1SDimitry Andric 1090fe6060f1SDimitry Andric } else if (parseImmediate(Operands) != MatchOperand_Success) { 1091fe6060f1SDimitry Andric Error(getLoc(), "expected imm"); 1092fe6060f1SDimitry Andric return MatchOperand_ParseFail; 1093fe6060f1SDimitry Andric } 1094fe6060f1SDimitry Andric 1095fe6060f1SDimitry Andric if (getLexer().isNot(AsmToken::RParen)) { 1096fe6060f1SDimitry Andric Error(getLoc(), "expected ')'"); 1097fe6060f1SDimitry Andric return MatchOperand_ParseFail; 1098fe6060f1SDimitry Andric } 1099fe6060f1SDimitry Andric 1100fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createToken(")", getLoc())); 1101fe6060f1SDimitry Andric 1102fe6060f1SDimitry Andric getParser().Lex(); // Eat ')' 1103fe6060f1SDimitry Andric 1104fe6060f1SDimitry Andric return MatchOperand_Success; 1105fe6060f1SDimitry Andric } 1106fe6060f1SDimitry Andric 1107fe6060f1SDimitry Andric OperandMatchResultTy CSKYAsmParser::parseImmediate(OperandVector &Operands) { 1108fe6060f1SDimitry Andric switch (getLexer().getKind()) { 1109fe6060f1SDimitry Andric default: 1110fe6060f1SDimitry Andric return MatchOperand_NoMatch; 1111fe6060f1SDimitry Andric case AsmToken::LParen: 1112fe6060f1SDimitry Andric case AsmToken::Minus: 1113fe6060f1SDimitry Andric case AsmToken::Plus: 1114fe6060f1SDimitry Andric case AsmToken::Integer: 1115fe6060f1SDimitry Andric case AsmToken::String: 1116fe6060f1SDimitry Andric break; 1117fe6060f1SDimitry Andric } 1118fe6060f1SDimitry Andric 1119fe6060f1SDimitry Andric const MCExpr *IdVal; 1120fe6060f1SDimitry Andric SMLoc S = getLoc(); 1121349cc55cSDimitry Andric if (getParser().parseExpression(IdVal)) { 1122349cc55cSDimitry Andric Error(getLoc(), "unknown expression"); 1123fe6060f1SDimitry Andric return MatchOperand_ParseFail; 1124349cc55cSDimitry Andric } 1125fe6060f1SDimitry Andric 1126fe6060f1SDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1127fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createImm(IdVal, S, E)); 1128fe6060f1SDimitry Andric return MatchOperand_Success; 1129fe6060f1SDimitry Andric } 1130fe6060f1SDimitry Andric 1131fe6060f1SDimitry Andric /// Looks at a token type and creates the relevant operand from this 1132fe6060f1SDimitry Andric /// information, adding to Operands. If operand was parsed, returns false, else 1133fe6060f1SDimitry Andric /// true. 1134fe6060f1SDimitry Andric bool CSKYAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 1135fe6060f1SDimitry Andric // Check if the current operand has a custom associated parser, if so, try to 1136fe6060f1SDimitry Andric // custom parse the operand, or fallback to the general approach. 1137fe6060f1SDimitry Andric OperandMatchResultTy Result = 1138fe6060f1SDimitry Andric MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true); 1139fe6060f1SDimitry Andric if (Result == MatchOperand_Success) 1140fe6060f1SDimitry Andric return false; 1141fe6060f1SDimitry Andric if (Result == MatchOperand_ParseFail) 1142fe6060f1SDimitry Andric return true; 1143fe6060f1SDimitry Andric 1144fe6060f1SDimitry Andric // Attempt to parse token as register 1145349cc55cSDimitry Andric auto Res = parseRegister(Operands); 1146349cc55cSDimitry Andric if (Res == MatchOperand_Success) 1147fe6060f1SDimitry Andric return false; 1148349cc55cSDimitry Andric else if (Res == MatchOperand_ParseFail) 1149349cc55cSDimitry Andric return true; 1150fe6060f1SDimitry Andric 1151fe6060f1SDimitry Andric // Attempt to parse token as (register, imm) 1152349cc55cSDimitry Andric if (getLexer().is(AsmToken::LParen)) { 1153349cc55cSDimitry Andric Res = parseBaseRegImm(Operands); 1154349cc55cSDimitry Andric if (Res == MatchOperand_Success) 1155fe6060f1SDimitry Andric return false; 1156349cc55cSDimitry Andric else if (Res == MatchOperand_ParseFail) 1157349cc55cSDimitry Andric return true; 1158349cc55cSDimitry Andric } 1159fe6060f1SDimitry Andric 1160349cc55cSDimitry Andric Res = parseImmediate(Operands); 1161349cc55cSDimitry Andric if (Res == MatchOperand_Success) 1162fe6060f1SDimitry Andric return false; 1163349cc55cSDimitry Andric else if (Res == MatchOperand_ParseFail) 1164349cc55cSDimitry Andric return true; 1165fe6060f1SDimitry Andric 1166fe6060f1SDimitry Andric // Finally we have exhausted all options and must declare defeat. 1167fe6060f1SDimitry Andric Error(getLoc(), "unknown operand"); 1168fe6060f1SDimitry Andric return true; 1169fe6060f1SDimitry Andric } 1170fe6060f1SDimitry Andric 1171fe6060f1SDimitry Andric OperandMatchResultTy CSKYAsmParser::parseCSKYSymbol(OperandVector &Operands) { 1172fe6060f1SDimitry Andric SMLoc S = getLoc(); 1173fe6060f1SDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1174349cc55cSDimitry Andric const MCExpr *Res; 1175fe6060f1SDimitry Andric 1176fe6060f1SDimitry Andric if (getLexer().getKind() != AsmToken::Identifier) 1177fe6060f1SDimitry Andric return MatchOperand_NoMatch; 1178fe6060f1SDimitry Andric 1179fe6060f1SDimitry Andric StringRef Identifier; 1180349cc55cSDimitry Andric AsmToken Tok = getLexer().getTok(); 1181349cc55cSDimitry Andric 1182349cc55cSDimitry Andric if (getParser().parseIdentifier(Identifier)) { 1183349cc55cSDimitry Andric Error(getLoc(), "unknown identifier"); 1184fe6060f1SDimitry Andric return MatchOperand_ParseFail; 1185349cc55cSDimitry Andric } 1186fe6060f1SDimitry Andric 1187fe6060f1SDimitry Andric CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None; 1188fe6060f1SDimitry Andric if (Identifier.consume_back("@GOT")) 1189fe6060f1SDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOT; 1190fe6060f1SDimitry Andric else if (Identifier.consume_back("@GOTOFF")) 1191fe6060f1SDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOTOFF; 1192fe6060f1SDimitry Andric else if (Identifier.consume_back("@PLT")) 1193fe6060f1SDimitry Andric Kind = CSKYMCExpr::VK_CSKY_PLT; 1194fe6060f1SDimitry Andric else if (Identifier.consume_back("@GOTPC")) 1195fe6060f1SDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOTPC; 1196349cc55cSDimitry Andric else if (Identifier.consume_back("@TLSGD32")) 1197349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSGD; 1198349cc55cSDimitry Andric else if (Identifier.consume_back("@GOTTPOFF")) 1199349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSIE; 1200349cc55cSDimitry Andric else if (Identifier.consume_back("@TPOFF")) 1201349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSLE; 1202349cc55cSDimitry Andric else if (Identifier.consume_back("@TLSLDM32")) 1203349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSLDM; 1204349cc55cSDimitry Andric else if (Identifier.consume_back("@TLSLDO32")) 1205349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSLDO; 1206fe6060f1SDimitry Andric 1207349cc55cSDimitry Andric MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier); 1208fe6060f1SDimitry Andric 1209349cc55cSDimitry Andric if (!Sym) 1210349cc55cSDimitry Andric Sym = getContext().getOrCreateSymbol(Identifier); 1211349cc55cSDimitry Andric 1212349cc55cSDimitry Andric if (Sym->isVariable()) { 1213349cc55cSDimitry Andric const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1214349cc55cSDimitry Andric if (!isa<MCSymbolRefExpr>(V)) { 1215349cc55cSDimitry Andric getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1216349cc55cSDimitry Andric Error(getLoc(), "unknown symbol"); 1217349cc55cSDimitry Andric return MatchOperand_ParseFail; 1218349cc55cSDimitry Andric } 1219349cc55cSDimitry Andric Res = V; 1220349cc55cSDimitry Andric } else 1221349cc55cSDimitry Andric Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1222349cc55cSDimitry Andric 1223349cc55cSDimitry Andric MCBinaryExpr::Opcode Opcode; 1224349cc55cSDimitry Andric switch (getLexer().getKind()) { 1225349cc55cSDimitry Andric default: 1226fe6060f1SDimitry Andric if (Kind != CSKYMCExpr::VK_CSKY_None) 1227fe6060f1SDimitry Andric Res = CSKYMCExpr::create(Res, Kind, getContext()); 1228fe6060f1SDimitry Andric 1229fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createImm(Res, S, E)); 1230fe6060f1SDimitry Andric return MatchOperand_Success; 1231349cc55cSDimitry Andric case AsmToken::Plus: 1232349cc55cSDimitry Andric Opcode = MCBinaryExpr::Add; 1233349cc55cSDimitry Andric break; 1234349cc55cSDimitry Andric case AsmToken::Minus: 1235349cc55cSDimitry Andric Opcode = MCBinaryExpr::Sub; 1236349cc55cSDimitry Andric break; 1237349cc55cSDimitry Andric } 1238349cc55cSDimitry Andric 1239349cc55cSDimitry Andric getLexer().Lex(); // eat + or - 1240349cc55cSDimitry Andric 1241349cc55cSDimitry Andric const MCExpr *Expr; 1242349cc55cSDimitry Andric if (getParser().parseExpression(Expr)) { 1243349cc55cSDimitry Andric Error(getLoc(), "unknown expression"); 1244349cc55cSDimitry Andric return MatchOperand_ParseFail; 1245349cc55cSDimitry Andric } 1246349cc55cSDimitry Andric Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1247349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createImm(Res, S, E)); 1248349cc55cSDimitry Andric return MatchOperand_Success; 1249349cc55cSDimitry Andric } 1250349cc55cSDimitry Andric 1251349cc55cSDimitry Andric OperandMatchResultTy CSKYAsmParser::parseDataSymbol(OperandVector &Operands) { 1252349cc55cSDimitry Andric SMLoc S = getLoc(); 1253349cc55cSDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1254349cc55cSDimitry Andric const MCExpr *Res; 1255349cc55cSDimitry Andric 1256349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::LBrac) 1257349cc55cSDimitry Andric return MatchOperand_NoMatch; 1258349cc55cSDimitry Andric 1259349cc55cSDimitry Andric getLexer().Lex(); // Eat '['. 1260349cc55cSDimitry Andric 1261349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::Identifier) { 1262349cc55cSDimitry Andric const MCExpr *Expr; 1263349cc55cSDimitry Andric if (getParser().parseExpression(Expr)) { 1264349cc55cSDimitry Andric Error(getLoc(), "unknown expression"); 1265349cc55cSDimitry Andric return MatchOperand_ParseFail; 1266349cc55cSDimitry Andric } 1267349cc55cSDimitry Andric 1268349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::RBrac) { 1269349cc55cSDimitry Andric Error(getLoc(), "expected ]"); 1270349cc55cSDimitry Andric return MatchOperand_ParseFail; 1271349cc55cSDimitry Andric } 1272349cc55cSDimitry Andric 1273349cc55cSDimitry Andric getLexer().Lex(); // Eat ']'. 1274349cc55cSDimitry Andric 1275349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E)); 1276349cc55cSDimitry Andric return MatchOperand_Success; 1277349cc55cSDimitry Andric } 1278349cc55cSDimitry Andric 1279349cc55cSDimitry Andric AsmToken Tok = getLexer().getTok(); 1280349cc55cSDimitry Andric StringRef Identifier; 1281349cc55cSDimitry Andric 1282349cc55cSDimitry Andric if (getParser().parseIdentifier(Identifier)) { 1283349cc55cSDimitry Andric Error(getLoc(), "unknown identifier " + Identifier); 1284349cc55cSDimitry Andric return MatchOperand_ParseFail; 1285349cc55cSDimitry Andric } 1286349cc55cSDimitry Andric 1287349cc55cSDimitry Andric CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None; 1288349cc55cSDimitry Andric if (Identifier.consume_back("@GOT")) 1289349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOT_IMM18_BY4; 1290349cc55cSDimitry Andric else if (Identifier.consume_back("@PLT")) 1291349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_PLT_IMM18_BY4; 1292349cc55cSDimitry Andric 1293349cc55cSDimitry Andric MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier); 1294349cc55cSDimitry Andric 1295349cc55cSDimitry Andric if (!Sym) 1296349cc55cSDimitry Andric Sym = getContext().getOrCreateSymbol(Identifier); 1297349cc55cSDimitry Andric 1298349cc55cSDimitry Andric if (Sym->isVariable()) { 1299349cc55cSDimitry Andric const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1300349cc55cSDimitry Andric if (!isa<MCSymbolRefExpr>(V)) { 1301349cc55cSDimitry Andric getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1302349cc55cSDimitry Andric Error(getLoc(), "unknown symbol"); 1303349cc55cSDimitry Andric return MatchOperand_ParseFail; 1304349cc55cSDimitry Andric } 1305349cc55cSDimitry Andric Res = V; 1306349cc55cSDimitry Andric } else { 1307349cc55cSDimitry Andric Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1308349cc55cSDimitry Andric } 1309349cc55cSDimitry Andric 1310349cc55cSDimitry Andric MCBinaryExpr::Opcode Opcode; 1311349cc55cSDimitry Andric switch (getLexer().getKind()) { 1312349cc55cSDimitry Andric default: 1313349cc55cSDimitry Andric Error(getLoc(), "unknown symbol"); 1314349cc55cSDimitry Andric return MatchOperand_ParseFail; 1315349cc55cSDimitry Andric case AsmToken::RBrac: 1316349cc55cSDimitry Andric 1317349cc55cSDimitry Andric getLexer().Lex(); // Eat ']'. 1318349cc55cSDimitry Andric 1319349cc55cSDimitry Andric if (Kind != CSKYMCExpr::VK_CSKY_None) 1320349cc55cSDimitry Andric Res = CSKYMCExpr::create(Res, Kind, getContext()); 1321349cc55cSDimitry Andric 1322349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1323349cc55cSDimitry Andric return MatchOperand_Success; 1324349cc55cSDimitry Andric case AsmToken::Plus: 1325349cc55cSDimitry Andric Opcode = MCBinaryExpr::Add; 1326349cc55cSDimitry Andric break; 1327349cc55cSDimitry Andric case AsmToken::Minus: 1328349cc55cSDimitry Andric Opcode = MCBinaryExpr::Sub; 1329349cc55cSDimitry Andric break; 1330349cc55cSDimitry Andric } 1331349cc55cSDimitry Andric 1332349cc55cSDimitry Andric getLexer().Lex(); // eat + or - 1333349cc55cSDimitry Andric 1334349cc55cSDimitry Andric const MCExpr *Expr; 1335349cc55cSDimitry Andric if (getParser().parseExpression(Expr)) { 1336349cc55cSDimitry Andric Error(getLoc(), "unknown expression"); 1337349cc55cSDimitry Andric return MatchOperand_ParseFail; 1338349cc55cSDimitry Andric } 1339349cc55cSDimitry Andric 1340349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::RBrac) { 1341349cc55cSDimitry Andric Error(getLoc(), "expected ']'"); 1342349cc55cSDimitry Andric return MatchOperand_ParseFail; 1343349cc55cSDimitry Andric } 1344349cc55cSDimitry Andric 1345349cc55cSDimitry Andric getLexer().Lex(); // Eat ']'. 1346349cc55cSDimitry Andric 1347349cc55cSDimitry Andric Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1348349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1349349cc55cSDimitry Andric return MatchOperand_Success; 1350fe6060f1SDimitry Andric } 1351fe6060f1SDimitry Andric 1352fe6060f1SDimitry Andric OperandMatchResultTy 1353fe6060f1SDimitry Andric CSKYAsmParser::parseConstpoolSymbol(OperandVector &Operands) { 1354fe6060f1SDimitry Andric SMLoc S = getLoc(); 1355fe6060f1SDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1356349cc55cSDimitry Andric const MCExpr *Res; 1357fe6060f1SDimitry Andric 1358fe6060f1SDimitry Andric if (getLexer().getKind() != AsmToken::LBrac) 1359fe6060f1SDimitry Andric return MatchOperand_NoMatch; 1360fe6060f1SDimitry Andric 1361fe6060f1SDimitry Andric getLexer().Lex(); // Eat '['. 1362fe6060f1SDimitry Andric 1363349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::Identifier) { 1364349cc55cSDimitry Andric const MCExpr *Expr; 1365349cc55cSDimitry Andric if (getParser().parseExpression(Expr)) { 1366349cc55cSDimitry Andric Error(getLoc(), "unknown expression"); 1367fe6060f1SDimitry Andric return MatchOperand_ParseFail; 1368349cc55cSDimitry Andric } 1369fe6060f1SDimitry Andric 1370349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::RBrac) { 1371349cc55cSDimitry Andric Error(getLoc(), "expected ']'"); 1372349cc55cSDimitry Andric return MatchOperand_ParseFail; 1373349cc55cSDimitry Andric } 1374fe6060f1SDimitry Andric 1375fe6060f1SDimitry Andric getLexer().Lex(); // Eat ']'. 1376fe6060f1SDimitry Andric 1377349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E)); 1378349cc55cSDimitry Andric return MatchOperand_Success; 1379349cc55cSDimitry Andric } 1380349cc55cSDimitry Andric 1381349cc55cSDimitry Andric AsmToken Tok = getLexer().getTok(); 1382349cc55cSDimitry Andric StringRef Identifier; 1383349cc55cSDimitry Andric 1384349cc55cSDimitry Andric if (getParser().parseIdentifier(Identifier)) { 1385349cc55cSDimitry Andric Error(getLoc(), "unknown identifier"); 1386349cc55cSDimitry Andric return MatchOperand_ParseFail; 1387349cc55cSDimitry Andric } 1388349cc55cSDimitry Andric 1389349cc55cSDimitry Andric MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier); 1390349cc55cSDimitry Andric 1391349cc55cSDimitry Andric if (!Sym) 1392349cc55cSDimitry Andric Sym = getContext().getOrCreateSymbol(Identifier); 1393349cc55cSDimitry Andric 1394349cc55cSDimitry Andric if (Sym->isVariable()) { 1395349cc55cSDimitry Andric const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1396349cc55cSDimitry Andric if (!isa<MCSymbolRefExpr>(V)) { 1397349cc55cSDimitry Andric getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1398349cc55cSDimitry Andric Error(getLoc(), "unknown symbol"); 1399349cc55cSDimitry Andric return MatchOperand_ParseFail; 1400349cc55cSDimitry Andric } 1401349cc55cSDimitry Andric Res = V; 1402349cc55cSDimitry Andric } else { 1403349cc55cSDimitry Andric Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1404349cc55cSDimitry Andric } 1405349cc55cSDimitry Andric 1406349cc55cSDimitry Andric MCBinaryExpr::Opcode Opcode; 1407349cc55cSDimitry Andric switch (getLexer().getKind()) { 1408349cc55cSDimitry Andric default: 1409349cc55cSDimitry Andric Error(getLoc(), "unknown symbol"); 1410349cc55cSDimitry Andric return MatchOperand_ParseFail; 1411349cc55cSDimitry Andric case AsmToken::RBrac: 1412349cc55cSDimitry Andric 1413349cc55cSDimitry Andric getLexer().Lex(); // Eat ']'. 1414349cc55cSDimitry Andric 1415349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1416349cc55cSDimitry Andric return MatchOperand_Success; 1417349cc55cSDimitry Andric case AsmToken::Plus: 1418349cc55cSDimitry Andric Opcode = MCBinaryExpr::Add; 1419349cc55cSDimitry Andric break; 1420349cc55cSDimitry Andric case AsmToken::Minus: 1421349cc55cSDimitry Andric Opcode = MCBinaryExpr::Sub; 1422349cc55cSDimitry Andric break; 1423349cc55cSDimitry Andric } 1424349cc55cSDimitry Andric 1425349cc55cSDimitry Andric getLexer().Lex(); // eat + or - 1426349cc55cSDimitry Andric 1427349cc55cSDimitry Andric const MCExpr *Expr; 1428349cc55cSDimitry Andric if (getParser().parseExpression(Expr)) { 1429349cc55cSDimitry Andric Error(getLoc(), "unknown expression"); 1430349cc55cSDimitry Andric return MatchOperand_ParseFail; 1431349cc55cSDimitry Andric } 1432349cc55cSDimitry Andric 1433349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::RBrac) { 1434349cc55cSDimitry Andric Error(getLoc(), "expected ']'"); 1435349cc55cSDimitry Andric return MatchOperand_ParseFail; 1436349cc55cSDimitry Andric } 1437349cc55cSDimitry Andric 1438349cc55cSDimitry Andric getLexer().Lex(); // Eat ']'. 1439349cc55cSDimitry Andric 1440349cc55cSDimitry Andric Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1441349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1442349cc55cSDimitry Andric return MatchOperand_Success; 1443349cc55cSDimitry Andric } 1444349cc55cSDimitry Andric 1445349cc55cSDimitry Andric OperandMatchResultTy CSKYAsmParser::parsePSRFlag(OperandVector &Operands) { 1446349cc55cSDimitry Andric SMLoc S = getLoc(); 1447349cc55cSDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1448349cc55cSDimitry Andric 1449349cc55cSDimitry Andric unsigned Flag = 0; 1450349cc55cSDimitry Andric 1451349cc55cSDimitry Andric while (getLexer().isNot(AsmToken::EndOfStatement)) { 1452349cc55cSDimitry Andric StringRef Identifier; 1453349cc55cSDimitry Andric if (getParser().parseIdentifier(Identifier)) { 1454349cc55cSDimitry Andric Error(getLoc(), "unknown identifier " + Identifier); 1455349cc55cSDimitry Andric return MatchOperand_ParseFail; 1456349cc55cSDimitry Andric } 1457349cc55cSDimitry Andric 1458349cc55cSDimitry Andric if (Identifier == "sie") 1459349cc55cSDimitry Andric Flag = (1 << 4) | Flag; 1460349cc55cSDimitry Andric else if (Identifier == "ee") 1461349cc55cSDimitry Andric Flag = (1 << 3) | Flag; 1462349cc55cSDimitry Andric else if (Identifier == "ie") 1463349cc55cSDimitry Andric Flag = (1 << 2) | Flag; 1464349cc55cSDimitry Andric else if (Identifier == "fe") 1465349cc55cSDimitry Andric Flag = (1 << 1) | Flag; 1466349cc55cSDimitry Andric else if (Identifier == "af") 1467349cc55cSDimitry Andric Flag = (1 << 0) | Flag; 1468349cc55cSDimitry Andric else { 1469349cc55cSDimitry Andric Error(getLoc(), "expected " + Identifier); 1470349cc55cSDimitry Andric return MatchOperand_ParseFail; 1471349cc55cSDimitry Andric } 1472349cc55cSDimitry Andric 1473349cc55cSDimitry Andric if (getLexer().is(AsmToken::EndOfStatement)) 1474349cc55cSDimitry Andric break; 1475349cc55cSDimitry Andric 1476349cc55cSDimitry Andric if (getLexer().is(AsmToken::Comma)) { 1477349cc55cSDimitry Andric getLexer().Lex(); // eat ',' 1478349cc55cSDimitry Andric } else { 1479349cc55cSDimitry Andric Error(getLoc(), "expected ,"); 1480349cc55cSDimitry Andric return MatchOperand_ParseFail; 1481349cc55cSDimitry Andric } 1482349cc55cSDimitry Andric } 1483349cc55cSDimitry Andric 1484349cc55cSDimitry Andric Operands.push_back( 1485349cc55cSDimitry Andric CSKYOperand::createImm(MCConstantExpr::create(Flag, getContext()), S, E)); 1486349cc55cSDimitry Andric return MatchOperand_Success; 1487349cc55cSDimitry Andric } 1488349cc55cSDimitry Andric 1489349cc55cSDimitry Andric OperandMatchResultTy CSKYAsmParser::parseRegSeq(OperandVector &Operands) { 1490349cc55cSDimitry Andric SMLoc S = getLoc(); 1491349cc55cSDimitry Andric 1492349cc55cSDimitry Andric if (parseRegister(Operands) != MatchOperand_Success) 1493349cc55cSDimitry Andric return MatchOperand_NoMatch; 1494349cc55cSDimitry Andric 1495349cc55cSDimitry Andric auto Ry = Operands.back()->getReg(); 1496349cc55cSDimitry Andric Operands.pop_back(); 1497349cc55cSDimitry Andric 1498349cc55cSDimitry Andric if (getLexer().isNot(AsmToken::Minus)) { 1499349cc55cSDimitry Andric Error(getLoc(), "expected '-'"); 1500349cc55cSDimitry Andric return MatchOperand_ParseFail; 1501349cc55cSDimitry Andric } 1502349cc55cSDimitry Andric 1503349cc55cSDimitry Andric getLexer().Lex(); // eat '-' 1504349cc55cSDimitry Andric 1505349cc55cSDimitry Andric if (parseRegister(Operands) != MatchOperand_Success) { 1506349cc55cSDimitry Andric Error(getLoc(), "invalid register"); 1507349cc55cSDimitry Andric return MatchOperand_ParseFail; 1508349cc55cSDimitry Andric } 1509349cc55cSDimitry Andric 1510349cc55cSDimitry Andric auto Rz = Operands.back()->getReg(); 1511349cc55cSDimitry Andric Operands.pop_back(); 1512349cc55cSDimitry Andric 1513349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createRegSeq(Ry, Rz, S)); 1514349cc55cSDimitry Andric return MatchOperand_Success; 1515349cc55cSDimitry Andric } 1516349cc55cSDimitry Andric 1517349cc55cSDimitry Andric OperandMatchResultTy CSKYAsmParser::parseRegList(OperandVector &Operands) { 1518349cc55cSDimitry Andric SMLoc S = getLoc(); 1519349cc55cSDimitry Andric 1520349cc55cSDimitry Andric SmallVector<unsigned, 4> reglist; 1521349cc55cSDimitry Andric 1522349cc55cSDimitry Andric while (true) { 1523349cc55cSDimitry Andric 1524349cc55cSDimitry Andric if (parseRegister(Operands) != MatchOperand_Success) { 1525349cc55cSDimitry Andric Error(getLoc(), "invalid register"); 1526349cc55cSDimitry Andric return MatchOperand_ParseFail; 1527349cc55cSDimitry Andric } 1528349cc55cSDimitry Andric 1529349cc55cSDimitry Andric auto Ry = Operands.back()->getReg(); 1530349cc55cSDimitry Andric Operands.pop_back(); 1531349cc55cSDimitry Andric 1532349cc55cSDimitry Andric if (getLexer().is(AsmToken::Minus)) { 1533349cc55cSDimitry Andric getLexer().Lex(); // eat '-' 1534349cc55cSDimitry Andric 1535349cc55cSDimitry Andric if (parseRegister(Operands) != MatchOperand_Success) { 1536349cc55cSDimitry Andric Error(getLoc(), "invalid register"); 1537349cc55cSDimitry Andric return MatchOperand_ParseFail; 1538349cc55cSDimitry Andric } 1539349cc55cSDimitry Andric 1540349cc55cSDimitry Andric auto Rz = Operands.back()->getReg(); 1541349cc55cSDimitry Andric Operands.pop_back(); 1542349cc55cSDimitry Andric 1543349cc55cSDimitry Andric reglist.push_back(Ry); 1544349cc55cSDimitry Andric reglist.push_back(Rz); 1545349cc55cSDimitry Andric 1546349cc55cSDimitry Andric if (getLexer().is(AsmToken::Comma)) 1547349cc55cSDimitry Andric getLexer().Lex(); // eat ',' 1548349cc55cSDimitry Andric else if (getLexer().is(AsmToken::EndOfStatement)) 1549349cc55cSDimitry Andric break; 1550349cc55cSDimitry Andric 1551349cc55cSDimitry Andric } else if (getLexer().is(AsmToken::Comma)) { 1552349cc55cSDimitry Andric reglist.push_back(Ry); 1553349cc55cSDimitry Andric reglist.push_back(Ry); 1554349cc55cSDimitry Andric 1555349cc55cSDimitry Andric getLexer().Lex(); // eat ',' 1556349cc55cSDimitry Andric } else if (getLexer().is(AsmToken::EndOfStatement)) { 1557349cc55cSDimitry Andric reglist.push_back(Ry); 1558349cc55cSDimitry Andric reglist.push_back(Ry); 1559349cc55cSDimitry Andric break; 1560349cc55cSDimitry Andric } else { 1561349cc55cSDimitry Andric Error(getLoc(), "invalid register list"); 1562349cc55cSDimitry Andric return MatchOperand_ParseFail; 1563349cc55cSDimitry Andric } 1564349cc55cSDimitry Andric } 1565349cc55cSDimitry Andric 1566349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createRegList(reglist, S)); 1567fe6060f1SDimitry Andric return MatchOperand_Success; 1568fe6060f1SDimitry Andric } 1569fe6060f1SDimitry Andric 1570fe6060f1SDimitry Andric bool CSKYAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 1571fe6060f1SDimitry Andric SMLoc NameLoc, OperandVector &Operands) { 1572fe6060f1SDimitry Andric // First operand is token for instruction. 1573fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createToken(Name, NameLoc)); 1574fe6060f1SDimitry Andric 1575fe6060f1SDimitry Andric // If there are no more operands, then finish. 1576fe6060f1SDimitry Andric if (getLexer().is(AsmToken::EndOfStatement)) 1577fe6060f1SDimitry Andric return false; 1578fe6060f1SDimitry Andric 1579fe6060f1SDimitry Andric // Parse first operand. 1580fe6060f1SDimitry Andric if (parseOperand(Operands, Name)) 1581fe6060f1SDimitry Andric return true; 1582fe6060f1SDimitry Andric 1583fe6060f1SDimitry Andric // Parse until end of statement, consuming commas between operands. 1584fe6060f1SDimitry Andric while (getLexer().is(AsmToken::Comma)) { 1585fe6060f1SDimitry Andric // Consume comma token. 1586fe6060f1SDimitry Andric getLexer().Lex(); 1587fe6060f1SDimitry Andric 1588fe6060f1SDimitry Andric // Parse next operand. 1589fe6060f1SDimitry Andric if (parseOperand(Operands, Name)) 1590fe6060f1SDimitry Andric return true; 1591fe6060f1SDimitry Andric } 1592fe6060f1SDimitry Andric 1593fe6060f1SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) { 1594fe6060f1SDimitry Andric SMLoc Loc = getLexer().getLoc(); 1595fe6060f1SDimitry Andric getParser().eatToEndOfStatement(); 1596fe6060f1SDimitry Andric return Error(Loc, "unexpected token"); 1597fe6060f1SDimitry Andric } 1598fe6060f1SDimitry Andric 1599fe6060f1SDimitry Andric getParser().Lex(); // Consume the EndOfStatement. 1600fe6060f1SDimitry Andric return false; 1601fe6060f1SDimitry Andric } 1602fe6060f1SDimitry Andric 1603*bdd1243dSDimitry Andric OperandMatchResultTy CSKYAsmParser::tryParseRegister(MCRegister &RegNo, 1604fe6060f1SDimitry Andric SMLoc &StartLoc, 1605fe6060f1SDimitry Andric SMLoc &EndLoc) { 1606fe6060f1SDimitry Andric const AsmToken &Tok = getParser().getTok(); 1607fe6060f1SDimitry Andric StartLoc = Tok.getLoc(); 1608fe6060f1SDimitry Andric EndLoc = Tok.getEndLoc(); 1609fe6060f1SDimitry Andric 1610fe6060f1SDimitry Andric StringRef Name = getLexer().getTok().getIdentifier(); 1611fe6060f1SDimitry Andric 1612349cc55cSDimitry Andric if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) 1613fe6060f1SDimitry Andric return MatchOperand_NoMatch; 1614fe6060f1SDimitry Andric 1615fe6060f1SDimitry Andric getParser().Lex(); // Eat identifier token. 1616fe6060f1SDimitry Andric return MatchOperand_Success; 1617fe6060f1SDimitry Andric } 1618fe6060f1SDimitry Andric 161981ad6265SDimitry Andric bool CSKYAsmParser::ParseDirective(AsmToken DirectiveID) { 162081ad6265SDimitry Andric // This returns false if this function recognizes the directive 162181ad6265SDimitry Andric // regardless of whether it is successfully handles or reports an 162281ad6265SDimitry Andric // error. Otherwise it returns true to give the generic parser a 162381ad6265SDimitry Andric // chance at recognizing it. 162481ad6265SDimitry Andric StringRef IDVal = DirectiveID.getString(); 162581ad6265SDimitry Andric 162681ad6265SDimitry Andric if (IDVal == ".csky_attribute") 162781ad6265SDimitry Andric return parseDirectiveAttribute(); 162881ad6265SDimitry Andric 162981ad6265SDimitry Andric return true; 163081ad6265SDimitry Andric } 163181ad6265SDimitry Andric 163281ad6265SDimitry Andric /// parseDirectiveAttribute 163381ad6265SDimitry Andric /// ::= .attribute expression ',' ( expression | "string" ) 163481ad6265SDimitry Andric bool CSKYAsmParser::parseDirectiveAttribute() { 163581ad6265SDimitry Andric MCAsmParser &Parser = getParser(); 163681ad6265SDimitry Andric int64_t Tag; 163781ad6265SDimitry Andric SMLoc TagLoc; 163881ad6265SDimitry Andric TagLoc = Parser.getTok().getLoc(); 163981ad6265SDimitry Andric if (Parser.getTok().is(AsmToken::Identifier)) { 164081ad6265SDimitry Andric StringRef Name = Parser.getTok().getIdentifier(); 1641*bdd1243dSDimitry Andric std::optional<unsigned> Ret = 164281ad6265SDimitry Andric ELFAttrs::attrTypeFromString(Name, CSKYAttrs::getCSKYAttributeTags()); 1643*bdd1243dSDimitry Andric if (!Ret) { 164481ad6265SDimitry Andric Error(TagLoc, "attribute name not recognised: " + Name); 164581ad6265SDimitry Andric return false; 164681ad6265SDimitry Andric } 1647*bdd1243dSDimitry Andric Tag = *Ret; 164881ad6265SDimitry Andric Parser.Lex(); 164981ad6265SDimitry Andric } else { 165081ad6265SDimitry Andric const MCExpr *AttrExpr; 165181ad6265SDimitry Andric 165281ad6265SDimitry Andric TagLoc = Parser.getTok().getLoc(); 165381ad6265SDimitry Andric if (Parser.parseExpression(AttrExpr)) 165481ad6265SDimitry Andric return true; 165581ad6265SDimitry Andric 165681ad6265SDimitry Andric const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr); 165781ad6265SDimitry Andric if (check(!CE, TagLoc, "expected numeric constant")) 165881ad6265SDimitry Andric return true; 165981ad6265SDimitry Andric 166081ad6265SDimitry Andric Tag = CE->getValue(); 166181ad6265SDimitry Andric } 166281ad6265SDimitry Andric 166381ad6265SDimitry Andric if (Parser.parseToken(AsmToken::Comma, "comma expected")) 166481ad6265SDimitry Andric return true; 166581ad6265SDimitry Andric 166681ad6265SDimitry Andric StringRef StringValue; 166781ad6265SDimitry Andric int64_t IntegerValue = 0; 166881ad6265SDimitry Andric bool IsIntegerValue = ((Tag != CSKYAttrs::CSKY_ARCH_NAME) && 166981ad6265SDimitry Andric (Tag != CSKYAttrs::CSKY_CPU_NAME) && 167081ad6265SDimitry Andric (Tag != CSKYAttrs::CSKY_FPU_NUMBER_MODULE)); 167181ad6265SDimitry Andric 167281ad6265SDimitry Andric SMLoc ValueExprLoc = Parser.getTok().getLoc(); 167381ad6265SDimitry Andric if (IsIntegerValue) { 167481ad6265SDimitry Andric const MCExpr *ValueExpr; 167581ad6265SDimitry Andric if (Parser.parseExpression(ValueExpr)) 167681ad6265SDimitry Andric return true; 167781ad6265SDimitry Andric 167881ad6265SDimitry Andric const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr); 167981ad6265SDimitry Andric if (!CE) 168081ad6265SDimitry Andric return Error(ValueExprLoc, "expected numeric constant"); 168181ad6265SDimitry Andric IntegerValue = CE->getValue(); 168281ad6265SDimitry Andric } else { 168381ad6265SDimitry Andric if (Parser.getTok().isNot(AsmToken::String)) 168481ad6265SDimitry Andric return Error(Parser.getTok().getLoc(), "expected string constant"); 168581ad6265SDimitry Andric 168681ad6265SDimitry Andric StringValue = Parser.getTok().getStringContents(); 168781ad6265SDimitry Andric Parser.Lex(); 168881ad6265SDimitry Andric } 168981ad6265SDimitry Andric 169081ad6265SDimitry Andric if (Parser.parseEOL()) 169181ad6265SDimitry Andric return true; 169281ad6265SDimitry Andric 169381ad6265SDimitry Andric if (IsIntegerValue) 169481ad6265SDimitry Andric getTargetStreamer().emitAttribute(Tag, IntegerValue); 169581ad6265SDimitry Andric else if (Tag != CSKYAttrs::CSKY_ARCH_NAME && Tag != CSKYAttrs::CSKY_CPU_NAME) 169681ad6265SDimitry Andric getTargetStreamer().emitTextAttribute(Tag, StringValue); 169781ad6265SDimitry Andric else { 169881ad6265SDimitry Andric CSKY::ArchKind ID = (Tag == CSKYAttrs::CSKY_ARCH_NAME) 169981ad6265SDimitry Andric ? CSKY::parseArch(StringValue) 170081ad6265SDimitry Andric : CSKY::parseCPUArch(StringValue); 170181ad6265SDimitry Andric if (ID == CSKY::ArchKind::INVALID) 170281ad6265SDimitry Andric return Error(ValueExprLoc, (Tag == CSKYAttrs::CSKY_ARCH_NAME) 170381ad6265SDimitry Andric ? "unknown arch name" 170481ad6265SDimitry Andric : "unknown cpu name"); 170581ad6265SDimitry Andric 170681ad6265SDimitry Andric getTargetStreamer().emitTextAttribute(Tag, StringValue); 170781ad6265SDimitry Andric } 170881ad6265SDimitry Andric 170981ad6265SDimitry Andric return false; 171081ad6265SDimitry Andric } 171181ad6265SDimitry Andric 171281ad6265SDimitry Andric unsigned CSKYAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, 171381ad6265SDimitry Andric unsigned Kind) { 171481ad6265SDimitry Andric CSKYOperand &Op = static_cast<CSKYOperand &>(AsmOp); 171581ad6265SDimitry Andric 171681ad6265SDimitry Andric if (!Op.isReg()) 171781ad6265SDimitry Andric return Match_InvalidOperand; 171881ad6265SDimitry Andric 171981ad6265SDimitry Andric MCRegister Reg = Op.getReg(); 172081ad6265SDimitry Andric 172181ad6265SDimitry Andric if (CSKYMCRegisterClasses[CSKY::FPR32RegClassID].contains(Reg)) { 172281ad6265SDimitry Andric // As the parser couldn't differentiate an FPR64 from an FPR32, coerce the 172381ad6265SDimitry Andric // register from FPR32 to FPR64 if necessary. 172481ad6265SDimitry Andric if (Kind == MCK_FPR64 || Kind == MCK_sFPR64) { 172581ad6265SDimitry Andric Op.Reg.RegNum = convertFPR32ToFPR64(Reg); 172681ad6265SDimitry Andric if (Kind == MCK_sFPR64 && 172781ad6265SDimitry Andric (Op.Reg.RegNum < CSKY::F0_64 || Op.Reg.RegNum > CSKY::F15_64)) 172881ad6265SDimitry Andric return Match_InvalidRegOutOfRange; 172981ad6265SDimitry Andric if (Kind == MCK_FPR64 && 173081ad6265SDimitry Andric (Op.Reg.RegNum < CSKY::F0_64 || Op.Reg.RegNum > CSKY::F31_64)) 173181ad6265SDimitry Andric return Match_InvalidRegOutOfRange; 173281ad6265SDimitry Andric return Match_Success; 173381ad6265SDimitry Andric } 173481ad6265SDimitry Andric } 173581ad6265SDimitry Andric 173681ad6265SDimitry Andric if (CSKYMCRegisterClasses[CSKY::GPRRegClassID].contains(Reg)) { 173781ad6265SDimitry Andric if (Kind == MCK_GPRPair) { 173881ad6265SDimitry Andric Op.Reg.RegNum = MRI->getEncodingValue(Reg) + CSKY::R0_R1; 173981ad6265SDimitry Andric return Match_Success; 174081ad6265SDimitry Andric } 174181ad6265SDimitry Andric } 174281ad6265SDimitry Andric 174381ad6265SDimitry Andric return Match_InvalidOperand; 174481ad6265SDimitry Andric } 1745fe6060f1SDimitry Andric 17460eae32dcSDimitry Andric void CSKYAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) { 17470eae32dcSDimitry Andric MCInst CInst; 17480eae32dcSDimitry Andric bool Res = false; 17490eae32dcSDimitry Andric if (EnableCompressedInst) 1750*bdd1243dSDimitry Andric Res = compressInst(CInst, Inst, getSTI()); 17510eae32dcSDimitry Andric if (Res) 17520eae32dcSDimitry Andric ++CSKYNumInstrsCompressed; 17530eae32dcSDimitry Andric S.emitInstruction((Res ? CInst : Inst), getSTI()); 17540eae32dcSDimitry Andric } 17550eae32dcSDimitry Andric 1756fe6060f1SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYAsmParser() { 1757fe6060f1SDimitry Andric RegisterMCAsmParser<CSKYAsmParser> X(getTheCSKYTarget()); 1758fe6060f1SDimitry Andric } 1759