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" 12fe6060f1SDimitry Andric #include "TargetInfo/CSKYTargetInfo.h" 13fe6060f1SDimitry Andric #include "llvm/ADT/STLExtras.h" 140eae32dcSDimitry Andric #include "llvm/ADT/Statistic.h" 15fe6060f1SDimitry Andric #include "llvm/ADT/StringSwitch.h" 16fe6060f1SDimitry Andric #include "llvm/CodeGen/Register.h" 17fe6060f1SDimitry Andric #include "llvm/MC/MCContext.h" 18fe6060f1SDimitry Andric #include "llvm/MC/MCExpr.h" 19fe6060f1SDimitry Andric #include "llvm/MC/MCInst.h" 20fe6060f1SDimitry Andric #include "llvm/MC/MCParser/MCAsmLexer.h" 21fe6060f1SDimitry Andric #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 22fe6060f1SDimitry Andric #include "llvm/MC/MCParser/MCTargetAsmParser.h" 23fe6060f1SDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 24349cc55cSDimitry Andric #include "llvm/MC/MCSectionELF.h" 25fe6060f1SDimitry Andric #include "llvm/MC/MCStreamer.h" 26fe6060f1SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 27349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h" 28fe6060f1SDimitry Andric #include "llvm/Support/Casting.h" 290eae32dcSDimitry Andric #include "llvm/Support/CommandLine.h" 30349cc55cSDimitry Andric #include "llvm/Support/Debug.h" 31349cc55cSDimitry Andric 320eae32dcSDimitry Andric using namespace llvm; 330eae32dcSDimitry Andric 34349cc55cSDimitry Andric #define DEBUG_TYPE "csky-asm-parser" 35fe6060f1SDimitry Andric 360eae32dcSDimitry Andric // Include the auto-generated portion of the compress emitter. 370eae32dcSDimitry Andric #define GEN_COMPRESS_INSTR 380eae32dcSDimitry Andric #include "CSKYGenCompressInstEmitter.inc" 390eae32dcSDimitry Andric 400eae32dcSDimitry Andric STATISTIC(CSKYNumInstrsCompressed, 410eae32dcSDimitry Andric "Number of C-SKY Compressed instructions emitted"); 420eae32dcSDimitry Andric 430eae32dcSDimitry Andric static cl::opt<bool> 440eae32dcSDimitry Andric EnableCompressedInst("enable-csky-asm-compressed-inst", cl::Hidden, 450eae32dcSDimitry Andric cl::init(false), 460eae32dcSDimitry Andric cl::desc("Enable C-SKY asm compressed instruction")); 47fe6060f1SDimitry Andric 48fe6060f1SDimitry Andric namespace { 49fe6060f1SDimitry Andric struct CSKYOperand; 50fe6060f1SDimitry Andric 51fe6060f1SDimitry Andric class CSKYAsmParser : public MCTargetAsmParser { 52fe6060f1SDimitry Andric 53349cc55cSDimitry Andric const MCRegisterInfo *MRI; 54349cc55cSDimitry Andric 55fe6060f1SDimitry Andric bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo, 56fe6060f1SDimitry Andric int64_t Lower, int64_t Upper, Twine Msg); 57fe6060f1SDimitry Andric 58fe6060f1SDimitry Andric SMLoc getLoc() const { return getParser().getTok().getLoc(); } 59fe6060f1SDimitry Andric 60fe6060f1SDimitry Andric bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 61fe6060f1SDimitry Andric OperandVector &Operands, MCStreamer &Out, 62fe6060f1SDimitry Andric uint64_t &ErrorInfo, 63fe6060f1SDimitry Andric bool MatchingInlineAsm) override; 64fe6060f1SDimitry Andric 65fe6060f1SDimitry Andric bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 66fe6060f1SDimitry Andric 67fe6060f1SDimitry Andric bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 68fe6060f1SDimitry Andric SMLoc NameLoc, OperandVector &Operands) override; 69fe6060f1SDimitry Andric 70fe6060f1SDimitry Andric bool ParseDirective(AsmToken DirectiveID) override; 71fe6060f1SDimitry Andric 720eae32dcSDimitry Andric // Helper to actually emit an instruction to the MCStreamer. Also, when 730eae32dcSDimitry Andric // possible, compression of the instruction is performed. 740eae32dcSDimitry Andric void emitToStreamer(MCStreamer &S, const MCInst &Inst); 750eae32dcSDimitry Andric 76fe6060f1SDimitry Andric OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc, 77fe6060f1SDimitry Andric SMLoc &EndLoc) override; 78fe6060f1SDimitry Andric 79349cc55cSDimitry Andric bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands, 80349cc55cSDimitry Andric MCStreamer &Out); 81349cc55cSDimitry Andric 82fe6060f1SDimitry Andric // Auto-generated instruction matching functions 83fe6060f1SDimitry Andric #define GET_ASSEMBLER_HEADER 84fe6060f1SDimitry Andric #include "CSKYGenAsmMatcher.inc" 85fe6060f1SDimitry Andric 86fe6060f1SDimitry Andric OperandMatchResultTy parseImmediate(OperandVector &Operands); 87fe6060f1SDimitry Andric OperandMatchResultTy parseRegister(OperandVector &Operands); 88fe6060f1SDimitry Andric OperandMatchResultTy parseBaseRegImm(OperandVector &Operands); 89fe6060f1SDimitry Andric OperandMatchResultTy parseCSKYSymbol(OperandVector &Operands); 90fe6060f1SDimitry Andric OperandMatchResultTy parseConstpoolSymbol(OperandVector &Operands); 91349cc55cSDimitry Andric OperandMatchResultTy parseDataSymbol(OperandVector &Operands); 92349cc55cSDimitry Andric OperandMatchResultTy parsePSRFlag(OperandVector &Operands); 93349cc55cSDimitry Andric OperandMatchResultTy parseRegSeq(OperandVector &Operands); 94349cc55cSDimitry Andric OperandMatchResultTy parseRegList(OperandVector &Operands); 95fe6060f1SDimitry Andric 96fe6060f1SDimitry Andric bool parseOperand(OperandVector &Operands, StringRef Mnemonic); 97fe6060f1SDimitry Andric 98fe6060f1SDimitry Andric public: 99fe6060f1SDimitry Andric enum CSKYMatchResultTy { 100fe6060f1SDimitry Andric Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY, 101349cc55cSDimitry Andric Match_RequiresSameSrcAndDst, 102349cc55cSDimitry Andric Match_InvalidRegOutOfRange, 103fe6060f1SDimitry Andric #define GET_OPERAND_DIAGNOSTIC_TYPES 104fe6060f1SDimitry Andric #include "CSKYGenAsmMatcher.inc" 105fe6060f1SDimitry Andric #undef GET_OPERAND_DIAGNOSTIC_TYPES 106fe6060f1SDimitry Andric }; 107fe6060f1SDimitry Andric 108fe6060f1SDimitry Andric CSKYAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, 109fe6060f1SDimitry Andric const MCInstrInfo &MII, const MCTargetOptions &Options) 110fe6060f1SDimitry Andric : MCTargetAsmParser(Options, STI, MII) { 111fe6060f1SDimitry Andric setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 112fe6060f1SDimitry Andric } 113fe6060f1SDimitry Andric }; 114fe6060f1SDimitry Andric 115fe6060f1SDimitry Andric /// Instances of this class represent a parsed machine instruction. 116fe6060f1SDimitry Andric struct CSKYOperand : public MCParsedAsmOperand { 117349cc55cSDimitry Andric 118fe6060f1SDimitry Andric enum KindTy { 119fe6060f1SDimitry Andric Token, 120fe6060f1SDimitry Andric Register, 121fe6060f1SDimitry Andric Immediate, 122349cc55cSDimitry Andric RegisterSeq, 123349cc55cSDimitry Andric CPOP, 124349cc55cSDimitry Andric RegisterList 125fe6060f1SDimitry Andric } Kind; 126fe6060f1SDimitry Andric 127fe6060f1SDimitry Andric struct RegOp { 128fe6060f1SDimitry Andric unsigned RegNum; 129fe6060f1SDimitry Andric }; 130fe6060f1SDimitry Andric 131fe6060f1SDimitry Andric struct ImmOp { 132fe6060f1SDimitry Andric const MCExpr *Val; 133fe6060f1SDimitry Andric }; 134fe6060f1SDimitry Andric 135349cc55cSDimitry Andric struct ConstpoolOp { 136349cc55cSDimitry Andric const MCExpr *Val; 137349cc55cSDimitry Andric }; 138349cc55cSDimitry Andric 139349cc55cSDimitry Andric struct RegSeqOp { 140349cc55cSDimitry Andric unsigned RegNumFrom; 141349cc55cSDimitry Andric unsigned RegNumTo; 142349cc55cSDimitry Andric }; 143349cc55cSDimitry Andric 144349cc55cSDimitry Andric struct RegListOp { 145349cc55cSDimitry Andric unsigned List1From = 0; 146349cc55cSDimitry Andric unsigned List1To = 0; 147349cc55cSDimitry Andric unsigned List2From = 0; 148349cc55cSDimitry Andric unsigned List2To = 0; 149349cc55cSDimitry Andric unsigned List3From = 0; 150349cc55cSDimitry Andric unsigned List3To = 0; 151349cc55cSDimitry Andric unsigned List4From = 0; 152349cc55cSDimitry Andric unsigned List4To = 0; 153349cc55cSDimitry Andric }; 154349cc55cSDimitry Andric 155fe6060f1SDimitry Andric SMLoc StartLoc, EndLoc; 156fe6060f1SDimitry Andric union { 157fe6060f1SDimitry Andric StringRef Tok; 158fe6060f1SDimitry Andric RegOp Reg; 159fe6060f1SDimitry Andric ImmOp Imm; 160349cc55cSDimitry Andric ConstpoolOp CPool; 161349cc55cSDimitry Andric RegSeqOp RegSeq; 162349cc55cSDimitry Andric RegListOp RegList; 163fe6060f1SDimitry Andric }; 164fe6060f1SDimitry Andric 165fe6060f1SDimitry Andric CSKYOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 166fe6060f1SDimitry Andric 167fe6060f1SDimitry Andric public: 168fe6060f1SDimitry Andric CSKYOperand(const CSKYOperand &o) : MCParsedAsmOperand() { 169fe6060f1SDimitry Andric Kind = o.Kind; 170fe6060f1SDimitry Andric StartLoc = o.StartLoc; 171fe6060f1SDimitry Andric EndLoc = o.EndLoc; 172fe6060f1SDimitry Andric switch (Kind) { 173fe6060f1SDimitry Andric case Register: 174fe6060f1SDimitry Andric Reg = o.Reg; 175fe6060f1SDimitry Andric break; 176349cc55cSDimitry Andric case RegisterSeq: 177349cc55cSDimitry Andric RegSeq = o.RegSeq; 178349cc55cSDimitry Andric break; 179349cc55cSDimitry Andric case CPOP: 180349cc55cSDimitry Andric CPool = o.CPool; 181349cc55cSDimitry Andric break; 182fe6060f1SDimitry Andric case Immediate: 183fe6060f1SDimitry Andric Imm = o.Imm; 184fe6060f1SDimitry Andric break; 185fe6060f1SDimitry Andric case Token: 186fe6060f1SDimitry Andric Tok = o.Tok; 187fe6060f1SDimitry Andric break; 188349cc55cSDimitry Andric case RegisterList: 189349cc55cSDimitry Andric RegList = o.RegList; 190349cc55cSDimitry Andric break; 191fe6060f1SDimitry Andric } 192fe6060f1SDimitry Andric } 193fe6060f1SDimitry Andric 194fe6060f1SDimitry Andric bool isToken() const override { return Kind == Token; } 195fe6060f1SDimitry Andric bool isReg() const override { return Kind == Register; } 196fe6060f1SDimitry Andric bool isImm() const override { return Kind == Immediate; } 197349cc55cSDimitry Andric bool isRegisterSeq() const { return Kind == RegisterSeq; } 198349cc55cSDimitry Andric bool isRegisterList() const { return Kind == RegisterList; } 199349cc55cSDimitry Andric bool isConstPoolOp() const { return Kind == CPOP; } 200349cc55cSDimitry Andric 201fe6060f1SDimitry Andric bool isMem() const override { return false; } 202fe6060f1SDimitry Andric 203fe6060f1SDimitry Andric static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm) { 204fe6060f1SDimitry Andric if (auto CE = dyn_cast<MCConstantExpr>(Expr)) { 205fe6060f1SDimitry Andric Imm = CE->getValue(); 206fe6060f1SDimitry Andric return true; 207fe6060f1SDimitry Andric } 208fe6060f1SDimitry Andric 209fe6060f1SDimitry Andric return false; 210fe6060f1SDimitry Andric } 211fe6060f1SDimitry Andric 212fe6060f1SDimitry Andric template <unsigned num, unsigned shift = 0> bool isUImm() const { 213fe6060f1SDimitry Andric if (!isImm()) 214fe6060f1SDimitry Andric return false; 215fe6060f1SDimitry Andric 216fe6060f1SDimitry Andric int64_t Imm; 217fe6060f1SDimitry Andric bool IsConstantImm = evaluateConstantImm(getImm(), Imm); 218fe6060f1SDimitry Andric return IsConstantImm && isShiftedUInt<num, shift>(Imm); 219fe6060f1SDimitry Andric } 220fe6060f1SDimitry Andric 221fe6060f1SDimitry Andric template <unsigned num> bool isOImm() const { 222fe6060f1SDimitry Andric if (!isImm()) 223fe6060f1SDimitry Andric return false; 224fe6060f1SDimitry Andric 225fe6060f1SDimitry Andric int64_t Imm; 226fe6060f1SDimitry Andric bool IsConstantImm = evaluateConstantImm(getImm(), Imm); 227fe6060f1SDimitry Andric return IsConstantImm && isUInt<num>(Imm - 1); 228fe6060f1SDimitry Andric } 229fe6060f1SDimitry Andric 230fe6060f1SDimitry Andric template <unsigned num, unsigned shift = 0> bool isSImm() const { 231fe6060f1SDimitry Andric if (!isImm()) 232fe6060f1SDimitry Andric return false; 233fe6060f1SDimitry Andric 234fe6060f1SDimitry Andric int64_t Imm; 235fe6060f1SDimitry Andric bool IsConstantImm = evaluateConstantImm(getImm(), Imm); 236fe6060f1SDimitry Andric return IsConstantImm && isShiftedInt<num, shift>(Imm); 237fe6060f1SDimitry Andric } 238fe6060f1SDimitry Andric 239349cc55cSDimitry Andric bool isUImm1() const { return isUImm<1>(); } 240fe6060f1SDimitry Andric bool isUImm2() const { return isUImm<2>(); } 241349cc55cSDimitry Andric bool isUImm3() const { return isUImm<3>(); } 242349cc55cSDimitry Andric bool isUImm4() const { return isUImm<4>(); } 243fe6060f1SDimitry Andric bool isUImm5() const { return isUImm<5>(); } 244349cc55cSDimitry Andric bool isUImm6() const { return isUImm<6>(); } 245349cc55cSDimitry Andric bool isUImm7() const { return isUImm<7>(); } 246349cc55cSDimitry Andric bool isUImm8() const { return isUImm<8>(); } 247fe6060f1SDimitry Andric bool isUImm12() const { return isUImm<12>(); } 248fe6060f1SDimitry Andric bool isUImm16() const { return isUImm<16>(); } 249349cc55cSDimitry Andric bool isUImm20() const { return isUImm<20>(); } 250349cc55cSDimitry Andric bool isUImm24() const { return isUImm<24>(); } 251fe6060f1SDimitry Andric 252349cc55cSDimitry Andric bool isOImm3() const { return isOImm<3>(); } 253349cc55cSDimitry Andric bool isOImm4() const { return isOImm<4>(); } 254349cc55cSDimitry Andric bool isOImm5() const { return isOImm<5>(); } 255349cc55cSDimitry Andric bool isOImm6() const { return isOImm<6>(); } 256349cc55cSDimitry Andric bool isOImm8() const { return isOImm<8>(); } 257fe6060f1SDimitry Andric bool isOImm12() const { return isOImm<12>(); } 258fe6060f1SDimitry Andric bool isOImm16() const { return isOImm<16>(); } 259fe6060f1SDimitry Andric 260349cc55cSDimitry Andric bool isSImm8() const { return isSImm<8>(); } 261349cc55cSDimitry Andric 262349cc55cSDimitry Andric bool isUImm5Shift1() { return isUImm<5, 1>(); } 263349cc55cSDimitry Andric bool isUImm5Shift2() { return isUImm<5, 2>(); } 264349cc55cSDimitry Andric bool isUImm7Shift1() { return isUImm<7, 1>(); } 265349cc55cSDimitry Andric bool isUImm7Shift2() { return isUImm<7, 2>(); } 266349cc55cSDimitry Andric bool isUImm7Shift3() { return isUImm<7, 3>(); } 267349cc55cSDimitry Andric bool isUImm8Shift2() { return isUImm<8, 2>(); } 268349cc55cSDimitry Andric bool isUImm8Shift3() { return isUImm<8, 3>(); } 269349cc55cSDimitry Andric bool isUImm8Shift8() { return isUImm<8, 8>(); } 270349cc55cSDimitry Andric bool isUImm8Shift16() { return isUImm<8, 16>(); } 271349cc55cSDimitry Andric bool isUImm8Shift24() { return isUImm<8, 24>(); } 272fe6060f1SDimitry Andric bool isUImm12Shift1() { return isUImm<12, 1>(); } 273fe6060f1SDimitry Andric bool isUImm12Shift2() { return isUImm<12, 2>(); } 274349cc55cSDimitry Andric bool isUImm16Shift8() { return isUImm<16, 8>(); } 275349cc55cSDimitry Andric bool isUImm16Shift16() { return isUImm<16, 16>(); } 276349cc55cSDimitry Andric bool isUImm24Shift8() { return isUImm<24, 8>(); } 277fe6060f1SDimitry Andric 278fe6060f1SDimitry Andric bool isSImm16Shift1() { return isSImm<16, 1>(); } 279fe6060f1SDimitry Andric 280349cc55cSDimitry Andric bool isCSKYSymbol() const { return isImm(); } 281349cc55cSDimitry Andric 282349cc55cSDimitry Andric bool isConstpool() const { return isConstPoolOp(); } 283349cc55cSDimitry Andric bool isDataSymbol() const { return isConstPoolOp(); } 284349cc55cSDimitry Andric 285349cc55cSDimitry Andric bool isPSRFlag() const { 286fe6060f1SDimitry Andric int64_t Imm; 287349cc55cSDimitry Andric // Must be of 'immediate' type and a constant. 288349cc55cSDimitry Andric if (!isImm() || !evaluateConstantImm(getImm(), Imm)) 289349cc55cSDimitry Andric return false; 290349cc55cSDimitry Andric 291349cc55cSDimitry Andric return isUInt<5>(Imm); 292349cc55cSDimitry Andric } 293349cc55cSDimitry Andric 294349cc55cSDimitry Andric template <unsigned MIN, unsigned MAX> bool isRegSeqTemplate() const { 295349cc55cSDimitry Andric if (!isRegisterSeq()) 296349cc55cSDimitry Andric return false; 297349cc55cSDimitry Andric 298349cc55cSDimitry Andric std::pair<unsigned, unsigned> regSeq = getRegSeq(); 299349cc55cSDimitry Andric 300349cc55cSDimitry Andric return MIN <= regSeq.first && regSeq.first <= regSeq.second && 301349cc55cSDimitry Andric regSeq.second <= MAX; 302349cc55cSDimitry Andric } 303349cc55cSDimitry Andric 304349cc55cSDimitry Andric bool isRegSeq() const { return isRegSeqTemplate<CSKY::R0, CSKY::R31>(); } 305349cc55cSDimitry Andric 306*04eeddc0SDimitry Andric bool isRegSeqV1() const { 307*04eeddc0SDimitry Andric return isRegSeqTemplate<CSKY::F0_32, CSKY::F15_32>(); 308*04eeddc0SDimitry Andric } 309*04eeddc0SDimitry Andric 310*04eeddc0SDimitry Andric bool isRegSeqV2() const { 311*04eeddc0SDimitry Andric return isRegSeqTemplate<CSKY::F0_32, CSKY::F31_32>(); 312*04eeddc0SDimitry Andric } 313*04eeddc0SDimitry Andric 314349cc55cSDimitry Andric static bool isLegalRegList(unsigned from, unsigned to) { 315349cc55cSDimitry Andric if (from == 0 && to == 0) 316349cc55cSDimitry Andric return true; 317349cc55cSDimitry Andric 318349cc55cSDimitry Andric if (from == to) { 319349cc55cSDimitry Andric if (from != CSKY::R4 && from != CSKY::R15 && from != CSKY::R16 && 320349cc55cSDimitry Andric from != CSKY::R28) 321349cc55cSDimitry Andric return false; 322349cc55cSDimitry Andric 323349cc55cSDimitry Andric return true; 324349cc55cSDimitry Andric } else { 325349cc55cSDimitry Andric if (from != CSKY::R4 && from != CSKY::R16) 326349cc55cSDimitry Andric return false; 327349cc55cSDimitry Andric 328349cc55cSDimitry Andric if (from == CSKY::R4 && to > CSKY::R4 && to < CSKY::R12) 329349cc55cSDimitry Andric return true; 330349cc55cSDimitry Andric else if (from == CSKY::R16 && to > CSKY::R16 && to < CSKY::R18) 331349cc55cSDimitry Andric return true; 332349cc55cSDimitry Andric else 333349cc55cSDimitry Andric return false; 334349cc55cSDimitry Andric } 335349cc55cSDimitry Andric } 336349cc55cSDimitry Andric 337349cc55cSDimitry Andric bool isRegList() const { 338349cc55cSDimitry Andric if (!isRegisterList()) 339349cc55cSDimitry Andric return false; 340349cc55cSDimitry Andric 341349cc55cSDimitry Andric auto regList = getRegList(); 342349cc55cSDimitry Andric 343349cc55cSDimitry Andric if (!isLegalRegList(regList.List1From, regList.List1To)) 344349cc55cSDimitry Andric return false; 345349cc55cSDimitry Andric if (!isLegalRegList(regList.List2From, regList.List2To)) 346349cc55cSDimitry Andric return false; 347349cc55cSDimitry Andric if (!isLegalRegList(regList.List3From, regList.List3To)) 348349cc55cSDimitry Andric return false; 349349cc55cSDimitry Andric if (!isLegalRegList(regList.List4From, regList.List4To)) 350349cc55cSDimitry Andric return false; 351349cc55cSDimitry Andric 352349cc55cSDimitry Andric return true; 353349cc55cSDimitry Andric } 354349cc55cSDimitry Andric 355349cc55cSDimitry Andric bool isExtImm6() { 356349cc55cSDimitry Andric if (!isImm()) 357349cc55cSDimitry Andric return false; 358349cc55cSDimitry Andric 359349cc55cSDimitry Andric int64_t Imm; 360349cc55cSDimitry Andric bool IsConstantImm = evaluateConstantImm(getImm(), Imm); 361349cc55cSDimitry Andric if (!IsConstantImm) 362349cc55cSDimitry Andric return false; 363349cc55cSDimitry Andric 364349cc55cSDimitry Andric int uimm4 = Imm & 0xf; 365349cc55cSDimitry Andric 366349cc55cSDimitry Andric return isShiftedUInt<6, 0>(Imm) && uimm4 >= 0 && uimm4 <= 14; 367fe6060f1SDimitry Andric } 368fe6060f1SDimitry Andric 369fe6060f1SDimitry Andric /// Gets location of the first token of this operand. 370fe6060f1SDimitry Andric SMLoc getStartLoc() const override { return StartLoc; } 371fe6060f1SDimitry Andric /// Gets location of the last token of this operand. 372fe6060f1SDimitry Andric SMLoc getEndLoc() const override { return EndLoc; } 373fe6060f1SDimitry Andric 374fe6060f1SDimitry Andric unsigned getReg() const override { 375fe6060f1SDimitry Andric assert(Kind == Register && "Invalid type access!"); 376fe6060f1SDimitry Andric return Reg.RegNum; 377fe6060f1SDimitry Andric } 378fe6060f1SDimitry Andric 379349cc55cSDimitry Andric std::pair<unsigned, unsigned> getRegSeq() const { 380349cc55cSDimitry Andric assert(Kind == RegisterSeq && "Invalid type access!"); 381349cc55cSDimitry Andric return std::pair<unsigned, unsigned>(RegSeq.RegNumFrom, RegSeq.RegNumTo); 382349cc55cSDimitry Andric } 383349cc55cSDimitry Andric 384349cc55cSDimitry Andric RegListOp getRegList() const { 385349cc55cSDimitry Andric assert(Kind == RegisterList && "Invalid type access!"); 386349cc55cSDimitry Andric return RegList; 387349cc55cSDimitry Andric } 388349cc55cSDimitry Andric 389fe6060f1SDimitry Andric const MCExpr *getImm() const { 390fe6060f1SDimitry Andric assert(Kind == Immediate && "Invalid type access!"); 391fe6060f1SDimitry Andric return Imm.Val; 392fe6060f1SDimitry Andric } 393fe6060f1SDimitry Andric 394349cc55cSDimitry Andric const MCExpr *getConstpoolOp() const { 395349cc55cSDimitry Andric assert(Kind == CPOP && "Invalid type access!"); 396349cc55cSDimitry Andric return CPool.Val; 397349cc55cSDimitry Andric } 398349cc55cSDimitry Andric 399fe6060f1SDimitry Andric StringRef getToken() const { 400fe6060f1SDimitry Andric assert(Kind == Token && "Invalid type access!"); 401fe6060f1SDimitry Andric return Tok; 402fe6060f1SDimitry Andric } 403fe6060f1SDimitry Andric 404fe6060f1SDimitry Andric void print(raw_ostream &OS) const override { 405349cc55cSDimitry Andric auto RegName = [](unsigned Reg) { 406349cc55cSDimitry Andric if (Reg) 407349cc55cSDimitry Andric return CSKYInstPrinter::getRegisterName(Reg); 408349cc55cSDimitry Andric else 409349cc55cSDimitry Andric return "noreg"; 410349cc55cSDimitry Andric }; 411349cc55cSDimitry Andric 412fe6060f1SDimitry Andric switch (Kind) { 413349cc55cSDimitry Andric case CPOP: 414349cc55cSDimitry Andric OS << *getConstpoolOp(); 415349cc55cSDimitry Andric break; 416fe6060f1SDimitry Andric case Immediate: 417fe6060f1SDimitry Andric OS << *getImm(); 418fe6060f1SDimitry Andric break; 419349cc55cSDimitry Andric case KindTy::Register: 420349cc55cSDimitry Andric OS << "<register " << RegName(getReg()) << ">"; 421349cc55cSDimitry Andric break; 422349cc55cSDimitry Andric case RegisterSeq: 423349cc55cSDimitry Andric OS << "<register-seq "; 424349cc55cSDimitry Andric OS << RegName(getRegSeq().first) << "-" << RegName(getRegSeq().second) 425349cc55cSDimitry Andric << ">"; 426349cc55cSDimitry Andric break; 427349cc55cSDimitry Andric case RegisterList: 428349cc55cSDimitry Andric OS << "<register-list "; 429349cc55cSDimitry Andric OS << RegName(getRegList().List1From) << "-" 430349cc55cSDimitry Andric << RegName(getRegList().List1To) << ","; 431349cc55cSDimitry Andric OS << RegName(getRegList().List2From) << "-" 432349cc55cSDimitry Andric << RegName(getRegList().List2To) << ","; 433349cc55cSDimitry Andric OS << RegName(getRegList().List3From) << "-" 434349cc55cSDimitry Andric << RegName(getRegList().List3To) << ","; 435349cc55cSDimitry Andric OS << RegName(getRegList().List4From) << "-" 436349cc55cSDimitry Andric << RegName(getRegList().List4To); 437fe6060f1SDimitry Andric break; 438fe6060f1SDimitry Andric case Token: 439fe6060f1SDimitry Andric OS << "'" << getToken() << "'"; 440fe6060f1SDimitry Andric break; 441fe6060f1SDimitry Andric } 442fe6060f1SDimitry Andric } 443fe6060f1SDimitry Andric 444fe6060f1SDimitry Andric static std::unique_ptr<CSKYOperand> createToken(StringRef Str, SMLoc S) { 445fe6060f1SDimitry Andric auto Op = std::make_unique<CSKYOperand>(Token); 446fe6060f1SDimitry Andric Op->Tok = Str; 447fe6060f1SDimitry Andric Op->StartLoc = S; 448fe6060f1SDimitry Andric Op->EndLoc = S; 449fe6060f1SDimitry Andric return Op; 450fe6060f1SDimitry Andric } 451fe6060f1SDimitry Andric 452fe6060f1SDimitry Andric static std::unique_ptr<CSKYOperand> createReg(unsigned RegNo, SMLoc S, 453fe6060f1SDimitry Andric SMLoc E) { 454fe6060f1SDimitry Andric auto Op = std::make_unique<CSKYOperand>(Register); 455fe6060f1SDimitry Andric Op->Reg.RegNum = RegNo; 456fe6060f1SDimitry Andric Op->StartLoc = S; 457fe6060f1SDimitry Andric Op->EndLoc = E; 458fe6060f1SDimitry Andric return Op; 459fe6060f1SDimitry Andric } 460fe6060f1SDimitry Andric 461349cc55cSDimitry Andric static std::unique_ptr<CSKYOperand> createRegSeq(unsigned RegNoFrom, 462349cc55cSDimitry Andric unsigned RegNoTo, SMLoc S) { 463349cc55cSDimitry Andric auto Op = std::make_unique<CSKYOperand>(RegisterSeq); 464349cc55cSDimitry Andric Op->RegSeq.RegNumFrom = RegNoFrom; 465349cc55cSDimitry Andric Op->RegSeq.RegNumTo = RegNoTo; 466349cc55cSDimitry Andric Op->StartLoc = S; 467349cc55cSDimitry Andric Op->EndLoc = S; 468349cc55cSDimitry Andric return Op; 469349cc55cSDimitry Andric } 470349cc55cSDimitry Andric 471349cc55cSDimitry Andric static std::unique_ptr<CSKYOperand> 472349cc55cSDimitry Andric createRegList(SmallVector<unsigned, 4> reglist, SMLoc S) { 473349cc55cSDimitry Andric auto Op = std::make_unique<CSKYOperand>(RegisterList); 474349cc55cSDimitry Andric Op->RegList.List1From = 0; 475349cc55cSDimitry Andric Op->RegList.List1To = 0; 476349cc55cSDimitry Andric Op->RegList.List2From = 0; 477349cc55cSDimitry Andric Op->RegList.List2To = 0; 478349cc55cSDimitry Andric Op->RegList.List3From = 0; 479349cc55cSDimitry Andric Op->RegList.List3To = 0; 480349cc55cSDimitry Andric Op->RegList.List4From = 0; 481349cc55cSDimitry Andric Op->RegList.List4To = 0; 482349cc55cSDimitry Andric 483349cc55cSDimitry Andric for (unsigned i = 0; i < reglist.size(); i += 2) { 484349cc55cSDimitry Andric if (Op->RegList.List1From == 0) { 485349cc55cSDimitry Andric Op->RegList.List1From = reglist[i]; 486349cc55cSDimitry Andric Op->RegList.List1To = reglist[i + 1]; 487349cc55cSDimitry Andric } else if (Op->RegList.List2From == 0) { 488349cc55cSDimitry Andric Op->RegList.List2From = reglist[i]; 489349cc55cSDimitry Andric Op->RegList.List2To = reglist[i + 1]; 490349cc55cSDimitry Andric } else if (Op->RegList.List3From == 0) { 491349cc55cSDimitry Andric Op->RegList.List3From = reglist[i]; 492349cc55cSDimitry Andric Op->RegList.List3To = reglist[i + 1]; 493349cc55cSDimitry Andric } else if (Op->RegList.List4From == 0) { 494349cc55cSDimitry Andric Op->RegList.List4From = reglist[i]; 495349cc55cSDimitry Andric Op->RegList.List4To = reglist[i + 1]; 496349cc55cSDimitry Andric } else { 497349cc55cSDimitry Andric assert(0); 498349cc55cSDimitry Andric } 499349cc55cSDimitry Andric } 500349cc55cSDimitry Andric 501349cc55cSDimitry Andric Op->StartLoc = S; 502349cc55cSDimitry Andric Op->EndLoc = S; 503349cc55cSDimitry Andric return Op; 504349cc55cSDimitry Andric } 505349cc55cSDimitry Andric 506fe6060f1SDimitry Andric static std::unique_ptr<CSKYOperand> createImm(const MCExpr *Val, SMLoc S, 507fe6060f1SDimitry Andric SMLoc E) { 508fe6060f1SDimitry Andric auto Op = std::make_unique<CSKYOperand>(Immediate); 509fe6060f1SDimitry Andric Op->Imm.Val = Val; 510fe6060f1SDimitry Andric Op->StartLoc = S; 511fe6060f1SDimitry Andric Op->EndLoc = E; 512fe6060f1SDimitry Andric return Op; 513fe6060f1SDimitry Andric } 514fe6060f1SDimitry Andric 515349cc55cSDimitry Andric static std::unique_ptr<CSKYOperand> createConstpoolOp(const MCExpr *Val, 516349cc55cSDimitry Andric SMLoc S, SMLoc E) { 517349cc55cSDimitry Andric auto Op = std::make_unique<CSKYOperand>(CPOP); 518349cc55cSDimitry Andric Op->CPool.Val = Val; 519349cc55cSDimitry Andric Op->StartLoc = S; 520349cc55cSDimitry Andric Op->EndLoc = E; 521349cc55cSDimitry Andric return Op; 522349cc55cSDimitry Andric } 523349cc55cSDimitry Andric 524fe6060f1SDimitry Andric void addExpr(MCInst &Inst, const MCExpr *Expr) const { 525fe6060f1SDimitry Andric assert(Expr && "Expr shouldn't be null!"); 526fe6060f1SDimitry Andric if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) 527fe6060f1SDimitry Andric Inst.addOperand(MCOperand::createImm(CE->getValue())); 528fe6060f1SDimitry Andric else 529fe6060f1SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr)); 530fe6060f1SDimitry Andric } 531fe6060f1SDimitry Andric 532fe6060f1SDimitry Andric // Used by the TableGen Code. 533fe6060f1SDimitry Andric void addRegOperands(MCInst &Inst, unsigned N) const { 534fe6060f1SDimitry Andric assert(N == 1 && "Invalid number of operands!"); 535fe6060f1SDimitry Andric Inst.addOperand(MCOperand::createReg(getReg())); 536fe6060f1SDimitry Andric } 537fe6060f1SDimitry Andric 538fe6060f1SDimitry Andric void addImmOperands(MCInst &Inst, unsigned N) const { 539fe6060f1SDimitry Andric assert(N == 1 && "Invalid number of operands!"); 540fe6060f1SDimitry Andric addExpr(Inst, getImm()); 541fe6060f1SDimitry Andric } 542349cc55cSDimitry Andric 543349cc55cSDimitry Andric void addConstpoolOperands(MCInst &Inst, unsigned N) const { 544349cc55cSDimitry Andric assert(N == 1 && "Invalid number of operands!"); 545349cc55cSDimitry Andric Inst.addOperand(MCOperand::createExpr(getConstpoolOp())); 546349cc55cSDimitry Andric } 547349cc55cSDimitry Andric 548349cc55cSDimitry Andric void addRegSeqOperands(MCInst &Inst, unsigned N) const { 549349cc55cSDimitry Andric assert(N == 2 && "Invalid number of operands!"); 550349cc55cSDimitry Andric auto regSeq = getRegSeq(); 551349cc55cSDimitry Andric 552349cc55cSDimitry Andric Inst.addOperand(MCOperand::createReg(regSeq.first)); 553349cc55cSDimitry Andric Inst.addOperand(MCOperand::createReg(regSeq.second)); 554349cc55cSDimitry Andric } 555349cc55cSDimitry Andric 556349cc55cSDimitry Andric static unsigned getListValue(unsigned ListFrom, unsigned ListTo) { 557349cc55cSDimitry Andric if (ListFrom == ListTo && ListFrom == CSKY::R15) 558349cc55cSDimitry Andric return (1 << 4); 559349cc55cSDimitry Andric else if (ListFrom == ListTo && ListFrom == CSKY::R28) 560349cc55cSDimitry Andric return (1 << 8); 561349cc55cSDimitry Andric else if (ListFrom == CSKY::R4) 562349cc55cSDimitry Andric return ListTo - ListFrom + 1; 563349cc55cSDimitry Andric else if (ListFrom == CSKY::R16) 564349cc55cSDimitry Andric return ((ListTo - ListFrom + 1) << 5); 565349cc55cSDimitry Andric else 566349cc55cSDimitry Andric return 0; 567349cc55cSDimitry Andric } 568349cc55cSDimitry Andric 569349cc55cSDimitry Andric void addRegListOperands(MCInst &Inst, unsigned N) const { 570349cc55cSDimitry Andric assert(N == 1 && "Invalid number of operands!"); 571349cc55cSDimitry Andric auto regList = getRegList(); 572349cc55cSDimitry Andric 573349cc55cSDimitry Andric unsigned V = 0; 574349cc55cSDimitry Andric 575349cc55cSDimitry Andric unsigned T = getListValue(regList.List1From, regList.List1To); 576349cc55cSDimitry Andric if (T != 0) 577349cc55cSDimitry Andric V = V | T; 578349cc55cSDimitry Andric 579349cc55cSDimitry Andric T = getListValue(regList.List2From, regList.List2To); 580349cc55cSDimitry Andric if (T != 0) 581349cc55cSDimitry Andric V = V | T; 582349cc55cSDimitry Andric 583349cc55cSDimitry Andric T = getListValue(regList.List3From, regList.List3To); 584349cc55cSDimitry Andric if (T != 0) 585349cc55cSDimitry Andric V = V | T; 586349cc55cSDimitry Andric 587349cc55cSDimitry Andric T = getListValue(regList.List4From, regList.List4To); 588349cc55cSDimitry Andric if (T != 0) 589349cc55cSDimitry Andric V = V | T; 590349cc55cSDimitry Andric 591349cc55cSDimitry Andric Inst.addOperand(MCOperand::createImm(V)); 592349cc55cSDimitry Andric } 593349cc55cSDimitry Andric 594349cc55cSDimitry Andric bool isValidForTie(const CSKYOperand &Other) const { 595349cc55cSDimitry Andric if (Kind != Other.Kind) 596349cc55cSDimitry Andric return false; 597349cc55cSDimitry Andric 598349cc55cSDimitry Andric switch (Kind) { 599349cc55cSDimitry Andric default: 600349cc55cSDimitry Andric llvm_unreachable("Unexpected kind"); 601349cc55cSDimitry Andric return false; 602349cc55cSDimitry Andric case Register: 603349cc55cSDimitry Andric return Reg.RegNum == Other.Reg.RegNum; 604349cc55cSDimitry Andric } 605349cc55cSDimitry Andric } 606fe6060f1SDimitry Andric }; 607fe6060f1SDimitry Andric } // end anonymous namespace. 608fe6060f1SDimitry Andric 609fe6060f1SDimitry Andric #define GET_REGISTER_MATCHER 610fe6060f1SDimitry Andric #define GET_SUBTARGET_FEATURE_NAME 611fe6060f1SDimitry Andric #define GET_MATCHER_IMPLEMENTATION 612fe6060f1SDimitry Andric #define GET_MNEMONIC_SPELL_CHECKER 613fe6060f1SDimitry Andric #include "CSKYGenAsmMatcher.inc" 614fe6060f1SDimitry Andric 615fe6060f1SDimitry Andric static std::string CSKYMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, 616fe6060f1SDimitry Andric unsigned VariantID = 0); 617fe6060f1SDimitry Andric 618fe6060f1SDimitry Andric bool CSKYAsmParser::generateImmOutOfRangeError( 619fe6060f1SDimitry Andric OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper, 620fe6060f1SDimitry Andric Twine Msg = "immediate must be an integer in the range") { 621fe6060f1SDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 622fe6060f1SDimitry Andric return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]"); 623fe6060f1SDimitry Andric } 624fe6060f1SDimitry Andric 625fe6060f1SDimitry Andric bool CSKYAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 626fe6060f1SDimitry Andric OperandVector &Operands, 627fe6060f1SDimitry Andric MCStreamer &Out, 628fe6060f1SDimitry Andric uint64_t &ErrorInfo, 629fe6060f1SDimitry Andric bool MatchingInlineAsm) { 630fe6060f1SDimitry Andric MCInst Inst; 631fe6060f1SDimitry Andric FeatureBitset MissingFeatures; 632fe6060f1SDimitry Andric 633fe6060f1SDimitry Andric auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures, 634fe6060f1SDimitry Andric MatchingInlineAsm); 635fe6060f1SDimitry Andric switch (Result) { 636fe6060f1SDimitry Andric default: 637fe6060f1SDimitry Andric break; 638fe6060f1SDimitry Andric case Match_Success: 639349cc55cSDimitry Andric return processInstruction(Inst, IDLoc, Operands, Out); 640fe6060f1SDimitry Andric case Match_MissingFeature: { 641fe6060f1SDimitry Andric assert(MissingFeatures.any() && "Unknown missing features!"); 642fe6060f1SDimitry Andric ListSeparator LS; 643fe6060f1SDimitry Andric std::string Msg = "instruction requires the following: "; 644fe6060f1SDimitry Andric for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) { 645fe6060f1SDimitry Andric if (MissingFeatures[i]) { 646fe6060f1SDimitry Andric Msg += LS; 647fe6060f1SDimitry Andric Msg += getSubtargetFeatureName(i); 648fe6060f1SDimitry Andric } 649fe6060f1SDimitry Andric } 650fe6060f1SDimitry Andric return Error(IDLoc, Msg); 651fe6060f1SDimitry Andric } 652fe6060f1SDimitry Andric case Match_MnemonicFail: { 653fe6060f1SDimitry Andric FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits()); 654fe6060f1SDimitry Andric std::string Suggestion = 655fe6060f1SDimitry Andric CSKYMnemonicSpellCheck(((CSKYOperand &)*Operands[0]).getToken(), FBS); 656fe6060f1SDimitry Andric return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion); 657fe6060f1SDimitry Andric } 658fe6060f1SDimitry Andric case Match_InvalidTiedOperand: 659fe6060f1SDimitry Andric case Match_InvalidOperand: { 660fe6060f1SDimitry Andric SMLoc ErrorLoc = IDLoc; 661fe6060f1SDimitry Andric if (ErrorInfo != ~0U) { 662fe6060f1SDimitry Andric if (ErrorInfo >= Operands.size()) 663fe6060f1SDimitry Andric return Error(ErrorLoc, "too few operands for instruction"); 664fe6060f1SDimitry Andric 665fe6060f1SDimitry Andric ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 666fe6060f1SDimitry Andric if (ErrorLoc == SMLoc()) 667fe6060f1SDimitry Andric ErrorLoc = IDLoc; 668fe6060f1SDimitry Andric } 669fe6060f1SDimitry Andric return Error(ErrorLoc, "invalid operand for instruction"); 670fe6060f1SDimitry Andric } 671fe6060f1SDimitry Andric } 672fe6060f1SDimitry Andric 673fe6060f1SDimitry Andric // Handle the case when the error message is of specific type 674fe6060f1SDimitry Andric // other than the generic Match_InvalidOperand, and the 675fe6060f1SDimitry Andric // corresponding operand is missing. 676fe6060f1SDimitry Andric if (Result > FIRST_TARGET_MATCH_RESULT_TY) { 677fe6060f1SDimitry Andric SMLoc ErrorLoc = IDLoc; 678fe6060f1SDimitry Andric if (ErrorInfo != ~0U && ErrorInfo >= Operands.size()) 679fe6060f1SDimitry Andric return Error(ErrorLoc, "too few operands for instruction"); 680fe6060f1SDimitry Andric } 681fe6060f1SDimitry Andric 682fe6060f1SDimitry Andric switch (Result) { 683fe6060f1SDimitry Andric default: 684fe6060f1SDimitry Andric break; 685349cc55cSDimitry Andric case Match_InvalidSImm8: 686349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7), 687349cc55cSDimitry Andric (1 << 7) - 1); 688349cc55cSDimitry Andric case Match_InvalidOImm3: 689349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 3)); 690349cc55cSDimitry Andric case Match_InvalidOImm4: 691349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4)); 692349cc55cSDimitry Andric case Match_InvalidOImm5: 693349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5)); 694349cc55cSDimitry Andric case Match_InvalidOImm6: 695349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6)); 696349cc55cSDimitry Andric case Match_InvalidOImm8: 697349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 8)); 698fe6060f1SDimitry Andric case Match_InvalidOImm12: 699fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 12)); 700fe6060f1SDimitry Andric case Match_InvalidOImm16: 701fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16)); 702349cc55cSDimitry Andric case Match_InvalidUImm1: 703349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1); 704fe6060f1SDimitry Andric case Match_InvalidUImm2: 705fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1); 706349cc55cSDimitry Andric case Match_InvalidUImm3: 707349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1); 708349cc55cSDimitry Andric case Match_InvalidUImm4: 709349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1); 710fe6060f1SDimitry Andric case Match_InvalidUImm5: 711fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 712349cc55cSDimitry Andric case Match_InvalidUImm6: 713349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); 714349cc55cSDimitry Andric case Match_InvalidUImm7: 715349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1); 716349cc55cSDimitry Andric case Match_InvalidUImm8: 717349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1); 718fe6060f1SDimitry Andric case Match_InvalidUImm12: 719fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1); 720349cc55cSDimitry Andric case Match_InvalidUImm16: 721349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 16) - 1); 722349cc55cSDimitry Andric case Match_InvalidUImm5Shift1: 723349cc55cSDimitry Andric return generateImmOutOfRangeError( 724349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 5) - 2, 725349cc55cSDimitry Andric "immediate must be a multiple of 2 bytes in the range"); 726fe6060f1SDimitry Andric case Match_InvalidUImm12Shift1: 727fe6060f1SDimitry Andric return generateImmOutOfRangeError( 728fe6060f1SDimitry Andric Operands, ErrorInfo, 0, (1 << 12) - 2, 729fe6060f1SDimitry Andric "immediate must be a multiple of 2 bytes in the range"); 730349cc55cSDimitry Andric case Match_InvalidUImm5Shift2: 731349cc55cSDimitry Andric return generateImmOutOfRangeError( 732349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 5) - 4, 733349cc55cSDimitry Andric "immediate must be a multiple of 4 bytes in the range"); 734349cc55cSDimitry Andric case Match_InvalidUImm7Shift1: 735349cc55cSDimitry Andric return generateImmOutOfRangeError( 736349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 7) - 2, 737349cc55cSDimitry Andric "immediate must be a multiple of 2 bytes in the range"); 738349cc55cSDimitry Andric case Match_InvalidUImm7Shift2: 739349cc55cSDimitry Andric return generateImmOutOfRangeError( 740349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 7) - 4, 741349cc55cSDimitry Andric "immediate must be a multiple of 4 bytes in the range"); 742349cc55cSDimitry Andric case Match_InvalidUImm8Shift2: 743349cc55cSDimitry Andric return generateImmOutOfRangeError( 744349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 8) - 4, 745349cc55cSDimitry Andric "immediate must be a multiple of 4 bytes in the range"); 746349cc55cSDimitry Andric case Match_InvalidUImm8Shift3: 747349cc55cSDimitry Andric return generateImmOutOfRangeError( 748349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 8) - 8, 749349cc55cSDimitry Andric "immediate must be a multiple of 8 bytes in the range"); 750349cc55cSDimitry Andric case Match_InvalidUImm8Shift8: 751349cc55cSDimitry Andric return generateImmOutOfRangeError( 752349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 8) - 256, 753349cc55cSDimitry Andric "immediate must be a multiple of 256 bytes in the range"); 754fe6060f1SDimitry Andric case Match_InvalidUImm12Shift2: 755fe6060f1SDimitry Andric return generateImmOutOfRangeError( 756fe6060f1SDimitry Andric Operands, ErrorInfo, 0, (1 << 12) - 4, 757fe6060f1SDimitry Andric "immediate must be a multiple of 4 bytes in the range"); 758fe6060f1SDimitry Andric case Match_InvalidCSKYSymbol: { 759fe6060f1SDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 760fe6060f1SDimitry Andric return Error(ErrorLoc, "operand must be a symbol name"); 761fe6060f1SDimitry Andric } 762fe6060f1SDimitry Andric case Match_InvalidConstpool: { 763fe6060f1SDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 764fe6060f1SDimitry Andric return Error(ErrorLoc, "operand must be a constpool symbol name"); 765fe6060f1SDimitry Andric } 766349cc55cSDimitry Andric case Match_InvalidPSRFlag: { 767349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 768349cc55cSDimitry Andric return Error(ErrorLoc, "psrset operand is not valid"); 769349cc55cSDimitry Andric } 770349cc55cSDimitry Andric case Match_InvalidRegSeq: { 771349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 772349cc55cSDimitry Andric return Error(ErrorLoc, "Register sequence is not valid"); 773349cc55cSDimitry Andric } 774349cc55cSDimitry Andric case Match_InvalidRegOutOfRange: { 775349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 776349cc55cSDimitry Andric return Error(ErrorLoc, "register is out of range"); 777349cc55cSDimitry Andric } 778349cc55cSDimitry Andric case Match_RequiresSameSrcAndDst: { 779349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 780349cc55cSDimitry Andric return Error(ErrorLoc, "src and dst operand must be same"); 781349cc55cSDimitry Andric } 782349cc55cSDimitry Andric case Match_InvalidRegList: { 783349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 784349cc55cSDimitry Andric return Error(ErrorLoc, "invalid register list"); 785349cc55cSDimitry Andric } 786349cc55cSDimitry Andric } 787349cc55cSDimitry Andric LLVM_DEBUG(dbgs() << "Result = " << Result); 788349cc55cSDimitry Andric llvm_unreachable("Unknown match type detected!"); 789fe6060f1SDimitry Andric } 790fe6060f1SDimitry Andric 791349cc55cSDimitry Andric bool CSKYAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 792349cc55cSDimitry Andric OperandVector &Operands, 793349cc55cSDimitry Andric MCStreamer &Out) { 794349cc55cSDimitry Andric 7950eae32dcSDimitry Andric switch (Inst.getOpcode()) { 7960eae32dcSDimitry Andric default: 7970eae32dcSDimitry Andric break; 7980eae32dcSDimitry Andric case CSKY::LDQ32: 7990eae32dcSDimitry Andric case CSKY::STQ32: 800349cc55cSDimitry Andric if (Inst.getOperand(1).getReg() != CSKY::R4 || 801349cc55cSDimitry Andric Inst.getOperand(2).getReg() != CSKY::R7) { 802349cc55cSDimitry Andric return Error(IDLoc, "Register sequence is not valid. 'r4-r7' expected"); 803349cc55cSDimitry Andric } 804349cc55cSDimitry Andric Inst.setOpcode(Inst.getOpcode() == CSKY::LDQ32 ? CSKY::LDM32 : CSKY::STM32); 8050eae32dcSDimitry Andric break; 8060eae32dcSDimitry Andric case CSKY::SEXT32: 8070eae32dcSDimitry Andric case CSKY::ZEXT32: 808349cc55cSDimitry Andric if (Inst.getOperand(2).getImm() < Inst.getOperand(3).getImm()) 809349cc55cSDimitry Andric return Error(IDLoc, "msb must be greater or equal to lsb"); 8100eae32dcSDimitry Andric break; 8110eae32dcSDimitry Andric case CSKY::INS32: 812349cc55cSDimitry Andric if (Inst.getOperand(3).getImm() < Inst.getOperand(4).getImm()) 813349cc55cSDimitry Andric return Error(IDLoc, "msb must be greater or equal to lsb"); 8140eae32dcSDimitry Andric break; 8150eae32dcSDimitry Andric case CSKY::IDLY32: 816349cc55cSDimitry Andric if (Inst.getOperand(0).getImm() > 32 || Inst.getOperand(0).getImm() < 0) 817349cc55cSDimitry Andric return Error(IDLoc, "n must be in range [0,32]"); 8180eae32dcSDimitry Andric break; 8190eae32dcSDimitry Andric case CSKY::ADDC32: 8200eae32dcSDimitry Andric case CSKY::SUBC32: 8210eae32dcSDimitry Andric case CSKY::ADDC16: 8220eae32dcSDimitry Andric case CSKY::SUBC16: 8230eae32dcSDimitry Andric Inst.erase(std::next(Inst.begin())); 8240eae32dcSDimitry Andric Inst.erase(std::prev(Inst.end())); 8250eae32dcSDimitry Andric Inst.insert(std::next(Inst.begin()), MCOperand::createReg(CSKY::C)); 8260eae32dcSDimitry Andric Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C)); 8270eae32dcSDimitry Andric break; 8280eae32dcSDimitry Andric case CSKY::CMPNEI32: 8290eae32dcSDimitry Andric case CSKY::CMPNEI16: 8300eae32dcSDimitry Andric case CSKY::CMPNE32: 8310eae32dcSDimitry Andric case CSKY::CMPNE16: 8320eae32dcSDimitry Andric case CSKY::CMPHSI32: 8330eae32dcSDimitry Andric case CSKY::CMPHSI16: 8340eae32dcSDimitry Andric case CSKY::CMPHS32: 8350eae32dcSDimitry Andric case CSKY::CMPHS16: 8360eae32dcSDimitry Andric case CSKY::CMPLTI32: 8370eae32dcSDimitry Andric case CSKY::CMPLTI16: 8380eae32dcSDimitry Andric case CSKY::CMPLT32: 8390eae32dcSDimitry Andric case CSKY::CMPLT16: 8400eae32dcSDimitry Andric case CSKY::BTSTI32: 8410eae32dcSDimitry Andric Inst.erase(Inst.begin()); 8420eae32dcSDimitry Andric Inst.insert(Inst.begin(), MCOperand::createReg(CSKY::C)); 8430eae32dcSDimitry Andric break; 8440eae32dcSDimitry Andric case CSKY::MVCV32: 8450eae32dcSDimitry Andric Inst.erase(std::next(Inst.begin())); 8460eae32dcSDimitry Andric Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C)); 8470eae32dcSDimitry Andric break; 848349cc55cSDimitry Andric } 849349cc55cSDimitry Andric 8500eae32dcSDimitry Andric emitToStreamer(Out, Inst); 851349cc55cSDimitry Andric return false; 852fe6060f1SDimitry Andric } 853fe6060f1SDimitry Andric 854fe6060f1SDimitry Andric // Attempts to match Name as a register (either using the default name or 855fe6060f1SDimitry Andric // alternative ABI names), setting RegNo to the matching register. Upon 856fe6060f1SDimitry Andric // failure, returns true and sets RegNo to 0. 857349cc55cSDimitry Andric static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, 858349cc55cSDimitry Andric MCRegister &RegNo, StringRef Name) { 859fe6060f1SDimitry Andric RegNo = MatchRegisterName(Name); 860fe6060f1SDimitry Andric 861fe6060f1SDimitry Andric if (RegNo == CSKY::NoRegister) 862fe6060f1SDimitry Andric RegNo = MatchRegisterAltName(Name); 863fe6060f1SDimitry Andric 864fe6060f1SDimitry Andric return RegNo == CSKY::NoRegister; 865fe6060f1SDimitry Andric } 866fe6060f1SDimitry Andric 867fe6060f1SDimitry Andric bool CSKYAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 868fe6060f1SDimitry Andric SMLoc &EndLoc) { 869fe6060f1SDimitry Andric const AsmToken &Tok = getParser().getTok(); 870fe6060f1SDimitry Andric StartLoc = Tok.getLoc(); 871fe6060f1SDimitry Andric EndLoc = Tok.getEndLoc(); 872fe6060f1SDimitry Andric StringRef Name = getLexer().getTok().getIdentifier(); 873fe6060f1SDimitry Andric 874349cc55cSDimitry Andric if (!matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) { 875fe6060f1SDimitry Andric getParser().Lex(); // Eat identifier token. 876fe6060f1SDimitry Andric return false; 877fe6060f1SDimitry Andric } 878fe6060f1SDimitry Andric 879349cc55cSDimitry Andric return MatchOperand_NoMatch; 880fe6060f1SDimitry Andric } 881fe6060f1SDimitry Andric 882fe6060f1SDimitry Andric OperandMatchResultTy CSKYAsmParser::parseRegister(OperandVector &Operands) { 883fe6060f1SDimitry Andric SMLoc S = getLoc(); 884fe6060f1SDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 885fe6060f1SDimitry Andric 886fe6060f1SDimitry Andric switch (getLexer().getKind()) { 887fe6060f1SDimitry Andric default: 888fe6060f1SDimitry Andric return MatchOperand_NoMatch; 889fe6060f1SDimitry Andric case AsmToken::Identifier: { 890fe6060f1SDimitry Andric StringRef Name = getLexer().getTok().getIdentifier(); 891fe6060f1SDimitry Andric MCRegister RegNo; 892fe6060f1SDimitry Andric 893349cc55cSDimitry Andric if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) 894fe6060f1SDimitry Andric return MatchOperand_NoMatch; 895fe6060f1SDimitry Andric 896fe6060f1SDimitry Andric getLexer().Lex(); 897fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createReg(RegNo, S, E)); 898fe6060f1SDimitry Andric 899fe6060f1SDimitry Andric return MatchOperand_Success; 900fe6060f1SDimitry Andric } 901fe6060f1SDimitry Andric } 902fe6060f1SDimitry Andric } 903fe6060f1SDimitry Andric 904fe6060f1SDimitry Andric OperandMatchResultTy CSKYAsmParser::parseBaseRegImm(OperandVector &Operands) { 905fe6060f1SDimitry Andric assert(getLexer().is(AsmToken::LParen)); 906fe6060f1SDimitry Andric 907fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createToken("(", getLoc())); 908fe6060f1SDimitry Andric 909fe6060f1SDimitry Andric auto Tok = getParser().Lex(); // Eat '(' 910fe6060f1SDimitry Andric 911fe6060f1SDimitry Andric if (parseRegister(Operands) != MatchOperand_Success) { 912fe6060f1SDimitry Andric getLexer().UnLex(Tok); 913fe6060f1SDimitry Andric Operands.pop_back(); 914349cc55cSDimitry Andric return MatchOperand_NoMatch; 915349cc55cSDimitry Andric } 916349cc55cSDimitry Andric 917349cc55cSDimitry Andric if (getLexer().is(AsmToken::RParen)) { 918349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createToken(")", getLoc())); 919349cc55cSDimitry Andric getParser().Lex(); // Eat ')' 920349cc55cSDimitry Andric return MatchOperand_Success; 921fe6060f1SDimitry Andric } 922fe6060f1SDimitry Andric 923fe6060f1SDimitry Andric if (getLexer().isNot(AsmToken::Comma)) { 924fe6060f1SDimitry Andric Error(getLoc(), "expected ','"); 925fe6060f1SDimitry Andric return MatchOperand_ParseFail; 926fe6060f1SDimitry Andric } 927fe6060f1SDimitry Andric 928fe6060f1SDimitry Andric getParser().Lex(); // Eat ',' 929fe6060f1SDimitry Andric 930fe6060f1SDimitry Andric if (parseRegister(Operands) == MatchOperand_Success) { 931fe6060f1SDimitry Andric if (getLexer().isNot(AsmToken::LessLess)) { 932fe6060f1SDimitry Andric Error(getLoc(), "expected '<<'"); 933fe6060f1SDimitry Andric return MatchOperand_ParseFail; 934fe6060f1SDimitry Andric } 935fe6060f1SDimitry Andric 936fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createToken("<<", getLoc())); 937fe6060f1SDimitry Andric 938fe6060f1SDimitry Andric getParser().Lex(); // Eat '<<' 939fe6060f1SDimitry Andric 940fe6060f1SDimitry Andric if (parseImmediate(Operands) != MatchOperand_Success) { 941fe6060f1SDimitry Andric Error(getLoc(), "expected imm"); 942fe6060f1SDimitry Andric return MatchOperand_ParseFail; 943fe6060f1SDimitry Andric } 944fe6060f1SDimitry Andric 945fe6060f1SDimitry Andric } else if (parseImmediate(Operands) != MatchOperand_Success) { 946fe6060f1SDimitry Andric Error(getLoc(), "expected imm"); 947fe6060f1SDimitry Andric return MatchOperand_ParseFail; 948fe6060f1SDimitry Andric } 949fe6060f1SDimitry Andric 950fe6060f1SDimitry Andric if (getLexer().isNot(AsmToken::RParen)) { 951fe6060f1SDimitry Andric Error(getLoc(), "expected ')'"); 952fe6060f1SDimitry Andric return MatchOperand_ParseFail; 953fe6060f1SDimitry Andric } 954fe6060f1SDimitry Andric 955fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createToken(")", getLoc())); 956fe6060f1SDimitry Andric 957fe6060f1SDimitry Andric getParser().Lex(); // Eat ')' 958fe6060f1SDimitry Andric 959fe6060f1SDimitry Andric return MatchOperand_Success; 960fe6060f1SDimitry Andric } 961fe6060f1SDimitry Andric 962fe6060f1SDimitry Andric OperandMatchResultTy CSKYAsmParser::parseImmediate(OperandVector &Operands) { 963fe6060f1SDimitry Andric switch (getLexer().getKind()) { 964fe6060f1SDimitry Andric default: 965fe6060f1SDimitry Andric return MatchOperand_NoMatch; 966fe6060f1SDimitry Andric case AsmToken::LParen: 967fe6060f1SDimitry Andric case AsmToken::Minus: 968fe6060f1SDimitry Andric case AsmToken::Plus: 969fe6060f1SDimitry Andric case AsmToken::Integer: 970fe6060f1SDimitry Andric case AsmToken::String: 971fe6060f1SDimitry Andric break; 972fe6060f1SDimitry Andric } 973fe6060f1SDimitry Andric 974fe6060f1SDimitry Andric const MCExpr *IdVal; 975fe6060f1SDimitry Andric SMLoc S = getLoc(); 976349cc55cSDimitry Andric if (getParser().parseExpression(IdVal)) { 977349cc55cSDimitry Andric Error(getLoc(), "unknown expression"); 978fe6060f1SDimitry Andric return MatchOperand_ParseFail; 979349cc55cSDimitry Andric } 980fe6060f1SDimitry Andric 981fe6060f1SDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 982fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createImm(IdVal, S, E)); 983fe6060f1SDimitry Andric return MatchOperand_Success; 984fe6060f1SDimitry Andric } 985fe6060f1SDimitry Andric 986fe6060f1SDimitry Andric /// Looks at a token type and creates the relevant operand from this 987fe6060f1SDimitry Andric /// information, adding to Operands. If operand was parsed, returns false, else 988fe6060f1SDimitry Andric /// true. 989fe6060f1SDimitry Andric bool CSKYAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 990fe6060f1SDimitry Andric // Check if the current operand has a custom associated parser, if so, try to 991fe6060f1SDimitry Andric // custom parse the operand, or fallback to the general approach. 992fe6060f1SDimitry Andric OperandMatchResultTy Result = 993fe6060f1SDimitry Andric MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true); 994fe6060f1SDimitry Andric if (Result == MatchOperand_Success) 995fe6060f1SDimitry Andric return false; 996fe6060f1SDimitry Andric if (Result == MatchOperand_ParseFail) 997fe6060f1SDimitry Andric return true; 998fe6060f1SDimitry Andric 999fe6060f1SDimitry Andric // Attempt to parse token as register 1000349cc55cSDimitry Andric auto Res = parseRegister(Operands); 1001349cc55cSDimitry Andric if (Res == MatchOperand_Success) 1002fe6060f1SDimitry Andric return false; 1003349cc55cSDimitry Andric else if (Res == MatchOperand_ParseFail) 1004349cc55cSDimitry Andric return true; 1005fe6060f1SDimitry Andric 1006fe6060f1SDimitry Andric // Attempt to parse token as (register, imm) 1007349cc55cSDimitry Andric if (getLexer().is(AsmToken::LParen)) { 1008349cc55cSDimitry Andric Res = parseBaseRegImm(Operands); 1009349cc55cSDimitry Andric if (Res == MatchOperand_Success) 1010fe6060f1SDimitry Andric return false; 1011349cc55cSDimitry Andric else if (Res == MatchOperand_ParseFail) 1012349cc55cSDimitry Andric return true; 1013349cc55cSDimitry Andric } 1014fe6060f1SDimitry Andric 1015349cc55cSDimitry Andric Res = parseImmediate(Operands); 1016349cc55cSDimitry Andric if (Res == MatchOperand_Success) 1017fe6060f1SDimitry Andric return false; 1018349cc55cSDimitry Andric else if (Res == MatchOperand_ParseFail) 1019349cc55cSDimitry Andric return true; 1020fe6060f1SDimitry Andric 1021fe6060f1SDimitry Andric // Finally we have exhausted all options and must declare defeat. 1022fe6060f1SDimitry Andric Error(getLoc(), "unknown operand"); 1023fe6060f1SDimitry Andric return true; 1024fe6060f1SDimitry Andric } 1025fe6060f1SDimitry Andric 1026fe6060f1SDimitry Andric OperandMatchResultTy CSKYAsmParser::parseCSKYSymbol(OperandVector &Operands) { 1027fe6060f1SDimitry Andric SMLoc S = getLoc(); 1028fe6060f1SDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1029349cc55cSDimitry Andric const MCExpr *Res; 1030fe6060f1SDimitry Andric 1031fe6060f1SDimitry Andric if (getLexer().getKind() != AsmToken::Identifier) 1032fe6060f1SDimitry Andric return MatchOperand_NoMatch; 1033fe6060f1SDimitry Andric 1034fe6060f1SDimitry Andric StringRef Identifier; 1035349cc55cSDimitry Andric AsmToken Tok = getLexer().getTok(); 1036349cc55cSDimitry Andric 1037349cc55cSDimitry Andric if (getParser().parseIdentifier(Identifier)) { 1038349cc55cSDimitry Andric Error(getLoc(), "unknown identifier"); 1039fe6060f1SDimitry Andric return MatchOperand_ParseFail; 1040349cc55cSDimitry Andric } 1041fe6060f1SDimitry Andric 1042fe6060f1SDimitry Andric CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None; 1043fe6060f1SDimitry Andric if (Identifier.consume_back("@GOT")) 1044fe6060f1SDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOT; 1045fe6060f1SDimitry Andric else if (Identifier.consume_back("@GOTOFF")) 1046fe6060f1SDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOTOFF; 1047fe6060f1SDimitry Andric else if (Identifier.consume_back("@PLT")) 1048fe6060f1SDimitry Andric Kind = CSKYMCExpr::VK_CSKY_PLT; 1049fe6060f1SDimitry Andric else if (Identifier.consume_back("@GOTPC")) 1050fe6060f1SDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOTPC; 1051349cc55cSDimitry Andric else if (Identifier.consume_back("@TLSGD32")) 1052349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSGD; 1053349cc55cSDimitry Andric else if (Identifier.consume_back("@GOTTPOFF")) 1054349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSIE; 1055349cc55cSDimitry Andric else if (Identifier.consume_back("@TPOFF")) 1056349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSLE; 1057349cc55cSDimitry Andric else if (Identifier.consume_back("@TLSLDM32")) 1058349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSLDM; 1059349cc55cSDimitry Andric else if (Identifier.consume_back("@TLSLDO32")) 1060349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSLDO; 1061fe6060f1SDimitry Andric 1062349cc55cSDimitry Andric MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier); 1063fe6060f1SDimitry Andric 1064349cc55cSDimitry Andric if (!Sym) 1065349cc55cSDimitry Andric Sym = getContext().getOrCreateSymbol(Identifier); 1066349cc55cSDimitry Andric 1067349cc55cSDimitry Andric if (Sym->isVariable()) { 1068349cc55cSDimitry Andric const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1069349cc55cSDimitry Andric if (!isa<MCSymbolRefExpr>(V)) { 1070349cc55cSDimitry Andric getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1071349cc55cSDimitry Andric Error(getLoc(), "unknown symbol"); 1072349cc55cSDimitry Andric return MatchOperand_ParseFail; 1073349cc55cSDimitry Andric } 1074349cc55cSDimitry Andric Res = V; 1075349cc55cSDimitry Andric } else 1076349cc55cSDimitry Andric Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1077349cc55cSDimitry Andric 1078349cc55cSDimitry Andric MCBinaryExpr::Opcode Opcode; 1079349cc55cSDimitry Andric switch (getLexer().getKind()) { 1080349cc55cSDimitry Andric default: 1081fe6060f1SDimitry Andric if (Kind != CSKYMCExpr::VK_CSKY_None) 1082fe6060f1SDimitry Andric Res = CSKYMCExpr::create(Res, Kind, getContext()); 1083fe6060f1SDimitry Andric 1084fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createImm(Res, S, E)); 1085fe6060f1SDimitry Andric return MatchOperand_Success; 1086349cc55cSDimitry Andric case AsmToken::Plus: 1087349cc55cSDimitry Andric Opcode = MCBinaryExpr::Add; 1088349cc55cSDimitry Andric break; 1089349cc55cSDimitry Andric case AsmToken::Minus: 1090349cc55cSDimitry Andric Opcode = MCBinaryExpr::Sub; 1091349cc55cSDimitry Andric break; 1092349cc55cSDimitry Andric } 1093349cc55cSDimitry Andric 1094349cc55cSDimitry Andric getLexer().Lex(); // eat + or - 1095349cc55cSDimitry Andric 1096349cc55cSDimitry Andric const MCExpr *Expr; 1097349cc55cSDimitry Andric if (getParser().parseExpression(Expr)) { 1098349cc55cSDimitry Andric Error(getLoc(), "unknown expression"); 1099349cc55cSDimitry Andric return MatchOperand_ParseFail; 1100349cc55cSDimitry Andric } 1101349cc55cSDimitry Andric Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1102349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createImm(Res, S, E)); 1103349cc55cSDimitry Andric return MatchOperand_Success; 1104349cc55cSDimitry Andric } 1105349cc55cSDimitry Andric 1106349cc55cSDimitry Andric OperandMatchResultTy CSKYAsmParser::parseDataSymbol(OperandVector &Operands) { 1107349cc55cSDimitry Andric SMLoc S = getLoc(); 1108349cc55cSDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1109349cc55cSDimitry Andric const MCExpr *Res; 1110349cc55cSDimitry Andric 1111349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::LBrac) 1112349cc55cSDimitry Andric return MatchOperand_NoMatch; 1113349cc55cSDimitry Andric 1114349cc55cSDimitry Andric getLexer().Lex(); // Eat '['. 1115349cc55cSDimitry Andric 1116349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::Identifier) { 1117349cc55cSDimitry Andric const MCExpr *Expr; 1118349cc55cSDimitry Andric if (getParser().parseExpression(Expr)) { 1119349cc55cSDimitry Andric Error(getLoc(), "unknown expression"); 1120349cc55cSDimitry Andric return MatchOperand_ParseFail; 1121349cc55cSDimitry Andric } 1122349cc55cSDimitry Andric 1123349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::RBrac) { 1124349cc55cSDimitry Andric Error(getLoc(), "expected ]"); 1125349cc55cSDimitry Andric return MatchOperand_ParseFail; 1126349cc55cSDimitry Andric } 1127349cc55cSDimitry Andric 1128349cc55cSDimitry Andric getLexer().Lex(); // Eat ']'. 1129349cc55cSDimitry Andric 1130349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E)); 1131349cc55cSDimitry Andric return MatchOperand_Success; 1132349cc55cSDimitry Andric } 1133349cc55cSDimitry Andric 1134349cc55cSDimitry Andric AsmToken Tok = getLexer().getTok(); 1135349cc55cSDimitry Andric StringRef Identifier; 1136349cc55cSDimitry Andric 1137349cc55cSDimitry Andric if (getParser().parseIdentifier(Identifier)) { 1138349cc55cSDimitry Andric Error(getLoc(), "unknown identifier " + Identifier); 1139349cc55cSDimitry Andric return MatchOperand_ParseFail; 1140349cc55cSDimitry Andric } 1141349cc55cSDimitry Andric 1142349cc55cSDimitry Andric CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None; 1143349cc55cSDimitry Andric if (Identifier.consume_back("@GOT")) 1144349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOT_IMM18_BY4; 1145349cc55cSDimitry Andric else if (Identifier.consume_back("@PLT")) 1146349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_PLT_IMM18_BY4; 1147349cc55cSDimitry Andric 1148349cc55cSDimitry Andric MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier); 1149349cc55cSDimitry Andric 1150349cc55cSDimitry Andric if (!Sym) 1151349cc55cSDimitry Andric Sym = getContext().getOrCreateSymbol(Identifier); 1152349cc55cSDimitry Andric 1153349cc55cSDimitry Andric if (Sym->isVariable()) { 1154349cc55cSDimitry Andric const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1155349cc55cSDimitry Andric if (!isa<MCSymbolRefExpr>(V)) { 1156349cc55cSDimitry Andric getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1157349cc55cSDimitry Andric Error(getLoc(), "unknown symbol"); 1158349cc55cSDimitry Andric return MatchOperand_ParseFail; 1159349cc55cSDimitry Andric } 1160349cc55cSDimitry Andric Res = V; 1161349cc55cSDimitry Andric } else { 1162349cc55cSDimitry Andric Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1163349cc55cSDimitry Andric } 1164349cc55cSDimitry Andric 1165349cc55cSDimitry Andric MCBinaryExpr::Opcode Opcode; 1166349cc55cSDimitry Andric switch (getLexer().getKind()) { 1167349cc55cSDimitry Andric default: 1168349cc55cSDimitry Andric Error(getLoc(), "unknown symbol"); 1169349cc55cSDimitry Andric return MatchOperand_ParseFail; 1170349cc55cSDimitry Andric case AsmToken::RBrac: 1171349cc55cSDimitry Andric 1172349cc55cSDimitry Andric getLexer().Lex(); // Eat ']'. 1173349cc55cSDimitry Andric 1174349cc55cSDimitry Andric if (Kind != CSKYMCExpr::VK_CSKY_None) 1175349cc55cSDimitry Andric Res = CSKYMCExpr::create(Res, Kind, getContext()); 1176349cc55cSDimitry Andric 1177349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1178349cc55cSDimitry Andric return MatchOperand_Success; 1179349cc55cSDimitry Andric case AsmToken::Plus: 1180349cc55cSDimitry Andric Opcode = MCBinaryExpr::Add; 1181349cc55cSDimitry Andric break; 1182349cc55cSDimitry Andric case AsmToken::Minus: 1183349cc55cSDimitry Andric Opcode = MCBinaryExpr::Sub; 1184349cc55cSDimitry Andric break; 1185349cc55cSDimitry Andric } 1186349cc55cSDimitry Andric 1187349cc55cSDimitry Andric getLexer().Lex(); // eat + or - 1188349cc55cSDimitry Andric 1189349cc55cSDimitry Andric const MCExpr *Expr; 1190349cc55cSDimitry Andric if (getParser().parseExpression(Expr)) { 1191349cc55cSDimitry Andric Error(getLoc(), "unknown expression"); 1192349cc55cSDimitry Andric return MatchOperand_ParseFail; 1193349cc55cSDimitry Andric } 1194349cc55cSDimitry Andric 1195349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::RBrac) { 1196349cc55cSDimitry Andric Error(getLoc(), "expected ']'"); 1197349cc55cSDimitry Andric return MatchOperand_ParseFail; 1198349cc55cSDimitry Andric } 1199349cc55cSDimitry Andric 1200349cc55cSDimitry Andric getLexer().Lex(); // Eat ']'. 1201349cc55cSDimitry Andric 1202349cc55cSDimitry Andric Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1203349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1204349cc55cSDimitry Andric return MatchOperand_Success; 1205fe6060f1SDimitry Andric } 1206fe6060f1SDimitry Andric 1207fe6060f1SDimitry Andric OperandMatchResultTy 1208fe6060f1SDimitry Andric CSKYAsmParser::parseConstpoolSymbol(OperandVector &Operands) { 1209fe6060f1SDimitry Andric SMLoc S = getLoc(); 1210fe6060f1SDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1211349cc55cSDimitry Andric const MCExpr *Res; 1212fe6060f1SDimitry Andric 1213fe6060f1SDimitry Andric if (getLexer().getKind() != AsmToken::LBrac) 1214fe6060f1SDimitry Andric return MatchOperand_NoMatch; 1215fe6060f1SDimitry Andric 1216fe6060f1SDimitry Andric getLexer().Lex(); // Eat '['. 1217fe6060f1SDimitry Andric 1218349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::Identifier) { 1219349cc55cSDimitry Andric const MCExpr *Expr; 1220349cc55cSDimitry Andric if (getParser().parseExpression(Expr)) { 1221349cc55cSDimitry Andric Error(getLoc(), "unknown expression"); 1222fe6060f1SDimitry Andric return MatchOperand_ParseFail; 1223349cc55cSDimitry Andric } 1224fe6060f1SDimitry Andric 1225349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::RBrac) { 1226349cc55cSDimitry Andric Error(getLoc(), "expected ']'"); 1227349cc55cSDimitry Andric return MatchOperand_ParseFail; 1228349cc55cSDimitry Andric } 1229fe6060f1SDimitry Andric 1230fe6060f1SDimitry Andric getLexer().Lex(); // Eat ']'. 1231fe6060f1SDimitry Andric 1232349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E)); 1233349cc55cSDimitry Andric return MatchOperand_Success; 1234349cc55cSDimitry Andric } 1235349cc55cSDimitry Andric 1236349cc55cSDimitry Andric AsmToken Tok = getLexer().getTok(); 1237349cc55cSDimitry Andric StringRef Identifier; 1238349cc55cSDimitry Andric 1239349cc55cSDimitry Andric if (getParser().parseIdentifier(Identifier)) { 1240349cc55cSDimitry Andric Error(getLoc(), "unknown identifier"); 1241349cc55cSDimitry Andric return MatchOperand_ParseFail; 1242349cc55cSDimitry Andric } 1243349cc55cSDimitry Andric 1244349cc55cSDimitry Andric MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier); 1245349cc55cSDimitry Andric 1246349cc55cSDimitry Andric if (!Sym) 1247349cc55cSDimitry Andric Sym = getContext().getOrCreateSymbol(Identifier); 1248349cc55cSDimitry Andric 1249349cc55cSDimitry Andric if (Sym->isVariable()) { 1250349cc55cSDimitry Andric const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1251349cc55cSDimitry Andric if (!isa<MCSymbolRefExpr>(V)) { 1252349cc55cSDimitry Andric getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1253349cc55cSDimitry Andric Error(getLoc(), "unknown symbol"); 1254349cc55cSDimitry Andric return MatchOperand_ParseFail; 1255349cc55cSDimitry Andric } 1256349cc55cSDimitry Andric Res = V; 1257349cc55cSDimitry Andric } else { 1258349cc55cSDimitry Andric Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1259349cc55cSDimitry Andric } 1260349cc55cSDimitry Andric 1261349cc55cSDimitry Andric MCBinaryExpr::Opcode Opcode; 1262349cc55cSDimitry Andric switch (getLexer().getKind()) { 1263349cc55cSDimitry Andric default: 1264349cc55cSDimitry Andric Error(getLoc(), "unknown symbol"); 1265349cc55cSDimitry Andric return MatchOperand_ParseFail; 1266349cc55cSDimitry Andric case AsmToken::RBrac: 1267349cc55cSDimitry Andric 1268349cc55cSDimitry Andric getLexer().Lex(); // Eat ']'. 1269349cc55cSDimitry Andric 1270349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1271349cc55cSDimitry Andric return MatchOperand_Success; 1272349cc55cSDimitry Andric case AsmToken::Plus: 1273349cc55cSDimitry Andric Opcode = MCBinaryExpr::Add; 1274349cc55cSDimitry Andric break; 1275349cc55cSDimitry Andric case AsmToken::Minus: 1276349cc55cSDimitry Andric Opcode = MCBinaryExpr::Sub; 1277349cc55cSDimitry Andric break; 1278349cc55cSDimitry Andric } 1279349cc55cSDimitry Andric 1280349cc55cSDimitry Andric getLexer().Lex(); // eat + or - 1281349cc55cSDimitry Andric 1282349cc55cSDimitry Andric const MCExpr *Expr; 1283349cc55cSDimitry Andric if (getParser().parseExpression(Expr)) { 1284349cc55cSDimitry Andric Error(getLoc(), "unknown expression"); 1285349cc55cSDimitry Andric return MatchOperand_ParseFail; 1286349cc55cSDimitry Andric } 1287349cc55cSDimitry Andric 1288349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::RBrac) { 1289349cc55cSDimitry Andric Error(getLoc(), "expected ']'"); 1290349cc55cSDimitry Andric return MatchOperand_ParseFail; 1291349cc55cSDimitry Andric } 1292349cc55cSDimitry Andric 1293349cc55cSDimitry Andric getLexer().Lex(); // Eat ']'. 1294349cc55cSDimitry Andric 1295349cc55cSDimitry Andric Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1296349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1297349cc55cSDimitry Andric return MatchOperand_Success; 1298349cc55cSDimitry Andric } 1299349cc55cSDimitry Andric 1300349cc55cSDimitry Andric OperandMatchResultTy CSKYAsmParser::parsePSRFlag(OperandVector &Operands) { 1301349cc55cSDimitry Andric SMLoc S = getLoc(); 1302349cc55cSDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1303349cc55cSDimitry Andric 1304349cc55cSDimitry Andric unsigned Flag = 0; 1305349cc55cSDimitry Andric 1306349cc55cSDimitry Andric while (getLexer().isNot(AsmToken::EndOfStatement)) { 1307349cc55cSDimitry Andric StringRef Identifier; 1308349cc55cSDimitry Andric if (getParser().parseIdentifier(Identifier)) { 1309349cc55cSDimitry Andric Error(getLoc(), "unknown identifier " + Identifier); 1310349cc55cSDimitry Andric return MatchOperand_ParseFail; 1311349cc55cSDimitry Andric } 1312349cc55cSDimitry Andric 1313349cc55cSDimitry Andric if (Identifier == "sie") 1314349cc55cSDimitry Andric Flag = (1 << 4) | Flag; 1315349cc55cSDimitry Andric else if (Identifier == "ee") 1316349cc55cSDimitry Andric Flag = (1 << 3) | Flag; 1317349cc55cSDimitry Andric else if (Identifier == "ie") 1318349cc55cSDimitry Andric Flag = (1 << 2) | Flag; 1319349cc55cSDimitry Andric else if (Identifier == "fe") 1320349cc55cSDimitry Andric Flag = (1 << 1) | Flag; 1321349cc55cSDimitry Andric else if (Identifier == "af") 1322349cc55cSDimitry Andric Flag = (1 << 0) | Flag; 1323349cc55cSDimitry Andric else { 1324349cc55cSDimitry Andric Error(getLoc(), "expected " + Identifier); 1325349cc55cSDimitry Andric return MatchOperand_ParseFail; 1326349cc55cSDimitry Andric } 1327349cc55cSDimitry Andric 1328349cc55cSDimitry Andric if (getLexer().is(AsmToken::EndOfStatement)) 1329349cc55cSDimitry Andric break; 1330349cc55cSDimitry Andric 1331349cc55cSDimitry Andric if (getLexer().is(AsmToken::Comma)) { 1332349cc55cSDimitry Andric getLexer().Lex(); // eat ',' 1333349cc55cSDimitry Andric } else { 1334349cc55cSDimitry Andric Error(getLoc(), "expected ,"); 1335349cc55cSDimitry Andric return MatchOperand_ParseFail; 1336349cc55cSDimitry Andric } 1337349cc55cSDimitry Andric } 1338349cc55cSDimitry Andric 1339349cc55cSDimitry Andric Operands.push_back( 1340349cc55cSDimitry Andric CSKYOperand::createImm(MCConstantExpr::create(Flag, getContext()), S, E)); 1341349cc55cSDimitry Andric return MatchOperand_Success; 1342349cc55cSDimitry Andric } 1343349cc55cSDimitry Andric 1344349cc55cSDimitry Andric OperandMatchResultTy CSKYAsmParser::parseRegSeq(OperandVector &Operands) { 1345349cc55cSDimitry Andric SMLoc S = getLoc(); 1346349cc55cSDimitry Andric 1347349cc55cSDimitry Andric if (parseRegister(Operands) != MatchOperand_Success) 1348349cc55cSDimitry Andric return MatchOperand_NoMatch; 1349349cc55cSDimitry Andric 1350349cc55cSDimitry Andric auto Ry = Operands.back()->getReg(); 1351349cc55cSDimitry Andric Operands.pop_back(); 1352349cc55cSDimitry Andric 1353349cc55cSDimitry Andric if (getLexer().isNot(AsmToken::Minus)) { 1354349cc55cSDimitry Andric Error(getLoc(), "expected '-'"); 1355349cc55cSDimitry Andric return MatchOperand_ParseFail; 1356349cc55cSDimitry Andric } 1357349cc55cSDimitry Andric 1358349cc55cSDimitry Andric getLexer().Lex(); // eat '-' 1359349cc55cSDimitry Andric 1360349cc55cSDimitry Andric if (parseRegister(Operands) != MatchOperand_Success) { 1361349cc55cSDimitry Andric Error(getLoc(), "invalid register"); 1362349cc55cSDimitry Andric return MatchOperand_ParseFail; 1363349cc55cSDimitry Andric } 1364349cc55cSDimitry Andric 1365349cc55cSDimitry Andric auto Rz = Operands.back()->getReg(); 1366349cc55cSDimitry Andric Operands.pop_back(); 1367349cc55cSDimitry Andric 1368349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createRegSeq(Ry, Rz, S)); 1369349cc55cSDimitry Andric return MatchOperand_Success; 1370349cc55cSDimitry Andric } 1371349cc55cSDimitry Andric 1372349cc55cSDimitry Andric OperandMatchResultTy CSKYAsmParser::parseRegList(OperandVector &Operands) { 1373349cc55cSDimitry Andric SMLoc S = getLoc(); 1374349cc55cSDimitry Andric 1375349cc55cSDimitry Andric SmallVector<unsigned, 4> reglist; 1376349cc55cSDimitry Andric 1377349cc55cSDimitry Andric while (true) { 1378349cc55cSDimitry Andric 1379349cc55cSDimitry Andric if (parseRegister(Operands) != MatchOperand_Success) { 1380349cc55cSDimitry Andric Error(getLoc(), "invalid register"); 1381349cc55cSDimitry Andric return MatchOperand_ParseFail; 1382349cc55cSDimitry Andric } 1383349cc55cSDimitry Andric 1384349cc55cSDimitry Andric auto Ry = Operands.back()->getReg(); 1385349cc55cSDimitry Andric Operands.pop_back(); 1386349cc55cSDimitry Andric 1387349cc55cSDimitry Andric if (getLexer().is(AsmToken::Minus)) { 1388349cc55cSDimitry Andric getLexer().Lex(); // eat '-' 1389349cc55cSDimitry Andric 1390349cc55cSDimitry Andric if (parseRegister(Operands) != MatchOperand_Success) { 1391349cc55cSDimitry Andric Error(getLoc(), "invalid register"); 1392349cc55cSDimitry Andric return MatchOperand_ParseFail; 1393349cc55cSDimitry Andric } 1394349cc55cSDimitry Andric 1395349cc55cSDimitry Andric auto Rz = Operands.back()->getReg(); 1396349cc55cSDimitry Andric Operands.pop_back(); 1397349cc55cSDimitry Andric 1398349cc55cSDimitry Andric reglist.push_back(Ry); 1399349cc55cSDimitry Andric reglist.push_back(Rz); 1400349cc55cSDimitry Andric 1401349cc55cSDimitry Andric if (getLexer().is(AsmToken::Comma)) 1402349cc55cSDimitry Andric getLexer().Lex(); // eat ',' 1403349cc55cSDimitry Andric else if (getLexer().is(AsmToken::EndOfStatement)) 1404349cc55cSDimitry Andric break; 1405349cc55cSDimitry Andric 1406349cc55cSDimitry Andric } else if (getLexer().is(AsmToken::Comma)) { 1407349cc55cSDimitry Andric reglist.push_back(Ry); 1408349cc55cSDimitry Andric reglist.push_back(Ry); 1409349cc55cSDimitry Andric 1410349cc55cSDimitry Andric getLexer().Lex(); // eat ',' 1411349cc55cSDimitry Andric } else if (getLexer().is(AsmToken::EndOfStatement)) { 1412349cc55cSDimitry Andric reglist.push_back(Ry); 1413349cc55cSDimitry Andric reglist.push_back(Ry); 1414349cc55cSDimitry Andric break; 1415349cc55cSDimitry Andric } else { 1416349cc55cSDimitry Andric Error(getLoc(), "invalid register list"); 1417349cc55cSDimitry Andric return MatchOperand_ParseFail; 1418349cc55cSDimitry Andric } 1419349cc55cSDimitry Andric } 1420349cc55cSDimitry Andric 1421349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createRegList(reglist, S)); 1422fe6060f1SDimitry Andric return MatchOperand_Success; 1423fe6060f1SDimitry Andric } 1424fe6060f1SDimitry Andric 1425fe6060f1SDimitry Andric bool CSKYAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 1426fe6060f1SDimitry Andric SMLoc NameLoc, OperandVector &Operands) { 1427fe6060f1SDimitry Andric // First operand is token for instruction. 1428fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createToken(Name, NameLoc)); 1429fe6060f1SDimitry Andric 1430fe6060f1SDimitry Andric // If there are no more operands, then finish. 1431fe6060f1SDimitry Andric if (getLexer().is(AsmToken::EndOfStatement)) 1432fe6060f1SDimitry Andric return false; 1433fe6060f1SDimitry Andric 1434fe6060f1SDimitry Andric // Parse first operand. 1435fe6060f1SDimitry Andric if (parseOperand(Operands, Name)) 1436fe6060f1SDimitry Andric return true; 1437fe6060f1SDimitry Andric 1438fe6060f1SDimitry Andric // Parse until end of statement, consuming commas between operands. 1439fe6060f1SDimitry Andric while (getLexer().is(AsmToken::Comma)) { 1440fe6060f1SDimitry Andric // Consume comma token. 1441fe6060f1SDimitry Andric getLexer().Lex(); 1442fe6060f1SDimitry Andric 1443fe6060f1SDimitry Andric // Parse next operand. 1444fe6060f1SDimitry Andric if (parseOperand(Operands, Name)) 1445fe6060f1SDimitry Andric return true; 1446fe6060f1SDimitry Andric } 1447fe6060f1SDimitry Andric 1448fe6060f1SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) { 1449fe6060f1SDimitry Andric SMLoc Loc = getLexer().getLoc(); 1450fe6060f1SDimitry Andric getParser().eatToEndOfStatement(); 1451fe6060f1SDimitry Andric return Error(Loc, "unexpected token"); 1452fe6060f1SDimitry Andric } 1453fe6060f1SDimitry Andric 1454fe6060f1SDimitry Andric getParser().Lex(); // Consume the EndOfStatement. 1455fe6060f1SDimitry Andric return false; 1456fe6060f1SDimitry Andric } 1457fe6060f1SDimitry Andric 1458fe6060f1SDimitry Andric OperandMatchResultTy CSKYAsmParser::tryParseRegister(unsigned &RegNo, 1459fe6060f1SDimitry Andric SMLoc &StartLoc, 1460fe6060f1SDimitry Andric SMLoc &EndLoc) { 1461fe6060f1SDimitry Andric const AsmToken &Tok = getParser().getTok(); 1462fe6060f1SDimitry Andric StartLoc = Tok.getLoc(); 1463fe6060f1SDimitry Andric EndLoc = Tok.getEndLoc(); 1464fe6060f1SDimitry Andric 1465fe6060f1SDimitry Andric StringRef Name = getLexer().getTok().getIdentifier(); 1466fe6060f1SDimitry Andric 1467349cc55cSDimitry Andric if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) 1468fe6060f1SDimitry Andric return MatchOperand_NoMatch; 1469fe6060f1SDimitry Andric 1470fe6060f1SDimitry Andric getParser().Lex(); // Eat identifier token. 1471fe6060f1SDimitry Andric return MatchOperand_Success; 1472fe6060f1SDimitry Andric } 1473fe6060f1SDimitry Andric 1474fe6060f1SDimitry Andric bool CSKYAsmParser::ParseDirective(AsmToken DirectiveID) { return true; } 1475fe6060f1SDimitry Andric 14760eae32dcSDimitry Andric void CSKYAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) { 14770eae32dcSDimitry Andric MCInst CInst; 14780eae32dcSDimitry Andric bool Res = false; 14790eae32dcSDimitry Andric if (EnableCompressedInst) 14800eae32dcSDimitry Andric Res = compressInst(CInst, Inst, getSTI(), S.getContext()); 14810eae32dcSDimitry Andric if (Res) 14820eae32dcSDimitry Andric ++CSKYNumInstrsCompressed; 14830eae32dcSDimitry Andric S.emitInstruction((Res ? CInst : Inst), getSTI()); 14840eae32dcSDimitry Andric } 14850eae32dcSDimitry Andric 1486fe6060f1SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYAsmParser() { 1487fe6060f1SDimitry Andric RegisterMCAsmParser<CSKYAsmParser> X(getTheCSKYTarget()); 1488fe6060f1SDimitry Andric } 1489