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" 14*0eae32dcSDimitry 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" 29*0eae32dcSDimitry Andric #include "llvm/Support/CommandLine.h" 30349cc55cSDimitry Andric #include "llvm/Support/Debug.h" 31349cc55cSDimitry Andric 32*0eae32dcSDimitry Andric using namespace llvm; 33*0eae32dcSDimitry Andric 34349cc55cSDimitry Andric #define DEBUG_TYPE "csky-asm-parser" 35fe6060f1SDimitry Andric 36*0eae32dcSDimitry Andric // Include the auto-generated portion of the compress emitter. 37*0eae32dcSDimitry Andric #define GEN_COMPRESS_INSTR 38*0eae32dcSDimitry Andric #include "CSKYGenCompressInstEmitter.inc" 39*0eae32dcSDimitry Andric 40*0eae32dcSDimitry Andric STATISTIC(CSKYNumInstrsCompressed, 41*0eae32dcSDimitry Andric "Number of C-SKY Compressed instructions emitted"); 42*0eae32dcSDimitry Andric 43*0eae32dcSDimitry Andric static cl::opt<bool> 44*0eae32dcSDimitry Andric EnableCompressedInst("enable-csky-asm-compressed-inst", cl::Hidden, 45*0eae32dcSDimitry Andric cl::init(false), 46*0eae32dcSDimitry 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 72*0eae32dcSDimitry Andric // Helper to actually emit an instruction to the MCStreamer. Also, when 73*0eae32dcSDimitry Andric // possible, compression of the instruction is performed. 74*0eae32dcSDimitry Andric void emitToStreamer(MCStreamer &S, const MCInst &Inst); 75*0eae32dcSDimitry 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 306349cc55cSDimitry Andric static bool isLegalRegList(unsigned from, unsigned to) { 307349cc55cSDimitry Andric if (from == 0 && to == 0) 308349cc55cSDimitry Andric return true; 309349cc55cSDimitry Andric 310349cc55cSDimitry Andric if (from == to) { 311349cc55cSDimitry Andric if (from != CSKY::R4 && from != CSKY::R15 && from != CSKY::R16 && 312349cc55cSDimitry Andric from != CSKY::R28) 313349cc55cSDimitry Andric return false; 314349cc55cSDimitry Andric 315349cc55cSDimitry Andric return true; 316349cc55cSDimitry Andric } else { 317349cc55cSDimitry Andric if (from != CSKY::R4 && from != CSKY::R16) 318349cc55cSDimitry Andric return false; 319349cc55cSDimitry Andric 320349cc55cSDimitry Andric if (from == CSKY::R4 && to > CSKY::R4 && to < CSKY::R12) 321349cc55cSDimitry Andric return true; 322349cc55cSDimitry Andric else if (from == CSKY::R16 && to > CSKY::R16 && to < CSKY::R18) 323349cc55cSDimitry Andric return true; 324349cc55cSDimitry Andric else 325349cc55cSDimitry Andric return false; 326349cc55cSDimitry Andric } 327349cc55cSDimitry Andric } 328349cc55cSDimitry Andric 329349cc55cSDimitry Andric bool isRegList() const { 330349cc55cSDimitry Andric if (!isRegisterList()) 331349cc55cSDimitry Andric return false; 332349cc55cSDimitry Andric 333349cc55cSDimitry Andric auto regList = getRegList(); 334349cc55cSDimitry Andric 335349cc55cSDimitry Andric if (!isLegalRegList(regList.List1From, regList.List1To)) 336349cc55cSDimitry Andric return false; 337349cc55cSDimitry Andric if (!isLegalRegList(regList.List2From, regList.List2To)) 338349cc55cSDimitry Andric return false; 339349cc55cSDimitry Andric if (!isLegalRegList(regList.List3From, regList.List3To)) 340349cc55cSDimitry Andric return false; 341349cc55cSDimitry Andric if (!isLegalRegList(regList.List4From, regList.List4To)) 342349cc55cSDimitry Andric return false; 343349cc55cSDimitry Andric 344349cc55cSDimitry Andric return true; 345349cc55cSDimitry Andric } 346349cc55cSDimitry Andric 347349cc55cSDimitry Andric bool isExtImm6() { 348349cc55cSDimitry Andric if (!isImm()) 349349cc55cSDimitry Andric return false; 350349cc55cSDimitry Andric 351349cc55cSDimitry Andric int64_t Imm; 352349cc55cSDimitry Andric bool IsConstantImm = evaluateConstantImm(getImm(), Imm); 353349cc55cSDimitry Andric if (!IsConstantImm) 354349cc55cSDimitry Andric return false; 355349cc55cSDimitry Andric 356349cc55cSDimitry Andric int uimm4 = Imm & 0xf; 357349cc55cSDimitry Andric 358349cc55cSDimitry Andric return isShiftedUInt<6, 0>(Imm) && uimm4 >= 0 && uimm4 <= 14; 359fe6060f1SDimitry Andric } 360fe6060f1SDimitry Andric 361fe6060f1SDimitry Andric /// Gets location of the first token of this operand. 362fe6060f1SDimitry Andric SMLoc getStartLoc() const override { return StartLoc; } 363fe6060f1SDimitry Andric /// Gets location of the last token of this operand. 364fe6060f1SDimitry Andric SMLoc getEndLoc() const override { return EndLoc; } 365fe6060f1SDimitry Andric 366fe6060f1SDimitry Andric unsigned getReg() const override { 367fe6060f1SDimitry Andric assert(Kind == Register && "Invalid type access!"); 368fe6060f1SDimitry Andric return Reg.RegNum; 369fe6060f1SDimitry Andric } 370fe6060f1SDimitry Andric 371349cc55cSDimitry Andric std::pair<unsigned, unsigned> getRegSeq() const { 372349cc55cSDimitry Andric assert(Kind == RegisterSeq && "Invalid type access!"); 373349cc55cSDimitry Andric return std::pair<unsigned, unsigned>(RegSeq.RegNumFrom, RegSeq.RegNumTo); 374349cc55cSDimitry Andric } 375349cc55cSDimitry Andric 376349cc55cSDimitry Andric RegListOp getRegList() const { 377349cc55cSDimitry Andric assert(Kind == RegisterList && "Invalid type access!"); 378349cc55cSDimitry Andric return RegList; 379349cc55cSDimitry Andric } 380349cc55cSDimitry Andric 381fe6060f1SDimitry Andric const MCExpr *getImm() const { 382fe6060f1SDimitry Andric assert(Kind == Immediate && "Invalid type access!"); 383fe6060f1SDimitry Andric return Imm.Val; 384fe6060f1SDimitry Andric } 385fe6060f1SDimitry Andric 386349cc55cSDimitry Andric const MCExpr *getConstpoolOp() const { 387349cc55cSDimitry Andric assert(Kind == CPOP && "Invalid type access!"); 388349cc55cSDimitry Andric return CPool.Val; 389349cc55cSDimitry Andric } 390349cc55cSDimitry Andric 391fe6060f1SDimitry Andric StringRef getToken() const { 392fe6060f1SDimitry Andric assert(Kind == Token && "Invalid type access!"); 393fe6060f1SDimitry Andric return Tok; 394fe6060f1SDimitry Andric } 395fe6060f1SDimitry Andric 396fe6060f1SDimitry Andric void print(raw_ostream &OS) const override { 397349cc55cSDimitry Andric auto RegName = [](unsigned Reg) { 398349cc55cSDimitry Andric if (Reg) 399349cc55cSDimitry Andric return CSKYInstPrinter::getRegisterName(Reg); 400349cc55cSDimitry Andric else 401349cc55cSDimitry Andric return "noreg"; 402349cc55cSDimitry Andric }; 403349cc55cSDimitry Andric 404fe6060f1SDimitry Andric switch (Kind) { 405349cc55cSDimitry Andric case CPOP: 406349cc55cSDimitry Andric OS << *getConstpoolOp(); 407349cc55cSDimitry Andric break; 408fe6060f1SDimitry Andric case Immediate: 409fe6060f1SDimitry Andric OS << *getImm(); 410fe6060f1SDimitry Andric break; 411349cc55cSDimitry Andric case KindTy::Register: 412349cc55cSDimitry Andric OS << "<register " << RegName(getReg()) << ">"; 413349cc55cSDimitry Andric break; 414349cc55cSDimitry Andric case RegisterSeq: 415349cc55cSDimitry Andric OS << "<register-seq "; 416349cc55cSDimitry Andric OS << RegName(getRegSeq().first) << "-" << RegName(getRegSeq().second) 417349cc55cSDimitry Andric << ">"; 418349cc55cSDimitry Andric break; 419349cc55cSDimitry Andric case RegisterList: 420349cc55cSDimitry Andric OS << "<register-list "; 421349cc55cSDimitry Andric OS << RegName(getRegList().List1From) << "-" 422349cc55cSDimitry Andric << RegName(getRegList().List1To) << ","; 423349cc55cSDimitry Andric OS << RegName(getRegList().List2From) << "-" 424349cc55cSDimitry Andric << RegName(getRegList().List2To) << ","; 425349cc55cSDimitry Andric OS << RegName(getRegList().List3From) << "-" 426349cc55cSDimitry Andric << RegName(getRegList().List3To) << ","; 427349cc55cSDimitry Andric OS << RegName(getRegList().List4From) << "-" 428349cc55cSDimitry Andric << RegName(getRegList().List4To); 429fe6060f1SDimitry Andric break; 430fe6060f1SDimitry Andric case Token: 431fe6060f1SDimitry Andric OS << "'" << getToken() << "'"; 432fe6060f1SDimitry Andric break; 433fe6060f1SDimitry Andric } 434fe6060f1SDimitry Andric } 435fe6060f1SDimitry Andric 436fe6060f1SDimitry Andric static std::unique_ptr<CSKYOperand> createToken(StringRef Str, SMLoc S) { 437fe6060f1SDimitry Andric auto Op = std::make_unique<CSKYOperand>(Token); 438fe6060f1SDimitry Andric Op->Tok = Str; 439fe6060f1SDimitry Andric Op->StartLoc = S; 440fe6060f1SDimitry Andric Op->EndLoc = S; 441fe6060f1SDimitry Andric return Op; 442fe6060f1SDimitry Andric } 443fe6060f1SDimitry Andric 444fe6060f1SDimitry Andric static std::unique_ptr<CSKYOperand> createReg(unsigned RegNo, SMLoc S, 445fe6060f1SDimitry Andric SMLoc E) { 446fe6060f1SDimitry Andric auto Op = std::make_unique<CSKYOperand>(Register); 447fe6060f1SDimitry Andric Op->Reg.RegNum = RegNo; 448fe6060f1SDimitry Andric Op->StartLoc = S; 449fe6060f1SDimitry Andric Op->EndLoc = E; 450fe6060f1SDimitry Andric return Op; 451fe6060f1SDimitry Andric } 452fe6060f1SDimitry Andric 453349cc55cSDimitry Andric static std::unique_ptr<CSKYOperand> createRegSeq(unsigned RegNoFrom, 454349cc55cSDimitry Andric unsigned RegNoTo, SMLoc S) { 455349cc55cSDimitry Andric auto Op = std::make_unique<CSKYOperand>(RegisterSeq); 456349cc55cSDimitry Andric Op->RegSeq.RegNumFrom = RegNoFrom; 457349cc55cSDimitry Andric Op->RegSeq.RegNumTo = RegNoTo; 458349cc55cSDimitry Andric Op->StartLoc = S; 459349cc55cSDimitry Andric Op->EndLoc = S; 460349cc55cSDimitry Andric return Op; 461349cc55cSDimitry Andric } 462349cc55cSDimitry Andric 463349cc55cSDimitry Andric static std::unique_ptr<CSKYOperand> 464349cc55cSDimitry Andric createRegList(SmallVector<unsigned, 4> reglist, SMLoc S) { 465349cc55cSDimitry Andric auto Op = std::make_unique<CSKYOperand>(RegisterList); 466349cc55cSDimitry Andric Op->RegList.List1From = 0; 467349cc55cSDimitry Andric Op->RegList.List1To = 0; 468349cc55cSDimitry Andric Op->RegList.List2From = 0; 469349cc55cSDimitry Andric Op->RegList.List2To = 0; 470349cc55cSDimitry Andric Op->RegList.List3From = 0; 471349cc55cSDimitry Andric Op->RegList.List3To = 0; 472349cc55cSDimitry Andric Op->RegList.List4From = 0; 473349cc55cSDimitry Andric Op->RegList.List4To = 0; 474349cc55cSDimitry Andric 475349cc55cSDimitry Andric for (unsigned i = 0; i < reglist.size(); i += 2) { 476349cc55cSDimitry Andric if (Op->RegList.List1From == 0) { 477349cc55cSDimitry Andric Op->RegList.List1From = reglist[i]; 478349cc55cSDimitry Andric Op->RegList.List1To = reglist[i + 1]; 479349cc55cSDimitry Andric } else if (Op->RegList.List2From == 0) { 480349cc55cSDimitry Andric Op->RegList.List2From = reglist[i]; 481349cc55cSDimitry Andric Op->RegList.List2To = reglist[i + 1]; 482349cc55cSDimitry Andric } else if (Op->RegList.List3From == 0) { 483349cc55cSDimitry Andric Op->RegList.List3From = reglist[i]; 484349cc55cSDimitry Andric Op->RegList.List3To = reglist[i + 1]; 485349cc55cSDimitry Andric } else if (Op->RegList.List4From == 0) { 486349cc55cSDimitry Andric Op->RegList.List4From = reglist[i]; 487349cc55cSDimitry Andric Op->RegList.List4To = reglist[i + 1]; 488349cc55cSDimitry Andric } else { 489349cc55cSDimitry Andric assert(0); 490349cc55cSDimitry Andric } 491349cc55cSDimitry Andric } 492349cc55cSDimitry Andric 493349cc55cSDimitry Andric Op->StartLoc = S; 494349cc55cSDimitry Andric Op->EndLoc = S; 495349cc55cSDimitry Andric return Op; 496349cc55cSDimitry Andric } 497349cc55cSDimitry Andric 498fe6060f1SDimitry Andric static std::unique_ptr<CSKYOperand> createImm(const MCExpr *Val, SMLoc S, 499fe6060f1SDimitry Andric SMLoc E) { 500fe6060f1SDimitry Andric auto Op = std::make_unique<CSKYOperand>(Immediate); 501fe6060f1SDimitry Andric Op->Imm.Val = Val; 502fe6060f1SDimitry Andric Op->StartLoc = S; 503fe6060f1SDimitry Andric Op->EndLoc = E; 504fe6060f1SDimitry Andric return Op; 505fe6060f1SDimitry Andric } 506fe6060f1SDimitry Andric 507349cc55cSDimitry Andric static std::unique_ptr<CSKYOperand> createConstpoolOp(const MCExpr *Val, 508349cc55cSDimitry Andric SMLoc S, SMLoc E) { 509349cc55cSDimitry Andric auto Op = std::make_unique<CSKYOperand>(CPOP); 510349cc55cSDimitry Andric Op->CPool.Val = Val; 511349cc55cSDimitry Andric Op->StartLoc = S; 512349cc55cSDimitry Andric Op->EndLoc = E; 513349cc55cSDimitry Andric return Op; 514349cc55cSDimitry Andric } 515349cc55cSDimitry Andric 516fe6060f1SDimitry Andric void addExpr(MCInst &Inst, const MCExpr *Expr) const { 517fe6060f1SDimitry Andric assert(Expr && "Expr shouldn't be null!"); 518fe6060f1SDimitry Andric if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) 519fe6060f1SDimitry Andric Inst.addOperand(MCOperand::createImm(CE->getValue())); 520fe6060f1SDimitry Andric else 521fe6060f1SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr)); 522fe6060f1SDimitry Andric } 523fe6060f1SDimitry Andric 524fe6060f1SDimitry Andric // Used by the TableGen Code. 525fe6060f1SDimitry Andric void addRegOperands(MCInst &Inst, unsigned N) const { 526fe6060f1SDimitry Andric assert(N == 1 && "Invalid number of operands!"); 527fe6060f1SDimitry Andric Inst.addOperand(MCOperand::createReg(getReg())); 528fe6060f1SDimitry Andric } 529fe6060f1SDimitry Andric 530fe6060f1SDimitry Andric void addImmOperands(MCInst &Inst, unsigned N) const { 531fe6060f1SDimitry Andric assert(N == 1 && "Invalid number of operands!"); 532fe6060f1SDimitry Andric addExpr(Inst, getImm()); 533fe6060f1SDimitry Andric } 534349cc55cSDimitry Andric 535349cc55cSDimitry Andric void addConstpoolOperands(MCInst &Inst, unsigned N) const { 536349cc55cSDimitry Andric assert(N == 1 && "Invalid number of operands!"); 537349cc55cSDimitry Andric Inst.addOperand(MCOperand::createExpr(getConstpoolOp())); 538349cc55cSDimitry Andric } 539349cc55cSDimitry Andric 540349cc55cSDimitry Andric void addRegSeqOperands(MCInst &Inst, unsigned N) const { 541349cc55cSDimitry Andric assert(N == 2 && "Invalid number of operands!"); 542349cc55cSDimitry Andric auto regSeq = getRegSeq(); 543349cc55cSDimitry Andric 544349cc55cSDimitry Andric Inst.addOperand(MCOperand::createReg(regSeq.first)); 545349cc55cSDimitry Andric Inst.addOperand(MCOperand::createReg(regSeq.second)); 546349cc55cSDimitry Andric } 547349cc55cSDimitry Andric 548349cc55cSDimitry Andric static unsigned getListValue(unsigned ListFrom, unsigned ListTo) { 549349cc55cSDimitry Andric if (ListFrom == ListTo && ListFrom == CSKY::R15) 550349cc55cSDimitry Andric return (1 << 4); 551349cc55cSDimitry Andric else if (ListFrom == ListTo && ListFrom == CSKY::R28) 552349cc55cSDimitry Andric return (1 << 8); 553349cc55cSDimitry Andric else if (ListFrom == CSKY::R4) 554349cc55cSDimitry Andric return ListTo - ListFrom + 1; 555349cc55cSDimitry Andric else if (ListFrom == CSKY::R16) 556349cc55cSDimitry Andric return ((ListTo - ListFrom + 1) << 5); 557349cc55cSDimitry Andric else 558349cc55cSDimitry Andric return 0; 559349cc55cSDimitry Andric } 560349cc55cSDimitry Andric 561349cc55cSDimitry Andric void addRegListOperands(MCInst &Inst, unsigned N) const { 562349cc55cSDimitry Andric assert(N == 1 && "Invalid number of operands!"); 563349cc55cSDimitry Andric auto regList = getRegList(); 564349cc55cSDimitry Andric 565349cc55cSDimitry Andric unsigned V = 0; 566349cc55cSDimitry Andric 567349cc55cSDimitry Andric unsigned T = getListValue(regList.List1From, regList.List1To); 568349cc55cSDimitry Andric if (T != 0) 569349cc55cSDimitry Andric V = V | T; 570349cc55cSDimitry Andric 571349cc55cSDimitry Andric T = getListValue(regList.List2From, regList.List2To); 572349cc55cSDimitry Andric if (T != 0) 573349cc55cSDimitry Andric V = V | T; 574349cc55cSDimitry Andric 575349cc55cSDimitry Andric T = getListValue(regList.List3From, regList.List3To); 576349cc55cSDimitry Andric if (T != 0) 577349cc55cSDimitry Andric V = V | T; 578349cc55cSDimitry Andric 579349cc55cSDimitry Andric T = getListValue(regList.List4From, regList.List4To); 580349cc55cSDimitry Andric if (T != 0) 581349cc55cSDimitry Andric V = V | T; 582349cc55cSDimitry Andric 583349cc55cSDimitry Andric Inst.addOperand(MCOperand::createImm(V)); 584349cc55cSDimitry Andric } 585349cc55cSDimitry Andric 586349cc55cSDimitry Andric bool isValidForTie(const CSKYOperand &Other) const { 587349cc55cSDimitry Andric if (Kind != Other.Kind) 588349cc55cSDimitry Andric return false; 589349cc55cSDimitry Andric 590349cc55cSDimitry Andric switch (Kind) { 591349cc55cSDimitry Andric default: 592349cc55cSDimitry Andric llvm_unreachable("Unexpected kind"); 593349cc55cSDimitry Andric return false; 594349cc55cSDimitry Andric case Register: 595349cc55cSDimitry Andric return Reg.RegNum == Other.Reg.RegNum; 596349cc55cSDimitry Andric } 597349cc55cSDimitry Andric } 598fe6060f1SDimitry Andric }; 599fe6060f1SDimitry Andric } // end anonymous namespace. 600fe6060f1SDimitry Andric 601fe6060f1SDimitry Andric #define GET_REGISTER_MATCHER 602fe6060f1SDimitry Andric #define GET_SUBTARGET_FEATURE_NAME 603fe6060f1SDimitry Andric #define GET_MATCHER_IMPLEMENTATION 604fe6060f1SDimitry Andric #define GET_MNEMONIC_SPELL_CHECKER 605fe6060f1SDimitry Andric #include "CSKYGenAsmMatcher.inc" 606fe6060f1SDimitry Andric 607fe6060f1SDimitry Andric static std::string CSKYMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, 608fe6060f1SDimitry Andric unsigned VariantID = 0); 609fe6060f1SDimitry Andric 610fe6060f1SDimitry Andric bool CSKYAsmParser::generateImmOutOfRangeError( 611fe6060f1SDimitry Andric OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper, 612fe6060f1SDimitry Andric Twine Msg = "immediate must be an integer in the range") { 613fe6060f1SDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 614fe6060f1SDimitry Andric return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]"); 615fe6060f1SDimitry Andric } 616fe6060f1SDimitry Andric 617fe6060f1SDimitry Andric bool CSKYAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 618fe6060f1SDimitry Andric OperandVector &Operands, 619fe6060f1SDimitry Andric MCStreamer &Out, 620fe6060f1SDimitry Andric uint64_t &ErrorInfo, 621fe6060f1SDimitry Andric bool MatchingInlineAsm) { 622fe6060f1SDimitry Andric MCInst Inst; 623fe6060f1SDimitry Andric FeatureBitset MissingFeatures; 624fe6060f1SDimitry Andric 625fe6060f1SDimitry Andric auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures, 626fe6060f1SDimitry Andric MatchingInlineAsm); 627fe6060f1SDimitry Andric switch (Result) { 628fe6060f1SDimitry Andric default: 629fe6060f1SDimitry Andric break; 630fe6060f1SDimitry Andric case Match_Success: 631349cc55cSDimitry Andric return processInstruction(Inst, IDLoc, Operands, Out); 632fe6060f1SDimitry Andric case Match_MissingFeature: { 633fe6060f1SDimitry Andric assert(MissingFeatures.any() && "Unknown missing features!"); 634fe6060f1SDimitry Andric ListSeparator LS; 635fe6060f1SDimitry Andric std::string Msg = "instruction requires the following: "; 636fe6060f1SDimitry Andric for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) { 637fe6060f1SDimitry Andric if (MissingFeatures[i]) { 638fe6060f1SDimitry Andric Msg += LS; 639fe6060f1SDimitry Andric Msg += getSubtargetFeatureName(i); 640fe6060f1SDimitry Andric } 641fe6060f1SDimitry Andric } 642fe6060f1SDimitry Andric return Error(IDLoc, Msg); 643fe6060f1SDimitry Andric } 644fe6060f1SDimitry Andric case Match_MnemonicFail: { 645fe6060f1SDimitry Andric FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits()); 646fe6060f1SDimitry Andric std::string Suggestion = 647fe6060f1SDimitry Andric CSKYMnemonicSpellCheck(((CSKYOperand &)*Operands[0]).getToken(), FBS); 648fe6060f1SDimitry Andric return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion); 649fe6060f1SDimitry Andric } 650fe6060f1SDimitry Andric case Match_InvalidTiedOperand: 651fe6060f1SDimitry Andric case Match_InvalidOperand: { 652fe6060f1SDimitry Andric SMLoc ErrorLoc = IDLoc; 653fe6060f1SDimitry Andric if (ErrorInfo != ~0U) { 654fe6060f1SDimitry Andric if (ErrorInfo >= Operands.size()) 655fe6060f1SDimitry Andric return Error(ErrorLoc, "too few operands for instruction"); 656fe6060f1SDimitry Andric 657fe6060f1SDimitry Andric ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 658fe6060f1SDimitry Andric if (ErrorLoc == SMLoc()) 659fe6060f1SDimitry Andric ErrorLoc = IDLoc; 660fe6060f1SDimitry Andric } 661fe6060f1SDimitry Andric return Error(ErrorLoc, "invalid operand for instruction"); 662fe6060f1SDimitry Andric } 663fe6060f1SDimitry Andric } 664fe6060f1SDimitry Andric 665fe6060f1SDimitry Andric // Handle the case when the error message is of specific type 666fe6060f1SDimitry Andric // other than the generic Match_InvalidOperand, and the 667fe6060f1SDimitry Andric // corresponding operand is missing. 668fe6060f1SDimitry Andric if (Result > FIRST_TARGET_MATCH_RESULT_TY) { 669fe6060f1SDimitry Andric SMLoc ErrorLoc = IDLoc; 670fe6060f1SDimitry Andric if (ErrorInfo != ~0U && ErrorInfo >= Operands.size()) 671fe6060f1SDimitry Andric return Error(ErrorLoc, "too few operands for instruction"); 672fe6060f1SDimitry Andric } 673fe6060f1SDimitry Andric 674fe6060f1SDimitry Andric switch (Result) { 675fe6060f1SDimitry Andric default: 676fe6060f1SDimitry Andric break; 677349cc55cSDimitry Andric case Match_InvalidSImm8: 678349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7), 679349cc55cSDimitry Andric (1 << 7) - 1); 680349cc55cSDimitry Andric case Match_InvalidOImm3: 681349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 3)); 682349cc55cSDimitry Andric case Match_InvalidOImm4: 683349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4)); 684349cc55cSDimitry Andric case Match_InvalidOImm5: 685349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5)); 686349cc55cSDimitry Andric case Match_InvalidOImm6: 687349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6)); 688349cc55cSDimitry Andric case Match_InvalidOImm8: 689349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 8)); 690fe6060f1SDimitry Andric case Match_InvalidOImm12: 691fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 12)); 692fe6060f1SDimitry Andric case Match_InvalidOImm16: 693fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16)); 694349cc55cSDimitry Andric case Match_InvalidUImm1: 695349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1); 696fe6060f1SDimitry Andric case Match_InvalidUImm2: 697fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1); 698349cc55cSDimitry Andric case Match_InvalidUImm3: 699349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1); 700349cc55cSDimitry Andric case Match_InvalidUImm4: 701349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1); 702fe6060f1SDimitry Andric case Match_InvalidUImm5: 703fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 704349cc55cSDimitry Andric case Match_InvalidUImm6: 705349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); 706349cc55cSDimitry Andric case Match_InvalidUImm7: 707349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1); 708349cc55cSDimitry Andric case Match_InvalidUImm8: 709349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1); 710fe6060f1SDimitry Andric case Match_InvalidUImm12: 711fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1); 712349cc55cSDimitry Andric case Match_InvalidUImm16: 713349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 16) - 1); 714349cc55cSDimitry Andric case Match_InvalidUImm5Shift1: 715349cc55cSDimitry Andric return generateImmOutOfRangeError( 716349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 5) - 2, 717349cc55cSDimitry Andric "immediate must be a multiple of 2 bytes in the range"); 718fe6060f1SDimitry Andric case Match_InvalidUImm12Shift1: 719fe6060f1SDimitry Andric return generateImmOutOfRangeError( 720fe6060f1SDimitry Andric Operands, ErrorInfo, 0, (1 << 12) - 2, 721fe6060f1SDimitry Andric "immediate must be a multiple of 2 bytes in the range"); 722349cc55cSDimitry Andric case Match_InvalidUImm5Shift2: 723349cc55cSDimitry Andric return generateImmOutOfRangeError( 724349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 5) - 4, 725349cc55cSDimitry Andric "immediate must be a multiple of 4 bytes in the range"); 726349cc55cSDimitry Andric case Match_InvalidUImm7Shift1: 727349cc55cSDimitry Andric return generateImmOutOfRangeError( 728349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 7) - 2, 729349cc55cSDimitry Andric "immediate must be a multiple of 2 bytes in the range"); 730349cc55cSDimitry Andric case Match_InvalidUImm7Shift2: 731349cc55cSDimitry Andric return generateImmOutOfRangeError( 732349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 7) - 4, 733349cc55cSDimitry Andric "immediate must be a multiple of 4 bytes in the range"); 734349cc55cSDimitry Andric case Match_InvalidUImm8Shift2: 735349cc55cSDimitry Andric return generateImmOutOfRangeError( 736349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 8) - 4, 737349cc55cSDimitry Andric "immediate must be a multiple of 4 bytes in the range"); 738349cc55cSDimitry Andric case Match_InvalidUImm8Shift3: 739349cc55cSDimitry Andric return generateImmOutOfRangeError( 740349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 8) - 8, 741349cc55cSDimitry Andric "immediate must be a multiple of 8 bytes in the range"); 742349cc55cSDimitry Andric case Match_InvalidUImm8Shift8: 743349cc55cSDimitry Andric return generateImmOutOfRangeError( 744349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 8) - 256, 745349cc55cSDimitry Andric "immediate must be a multiple of 256 bytes in the range"); 746fe6060f1SDimitry Andric case Match_InvalidUImm12Shift2: 747fe6060f1SDimitry Andric return generateImmOutOfRangeError( 748fe6060f1SDimitry Andric Operands, ErrorInfo, 0, (1 << 12) - 4, 749fe6060f1SDimitry Andric "immediate must be a multiple of 4 bytes in the range"); 750fe6060f1SDimitry Andric case Match_InvalidCSKYSymbol: { 751fe6060f1SDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 752fe6060f1SDimitry Andric return Error(ErrorLoc, "operand must be a symbol name"); 753fe6060f1SDimitry Andric } 754fe6060f1SDimitry Andric case Match_InvalidConstpool: { 755fe6060f1SDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 756fe6060f1SDimitry Andric return Error(ErrorLoc, "operand must be a constpool symbol name"); 757fe6060f1SDimitry Andric } 758349cc55cSDimitry Andric case Match_InvalidPSRFlag: { 759349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 760349cc55cSDimitry Andric return Error(ErrorLoc, "psrset operand is not valid"); 761349cc55cSDimitry Andric } 762349cc55cSDimitry Andric case Match_InvalidRegSeq: { 763349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 764349cc55cSDimitry Andric return Error(ErrorLoc, "Register sequence is not valid"); 765349cc55cSDimitry Andric } 766349cc55cSDimitry Andric case Match_InvalidRegOutOfRange: { 767349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 768349cc55cSDimitry Andric return Error(ErrorLoc, "register is out of range"); 769349cc55cSDimitry Andric } 770349cc55cSDimitry Andric case Match_RequiresSameSrcAndDst: { 771349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 772349cc55cSDimitry Andric return Error(ErrorLoc, "src and dst operand must be same"); 773349cc55cSDimitry Andric } 774349cc55cSDimitry Andric case Match_InvalidRegList: { 775349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 776349cc55cSDimitry Andric return Error(ErrorLoc, "invalid register list"); 777349cc55cSDimitry Andric } 778349cc55cSDimitry Andric } 779349cc55cSDimitry Andric LLVM_DEBUG(dbgs() << "Result = " << Result); 780349cc55cSDimitry Andric llvm_unreachable("Unknown match type detected!"); 781fe6060f1SDimitry Andric } 782fe6060f1SDimitry Andric 783349cc55cSDimitry Andric bool CSKYAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 784349cc55cSDimitry Andric OperandVector &Operands, 785349cc55cSDimitry Andric MCStreamer &Out) { 786349cc55cSDimitry Andric 787*0eae32dcSDimitry Andric switch (Inst.getOpcode()) { 788*0eae32dcSDimitry Andric default: 789*0eae32dcSDimitry Andric break; 790*0eae32dcSDimitry Andric case CSKY::LDQ32: 791*0eae32dcSDimitry Andric case CSKY::STQ32: 792349cc55cSDimitry Andric if (Inst.getOperand(1).getReg() != CSKY::R4 || 793349cc55cSDimitry Andric Inst.getOperand(2).getReg() != CSKY::R7) { 794349cc55cSDimitry Andric return Error(IDLoc, "Register sequence is not valid. 'r4-r7' expected"); 795349cc55cSDimitry Andric } 796349cc55cSDimitry Andric Inst.setOpcode(Inst.getOpcode() == CSKY::LDQ32 ? CSKY::LDM32 : CSKY::STM32); 797*0eae32dcSDimitry Andric break; 798*0eae32dcSDimitry Andric case CSKY::SEXT32: 799*0eae32dcSDimitry Andric case CSKY::ZEXT32: 800349cc55cSDimitry Andric if (Inst.getOperand(2).getImm() < Inst.getOperand(3).getImm()) 801349cc55cSDimitry Andric return Error(IDLoc, "msb must be greater or equal to lsb"); 802*0eae32dcSDimitry Andric break; 803*0eae32dcSDimitry Andric case CSKY::INS32: 804349cc55cSDimitry Andric if (Inst.getOperand(3).getImm() < Inst.getOperand(4).getImm()) 805349cc55cSDimitry Andric return Error(IDLoc, "msb must be greater or equal to lsb"); 806*0eae32dcSDimitry Andric break; 807*0eae32dcSDimitry Andric case CSKY::IDLY32: 808349cc55cSDimitry Andric if (Inst.getOperand(0).getImm() > 32 || Inst.getOperand(0).getImm() < 0) 809349cc55cSDimitry Andric return Error(IDLoc, "n must be in range [0,32]"); 810*0eae32dcSDimitry Andric break; 811*0eae32dcSDimitry Andric case CSKY::ADDC32: 812*0eae32dcSDimitry Andric case CSKY::SUBC32: 813*0eae32dcSDimitry Andric case CSKY::ADDC16: 814*0eae32dcSDimitry Andric case CSKY::SUBC16: 815*0eae32dcSDimitry Andric Inst.erase(std::next(Inst.begin())); 816*0eae32dcSDimitry Andric Inst.erase(std::prev(Inst.end())); 817*0eae32dcSDimitry Andric Inst.insert(std::next(Inst.begin()), MCOperand::createReg(CSKY::C)); 818*0eae32dcSDimitry Andric Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C)); 819*0eae32dcSDimitry Andric break; 820*0eae32dcSDimitry Andric case CSKY::CMPNEI32: 821*0eae32dcSDimitry Andric case CSKY::CMPNEI16: 822*0eae32dcSDimitry Andric case CSKY::CMPNE32: 823*0eae32dcSDimitry Andric case CSKY::CMPNE16: 824*0eae32dcSDimitry Andric case CSKY::CMPHSI32: 825*0eae32dcSDimitry Andric case CSKY::CMPHSI16: 826*0eae32dcSDimitry Andric case CSKY::CMPHS32: 827*0eae32dcSDimitry Andric case CSKY::CMPHS16: 828*0eae32dcSDimitry Andric case CSKY::CMPLTI32: 829*0eae32dcSDimitry Andric case CSKY::CMPLTI16: 830*0eae32dcSDimitry Andric case CSKY::CMPLT32: 831*0eae32dcSDimitry Andric case CSKY::CMPLT16: 832*0eae32dcSDimitry Andric case CSKY::BTSTI32: 833*0eae32dcSDimitry Andric Inst.erase(Inst.begin()); 834*0eae32dcSDimitry Andric Inst.insert(Inst.begin(), MCOperand::createReg(CSKY::C)); 835*0eae32dcSDimitry Andric break; 836*0eae32dcSDimitry Andric case CSKY::MVCV32: 837*0eae32dcSDimitry Andric Inst.erase(std::next(Inst.begin())); 838*0eae32dcSDimitry Andric Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C)); 839*0eae32dcSDimitry Andric break; 840349cc55cSDimitry Andric } 841349cc55cSDimitry Andric 842*0eae32dcSDimitry Andric emitToStreamer(Out, Inst); 843349cc55cSDimitry Andric return false; 844fe6060f1SDimitry Andric } 845fe6060f1SDimitry Andric 846fe6060f1SDimitry Andric // Attempts to match Name as a register (either using the default name or 847fe6060f1SDimitry Andric // alternative ABI names), setting RegNo to the matching register. Upon 848fe6060f1SDimitry Andric // failure, returns true and sets RegNo to 0. 849349cc55cSDimitry Andric static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, 850349cc55cSDimitry Andric MCRegister &RegNo, StringRef Name) { 851fe6060f1SDimitry Andric RegNo = MatchRegisterName(Name); 852fe6060f1SDimitry Andric 853fe6060f1SDimitry Andric if (RegNo == CSKY::NoRegister) 854fe6060f1SDimitry Andric RegNo = MatchRegisterAltName(Name); 855fe6060f1SDimitry Andric 856fe6060f1SDimitry Andric return RegNo == CSKY::NoRegister; 857fe6060f1SDimitry Andric } 858fe6060f1SDimitry Andric 859fe6060f1SDimitry Andric bool CSKYAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 860fe6060f1SDimitry Andric SMLoc &EndLoc) { 861fe6060f1SDimitry Andric const AsmToken &Tok = getParser().getTok(); 862fe6060f1SDimitry Andric StartLoc = Tok.getLoc(); 863fe6060f1SDimitry Andric EndLoc = Tok.getEndLoc(); 864fe6060f1SDimitry Andric StringRef Name = getLexer().getTok().getIdentifier(); 865fe6060f1SDimitry Andric 866349cc55cSDimitry Andric if (!matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) { 867fe6060f1SDimitry Andric getParser().Lex(); // Eat identifier token. 868fe6060f1SDimitry Andric return false; 869fe6060f1SDimitry Andric } 870fe6060f1SDimitry Andric 871349cc55cSDimitry Andric return MatchOperand_NoMatch; 872fe6060f1SDimitry Andric } 873fe6060f1SDimitry Andric 874fe6060f1SDimitry Andric OperandMatchResultTy CSKYAsmParser::parseRegister(OperandVector &Operands) { 875fe6060f1SDimitry Andric SMLoc S = getLoc(); 876fe6060f1SDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 877fe6060f1SDimitry Andric 878fe6060f1SDimitry Andric switch (getLexer().getKind()) { 879fe6060f1SDimitry Andric default: 880fe6060f1SDimitry Andric return MatchOperand_NoMatch; 881fe6060f1SDimitry Andric case AsmToken::Identifier: { 882fe6060f1SDimitry Andric StringRef Name = getLexer().getTok().getIdentifier(); 883fe6060f1SDimitry Andric MCRegister RegNo; 884fe6060f1SDimitry Andric 885349cc55cSDimitry Andric if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) 886fe6060f1SDimitry Andric return MatchOperand_NoMatch; 887fe6060f1SDimitry Andric 888fe6060f1SDimitry Andric getLexer().Lex(); 889fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createReg(RegNo, S, E)); 890fe6060f1SDimitry Andric 891fe6060f1SDimitry Andric return MatchOperand_Success; 892fe6060f1SDimitry Andric } 893fe6060f1SDimitry Andric } 894fe6060f1SDimitry Andric } 895fe6060f1SDimitry Andric 896fe6060f1SDimitry Andric OperandMatchResultTy CSKYAsmParser::parseBaseRegImm(OperandVector &Operands) { 897fe6060f1SDimitry Andric assert(getLexer().is(AsmToken::LParen)); 898fe6060f1SDimitry Andric 899fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createToken("(", getLoc())); 900fe6060f1SDimitry Andric 901fe6060f1SDimitry Andric auto Tok = getParser().Lex(); // Eat '(' 902fe6060f1SDimitry Andric 903fe6060f1SDimitry Andric if (parseRegister(Operands) != MatchOperand_Success) { 904fe6060f1SDimitry Andric getLexer().UnLex(Tok); 905fe6060f1SDimitry Andric Operands.pop_back(); 906349cc55cSDimitry Andric return MatchOperand_NoMatch; 907349cc55cSDimitry Andric } 908349cc55cSDimitry Andric 909349cc55cSDimitry Andric if (getLexer().is(AsmToken::RParen)) { 910349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createToken(")", getLoc())); 911349cc55cSDimitry Andric getParser().Lex(); // Eat ')' 912349cc55cSDimitry Andric return MatchOperand_Success; 913fe6060f1SDimitry Andric } 914fe6060f1SDimitry Andric 915fe6060f1SDimitry Andric if (getLexer().isNot(AsmToken::Comma)) { 916fe6060f1SDimitry Andric Error(getLoc(), "expected ','"); 917fe6060f1SDimitry Andric return MatchOperand_ParseFail; 918fe6060f1SDimitry Andric } 919fe6060f1SDimitry Andric 920fe6060f1SDimitry Andric getParser().Lex(); // Eat ',' 921fe6060f1SDimitry Andric 922fe6060f1SDimitry Andric if (parseRegister(Operands) == MatchOperand_Success) { 923fe6060f1SDimitry Andric if (getLexer().isNot(AsmToken::LessLess)) { 924fe6060f1SDimitry Andric Error(getLoc(), "expected '<<'"); 925fe6060f1SDimitry Andric return MatchOperand_ParseFail; 926fe6060f1SDimitry Andric } 927fe6060f1SDimitry Andric 928fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createToken("<<", getLoc())); 929fe6060f1SDimitry Andric 930fe6060f1SDimitry Andric getParser().Lex(); // Eat '<<' 931fe6060f1SDimitry Andric 932fe6060f1SDimitry Andric if (parseImmediate(Operands) != MatchOperand_Success) { 933fe6060f1SDimitry Andric Error(getLoc(), "expected imm"); 934fe6060f1SDimitry Andric return MatchOperand_ParseFail; 935fe6060f1SDimitry Andric } 936fe6060f1SDimitry Andric 937fe6060f1SDimitry Andric } else if (parseImmediate(Operands) != MatchOperand_Success) { 938fe6060f1SDimitry Andric Error(getLoc(), "expected imm"); 939fe6060f1SDimitry Andric return MatchOperand_ParseFail; 940fe6060f1SDimitry Andric } 941fe6060f1SDimitry Andric 942fe6060f1SDimitry Andric if (getLexer().isNot(AsmToken::RParen)) { 943fe6060f1SDimitry Andric Error(getLoc(), "expected ')'"); 944fe6060f1SDimitry Andric return MatchOperand_ParseFail; 945fe6060f1SDimitry Andric } 946fe6060f1SDimitry Andric 947fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createToken(")", getLoc())); 948fe6060f1SDimitry Andric 949fe6060f1SDimitry Andric getParser().Lex(); // Eat ')' 950fe6060f1SDimitry Andric 951fe6060f1SDimitry Andric return MatchOperand_Success; 952fe6060f1SDimitry Andric } 953fe6060f1SDimitry Andric 954fe6060f1SDimitry Andric OperandMatchResultTy CSKYAsmParser::parseImmediate(OperandVector &Operands) { 955fe6060f1SDimitry Andric switch (getLexer().getKind()) { 956fe6060f1SDimitry Andric default: 957fe6060f1SDimitry Andric return MatchOperand_NoMatch; 958fe6060f1SDimitry Andric case AsmToken::LParen: 959fe6060f1SDimitry Andric case AsmToken::Minus: 960fe6060f1SDimitry Andric case AsmToken::Plus: 961fe6060f1SDimitry Andric case AsmToken::Integer: 962fe6060f1SDimitry Andric case AsmToken::String: 963fe6060f1SDimitry Andric break; 964fe6060f1SDimitry Andric } 965fe6060f1SDimitry Andric 966fe6060f1SDimitry Andric const MCExpr *IdVal; 967fe6060f1SDimitry Andric SMLoc S = getLoc(); 968349cc55cSDimitry Andric if (getParser().parseExpression(IdVal)) { 969349cc55cSDimitry Andric Error(getLoc(), "unknown expression"); 970fe6060f1SDimitry Andric return MatchOperand_ParseFail; 971349cc55cSDimitry Andric } 972fe6060f1SDimitry Andric 973fe6060f1SDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 974fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createImm(IdVal, S, E)); 975fe6060f1SDimitry Andric return MatchOperand_Success; 976fe6060f1SDimitry Andric } 977fe6060f1SDimitry Andric 978fe6060f1SDimitry Andric /// Looks at a token type and creates the relevant operand from this 979fe6060f1SDimitry Andric /// information, adding to Operands. If operand was parsed, returns false, else 980fe6060f1SDimitry Andric /// true. 981fe6060f1SDimitry Andric bool CSKYAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 982fe6060f1SDimitry Andric // Check if the current operand has a custom associated parser, if so, try to 983fe6060f1SDimitry Andric // custom parse the operand, or fallback to the general approach. 984fe6060f1SDimitry Andric OperandMatchResultTy Result = 985fe6060f1SDimitry Andric MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true); 986fe6060f1SDimitry Andric if (Result == MatchOperand_Success) 987fe6060f1SDimitry Andric return false; 988fe6060f1SDimitry Andric if (Result == MatchOperand_ParseFail) 989fe6060f1SDimitry Andric return true; 990fe6060f1SDimitry Andric 991fe6060f1SDimitry Andric // Attempt to parse token as register 992349cc55cSDimitry Andric auto Res = parseRegister(Operands); 993349cc55cSDimitry Andric if (Res == MatchOperand_Success) 994fe6060f1SDimitry Andric return false; 995349cc55cSDimitry Andric else if (Res == MatchOperand_ParseFail) 996349cc55cSDimitry Andric return true; 997fe6060f1SDimitry Andric 998fe6060f1SDimitry Andric // Attempt to parse token as (register, imm) 999349cc55cSDimitry Andric if (getLexer().is(AsmToken::LParen)) { 1000349cc55cSDimitry Andric Res = parseBaseRegImm(Operands); 1001349cc55cSDimitry Andric if (Res == MatchOperand_Success) 1002fe6060f1SDimitry Andric return false; 1003349cc55cSDimitry Andric else if (Res == MatchOperand_ParseFail) 1004349cc55cSDimitry Andric return true; 1005349cc55cSDimitry Andric } 1006fe6060f1SDimitry Andric 1007349cc55cSDimitry Andric Res = parseImmediate(Operands); 1008349cc55cSDimitry Andric if (Res == MatchOperand_Success) 1009fe6060f1SDimitry Andric return false; 1010349cc55cSDimitry Andric else if (Res == MatchOperand_ParseFail) 1011349cc55cSDimitry Andric return true; 1012fe6060f1SDimitry Andric 1013fe6060f1SDimitry Andric // Finally we have exhausted all options and must declare defeat. 1014fe6060f1SDimitry Andric Error(getLoc(), "unknown operand"); 1015fe6060f1SDimitry Andric return true; 1016fe6060f1SDimitry Andric } 1017fe6060f1SDimitry Andric 1018fe6060f1SDimitry Andric OperandMatchResultTy CSKYAsmParser::parseCSKYSymbol(OperandVector &Operands) { 1019fe6060f1SDimitry Andric SMLoc S = getLoc(); 1020fe6060f1SDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1021349cc55cSDimitry Andric const MCExpr *Res; 1022fe6060f1SDimitry Andric 1023fe6060f1SDimitry Andric if (getLexer().getKind() != AsmToken::Identifier) 1024fe6060f1SDimitry Andric return MatchOperand_NoMatch; 1025fe6060f1SDimitry Andric 1026fe6060f1SDimitry Andric StringRef Identifier; 1027349cc55cSDimitry Andric AsmToken Tok = getLexer().getTok(); 1028349cc55cSDimitry Andric 1029349cc55cSDimitry Andric if (getParser().parseIdentifier(Identifier)) { 1030349cc55cSDimitry Andric Error(getLoc(), "unknown identifier"); 1031fe6060f1SDimitry Andric return MatchOperand_ParseFail; 1032349cc55cSDimitry Andric } 1033fe6060f1SDimitry Andric 1034fe6060f1SDimitry Andric CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None; 1035fe6060f1SDimitry Andric if (Identifier.consume_back("@GOT")) 1036fe6060f1SDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOT; 1037fe6060f1SDimitry Andric else if (Identifier.consume_back("@GOTOFF")) 1038fe6060f1SDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOTOFF; 1039fe6060f1SDimitry Andric else if (Identifier.consume_back("@PLT")) 1040fe6060f1SDimitry Andric Kind = CSKYMCExpr::VK_CSKY_PLT; 1041fe6060f1SDimitry Andric else if (Identifier.consume_back("@GOTPC")) 1042fe6060f1SDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOTPC; 1043349cc55cSDimitry Andric else if (Identifier.consume_back("@TLSGD32")) 1044349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSGD; 1045349cc55cSDimitry Andric else if (Identifier.consume_back("@GOTTPOFF")) 1046349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSIE; 1047349cc55cSDimitry Andric else if (Identifier.consume_back("@TPOFF")) 1048349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSLE; 1049349cc55cSDimitry Andric else if (Identifier.consume_back("@TLSLDM32")) 1050349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSLDM; 1051349cc55cSDimitry Andric else if (Identifier.consume_back("@TLSLDO32")) 1052349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSLDO; 1053fe6060f1SDimitry Andric 1054349cc55cSDimitry Andric MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier); 1055fe6060f1SDimitry Andric 1056349cc55cSDimitry Andric if (!Sym) 1057349cc55cSDimitry Andric Sym = getContext().getOrCreateSymbol(Identifier); 1058349cc55cSDimitry Andric 1059349cc55cSDimitry Andric if (Sym->isVariable()) { 1060349cc55cSDimitry Andric const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1061349cc55cSDimitry Andric if (!isa<MCSymbolRefExpr>(V)) { 1062349cc55cSDimitry Andric getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1063349cc55cSDimitry Andric Error(getLoc(), "unknown symbol"); 1064349cc55cSDimitry Andric return MatchOperand_ParseFail; 1065349cc55cSDimitry Andric } 1066349cc55cSDimitry Andric Res = V; 1067349cc55cSDimitry Andric } else 1068349cc55cSDimitry Andric Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1069349cc55cSDimitry Andric 1070349cc55cSDimitry Andric MCBinaryExpr::Opcode Opcode; 1071349cc55cSDimitry Andric switch (getLexer().getKind()) { 1072349cc55cSDimitry Andric default: 1073fe6060f1SDimitry Andric if (Kind != CSKYMCExpr::VK_CSKY_None) 1074fe6060f1SDimitry Andric Res = CSKYMCExpr::create(Res, Kind, getContext()); 1075fe6060f1SDimitry Andric 1076fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createImm(Res, S, E)); 1077fe6060f1SDimitry Andric return MatchOperand_Success; 1078349cc55cSDimitry Andric case AsmToken::Plus: 1079349cc55cSDimitry Andric Opcode = MCBinaryExpr::Add; 1080349cc55cSDimitry Andric break; 1081349cc55cSDimitry Andric case AsmToken::Minus: 1082349cc55cSDimitry Andric Opcode = MCBinaryExpr::Sub; 1083349cc55cSDimitry Andric break; 1084349cc55cSDimitry Andric } 1085349cc55cSDimitry Andric 1086349cc55cSDimitry Andric getLexer().Lex(); // eat + or - 1087349cc55cSDimitry Andric 1088349cc55cSDimitry Andric const MCExpr *Expr; 1089349cc55cSDimitry Andric if (getParser().parseExpression(Expr)) { 1090349cc55cSDimitry Andric Error(getLoc(), "unknown expression"); 1091349cc55cSDimitry Andric return MatchOperand_ParseFail; 1092349cc55cSDimitry Andric } 1093349cc55cSDimitry Andric Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1094349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createImm(Res, S, E)); 1095349cc55cSDimitry Andric return MatchOperand_Success; 1096349cc55cSDimitry Andric } 1097349cc55cSDimitry Andric 1098349cc55cSDimitry Andric OperandMatchResultTy CSKYAsmParser::parseDataSymbol(OperandVector &Operands) { 1099349cc55cSDimitry Andric SMLoc S = getLoc(); 1100349cc55cSDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1101349cc55cSDimitry Andric const MCExpr *Res; 1102349cc55cSDimitry Andric 1103349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::LBrac) 1104349cc55cSDimitry Andric return MatchOperand_NoMatch; 1105349cc55cSDimitry Andric 1106349cc55cSDimitry Andric getLexer().Lex(); // Eat '['. 1107349cc55cSDimitry Andric 1108349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::Identifier) { 1109349cc55cSDimitry Andric const MCExpr *Expr; 1110349cc55cSDimitry Andric if (getParser().parseExpression(Expr)) { 1111349cc55cSDimitry Andric Error(getLoc(), "unknown expression"); 1112349cc55cSDimitry Andric return MatchOperand_ParseFail; 1113349cc55cSDimitry Andric } 1114349cc55cSDimitry Andric 1115349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::RBrac) { 1116349cc55cSDimitry Andric Error(getLoc(), "expected ]"); 1117349cc55cSDimitry Andric return MatchOperand_ParseFail; 1118349cc55cSDimitry Andric } 1119349cc55cSDimitry Andric 1120349cc55cSDimitry Andric getLexer().Lex(); // Eat ']'. 1121349cc55cSDimitry Andric 1122349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E)); 1123349cc55cSDimitry Andric return MatchOperand_Success; 1124349cc55cSDimitry Andric } 1125349cc55cSDimitry Andric 1126349cc55cSDimitry Andric AsmToken Tok = getLexer().getTok(); 1127349cc55cSDimitry Andric StringRef Identifier; 1128349cc55cSDimitry Andric 1129349cc55cSDimitry Andric if (getParser().parseIdentifier(Identifier)) { 1130349cc55cSDimitry Andric Error(getLoc(), "unknown identifier " + Identifier); 1131349cc55cSDimitry Andric return MatchOperand_ParseFail; 1132349cc55cSDimitry Andric } 1133349cc55cSDimitry Andric 1134349cc55cSDimitry Andric CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None; 1135349cc55cSDimitry Andric if (Identifier.consume_back("@GOT")) 1136349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOT_IMM18_BY4; 1137349cc55cSDimitry Andric else if (Identifier.consume_back("@PLT")) 1138349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_PLT_IMM18_BY4; 1139349cc55cSDimitry Andric 1140349cc55cSDimitry Andric MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier); 1141349cc55cSDimitry Andric 1142349cc55cSDimitry Andric if (!Sym) 1143349cc55cSDimitry Andric Sym = getContext().getOrCreateSymbol(Identifier); 1144349cc55cSDimitry Andric 1145349cc55cSDimitry Andric if (Sym->isVariable()) { 1146349cc55cSDimitry Andric const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1147349cc55cSDimitry Andric if (!isa<MCSymbolRefExpr>(V)) { 1148349cc55cSDimitry Andric getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1149349cc55cSDimitry Andric Error(getLoc(), "unknown symbol"); 1150349cc55cSDimitry Andric return MatchOperand_ParseFail; 1151349cc55cSDimitry Andric } 1152349cc55cSDimitry Andric Res = V; 1153349cc55cSDimitry Andric } else { 1154349cc55cSDimitry Andric Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1155349cc55cSDimitry Andric } 1156349cc55cSDimitry Andric 1157349cc55cSDimitry Andric MCBinaryExpr::Opcode Opcode; 1158349cc55cSDimitry Andric switch (getLexer().getKind()) { 1159349cc55cSDimitry Andric default: 1160349cc55cSDimitry Andric Error(getLoc(), "unknown symbol"); 1161349cc55cSDimitry Andric return MatchOperand_ParseFail; 1162349cc55cSDimitry Andric case AsmToken::RBrac: 1163349cc55cSDimitry Andric 1164349cc55cSDimitry Andric getLexer().Lex(); // Eat ']'. 1165349cc55cSDimitry Andric 1166349cc55cSDimitry Andric if (Kind != CSKYMCExpr::VK_CSKY_None) 1167349cc55cSDimitry Andric Res = CSKYMCExpr::create(Res, Kind, getContext()); 1168349cc55cSDimitry Andric 1169349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1170349cc55cSDimitry Andric return MatchOperand_Success; 1171349cc55cSDimitry Andric case AsmToken::Plus: 1172349cc55cSDimitry Andric Opcode = MCBinaryExpr::Add; 1173349cc55cSDimitry Andric break; 1174349cc55cSDimitry Andric case AsmToken::Minus: 1175349cc55cSDimitry Andric Opcode = MCBinaryExpr::Sub; 1176349cc55cSDimitry Andric break; 1177349cc55cSDimitry Andric } 1178349cc55cSDimitry Andric 1179349cc55cSDimitry Andric getLexer().Lex(); // eat + or - 1180349cc55cSDimitry Andric 1181349cc55cSDimitry Andric const MCExpr *Expr; 1182349cc55cSDimitry Andric if (getParser().parseExpression(Expr)) { 1183349cc55cSDimitry Andric Error(getLoc(), "unknown expression"); 1184349cc55cSDimitry Andric return MatchOperand_ParseFail; 1185349cc55cSDimitry Andric } 1186349cc55cSDimitry Andric 1187349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::RBrac) { 1188349cc55cSDimitry Andric Error(getLoc(), "expected ']'"); 1189349cc55cSDimitry Andric return MatchOperand_ParseFail; 1190349cc55cSDimitry Andric } 1191349cc55cSDimitry Andric 1192349cc55cSDimitry Andric getLexer().Lex(); // Eat ']'. 1193349cc55cSDimitry Andric 1194349cc55cSDimitry Andric Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1195349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1196349cc55cSDimitry Andric return MatchOperand_Success; 1197fe6060f1SDimitry Andric } 1198fe6060f1SDimitry Andric 1199fe6060f1SDimitry Andric OperandMatchResultTy 1200fe6060f1SDimitry Andric CSKYAsmParser::parseConstpoolSymbol(OperandVector &Operands) { 1201fe6060f1SDimitry Andric SMLoc S = getLoc(); 1202fe6060f1SDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1203349cc55cSDimitry Andric const MCExpr *Res; 1204fe6060f1SDimitry Andric 1205fe6060f1SDimitry Andric if (getLexer().getKind() != AsmToken::LBrac) 1206fe6060f1SDimitry Andric return MatchOperand_NoMatch; 1207fe6060f1SDimitry Andric 1208fe6060f1SDimitry Andric getLexer().Lex(); // Eat '['. 1209fe6060f1SDimitry Andric 1210349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::Identifier) { 1211349cc55cSDimitry Andric const MCExpr *Expr; 1212349cc55cSDimitry Andric if (getParser().parseExpression(Expr)) { 1213349cc55cSDimitry Andric Error(getLoc(), "unknown expression"); 1214fe6060f1SDimitry Andric return MatchOperand_ParseFail; 1215349cc55cSDimitry Andric } 1216fe6060f1SDimitry Andric 1217349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::RBrac) { 1218349cc55cSDimitry Andric Error(getLoc(), "expected ']'"); 1219349cc55cSDimitry Andric return MatchOperand_ParseFail; 1220349cc55cSDimitry Andric } 1221fe6060f1SDimitry Andric 1222fe6060f1SDimitry Andric getLexer().Lex(); // Eat ']'. 1223fe6060f1SDimitry Andric 1224349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E)); 1225349cc55cSDimitry Andric return MatchOperand_Success; 1226349cc55cSDimitry Andric } 1227349cc55cSDimitry Andric 1228349cc55cSDimitry Andric AsmToken Tok = getLexer().getTok(); 1229349cc55cSDimitry Andric StringRef Identifier; 1230349cc55cSDimitry Andric 1231349cc55cSDimitry Andric if (getParser().parseIdentifier(Identifier)) { 1232349cc55cSDimitry Andric Error(getLoc(), "unknown identifier"); 1233349cc55cSDimitry Andric return MatchOperand_ParseFail; 1234349cc55cSDimitry Andric } 1235349cc55cSDimitry Andric 1236349cc55cSDimitry Andric MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier); 1237349cc55cSDimitry Andric 1238349cc55cSDimitry Andric if (!Sym) 1239349cc55cSDimitry Andric Sym = getContext().getOrCreateSymbol(Identifier); 1240349cc55cSDimitry Andric 1241349cc55cSDimitry Andric if (Sym->isVariable()) { 1242349cc55cSDimitry Andric const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1243349cc55cSDimitry Andric if (!isa<MCSymbolRefExpr>(V)) { 1244349cc55cSDimitry Andric getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1245349cc55cSDimitry Andric Error(getLoc(), "unknown symbol"); 1246349cc55cSDimitry Andric return MatchOperand_ParseFail; 1247349cc55cSDimitry Andric } 1248349cc55cSDimitry Andric Res = V; 1249349cc55cSDimitry Andric } else { 1250349cc55cSDimitry Andric Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1251349cc55cSDimitry Andric } 1252349cc55cSDimitry Andric 1253349cc55cSDimitry Andric MCBinaryExpr::Opcode Opcode; 1254349cc55cSDimitry Andric switch (getLexer().getKind()) { 1255349cc55cSDimitry Andric default: 1256349cc55cSDimitry Andric Error(getLoc(), "unknown symbol"); 1257349cc55cSDimitry Andric return MatchOperand_ParseFail; 1258349cc55cSDimitry Andric case AsmToken::RBrac: 1259349cc55cSDimitry Andric 1260349cc55cSDimitry Andric getLexer().Lex(); // Eat ']'. 1261349cc55cSDimitry Andric 1262349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1263349cc55cSDimitry Andric return MatchOperand_Success; 1264349cc55cSDimitry Andric case AsmToken::Plus: 1265349cc55cSDimitry Andric Opcode = MCBinaryExpr::Add; 1266349cc55cSDimitry Andric break; 1267349cc55cSDimitry Andric case AsmToken::Minus: 1268349cc55cSDimitry Andric Opcode = MCBinaryExpr::Sub; 1269349cc55cSDimitry Andric break; 1270349cc55cSDimitry Andric } 1271349cc55cSDimitry Andric 1272349cc55cSDimitry Andric getLexer().Lex(); // eat + or - 1273349cc55cSDimitry Andric 1274349cc55cSDimitry Andric const MCExpr *Expr; 1275349cc55cSDimitry Andric if (getParser().parseExpression(Expr)) { 1276349cc55cSDimitry Andric Error(getLoc(), "unknown expression"); 1277349cc55cSDimitry Andric return MatchOperand_ParseFail; 1278349cc55cSDimitry Andric } 1279349cc55cSDimitry Andric 1280349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::RBrac) { 1281349cc55cSDimitry Andric Error(getLoc(), "expected ']'"); 1282349cc55cSDimitry Andric return MatchOperand_ParseFail; 1283349cc55cSDimitry Andric } 1284349cc55cSDimitry Andric 1285349cc55cSDimitry Andric getLexer().Lex(); // Eat ']'. 1286349cc55cSDimitry Andric 1287349cc55cSDimitry Andric Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1288349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1289349cc55cSDimitry Andric return MatchOperand_Success; 1290349cc55cSDimitry Andric } 1291349cc55cSDimitry Andric 1292349cc55cSDimitry Andric OperandMatchResultTy CSKYAsmParser::parsePSRFlag(OperandVector &Operands) { 1293349cc55cSDimitry Andric SMLoc S = getLoc(); 1294349cc55cSDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1295349cc55cSDimitry Andric 1296349cc55cSDimitry Andric unsigned Flag = 0; 1297349cc55cSDimitry Andric 1298349cc55cSDimitry Andric while (getLexer().isNot(AsmToken::EndOfStatement)) { 1299349cc55cSDimitry Andric StringRef Identifier; 1300349cc55cSDimitry Andric if (getParser().parseIdentifier(Identifier)) { 1301349cc55cSDimitry Andric Error(getLoc(), "unknown identifier " + Identifier); 1302349cc55cSDimitry Andric return MatchOperand_ParseFail; 1303349cc55cSDimitry Andric } 1304349cc55cSDimitry Andric 1305349cc55cSDimitry Andric if (Identifier == "sie") 1306349cc55cSDimitry Andric Flag = (1 << 4) | Flag; 1307349cc55cSDimitry Andric else if (Identifier == "ee") 1308349cc55cSDimitry Andric Flag = (1 << 3) | Flag; 1309349cc55cSDimitry Andric else if (Identifier == "ie") 1310349cc55cSDimitry Andric Flag = (1 << 2) | Flag; 1311349cc55cSDimitry Andric else if (Identifier == "fe") 1312349cc55cSDimitry Andric Flag = (1 << 1) | Flag; 1313349cc55cSDimitry Andric else if (Identifier == "af") 1314349cc55cSDimitry Andric Flag = (1 << 0) | Flag; 1315349cc55cSDimitry Andric else { 1316349cc55cSDimitry Andric Error(getLoc(), "expected " + Identifier); 1317349cc55cSDimitry Andric return MatchOperand_ParseFail; 1318349cc55cSDimitry Andric } 1319349cc55cSDimitry Andric 1320349cc55cSDimitry Andric if (getLexer().is(AsmToken::EndOfStatement)) 1321349cc55cSDimitry Andric break; 1322349cc55cSDimitry Andric 1323349cc55cSDimitry Andric if (getLexer().is(AsmToken::Comma)) { 1324349cc55cSDimitry Andric getLexer().Lex(); // eat ',' 1325349cc55cSDimitry Andric } else { 1326349cc55cSDimitry Andric Error(getLoc(), "expected ,"); 1327349cc55cSDimitry Andric return MatchOperand_ParseFail; 1328349cc55cSDimitry Andric } 1329349cc55cSDimitry Andric } 1330349cc55cSDimitry Andric 1331349cc55cSDimitry Andric Operands.push_back( 1332349cc55cSDimitry Andric CSKYOperand::createImm(MCConstantExpr::create(Flag, getContext()), S, E)); 1333349cc55cSDimitry Andric return MatchOperand_Success; 1334349cc55cSDimitry Andric } 1335349cc55cSDimitry Andric 1336349cc55cSDimitry Andric OperandMatchResultTy CSKYAsmParser::parseRegSeq(OperandVector &Operands) { 1337349cc55cSDimitry Andric SMLoc S = getLoc(); 1338349cc55cSDimitry Andric 1339349cc55cSDimitry Andric if (parseRegister(Operands) != MatchOperand_Success) 1340349cc55cSDimitry Andric return MatchOperand_NoMatch; 1341349cc55cSDimitry Andric 1342349cc55cSDimitry Andric auto Ry = Operands.back()->getReg(); 1343349cc55cSDimitry Andric Operands.pop_back(); 1344349cc55cSDimitry Andric 1345349cc55cSDimitry Andric if (getLexer().isNot(AsmToken::Minus)) { 1346349cc55cSDimitry Andric Error(getLoc(), "expected '-'"); 1347349cc55cSDimitry Andric return MatchOperand_ParseFail; 1348349cc55cSDimitry Andric } 1349349cc55cSDimitry Andric 1350349cc55cSDimitry Andric getLexer().Lex(); // eat '-' 1351349cc55cSDimitry Andric 1352349cc55cSDimitry Andric if (parseRegister(Operands) != MatchOperand_Success) { 1353349cc55cSDimitry Andric Error(getLoc(), "invalid register"); 1354349cc55cSDimitry Andric return MatchOperand_ParseFail; 1355349cc55cSDimitry Andric } 1356349cc55cSDimitry Andric 1357349cc55cSDimitry Andric auto Rz = Operands.back()->getReg(); 1358349cc55cSDimitry Andric Operands.pop_back(); 1359349cc55cSDimitry Andric 1360349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createRegSeq(Ry, Rz, S)); 1361349cc55cSDimitry Andric return MatchOperand_Success; 1362349cc55cSDimitry Andric } 1363349cc55cSDimitry Andric 1364349cc55cSDimitry Andric OperandMatchResultTy CSKYAsmParser::parseRegList(OperandVector &Operands) { 1365349cc55cSDimitry Andric SMLoc S = getLoc(); 1366349cc55cSDimitry Andric 1367349cc55cSDimitry Andric SmallVector<unsigned, 4> reglist; 1368349cc55cSDimitry Andric 1369349cc55cSDimitry Andric while (true) { 1370349cc55cSDimitry Andric 1371349cc55cSDimitry Andric if (parseRegister(Operands) != MatchOperand_Success) { 1372349cc55cSDimitry Andric Error(getLoc(), "invalid register"); 1373349cc55cSDimitry Andric return MatchOperand_ParseFail; 1374349cc55cSDimitry Andric } 1375349cc55cSDimitry Andric 1376349cc55cSDimitry Andric auto Ry = Operands.back()->getReg(); 1377349cc55cSDimitry Andric Operands.pop_back(); 1378349cc55cSDimitry Andric 1379349cc55cSDimitry Andric if (getLexer().is(AsmToken::Minus)) { 1380349cc55cSDimitry Andric getLexer().Lex(); // eat '-' 1381349cc55cSDimitry Andric 1382349cc55cSDimitry Andric if (parseRegister(Operands) != MatchOperand_Success) { 1383349cc55cSDimitry Andric Error(getLoc(), "invalid register"); 1384349cc55cSDimitry Andric return MatchOperand_ParseFail; 1385349cc55cSDimitry Andric } 1386349cc55cSDimitry Andric 1387349cc55cSDimitry Andric auto Rz = Operands.back()->getReg(); 1388349cc55cSDimitry Andric Operands.pop_back(); 1389349cc55cSDimitry Andric 1390349cc55cSDimitry Andric reglist.push_back(Ry); 1391349cc55cSDimitry Andric reglist.push_back(Rz); 1392349cc55cSDimitry Andric 1393349cc55cSDimitry Andric if (getLexer().is(AsmToken::Comma)) 1394349cc55cSDimitry Andric getLexer().Lex(); // eat ',' 1395349cc55cSDimitry Andric else if (getLexer().is(AsmToken::EndOfStatement)) 1396349cc55cSDimitry Andric break; 1397349cc55cSDimitry Andric 1398349cc55cSDimitry Andric } else if (getLexer().is(AsmToken::Comma)) { 1399349cc55cSDimitry Andric reglist.push_back(Ry); 1400349cc55cSDimitry Andric reglist.push_back(Ry); 1401349cc55cSDimitry Andric 1402349cc55cSDimitry Andric getLexer().Lex(); // eat ',' 1403349cc55cSDimitry Andric } else if (getLexer().is(AsmToken::EndOfStatement)) { 1404349cc55cSDimitry Andric reglist.push_back(Ry); 1405349cc55cSDimitry Andric reglist.push_back(Ry); 1406349cc55cSDimitry Andric break; 1407349cc55cSDimitry Andric } else { 1408349cc55cSDimitry Andric Error(getLoc(), "invalid register list"); 1409349cc55cSDimitry Andric return MatchOperand_ParseFail; 1410349cc55cSDimitry Andric } 1411349cc55cSDimitry Andric } 1412349cc55cSDimitry Andric 1413349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createRegList(reglist, S)); 1414fe6060f1SDimitry Andric return MatchOperand_Success; 1415fe6060f1SDimitry Andric } 1416fe6060f1SDimitry Andric 1417fe6060f1SDimitry Andric bool CSKYAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 1418fe6060f1SDimitry Andric SMLoc NameLoc, OperandVector &Operands) { 1419fe6060f1SDimitry Andric // First operand is token for instruction. 1420fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createToken(Name, NameLoc)); 1421fe6060f1SDimitry Andric 1422fe6060f1SDimitry Andric // If there are no more operands, then finish. 1423fe6060f1SDimitry Andric if (getLexer().is(AsmToken::EndOfStatement)) 1424fe6060f1SDimitry Andric return false; 1425fe6060f1SDimitry Andric 1426fe6060f1SDimitry Andric // Parse first operand. 1427fe6060f1SDimitry Andric if (parseOperand(Operands, Name)) 1428fe6060f1SDimitry Andric return true; 1429fe6060f1SDimitry Andric 1430fe6060f1SDimitry Andric // Parse until end of statement, consuming commas between operands. 1431fe6060f1SDimitry Andric while (getLexer().is(AsmToken::Comma)) { 1432fe6060f1SDimitry Andric // Consume comma token. 1433fe6060f1SDimitry Andric getLexer().Lex(); 1434fe6060f1SDimitry Andric 1435fe6060f1SDimitry Andric // Parse next operand. 1436fe6060f1SDimitry Andric if (parseOperand(Operands, Name)) 1437fe6060f1SDimitry Andric return true; 1438fe6060f1SDimitry Andric } 1439fe6060f1SDimitry Andric 1440fe6060f1SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) { 1441fe6060f1SDimitry Andric SMLoc Loc = getLexer().getLoc(); 1442fe6060f1SDimitry Andric getParser().eatToEndOfStatement(); 1443fe6060f1SDimitry Andric return Error(Loc, "unexpected token"); 1444fe6060f1SDimitry Andric } 1445fe6060f1SDimitry Andric 1446fe6060f1SDimitry Andric getParser().Lex(); // Consume the EndOfStatement. 1447fe6060f1SDimitry Andric return false; 1448fe6060f1SDimitry Andric } 1449fe6060f1SDimitry Andric 1450fe6060f1SDimitry Andric OperandMatchResultTy CSKYAsmParser::tryParseRegister(unsigned &RegNo, 1451fe6060f1SDimitry Andric SMLoc &StartLoc, 1452fe6060f1SDimitry Andric SMLoc &EndLoc) { 1453fe6060f1SDimitry Andric const AsmToken &Tok = getParser().getTok(); 1454fe6060f1SDimitry Andric StartLoc = Tok.getLoc(); 1455fe6060f1SDimitry Andric EndLoc = Tok.getEndLoc(); 1456fe6060f1SDimitry Andric 1457fe6060f1SDimitry Andric StringRef Name = getLexer().getTok().getIdentifier(); 1458fe6060f1SDimitry Andric 1459349cc55cSDimitry Andric if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) 1460fe6060f1SDimitry Andric return MatchOperand_NoMatch; 1461fe6060f1SDimitry Andric 1462fe6060f1SDimitry Andric getParser().Lex(); // Eat identifier token. 1463fe6060f1SDimitry Andric return MatchOperand_Success; 1464fe6060f1SDimitry Andric } 1465fe6060f1SDimitry Andric 1466fe6060f1SDimitry Andric bool CSKYAsmParser::ParseDirective(AsmToken DirectiveID) { return true; } 1467fe6060f1SDimitry Andric 1468*0eae32dcSDimitry Andric void CSKYAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) { 1469*0eae32dcSDimitry Andric MCInst CInst; 1470*0eae32dcSDimitry Andric bool Res = false; 1471*0eae32dcSDimitry Andric if (EnableCompressedInst) 1472*0eae32dcSDimitry Andric Res = compressInst(CInst, Inst, getSTI(), S.getContext()); 1473*0eae32dcSDimitry Andric if (Res) 1474*0eae32dcSDimitry Andric ++CSKYNumInstrsCompressed; 1475*0eae32dcSDimitry Andric S.emitInstruction((Res ? CInst : Inst), getSTI()); 1476*0eae32dcSDimitry Andric } 1477*0eae32dcSDimitry Andric 1478fe6060f1SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYAsmParser() { 1479fe6060f1SDimitry Andric RegisterMCAsmParser<CSKYAsmParser> X(getTheCSKYTarget()); 1480fe6060f1SDimitry Andric } 1481