1*349cc55cSDimitry Andric //===---- CSKYAsmParser.cpp - Parse CSKY assembly to MCInst instructions --===// 2fe6060f1SDimitry Andric // 3*349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fe6060f1SDimitry Andric // 7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 8fe6060f1SDimitry Andric 9*349cc55cSDimitry 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" 14fe6060f1SDimitry Andric #include "llvm/ADT/StringSwitch.h" 15fe6060f1SDimitry Andric #include "llvm/CodeGen/Register.h" 16fe6060f1SDimitry Andric #include "llvm/MC/MCContext.h" 17fe6060f1SDimitry Andric #include "llvm/MC/MCExpr.h" 18fe6060f1SDimitry Andric #include "llvm/MC/MCInst.h" 19fe6060f1SDimitry Andric #include "llvm/MC/MCParser/MCAsmLexer.h" 20fe6060f1SDimitry Andric #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 21fe6060f1SDimitry Andric #include "llvm/MC/MCParser/MCTargetAsmParser.h" 22fe6060f1SDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 23*349cc55cSDimitry Andric #include "llvm/MC/MCSectionELF.h" 24fe6060f1SDimitry Andric #include "llvm/MC/MCStreamer.h" 25fe6060f1SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 26*349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h" 27fe6060f1SDimitry Andric #include "llvm/Support/Casting.h" 28*349cc55cSDimitry Andric #include "llvm/Support/Debug.h" 29*349cc55cSDimitry Andric 30*349cc55cSDimitry Andric #define DEBUG_TYPE "csky-asm-parser" 31fe6060f1SDimitry Andric 32fe6060f1SDimitry Andric using namespace llvm; 33fe6060f1SDimitry Andric 34fe6060f1SDimitry Andric namespace { 35fe6060f1SDimitry Andric struct CSKYOperand; 36fe6060f1SDimitry Andric 37fe6060f1SDimitry Andric class CSKYAsmParser : public MCTargetAsmParser { 38fe6060f1SDimitry Andric 39*349cc55cSDimitry Andric const MCRegisterInfo *MRI; 40*349cc55cSDimitry Andric 41fe6060f1SDimitry Andric bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo, 42fe6060f1SDimitry Andric int64_t Lower, int64_t Upper, Twine Msg); 43fe6060f1SDimitry Andric 44fe6060f1SDimitry Andric SMLoc getLoc() const { return getParser().getTok().getLoc(); } 45fe6060f1SDimitry Andric 46fe6060f1SDimitry Andric bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 47fe6060f1SDimitry Andric OperandVector &Operands, MCStreamer &Out, 48fe6060f1SDimitry Andric uint64_t &ErrorInfo, 49fe6060f1SDimitry Andric bool MatchingInlineAsm) override; 50fe6060f1SDimitry Andric 51fe6060f1SDimitry Andric bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 52fe6060f1SDimitry Andric 53fe6060f1SDimitry Andric bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 54fe6060f1SDimitry Andric SMLoc NameLoc, OperandVector &Operands) override; 55fe6060f1SDimitry Andric 56fe6060f1SDimitry Andric bool ParseDirective(AsmToken DirectiveID) override; 57fe6060f1SDimitry Andric 58fe6060f1SDimitry Andric OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc, 59fe6060f1SDimitry Andric SMLoc &EndLoc) override; 60fe6060f1SDimitry Andric 61*349cc55cSDimitry Andric bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands, 62*349cc55cSDimitry Andric MCStreamer &Out); 63*349cc55cSDimitry Andric 64fe6060f1SDimitry Andric // Auto-generated instruction matching functions 65fe6060f1SDimitry Andric #define GET_ASSEMBLER_HEADER 66fe6060f1SDimitry Andric #include "CSKYGenAsmMatcher.inc" 67fe6060f1SDimitry Andric 68fe6060f1SDimitry Andric OperandMatchResultTy parseImmediate(OperandVector &Operands); 69fe6060f1SDimitry Andric OperandMatchResultTy parseRegister(OperandVector &Operands); 70fe6060f1SDimitry Andric OperandMatchResultTy parseBaseRegImm(OperandVector &Operands); 71fe6060f1SDimitry Andric OperandMatchResultTy parseCSKYSymbol(OperandVector &Operands); 72fe6060f1SDimitry Andric OperandMatchResultTy parseConstpoolSymbol(OperandVector &Operands); 73*349cc55cSDimitry Andric OperandMatchResultTy parseDataSymbol(OperandVector &Operands); 74*349cc55cSDimitry Andric OperandMatchResultTy parsePSRFlag(OperandVector &Operands); 75*349cc55cSDimitry Andric OperandMatchResultTy parseRegSeq(OperandVector &Operands); 76*349cc55cSDimitry Andric OperandMatchResultTy parseRegList(OperandVector &Operands); 77fe6060f1SDimitry Andric 78fe6060f1SDimitry Andric bool parseOperand(OperandVector &Operands, StringRef Mnemonic); 79fe6060f1SDimitry Andric 80fe6060f1SDimitry Andric public: 81fe6060f1SDimitry Andric enum CSKYMatchResultTy { 82fe6060f1SDimitry Andric Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY, 83*349cc55cSDimitry Andric Match_RequiresSameSrcAndDst, 84*349cc55cSDimitry Andric Match_InvalidRegOutOfRange, 85fe6060f1SDimitry Andric #define GET_OPERAND_DIAGNOSTIC_TYPES 86fe6060f1SDimitry Andric #include "CSKYGenAsmMatcher.inc" 87fe6060f1SDimitry Andric #undef GET_OPERAND_DIAGNOSTIC_TYPES 88fe6060f1SDimitry Andric }; 89fe6060f1SDimitry Andric 90fe6060f1SDimitry Andric CSKYAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, 91fe6060f1SDimitry Andric const MCInstrInfo &MII, const MCTargetOptions &Options) 92fe6060f1SDimitry Andric : MCTargetAsmParser(Options, STI, MII) { 93fe6060f1SDimitry Andric setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 94fe6060f1SDimitry Andric } 95fe6060f1SDimitry Andric }; 96fe6060f1SDimitry Andric 97fe6060f1SDimitry Andric /// Instances of this class represent a parsed machine instruction. 98fe6060f1SDimitry Andric struct CSKYOperand : public MCParsedAsmOperand { 99*349cc55cSDimitry Andric 100fe6060f1SDimitry Andric enum KindTy { 101fe6060f1SDimitry Andric Token, 102fe6060f1SDimitry Andric Register, 103fe6060f1SDimitry Andric Immediate, 104*349cc55cSDimitry Andric RegisterSeq, 105*349cc55cSDimitry Andric CPOP, 106*349cc55cSDimitry Andric RegisterList 107fe6060f1SDimitry Andric } Kind; 108fe6060f1SDimitry Andric 109fe6060f1SDimitry Andric struct RegOp { 110fe6060f1SDimitry Andric unsigned RegNum; 111fe6060f1SDimitry Andric }; 112fe6060f1SDimitry Andric 113fe6060f1SDimitry Andric struct ImmOp { 114fe6060f1SDimitry Andric const MCExpr *Val; 115fe6060f1SDimitry Andric }; 116fe6060f1SDimitry Andric 117*349cc55cSDimitry Andric struct ConstpoolOp { 118*349cc55cSDimitry Andric const MCExpr *Val; 119*349cc55cSDimitry Andric }; 120*349cc55cSDimitry Andric 121*349cc55cSDimitry Andric struct RegSeqOp { 122*349cc55cSDimitry Andric unsigned RegNumFrom; 123*349cc55cSDimitry Andric unsigned RegNumTo; 124*349cc55cSDimitry Andric }; 125*349cc55cSDimitry Andric 126*349cc55cSDimitry Andric struct RegListOp { 127*349cc55cSDimitry Andric unsigned List1From = 0; 128*349cc55cSDimitry Andric unsigned List1To = 0; 129*349cc55cSDimitry Andric unsigned List2From = 0; 130*349cc55cSDimitry Andric unsigned List2To = 0; 131*349cc55cSDimitry Andric unsigned List3From = 0; 132*349cc55cSDimitry Andric unsigned List3To = 0; 133*349cc55cSDimitry Andric unsigned List4From = 0; 134*349cc55cSDimitry Andric unsigned List4To = 0; 135*349cc55cSDimitry Andric }; 136*349cc55cSDimitry Andric 137fe6060f1SDimitry Andric SMLoc StartLoc, EndLoc; 138fe6060f1SDimitry Andric union { 139fe6060f1SDimitry Andric StringRef Tok; 140fe6060f1SDimitry Andric RegOp Reg; 141fe6060f1SDimitry Andric ImmOp Imm; 142*349cc55cSDimitry Andric ConstpoolOp CPool; 143*349cc55cSDimitry Andric RegSeqOp RegSeq; 144*349cc55cSDimitry Andric RegListOp RegList; 145fe6060f1SDimitry Andric }; 146fe6060f1SDimitry Andric 147fe6060f1SDimitry Andric CSKYOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 148fe6060f1SDimitry Andric 149fe6060f1SDimitry Andric public: 150fe6060f1SDimitry Andric CSKYOperand(const CSKYOperand &o) : MCParsedAsmOperand() { 151fe6060f1SDimitry Andric Kind = o.Kind; 152fe6060f1SDimitry Andric StartLoc = o.StartLoc; 153fe6060f1SDimitry Andric EndLoc = o.EndLoc; 154fe6060f1SDimitry Andric switch (Kind) { 155fe6060f1SDimitry Andric case Register: 156fe6060f1SDimitry Andric Reg = o.Reg; 157fe6060f1SDimitry Andric break; 158*349cc55cSDimitry Andric case RegisterSeq: 159*349cc55cSDimitry Andric RegSeq = o.RegSeq; 160*349cc55cSDimitry Andric break; 161*349cc55cSDimitry Andric case CPOP: 162*349cc55cSDimitry Andric CPool = o.CPool; 163*349cc55cSDimitry Andric break; 164fe6060f1SDimitry Andric case Immediate: 165fe6060f1SDimitry Andric Imm = o.Imm; 166fe6060f1SDimitry Andric break; 167fe6060f1SDimitry Andric case Token: 168fe6060f1SDimitry Andric Tok = o.Tok; 169fe6060f1SDimitry Andric break; 170*349cc55cSDimitry Andric case RegisterList: 171*349cc55cSDimitry Andric RegList = o.RegList; 172*349cc55cSDimitry Andric break; 173fe6060f1SDimitry Andric } 174fe6060f1SDimitry Andric } 175fe6060f1SDimitry Andric 176fe6060f1SDimitry Andric bool isToken() const override { return Kind == Token; } 177fe6060f1SDimitry Andric bool isReg() const override { return Kind == Register; } 178fe6060f1SDimitry Andric bool isImm() const override { return Kind == Immediate; } 179*349cc55cSDimitry Andric bool isRegisterSeq() const { return Kind == RegisterSeq; } 180*349cc55cSDimitry Andric bool isRegisterList() const { return Kind == RegisterList; } 181*349cc55cSDimitry Andric bool isConstPoolOp() const { return Kind == CPOP; } 182*349cc55cSDimitry Andric 183fe6060f1SDimitry Andric bool isMem() const override { return false; } 184fe6060f1SDimitry Andric 185fe6060f1SDimitry Andric static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm) { 186fe6060f1SDimitry Andric if (auto CE = dyn_cast<MCConstantExpr>(Expr)) { 187fe6060f1SDimitry Andric Imm = CE->getValue(); 188fe6060f1SDimitry Andric return true; 189fe6060f1SDimitry Andric } 190fe6060f1SDimitry Andric 191fe6060f1SDimitry Andric return false; 192fe6060f1SDimitry Andric } 193fe6060f1SDimitry Andric 194fe6060f1SDimitry Andric template <unsigned num, unsigned shift = 0> bool isUImm() const { 195fe6060f1SDimitry Andric if (!isImm()) 196fe6060f1SDimitry Andric return false; 197fe6060f1SDimitry Andric 198fe6060f1SDimitry Andric int64_t Imm; 199fe6060f1SDimitry Andric bool IsConstantImm = evaluateConstantImm(getImm(), Imm); 200fe6060f1SDimitry Andric return IsConstantImm && isShiftedUInt<num, shift>(Imm); 201fe6060f1SDimitry Andric } 202fe6060f1SDimitry Andric 203fe6060f1SDimitry Andric template <unsigned num> bool isOImm() const { 204fe6060f1SDimitry Andric if (!isImm()) 205fe6060f1SDimitry Andric return false; 206fe6060f1SDimitry Andric 207fe6060f1SDimitry Andric int64_t Imm; 208fe6060f1SDimitry Andric bool IsConstantImm = evaluateConstantImm(getImm(), Imm); 209fe6060f1SDimitry Andric return IsConstantImm && isUInt<num>(Imm - 1); 210fe6060f1SDimitry Andric } 211fe6060f1SDimitry Andric 212fe6060f1SDimitry Andric template <unsigned num, unsigned shift = 0> bool isSImm() 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 && isShiftedInt<num, shift>(Imm); 219fe6060f1SDimitry Andric } 220fe6060f1SDimitry Andric 221*349cc55cSDimitry Andric bool isUImm1() const { return isUImm<1>(); } 222fe6060f1SDimitry Andric bool isUImm2() const { return isUImm<2>(); } 223*349cc55cSDimitry Andric bool isUImm3() const { return isUImm<3>(); } 224*349cc55cSDimitry Andric bool isUImm4() const { return isUImm<4>(); } 225fe6060f1SDimitry Andric bool isUImm5() const { return isUImm<5>(); } 226*349cc55cSDimitry Andric bool isUImm6() const { return isUImm<6>(); } 227*349cc55cSDimitry Andric bool isUImm7() const { return isUImm<7>(); } 228*349cc55cSDimitry Andric bool isUImm8() const { return isUImm<8>(); } 229fe6060f1SDimitry Andric bool isUImm12() const { return isUImm<12>(); } 230fe6060f1SDimitry Andric bool isUImm16() const { return isUImm<16>(); } 231*349cc55cSDimitry Andric bool isUImm20() const { return isUImm<20>(); } 232*349cc55cSDimitry Andric bool isUImm24() const { return isUImm<24>(); } 233fe6060f1SDimitry Andric 234*349cc55cSDimitry Andric bool isOImm3() const { return isOImm<3>(); } 235*349cc55cSDimitry Andric bool isOImm4() const { return isOImm<4>(); } 236*349cc55cSDimitry Andric bool isOImm5() const { return isOImm<5>(); } 237*349cc55cSDimitry Andric bool isOImm6() const { return isOImm<6>(); } 238*349cc55cSDimitry Andric bool isOImm8() const { return isOImm<8>(); } 239fe6060f1SDimitry Andric bool isOImm12() const { return isOImm<12>(); } 240fe6060f1SDimitry Andric bool isOImm16() const { return isOImm<16>(); } 241fe6060f1SDimitry Andric 242*349cc55cSDimitry Andric bool isSImm8() const { return isSImm<8>(); } 243*349cc55cSDimitry Andric 244*349cc55cSDimitry Andric bool isUImm5Shift1() { return isUImm<5, 1>(); } 245*349cc55cSDimitry Andric bool isUImm5Shift2() { return isUImm<5, 2>(); } 246*349cc55cSDimitry Andric bool isUImm7Shift1() { return isUImm<7, 1>(); } 247*349cc55cSDimitry Andric bool isUImm7Shift2() { return isUImm<7, 2>(); } 248*349cc55cSDimitry Andric bool isUImm7Shift3() { return isUImm<7, 3>(); } 249*349cc55cSDimitry Andric bool isUImm8Shift2() { return isUImm<8, 2>(); } 250*349cc55cSDimitry Andric bool isUImm8Shift3() { return isUImm<8, 3>(); } 251*349cc55cSDimitry Andric bool isUImm8Shift8() { return isUImm<8, 8>(); } 252*349cc55cSDimitry Andric bool isUImm8Shift16() { return isUImm<8, 16>(); } 253*349cc55cSDimitry Andric bool isUImm8Shift24() { return isUImm<8, 24>(); } 254fe6060f1SDimitry Andric bool isUImm12Shift1() { return isUImm<12, 1>(); } 255fe6060f1SDimitry Andric bool isUImm12Shift2() { return isUImm<12, 2>(); } 256*349cc55cSDimitry Andric bool isUImm16Shift8() { return isUImm<16, 8>(); } 257*349cc55cSDimitry Andric bool isUImm16Shift16() { return isUImm<16, 16>(); } 258*349cc55cSDimitry Andric bool isUImm24Shift8() { return isUImm<24, 8>(); } 259fe6060f1SDimitry Andric 260fe6060f1SDimitry Andric bool isSImm16Shift1() { return isSImm<16, 1>(); } 261fe6060f1SDimitry Andric 262*349cc55cSDimitry Andric bool isCSKYSymbol() const { return isImm(); } 263*349cc55cSDimitry Andric 264*349cc55cSDimitry Andric bool isConstpool() const { return isConstPoolOp(); } 265*349cc55cSDimitry Andric bool isDataSymbol() const { return isConstPoolOp(); } 266*349cc55cSDimitry Andric 267*349cc55cSDimitry Andric bool isSPOperand() const { 268*349cc55cSDimitry Andric if (!isReg()) 269*349cc55cSDimitry Andric return false; 270*349cc55cSDimitry Andric return getReg() == CSKY::R14; 271fe6060f1SDimitry Andric } 272fe6060f1SDimitry Andric 273*349cc55cSDimitry Andric bool isPSRFlag() const { 274fe6060f1SDimitry Andric int64_t Imm; 275*349cc55cSDimitry Andric // Must be of 'immediate' type and a constant. 276*349cc55cSDimitry Andric if (!isImm() || !evaluateConstantImm(getImm(), Imm)) 277*349cc55cSDimitry Andric return false; 278*349cc55cSDimitry Andric 279*349cc55cSDimitry Andric return isUInt<5>(Imm); 280*349cc55cSDimitry Andric } 281*349cc55cSDimitry Andric 282*349cc55cSDimitry Andric template <unsigned MIN, unsigned MAX> bool isRegSeqTemplate() const { 283*349cc55cSDimitry Andric if (!isRegisterSeq()) 284*349cc55cSDimitry Andric return false; 285*349cc55cSDimitry Andric 286*349cc55cSDimitry Andric std::pair<unsigned, unsigned> regSeq = getRegSeq(); 287*349cc55cSDimitry Andric 288*349cc55cSDimitry Andric return MIN <= regSeq.first && regSeq.first <= regSeq.second && 289*349cc55cSDimitry Andric regSeq.second <= MAX; 290*349cc55cSDimitry Andric } 291*349cc55cSDimitry Andric 292*349cc55cSDimitry Andric bool isRegSeq() const { return isRegSeqTemplate<CSKY::R0, CSKY::R31>(); } 293*349cc55cSDimitry Andric 294*349cc55cSDimitry Andric static bool isLegalRegList(unsigned from, unsigned to) { 295*349cc55cSDimitry Andric if (from == 0 && to == 0) 296*349cc55cSDimitry Andric return true; 297*349cc55cSDimitry Andric 298*349cc55cSDimitry Andric if (from == to) { 299*349cc55cSDimitry Andric if (from != CSKY::R4 && from != CSKY::R15 && from != CSKY::R16 && 300*349cc55cSDimitry Andric from != CSKY::R28) 301*349cc55cSDimitry Andric return false; 302*349cc55cSDimitry Andric 303*349cc55cSDimitry Andric return true; 304*349cc55cSDimitry Andric } else { 305*349cc55cSDimitry Andric if (from != CSKY::R4 && from != CSKY::R16) 306*349cc55cSDimitry Andric return false; 307*349cc55cSDimitry Andric 308*349cc55cSDimitry Andric if (from == CSKY::R4 && to > CSKY::R4 && to < CSKY::R12) 309*349cc55cSDimitry Andric return true; 310*349cc55cSDimitry Andric else if (from == CSKY::R16 && to > CSKY::R16 && to < CSKY::R18) 311*349cc55cSDimitry Andric return true; 312*349cc55cSDimitry Andric else 313*349cc55cSDimitry Andric return false; 314*349cc55cSDimitry Andric } 315*349cc55cSDimitry Andric } 316*349cc55cSDimitry Andric 317*349cc55cSDimitry Andric bool isRegList() const { 318*349cc55cSDimitry Andric if (!isRegisterList()) 319*349cc55cSDimitry Andric return false; 320*349cc55cSDimitry Andric 321*349cc55cSDimitry Andric auto regList = getRegList(); 322*349cc55cSDimitry Andric 323*349cc55cSDimitry Andric if (!isLegalRegList(regList.List1From, regList.List1To)) 324*349cc55cSDimitry Andric return false; 325*349cc55cSDimitry Andric if (!isLegalRegList(regList.List2From, regList.List2To)) 326*349cc55cSDimitry Andric return false; 327*349cc55cSDimitry Andric if (!isLegalRegList(regList.List3From, regList.List3To)) 328*349cc55cSDimitry Andric return false; 329*349cc55cSDimitry Andric if (!isLegalRegList(regList.List4From, regList.List4To)) 330*349cc55cSDimitry Andric return false; 331*349cc55cSDimitry Andric 332*349cc55cSDimitry Andric return true; 333*349cc55cSDimitry Andric } 334*349cc55cSDimitry Andric 335*349cc55cSDimitry Andric bool isExtImm6() { 336*349cc55cSDimitry Andric if (!isImm()) 337*349cc55cSDimitry Andric return false; 338*349cc55cSDimitry Andric 339*349cc55cSDimitry Andric int64_t Imm; 340*349cc55cSDimitry Andric bool IsConstantImm = evaluateConstantImm(getImm(), Imm); 341*349cc55cSDimitry Andric if (!IsConstantImm) 342*349cc55cSDimitry Andric return false; 343*349cc55cSDimitry Andric 344*349cc55cSDimitry Andric int uimm4 = Imm & 0xf; 345*349cc55cSDimitry Andric 346*349cc55cSDimitry Andric return isShiftedUInt<6, 0>(Imm) && uimm4 >= 0 && uimm4 <= 14; 347fe6060f1SDimitry Andric } 348fe6060f1SDimitry Andric 349fe6060f1SDimitry Andric /// Gets location of the first token of this operand. 350fe6060f1SDimitry Andric SMLoc getStartLoc() const override { return StartLoc; } 351fe6060f1SDimitry Andric /// Gets location of the last token of this operand. 352fe6060f1SDimitry Andric SMLoc getEndLoc() const override { return EndLoc; } 353fe6060f1SDimitry Andric 354fe6060f1SDimitry Andric unsigned getReg() const override { 355fe6060f1SDimitry Andric assert(Kind == Register && "Invalid type access!"); 356fe6060f1SDimitry Andric return Reg.RegNum; 357fe6060f1SDimitry Andric } 358fe6060f1SDimitry Andric 359*349cc55cSDimitry Andric std::pair<unsigned, unsigned> getRegSeq() const { 360*349cc55cSDimitry Andric assert(Kind == RegisterSeq && "Invalid type access!"); 361*349cc55cSDimitry Andric return std::pair<unsigned, unsigned>(RegSeq.RegNumFrom, RegSeq.RegNumTo); 362*349cc55cSDimitry Andric } 363*349cc55cSDimitry Andric 364*349cc55cSDimitry Andric RegListOp getRegList() const { 365*349cc55cSDimitry Andric assert(Kind == RegisterList && "Invalid type access!"); 366*349cc55cSDimitry Andric return RegList; 367*349cc55cSDimitry Andric } 368*349cc55cSDimitry Andric 369fe6060f1SDimitry Andric const MCExpr *getImm() const { 370fe6060f1SDimitry Andric assert(Kind == Immediate && "Invalid type access!"); 371fe6060f1SDimitry Andric return Imm.Val; 372fe6060f1SDimitry Andric } 373fe6060f1SDimitry Andric 374*349cc55cSDimitry Andric const MCExpr *getConstpoolOp() const { 375*349cc55cSDimitry Andric assert(Kind == CPOP && "Invalid type access!"); 376*349cc55cSDimitry Andric return CPool.Val; 377*349cc55cSDimitry Andric } 378*349cc55cSDimitry Andric 379fe6060f1SDimitry Andric StringRef getToken() const { 380fe6060f1SDimitry Andric assert(Kind == Token && "Invalid type access!"); 381fe6060f1SDimitry Andric return Tok; 382fe6060f1SDimitry Andric } 383fe6060f1SDimitry Andric 384fe6060f1SDimitry Andric void print(raw_ostream &OS) const override { 385*349cc55cSDimitry Andric auto RegName = [](unsigned Reg) { 386*349cc55cSDimitry Andric if (Reg) 387*349cc55cSDimitry Andric return CSKYInstPrinter::getRegisterName(Reg); 388*349cc55cSDimitry Andric else 389*349cc55cSDimitry Andric return "noreg"; 390*349cc55cSDimitry Andric }; 391*349cc55cSDimitry Andric 392fe6060f1SDimitry Andric switch (Kind) { 393*349cc55cSDimitry Andric case CPOP: 394*349cc55cSDimitry Andric OS << *getConstpoolOp(); 395*349cc55cSDimitry Andric break; 396fe6060f1SDimitry Andric case Immediate: 397fe6060f1SDimitry Andric OS << *getImm(); 398fe6060f1SDimitry Andric break; 399*349cc55cSDimitry Andric case KindTy::Register: 400*349cc55cSDimitry Andric OS << "<register " << RegName(getReg()) << ">"; 401*349cc55cSDimitry Andric break; 402*349cc55cSDimitry Andric case RegisterSeq: 403*349cc55cSDimitry Andric OS << "<register-seq "; 404*349cc55cSDimitry Andric OS << RegName(getRegSeq().first) << "-" << RegName(getRegSeq().second) 405*349cc55cSDimitry Andric << ">"; 406*349cc55cSDimitry Andric break; 407*349cc55cSDimitry Andric case RegisterList: 408*349cc55cSDimitry Andric OS << "<register-list "; 409*349cc55cSDimitry Andric OS << RegName(getRegList().List1From) << "-" 410*349cc55cSDimitry Andric << RegName(getRegList().List1To) << ","; 411*349cc55cSDimitry Andric OS << RegName(getRegList().List2From) << "-" 412*349cc55cSDimitry Andric << RegName(getRegList().List2To) << ","; 413*349cc55cSDimitry Andric OS << RegName(getRegList().List3From) << "-" 414*349cc55cSDimitry Andric << RegName(getRegList().List3To) << ","; 415*349cc55cSDimitry Andric OS << RegName(getRegList().List4From) << "-" 416*349cc55cSDimitry Andric << RegName(getRegList().List4To); 417fe6060f1SDimitry Andric break; 418fe6060f1SDimitry Andric case Token: 419fe6060f1SDimitry Andric OS << "'" << getToken() << "'"; 420fe6060f1SDimitry Andric break; 421fe6060f1SDimitry Andric } 422fe6060f1SDimitry Andric } 423fe6060f1SDimitry Andric 424fe6060f1SDimitry Andric static std::unique_ptr<CSKYOperand> createToken(StringRef Str, SMLoc S) { 425fe6060f1SDimitry Andric auto Op = std::make_unique<CSKYOperand>(Token); 426fe6060f1SDimitry Andric Op->Tok = Str; 427fe6060f1SDimitry Andric Op->StartLoc = S; 428fe6060f1SDimitry Andric Op->EndLoc = S; 429fe6060f1SDimitry Andric return Op; 430fe6060f1SDimitry Andric } 431fe6060f1SDimitry Andric 432fe6060f1SDimitry Andric static std::unique_ptr<CSKYOperand> createReg(unsigned RegNo, SMLoc S, 433fe6060f1SDimitry Andric SMLoc E) { 434fe6060f1SDimitry Andric auto Op = std::make_unique<CSKYOperand>(Register); 435fe6060f1SDimitry Andric Op->Reg.RegNum = RegNo; 436fe6060f1SDimitry Andric Op->StartLoc = S; 437fe6060f1SDimitry Andric Op->EndLoc = E; 438fe6060f1SDimitry Andric return Op; 439fe6060f1SDimitry Andric } 440fe6060f1SDimitry Andric 441*349cc55cSDimitry Andric static std::unique_ptr<CSKYOperand> createRegSeq(unsigned RegNoFrom, 442*349cc55cSDimitry Andric unsigned RegNoTo, SMLoc S) { 443*349cc55cSDimitry Andric auto Op = std::make_unique<CSKYOperand>(RegisterSeq); 444*349cc55cSDimitry Andric Op->RegSeq.RegNumFrom = RegNoFrom; 445*349cc55cSDimitry Andric Op->RegSeq.RegNumTo = RegNoTo; 446*349cc55cSDimitry Andric Op->StartLoc = S; 447*349cc55cSDimitry Andric Op->EndLoc = S; 448*349cc55cSDimitry Andric return Op; 449*349cc55cSDimitry Andric } 450*349cc55cSDimitry Andric 451*349cc55cSDimitry Andric static std::unique_ptr<CSKYOperand> 452*349cc55cSDimitry Andric createRegList(SmallVector<unsigned, 4> reglist, SMLoc S) { 453*349cc55cSDimitry Andric auto Op = std::make_unique<CSKYOperand>(RegisterList); 454*349cc55cSDimitry Andric Op->RegList.List1From = 0; 455*349cc55cSDimitry Andric Op->RegList.List1To = 0; 456*349cc55cSDimitry Andric Op->RegList.List2From = 0; 457*349cc55cSDimitry Andric Op->RegList.List2To = 0; 458*349cc55cSDimitry Andric Op->RegList.List3From = 0; 459*349cc55cSDimitry Andric Op->RegList.List3To = 0; 460*349cc55cSDimitry Andric Op->RegList.List4From = 0; 461*349cc55cSDimitry Andric Op->RegList.List4To = 0; 462*349cc55cSDimitry Andric 463*349cc55cSDimitry Andric for (unsigned i = 0; i < reglist.size(); i += 2) { 464*349cc55cSDimitry Andric if (Op->RegList.List1From == 0) { 465*349cc55cSDimitry Andric Op->RegList.List1From = reglist[i]; 466*349cc55cSDimitry Andric Op->RegList.List1To = reglist[i + 1]; 467*349cc55cSDimitry Andric } else if (Op->RegList.List2From == 0) { 468*349cc55cSDimitry Andric Op->RegList.List2From = reglist[i]; 469*349cc55cSDimitry Andric Op->RegList.List2To = reglist[i + 1]; 470*349cc55cSDimitry Andric } else if (Op->RegList.List3From == 0) { 471*349cc55cSDimitry Andric Op->RegList.List3From = reglist[i]; 472*349cc55cSDimitry Andric Op->RegList.List3To = reglist[i + 1]; 473*349cc55cSDimitry Andric } else if (Op->RegList.List4From == 0) { 474*349cc55cSDimitry Andric Op->RegList.List4From = reglist[i]; 475*349cc55cSDimitry Andric Op->RegList.List4To = reglist[i + 1]; 476*349cc55cSDimitry Andric } else { 477*349cc55cSDimitry Andric assert(0); 478*349cc55cSDimitry Andric } 479*349cc55cSDimitry Andric } 480*349cc55cSDimitry Andric 481*349cc55cSDimitry Andric Op->StartLoc = S; 482*349cc55cSDimitry Andric Op->EndLoc = S; 483*349cc55cSDimitry Andric return Op; 484*349cc55cSDimitry Andric } 485*349cc55cSDimitry Andric 486fe6060f1SDimitry Andric static std::unique_ptr<CSKYOperand> createImm(const MCExpr *Val, SMLoc S, 487fe6060f1SDimitry Andric SMLoc E) { 488fe6060f1SDimitry Andric auto Op = std::make_unique<CSKYOperand>(Immediate); 489fe6060f1SDimitry Andric Op->Imm.Val = Val; 490fe6060f1SDimitry Andric Op->StartLoc = S; 491fe6060f1SDimitry Andric Op->EndLoc = E; 492fe6060f1SDimitry Andric return Op; 493fe6060f1SDimitry Andric } 494fe6060f1SDimitry Andric 495*349cc55cSDimitry Andric static std::unique_ptr<CSKYOperand> createConstpoolOp(const MCExpr *Val, 496*349cc55cSDimitry Andric SMLoc S, SMLoc E) { 497*349cc55cSDimitry Andric auto Op = std::make_unique<CSKYOperand>(CPOP); 498*349cc55cSDimitry Andric Op->CPool.Val = Val; 499*349cc55cSDimitry Andric Op->StartLoc = S; 500*349cc55cSDimitry Andric Op->EndLoc = E; 501*349cc55cSDimitry Andric return Op; 502*349cc55cSDimitry Andric } 503*349cc55cSDimitry Andric 504fe6060f1SDimitry Andric void addExpr(MCInst &Inst, const MCExpr *Expr) const { 505fe6060f1SDimitry Andric assert(Expr && "Expr shouldn't be null!"); 506fe6060f1SDimitry Andric if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) 507fe6060f1SDimitry Andric Inst.addOperand(MCOperand::createImm(CE->getValue())); 508fe6060f1SDimitry Andric else 509fe6060f1SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr)); 510fe6060f1SDimitry Andric } 511fe6060f1SDimitry Andric 512fe6060f1SDimitry Andric // Used by the TableGen Code. 513fe6060f1SDimitry Andric void addRegOperands(MCInst &Inst, unsigned N) const { 514fe6060f1SDimitry Andric assert(N == 1 && "Invalid number of operands!"); 515fe6060f1SDimitry Andric Inst.addOperand(MCOperand::createReg(getReg())); 516fe6060f1SDimitry Andric } 517fe6060f1SDimitry Andric 518fe6060f1SDimitry Andric void addImmOperands(MCInst &Inst, unsigned N) const { 519fe6060f1SDimitry Andric assert(N == 1 && "Invalid number of operands!"); 520fe6060f1SDimitry Andric addExpr(Inst, getImm()); 521fe6060f1SDimitry Andric } 522*349cc55cSDimitry Andric 523*349cc55cSDimitry Andric void addConstpoolOperands(MCInst &Inst, unsigned N) const { 524*349cc55cSDimitry Andric assert(N == 1 && "Invalid number of operands!"); 525*349cc55cSDimitry Andric Inst.addOperand(MCOperand::createExpr(getConstpoolOp())); 526*349cc55cSDimitry Andric } 527*349cc55cSDimitry Andric 528*349cc55cSDimitry Andric void addRegSeqOperands(MCInst &Inst, unsigned N) const { 529*349cc55cSDimitry Andric assert(N == 2 && "Invalid number of operands!"); 530*349cc55cSDimitry Andric auto regSeq = getRegSeq(); 531*349cc55cSDimitry Andric 532*349cc55cSDimitry Andric Inst.addOperand(MCOperand::createReg(regSeq.first)); 533*349cc55cSDimitry Andric Inst.addOperand(MCOperand::createReg(regSeq.second)); 534*349cc55cSDimitry Andric } 535*349cc55cSDimitry Andric 536*349cc55cSDimitry Andric static unsigned getListValue(unsigned ListFrom, unsigned ListTo) { 537*349cc55cSDimitry Andric if (ListFrom == ListTo && ListFrom == CSKY::R15) 538*349cc55cSDimitry Andric return (1 << 4); 539*349cc55cSDimitry Andric else if (ListFrom == ListTo && ListFrom == CSKY::R28) 540*349cc55cSDimitry Andric return (1 << 8); 541*349cc55cSDimitry Andric else if (ListFrom == CSKY::R4) 542*349cc55cSDimitry Andric return ListTo - ListFrom + 1; 543*349cc55cSDimitry Andric else if (ListFrom == CSKY::R16) 544*349cc55cSDimitry Andric return ((ListTo - ListFrom + 1) << 5); 545*349cc55cSDimitry Andric else 546*349cc55cSDimitry Andric return 0; 547*349cc55cSDimitry Andric } 548*349cc55cSDimitry Andric 549*349cc55cSDimitry Andric void addRegListOperands(MCInst &Inst, unsigned N) const { 550*349cc55cSDimitry Andric assert(N == 1 && "Invalid number of operands!"); 551*349cc55cSDimitry Andric auto regList = getRegList(); 552*349cc55cSDimitry Andric 553*349cc55cSDimitry Andric unsigned V = 0; 554*349cc55cSDimitry Andric 555*349cc55cSDimitry Andric unsigned T = getListValue(regList.List1From, regList.List1To); 556*349cc55cSDimitry Andric if (T != 0) 557*349cc55cSDimitry Andric V = V | T; 558*349cc55cSDimitry Andric 559*349cc55cSDimitry Andric T = getListValue(regList.List2From, regList.List2To); 560*349cc55cSDimitry Andric if (T != 0) 561*349cc55cSDimitry Andric V = V | T; 562*349cc55cSDimitry Andric 563*349cc55cSDimitry Andric T = getListValue(regList.List3From, regList.List3To); 564*349cc55cSDimitry Andric if (T != 0) 565*349cc55cSDimitry Andric V = V | T; 566*349cc55cSDimitry Andric 567*349cc55cSDimitry Andric T = getListValue(regList.List4From, regList.List4To); 568*349cc55cSDimitry Andric if (T != 0) 569*349cc55cSDimitry Andric V = V | T; 570*349cc55cSDimitry Andric 571*349cc55cSDimitry Andric Inst.addOperand(MCOperand::createImm(V)); 572*349cc55cSDimitry Andric } 573*349cc55cSDimitry Andric 574*349cc55cSDimitry Andric bool isValidForTie(const CSKYOperand &Other) const { 575*349cc55cSDimitry Andric if (Kind != Other.Kind) 576*349cc55cSDimitry Andric return false; 577*349cc55cSDimitry Andric 578*349cc55cSDimitry Andric switch (Kind) { 579*349cc55cSDimitry Andric default: 580*349cc55cSDimitry Andric llvm_unreachable("Unexpected kind"); 581*349cc55cSDimitry Andric return false; 582*349cc55cSDimitry Andric case Register: 583*349cc55cSDimitry Andric return Reg.RegNum == Other.Reg.RegNum; 584*349cc55cSDimitry Andric } 585*349cc55cSDimitry Andric } 586fe6060f1SDimitry Andric }; 587fe6060f1SDimitry Andric } // end anonymous namespace. 588fe6060f1SDimitry Andric 589fe6060f1SDimitry Andric #define GET_REGISTER_MATCHER 590fe6060f1SDimitry Andric #define GET_SUBTARGET_FEATURE_NAME 591fe6060f1SDimitry Andric #define GET_MATCHER_IMPLEMENTATION 592fe6060f1SDimitry Andric #define GET_MNEMONIC_SPELL_CHECKER 593fe6060f1SDimitry Andric #include "CSKYGenAsmMatcher.inc" 594fe6060f1SDimitry Andric 595fe6060f1SDimitry Andric static std::string CSKYMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, 596fe6060f1SDimitry Andric unsigned VariantID = 0); 597fe6060f1SDimitry Andric 598fe6060f1SDimitry Andric bool CSKYAsmParser::generateImmOutOfRangeError( 599fe6060f1SDimitry Andric OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper, 600fe6060f1SDimitry Andric Twine Msg = "immediate must be an integer in the range") { 601fe6060f1SDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 602fe6060f1SDimitry Andric return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]"); 603fe6060f1SDimitry Andric } 604fe6060f1SDimitry Andric 605fe6060f1SDimitry Andric bool CSKYAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 606fe6060f1SDimitry Andric OperandVector &Operands, 607fe6060f1SDimitry Andric MCStreamer &Out, 608fe6060f1SDimitry Andric uint64_t &ErrorInfo, 609fe6060f1SDimitry Andric bool MatchingInlineAsm) { 610fe6060f1SDimitry Andric MCInst Inst; 611fe6060f1SDimitry Andric FeatureBitset MissingFeatures; 612fe6060f1SDimitry Andric 613fe6060f1SDimitry Andric auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures, 614fe6060f1SDimitry Andric MatchingInlineAsm); 615fe6060f1SDimitry Andric switch (Result) { 616fe6060f1SDimitry Andric default: 617fe6060f1SDimitry Andric break; 618fe6060f1SDimitry Andric case Match_Success: 619*349cc55cSDimitry Andric return processInstruction(Inst, IDLoc, Operands, Out); 620fe6060f1SDimitry Andric case Match_MissingFeature: { 621fe6060f1SDimitry Andric assert(MissingFeatures.any() && "Unknown missing features!"); 622fe6060f1SDimitry Andric ListSeparator LS; 623fe6060f1SDimitry Andric std::string Msg = "instruction requires the following: "; 624fe6060f1SDimitry Andric for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) { 625fe6060f1SDimitry Andric if (MissingFeatures[i]) { 626fe6060f1SDimitry Andric Msg += LS; 627fe6060f1SDimitry Andric Msg += getSubtargetFeatureName(i); 628fe6060f1SDimitry Andric } 629fe6060f1SDimitry Andric } 630fe6060f1SDimitry Andric return Error(IDLoc, Msg); 631fe6060f1SDimitry Andric } 632fe6060f1SDimitry Andric case Match_MnemonicFail: { 633fe6060f1SDimitry Andric FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits()); 634fe6060f1SDimitry Andric std::string Suggestion = 635fe6060f1SDimitry Andric CSKYMnemonicSpellCheck(((CSKYOperand &)*Operands[0]).getToken(), FBS); 636fe6060f1SDimitry Andric return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion); 637fe6060f1SDimitry Andric } 638fe6060f1SDimitry Andric case Match_InvalidTiedOperand: 639fe6060f1SDimitry Andric case Match_InvalidOperand: { 640fe6060f1SDimitry Andric SMLoc ErrorLoc = IDLoc; 641fe6060f1SDimitry Andric if (ErrorInfo != ~0U) { 642fe6060f1SDimitry Andric if (ErrorInfo >= Operands.size()) 643fe6060f1SDimitry Andric return Error(ErrorLoc, "too few operands for instruction"); 644fe6060f1SDimitry Andric 645fe6060f1SDimitry Andric ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 646fe6060f1SDimitry Andric if (ErrorLoc == SMLoc()) 647fe6060f1SDimitry Andric ErrorLoc = IDLoc; 648fe6060f1SDimitry Andric } 649fe6060f1SDimitry Andric return Error(ErrorLoc, "invalid operand for instruction"); 650fe6060f1SDimitry Andric } 651fe6060f1SDimitry Andric } 652fe6060f1SDimitry Andric 653fe6060f1SDimitry Andric // Handle the case when the error message is of specific type 654fe6060f1SDimitry Andric // other than the generic Match_InvalidOperand, and the 655fe6060f1SDimitry Andric // corresponding operand is missing. 656fe6060f1SDimitry Andric if (Result > FIRST_TARGET_MATCH_RESULT_TY) { 657fe6060f1SDimitry Andric SMLoc ErrorLoc = IDLoc; 658fe6060f1SDimitry Andric if (ErrorInfo != ~0U && ErrorInfo >= Operands.size()) 659fe6060f1SDimitry Andric return Error(ErrorLoc, "too few operands for instruction"); 660fe6060f1SDimitry Andric } 661fe6060f1SDimitry Andric 662fe6060f1SDimitry Andric switch (Result) { 663fe6060f1SDimitry Andric default: 664fe6060f1SDimitry Andric break; 665*349cc55cSDimitry Andric case Match_InvalidSImm8: 666*349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7), 667*349cc55cSDimitry Andric (1 << 7) - 1); 668*349cc55cSDimitry Andric case Match_InvalidOImm3: 669*349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 3)); 670*349cc55cSDimitry Andric case Match_InvalidOImm4: 671*349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4)); 672*349cc55cSDimitry Andric case Match_InvalidOImm5: 673*349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5)); 674*349cc55cSDimitry Andric case Match_InvalidOImm6: 675*349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6)); 676*349cc55cSDimitry Andric case Match_InvalidOImm8: 677*349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 8)); 678fe6060f1SDimitry Andric case Match_InvalidOImm12: 679fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 12)); 680fe6060f1SDimitry Andric case Match_InvalidOImm16: 681fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16)); 682*349cc55cSDimitry Andric case Match_InvalidUImm1: 683*349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1); 684fe6060f1SDimitry Andric case Match_InvalidUImm2: 685fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1); 686*349cc55cSDimitry Andric case Match_InvalidUImm3: 687*349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1); 688*349cc55cSDimitry Andric case Match_InvalidUImm4: 689*349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1); 690fe6060f1SDimitry Andric case Match_InvalidUImm5: 691fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 692*349cc55cSDimitry Andric case Match_InvalidUImm6: 693*349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); 694*349cc55cSDimitry Andric case Match_InvalidUImm7: 695*349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1); 696*349cc55cSDimitry Andric case Match_InvalidUImm8: 697*349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1); 698fe6060f1SDimitry Andric case Match_InvalidUImm12: 699fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1); 700*349cc55cSDimitry Andric case Match_InvalidUImm16: 701*349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 16) - 1); 702*349cc55cSDimitry Andric case Match_InvalidUImm5Shift1: 703*349cc55cSDimitry Andric return generateImmOutOfRangeError( 704*349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 5) - 2, 705*349cc55cSDimitry Andric "immediate must be a multiple of 2 bytes in the range"); 706fe6060f1SDimitry Andric case Match_InvalidUImm12Shift1: 707fe6060f1SDimitry Andric return generateImmOutOfRangeError( 708fe6060f1SDimitry Andric Operands, ErrorInfo, 0, (1 << 12) - 2, 709fe6060f1SDimitry Andric "immediate must be a multiple of 2 bytes in the range"); 710*349cc55cSDimitry Andric case Match_InvalidUImm5Shift2: 711*349cc55cSDimitry Andric return generateImmOutOfRangeError( 712*349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 5) - 4, 713*349cc55cSDimitry Andric "immediate must be a multiple of 4 bytes in the range"); 714*349cc55cSDimitry Andric case Match_InvalidUImm7Shift1: 715*349cc55cSDimitry Andric return generateImmOutOfRangeError( 716*349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 7) - 2, 717*349cc55cSDimitry Andric "immediate must be a multiple of 2 bytes in the range"); 718*349cc55cSDimitry Andric case Match_InvalidUImm7Shift2: 719*349cc55cSDimitry Andric return generateImmOutOfRangeError( 720*349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 7) - 4, 721*349cc55cSDimitry Andric "immediate must be a multiple of 4 bytes in the range"); 722*349cc55cSDimitry Andric case Match_InvalidUImm8Shift2: 723*349cc55cSDimitry Andric return generateImmOutOfRangeError( 724*349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 8) - 4, 725*349cc55cSDimitry Andric "immediate must be a multiple of 4 bytes in the range"); 726*349cc55cSDimitry Andric case Match_InvalidUImm8Shift3: 727*349cc55cSDimitry Andric return generateImmOutOfRangeError( 728*349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 8) - 8, 729*349cc55cSDimitry Andric "immediate must be a multiple of 8 bytes in the range"); 730*349cc55cSDimitry Andric case Match_InvalidUImm8Shift8: 731*349cc55cSDimitry Andric return generateImmOutOfRangeError( 732*349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 8) - 256, 733*349cc55cSDimitry Andric "immediate must be a multiple of 256 bytes in the range"); 734fe6060f1SDimitry Andric case Match_InvalidUImm12Shift2: 735fe6060f1SDimitry Andric return generateImmOutOfRangeError( 736fe6060f1SDimitry Andric Operands, ErrorInfo, 0, (1 << 12) - 4, 737fe6060f1SDimitry Andric "immediate must be a multiple of 4 bytes in the range"); 738fe6060f1SDimitry Andric case Match_InvalidCSKYSymbol: { 739fe6060f1SDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 740fe6060f1SDimitry Andric return Error(ErrorLoc, "operand must be a symbol name"); 741fe6060f1SDimitry Andric } 742fe6060f1SDimitry Andric case Match_InvalidConstpool: { 743fe6060f1SDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 744fe6060f1SDimitry Andric return Error(ErrorLoc, "operand must be a constpool symbol name"); 745fe6060f1SDimitry Andric } 746*349cc55cSDimitry Andric case Match_InvalidPSRFlag: { 747*349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 748*349cc55cSDimitry Andric return Error(ErrorLoc, "psrset operand is not valid"); 749*349cc55cSDimitry Andric } 750*349cc55cSDimitry Andric case Match_InvalidRegSeq: { 751*349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 752*349cc55cSDimitry Andric return Error(ErrorLoc, "Register sequence is not valid"); 753*349cc55cSDimitry Andric } 754*349cc55cSDimitry Andric case Match_InvalidRegOutOfRange: { 755*349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 756*349cc55cSDimitry Andric return Error(ErrorLoc, "register is out of range"); 757*349cc55cSDimitry Andric } 758*349cc55cSDimitry Andric case Match_InvalidSPOperand: { 759*349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 760*349cc55cSDimitry Andric return Error(ErrorLoc, "operand must be sp register"); 761*349cc55cSDimitry Andric } 762*349cc55cSDimitry Andric case Match_RequiresSameSrcAndDst: { 763*349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 764*349cc55cSDimitry Andric return Error(ErrorLoc, "src and dst operand must be same"); 765*349cc55cSDimitry Andric } 766*349cc55cSDimitry Andric case Match_InvalidRegList: { 767*349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 768*349cc55cSDimitry Andric return Error(ErrorLoc, "invalid register list"); 769*349cc55cSDimitry Andric } 770*349cc55cSDimitry Andric } 771*349cc55cSDimitry Andric LLVM_DEBUG(dbgs() << "Result = " << Result); 772*349cc55cSDimitry Andric llvm_unreachable("Unknown match type detected!"); 773fe6060f1SDimitry Andric } 774fe6060f1SDimitry Andric 775*349cc55cSDimitry Andric bool CSKYAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 776*349cc55cSDimitry Andric OperandVector &Operands, 777*349cc55cSDimitry Andric MCStreamer &Out) { 778*349cc55cSDimitry Andric 779*349cc55cSDimitry Andric if (Inst.getOpcode() == CSKY::LDQ32 || Inst.getOpcode() == CSKY::STQ32) { 780*349cc55cSDimitry Andric if (Inst.getOperand(1).getReg() != CSKY::R4 || 781*349cc55cSDimitry Andric Inst.getOperand(2).getReg() != CSKY::R7) { 782*349cc55cSDimitry Andric return Error(IDLoc, "Register sequence is not valid. 'r4-r7' expected"); 783*349cc55cSDimitry Andric } 784*349cc55cSDimitry Andric Inst.setOpcode(Inst.getOpcode() == CSKY::LDQ32 ? CSKY::LDM32 : CSKY::STM32); 785*349cc55cSDimitry Andric Out.emitInstruction(Inst, getSTI()); 786*349cc55cSDimitry Andric return false; 787*349cc55cSDimitry Andric } else if (Inst.getOpcode() == CSKY::SEXT32 || 788*349cc55cSDimitry Andric Inst.getOpcode() == CSKY::ZEXT32) { 789*349cc55cSDimitry Andric if (Inst.getOperand(2).getImm() < Inst.getOperand(3).getImm()) 790*349cc55cSDimitry Andric return Error(IDLoc, "msb must be greater or equal to lsb"); 791*349cc55cSDimitry Andric } else if (Inst.getOpcode() == CSKY::INS32) { 792*349cc55cSDimitry Andric if (Inst.getOperand(3).getImm() < Inst.getOperand(4).getImm()) 793*349cc55cSDimitry Andric return Error(IDLoc, "msb must be greater or equal to lsb"); 794*349cc55cSDimitry Andric } else if (Inst.getOpcode() == CSKY::IDLY32) { 795*349cc55cSDimitry Andric if (Inst.getOperand(0).getImm() > 32 || Inst.getOperand(0).getImm() < 0) 796*349cc55cSDimitry Andric return Error(IDLoc, "n must be in range [0,32]"); 797*349cc55cSDimitry Andric } 798*349cc55cSDimitry Andric 799*349cc55cSDimitry Andric Out.emitInstruction(Inst, getSTI()); 800*349cc55cSDimitry Andric return false; 801fe6060f1SDimitry Andric } 802fe6060f1SDimitry Andric 803fe6060f1SDimitry Andric // Attempts to match Name as a register (either using the default name or 804fe6060f1SDimitry Andric // alternative ABI names), setting RegNo to the matching register. Upon 805fe6060f1SDimitry Andric // failure, returns true and sets RegNo to 0. 806*349cc55cSDimitry Andric static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, 807*349cc55cSDimitry Andric MCRegister &RegNo, StringRef Name) { 808fe6060f1SDimitry Andric RegNo = MatchRegisterName(Name); 809fe6060f1SDimitry Andric 810fe6060f1SDimitry Andric if (RegNo == CSKY::NoRegister) 811fe6060f1SDimitry Andric RegNo = MatchRegisterAltName(Name); 812fe6060f1SDimitry Andric 813fe6060f1SDimitry Andric return RegNo == CSKY::NoRegister; 814fe6060f1SDimitry Andric } 815fe6060f1SDimitry Andric 816fe6060f1SDimitry Andric bool CSKYAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 817fe6060f1SDimitry Andric SMLoc &EndLoc) { 818fe6060f1SDimitry Andric const AsmToken &Tok = getParser().getTok(); 819fe6060f1SDimitry Andric StartLoc = Tok.getLoc(); 820fe6060f1SDimitry Andric EndLoc = Tok.getEndLoc(); 821fe6060f1SDimitry Andric StringRef Name = getLexer().getTok().getIdentifier(); 822fe6060f1SDimitry Andric 823*349cc55cSDimitry Andric if (!matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) { 824fe6060f1SDimitry Andric getParser().Lex(); // Eat identifier token. 825fe6060f1SDimitry Andric return false; 826fe6060f1SDimitry Andric } 827fe6060f1SDimitry Andric 828*349cc55cSDimitry Andric return MatchOperand_NoMatch; 829fe6060f1SDimitry Andric } 830fe6060f1SDimitry Andric 831fe6060f1SDimitry Andric OperandMatchResultTy CSKYAsmParser::parseRegister(OperandVector &Operands) { 832fe6060f1SDimitry Andric SMLoc S = getLoc(); 833fe6060f1SDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 834fe6060f1SDimitry Andric 835fe6060f1SDimitry Andric switch (getLexer().getKind()) { 836fe6060f1SDimitry Andric default: 837fe6060f1SDimitry Andric return MatchOperand_NoMatch; 838fe6060f1SDimitry Andric case AsmToken::Identifier: { 839fe6060f1SDimitry Andric StringRef Name = getLexer().getTok().getIdentifier(); 840fe6060f1SDimitry Andric MCRegister RegNo; 841fe6060f1SDimitry Andric 842*349cc55cSDimitry Andric if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) 843fe6060f1SDimitry Andric return MatchOperand_NoMatch; 844fe6060f1SDimitry Andric 845fe6060f1SDimitry Andric getLexer().Lex(); 846fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createReg(RegNo, S, E)); 847fe6060f1SDimitry Andric 848fe6060f1SDimitry Andric return MatchOperand_Success; 849fe6060f1SDimitry Andric } 850fe6060f1SDimitry Andric } 851fe6060f1SDimitry Andric } 852fe6060f1SDimitry Andric 853fe6060f1SDimitry Andric OperandMatchResultTy CSKYAsmParser::parseBaseRegImm(OperandVector &Operands) { 854fe6060f1SDimitry Andric assert(getLexer().is(AsmToken::LParen)); 855fe6060f1SDimitry Andric 856fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createToken("(", getLoc())); 857fe6060f1SDimitry Andric 858fe6060f1SDimitry Andric auto Tok = getParser().Lex(); // Eat '(' 859fe6060f1SDimitry Andric 860fe6060f1SDimitry Andric if (parseRegister(Operands) != MatchOperand_Success) { 861fe6060f1SDimitry Andric getLexer().UnLex(Tok); 862fe6060f1SDimitry Andric Operands.pop_back(); 863*349cc55cSDimitry Andric return MatchOperand_NoMatch; 864*349cc55cSDimitry Andric } 865*349cc55cSDimitry Andric 866*349cc55cSDimitry Andric if (getLexer().is(AsmToken::RParen)) { 867*349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createToken(")", getLoc())); 868*349cc55cSDimitry Andric getParser().Lex(); // Eat ')' 869*349cc55cSDimitry Andric return MatchOperand_Success; 870fe6060f1SDimitry Andric } 871fe6060f1SDimitry Andric 872fe6060f1SDimitry Andric if (getLexer().isNot(AsmToken::Comma)) { 873fe6060f1SDimitry Andric Error(getLoc(), "expected ','"); 874fe6060f1SDimitry Andric return MatchOperand_ParseFail; 875fe6060f1SDimitry Andric } 876fe6060f1SDimitry Andric 877fe6060f1SDimitry Andric getParser().Lex(); // Eat ',' 878fe6060f1SDimitry Andric 879fe6060f1SDimitry Andric if (parseRegister(Operands) == MatchOperand_Success) { 880fe6060f1SDimitry Andric if (getLexer().isNot(AsmToken::LessLess)) { 881fe6060f1SDimitry Andric Error(getLoc(), "expected '<<'"); 882fe6060f1SDimitry Andric return MatchOperand_ParseFail; 883fe6060f1SDimitry Andric } 884fe6060f1SDimitry Andric 885fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createToken("<<", getLoc())); 886fe6060f1SDimitry Andric 887fe6060f1SDimitry Andric getParser().Lex(); // Eat '<<' 888fe6060f1SDimitry Andric 889fe6060f1SDimitry Andric if (parseImmediate(Operands) != MatchOperand_Success) { 890fe6060f1SDimitry Andric Error(getLoc(), "expected imm"); 891fe6060f1SDimitry Andric return MatchOperand_ParseFail; 892fe6060f1SDimitry Andric } 893fe6060f1SDimitry Andric 894fe6060f1SDimitry Andric } else if (parseImmediate(Operands) != MatchOperand_Success) { 895fe6060f1SDimitry Andric Error(getLoc(), "expected imm"); 896fe6060f1SDimitry Andric return MatchOperand_ParseFail; 897fe6060f1SDimitry Andric } 898fe6060f1SDimitry Andric 899fe6060f1SDimitry Andric if (getLexer().isNot(AsmToken::RParen)) { 900fe6060f1SDimitry Andric Error(getLoc(), "expected ')'"); 901fe6060f1SDimitry Andric return MatchOperand_ParseFail; 902fe6060f1SDimitry Andric } 903fe6060f1SDimitry Andric 904fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createToken(")", getLoc())); 905fe6060f1SDimitry Andric 906fe6060f1SDimitry Andric getParser().Lex(); // Eat ')' 907fe6060f1SDimitry Andric 908fe6060f1SDimitry Andric return MatchOperand_Success; 909fe6060f1SDimitry Andric } 910fe6060f1SDimitry Andric 911fe6060f1SDimitry Andric OperandMatchResultTy CSKYAsmParser::parseImmediate(OperandVector &Operands) { 912fe6060f1SDimitry Andric switch (getLexer().getKind()) { 913fe6060f1SDimitry Andric default: 914fe6060f1SDimitry Andric return MatchOperand_NoMatch; 915fe6060f1SDimitry Andric case AsmToken::LParen: 916fe6060f1SDimitry Andric case AsmToken::Minus: 917fe6060f1SDimitry Andric case AsmToken::Plus: 918fe6060f1SDimitry Andric case AsmToken::Integer: 919fe6060f1SDimitry Andric case AsmToken::String: 920fe6060f1SDimitry Andric break; 921fe6060f1SDimitry Andric } 922fe6060f1SDimitry Andric 923fe6060f1SDimitry Andric const MCExpr *IdVal; 924fe6060f1SDimitry Andric SMLoc S = getLoc(); 925*349cc55cSDimitry Andric if (getParser().parseExpression(IdVal)) { 926*349cc55cSDimitry Andric Error(getLoc(), "unknown expression"); 927fe6060f1SDimitry Andric return MatchOperand_ParseFail; 928*349cc55cSDimitry Andric } 929fe6060f1SDimitry Andric 930fe6060f1SDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 931fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createImm(IdVal, S, E)); 932fe6060f1SDimitry Andric return MatchOperand_Success; 933fe6060f1SDimitry Andric } 934fe6060f1SDimitry Andric 935fe6060f1SDimitry Andric /// Looks at a token type and creates the relevant operand from this 936fe6060f1SDimitry Andric /// information, adding to Operands. If operand was parsed, returns false, else 937fe6060f1SDimitry Andric /// true. 938fe6060f1SDimitry Andric bool CSKYAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 939fe6060f1SDimitry Andric // Check if the current operand has a custom associated parser, if so, try to 940fe6060f1SDimitry Andric // custom parse the operand, or fallback to the general approach. 941fe6060f1SDimitry Andric OperandMatchResultTy Result = 942fe6060f1SDimitry Andric MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true); 943fe6060f1SDimitry Andric if (Result == MatchOperand_Success) 944fe6060f1SDimitry Andric return false; 945fe6060f1SDimitry Andric if (Result == MatchOperand_ParseFail) 946fe6060f1SDimitry Andric return true; 947fe6060f1SDimitry Andric 948fe6060f1SDimitry Andric // Attempt to parse token as register 949*349cc55cSDimitry Andric auto Res = parseRegister(Operands); 950*349cc55cSDimitry Andric if (Res == MatchOperand_Success) 951fe6060f1SDimitry Andric return false; 952*349cc55cSDimitry Andric else if (Res == MatchOperand_ParseFail) 953*349cc55cSDimitry Andric return true; 954fe6060f1SDimitry Andric 955fe6060f1SDimitry Andric // Attempt to parse token as (register, imm) 956*349cc55cSDimitry Andric if (getLexer().is(AsmToken::LParen)) { 957*349cc55cSDimitry Andric Res = parseBaseRegImm(Operands); 958*349cc55cSDimitry Andric if (Res == MatchOperand_Success) 959fe6060f1SDimitry Andric return false; 960*349cc55cSDimitry Andric else if (Res == MatchOperand_ParseFail) 961*349cc55cSDimitry Andric return true; 962*349cc55cSDimitry Andric } 963fe6060f1SDimitry Andric 964*349cc55cSDimitry Andric Res = parseImmediate(Operands); 965*349cc55cSDimitry Andric if (Res == MatchOperand_Success) 966fe6060f1SDimitry Andric return false; 967*349cc55cSDimitry Andric else if (Res == MatchOperand_ParseFail) 968*349cc55cSDimitry Andric return true; 969fe6060f1SDimitry Andric 970fe6060f1SDimitry Andric // Finally we have exhausted all options and must declare defeat. 971fe6060f1SDimitry Andric Error(getLoc(), "unknown operand"); 972fe6060f1SDimitry Andric return true; 973fe6060f1SDimitry Andric } 974fe6060f1SDimitry Andric 975fe6060f1SDimitry Andric OperandMatchResultTy CSKYAsmParser::parseCSKYSymbol(OperandVector &Operands) { 976fe6060f1SDimitry Andric SMLoc S = getLoc(); 977fe6060f1SDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 978*349cc55cSDimitry Andric const MCExpr *Res; 979fe6060f1SDimitry Andric 980fe6060f1SDimitry Andric if (getLexer().getKind() != AsmToken::Identifier) 981fe6060f1SDimitry Andric return MatchOperand_NoMatch; 982fe6060f1SDimitry Andric 983fe6060f1SDimitry Andric StringRef Identifier; 984*349cc55cSDimitry Andric AsmToken Tok = getLexer().getTok(); 985*349cc55cSDimitry Andric 986*349cc55cSDimitry Andric if (getParser().parseIdentifier(Identifier)) { 987*349cc55cSDimitry Andric Error(getLoc(), "unknown identifier"); 988fe6060f1SDimitry Andric return MatchOperand_ParseFail; 989*349cc55cSDimitry Andric } 990fe6060f1SDimitry Andric 991fe6060f1SDimitry Andric CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None; 992fe6060f1SDimitry Andric if (Identifier.consume_back("@GOT")) 993fe6060f1SDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOT; 994fe6060f1SDimitry Andric else if (Identifier.consume_back("@GOTOFF")) 995fe6060f1SDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOTOFF; 996fe6060f1SDimitry Andric else if (Identifier.consume_back("@PLT")) 997fe6060f1SDimitry Andric Kind = CSKYMCExpr::VK_CSKY_PLT; 998fe6060f1SDimitry Andric else if (Identifier.consume_back("@GOTPC")) 999fe6060f1SDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOTPC; 1000*349cc55cSDimitry Andric else if (Identifier.consume_back("@TLSGD32")) 1001*349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSGD; 1002*349cc55cSDimitry Andric else if (Identifier.consume_back("@GOTTPOFF")) 1003*349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSIE; 1004*349cc55cSDimitry Andric else if (Identifier.consume_back("@TPOFF")) 1005*349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSLE; 1006*349cc55cSDimitry Andric else if (Identifier.consume_back("@TLSLDM32")) 1007*349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSLDM; 1008*349cc55cSDimitry Andric else if (Identifier.consume_back("@TLSLDO32")) 1009*349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSLDO; 1010fe6060f1SDimitry Andric 1011*349cc55cSDimitry Andric MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier); 1012fe6060f1SDimitry Andric 1013*349cc55cSDimitry Andric if (!Sym) 1014*349cc55cSDimitry Andric Sym = getContext().getOrCreateSymbol(Identifier); 1015*349cc55cSDimitry Andric 1016*349cc55cSDimitry Andric if (Sym->isVariable()) { 1017*349cc55cSDimitry Andric const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1018*349cc55cSDimitry Andric if (!isa<MCSymbolRefExpr>(V)) { 1019*349cc55cSDimitry Andric getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1020*349cc55cSDimitry Andric Error(getLoc(), "unknown symbol"); 1021*349cc55cSDimitry Andric return MatchOperand_ParseFail; 1022*349cc55cSDimitry Andric } 1023*349cc55cSDimitry Andric Res = V; 1024*349cc55cSDimitry Andric } else 1025*349cc55cSDimitry Andric Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1026*349cc55cSDimitry Andric 1027*349cc55cSDimitry Andric MCBinaryExpr::Opcode Opcode; 1028*349cc55cSDimitry Andric switch (getLexer().getKind()) { 1029*349cc55cSDimitry Andric default: 1030fe6060f1SDimitry Andric if (Kind != CSKYMCExpr::VK_CSKY_None) 1031fe6060f1SDimitry Andric Res = CSKYMCExpr::create(Res, Kind, getContext()); 1032fe6060f1SDimitry Andric 1033fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createImm(Res, S, E)); 1034fe6060f1SDimitry Andric return MatchOperand_Success; 1035*349cc55cSDimitry Andric case AsmToken::Plus: 1036*349cc55cSDimitry Andric Opcode = MCBinaryExpr::Add; 1037*349cc55cSDimitry Andric break; 1038*349cc55cSDimitry Andric case AsmToken::Minus: 1039*349cc55cSDimitry Andric Opcode = MCBinaryExpr::Sub; 1040*349cc55cSDimitry Andric break; 1041*349cc55cSDimitry Andric } 1042*349cc55cSDimitry Andric 1043*349cc55cSDimitry Andric getLexer().Lex(); // eat + or - 1044*349cc55cSDimitry Andric 1045*349cc55cSDimitry Andric const MCExpr *Expr; 1046*349cc55cSDimitry Andric if (getParser().parseExpression(Expr)) { 1047*349cc55cSDimitry Andric Error(getLoc(), "unknown expression"); 1048*349cc55cSDimitry Andric return MatchOperand_ParseFail; 1049*349cc55cSDimitry Andric } 1050*349cc55cSDimitry Andric Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1051*349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createImm(Res, S, E)); 1052*349cc55cSDimitry Andric return MatchOperand_Success; 1053*349cc55cSDimitry Andric } 1054*349cc55cSDimitry Andric 1055*349cc55cSDimitry Andric OperandMatchResultTy CSKYAsmParser::parseDataSymbol(OperandVector &Operands) { 1056*349cc55cSDimitry Andric SMLoc S = getLoc(); 1057*349cc55cSDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1058*349cc55cSDimitry Andric const MCExpr *Res; 1059*349cc55cSDimitry Andric 1060*349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::LBrac) 1061*349cc55cSDimitry Andric return MatchOperand_NoMatch; 1062*349cc55cSDimitry Andric 1063*349cc55cSDimitry Andric getLexer().Lex(); // Eat '['. 1064*349cc55cSDimitry Andric 1065*349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::Identifier) { 1066*349cc55cSDimitry Andric const MCExpr *Expr; 1067*349cc55cSDimitry Andric if (getParser().parseExpression(Expr)) { 1068*349cc55cSDimitry Andric Error(getLoc(), "unknown expression"); 1069*349cc55cSDimitry Andric return MatchOperand_ParseFail; 1070*349cc55cSDimitry Andric } 1071*349cc55cSDimitry Andric 1072*349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::RBrac) { 1073*349cc55cSDimitry Andric Error(getLoc(), "expected ]"); 1074*349cc55cSDimitry Andric return MatchOperand_ParseFail; 1075*349cc55cSDimitry Andric } 1076*349cc55cSDimitry Andric 1077*349cc55cSDimitry Andric getLexer().Lex(); // Eat ']'. 1078*349cc55cSDimitry Andric 1079*349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E)); 1080*349cc55cSDimitry Andric return MatchOperand_Success; 1081*349cc55cSDimitry Andric } 1082*349cc55cSDimitry Andric 1083*349cc55cSDimitry Andric AsmToken Tok = getLexer().getTok(); 1084*349cc55cSDimitry Andric StringRef Identifier; 1085*349cc55cSDimitry Andric 1086*349cc55cSDimitry Andric if (getParser().parseIdentifier(Identifier)) { 1087*349cc55cSDimitry Andric Error(getLoc(), "unknown identifier " + Identifier); 1088*349cc55cSDimitry Andric return MatchOperand_ParseFail; 1089*349cc55cSDimitry Andric } 1090*349cc55cSDimitry Andric 1091*349cc55cSDimitry Andric CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None; 1092*349cc55cSDimitry Andric if (Identifier.consume_back("@GOT")) 1093*349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOT_IMM18_BY4; 1094*349cc55cSDimitry Andric else if (Identifier.consume_back("@PLT")) 1095*349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_PLT_IMM18_BY4; 1096*349cc55cSDimitry Andric 1097*349cc55cSDimitry Andric MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier); 1098*349cc55cSDimitry Andric 1099*349cc55cSDimitry Andric if (!Sym) 1100*349cc55cSDimitry Andric Sym = getContext().getOrCreateSymbol(Identifier); 1101*349cc55cSDimitry Andric 1102*349cc55cSDimitry Andric if (Sym->isVariable()) { 1103*349cc55cSDimitry Andric const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1104*349cc55cSDimitry Andric if (!isa<MCSymbolRefExpr>(V)) { 1105*349cc55cSDimitry Andric getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1106*349cc55cSDimitry Andric Error(getLoc(), "unknown symbol"); 1107*349cc55cSDimitry Andric return MatchOperand_ParseFail; 1108*349cc55cSDimitry Andric } 1109*349cc55cSDimitry Andric Res = V; 1110*349cc55cSDimitry Andric } else { 1111*349cc55cSDimitry Andric Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1112*349cc55cSDimitry Andric } 1113*349cc55cSDimitry Andric 1114*349cc55cSDimitry Andric MCBinaryExpr::Opcode Opcode; 1115*349cc55cSDimitry Andric switch (getLexer().getKind()) { 1116*349cc55cSDimitry Andric default: 1117*349cc55cSDimitry Andric Error(getLoc(), "unknown symbol"); 1118*349cc55cSDimitry Andric return MatchOperand_ParseFail; 1119*349cc55cSDimitry Andric case AsmToken::RBrac: 1120*349cc55cSDimitry Andric 1121*349cc55cSDimitry Andric getLexer().Lex(); // Eat ']'. 1122*349cc55cSDimitry Andric 1123*349cc55cSDimitry Andric if (Kind != CSKYMCExpr::VK_CSKY_None) 1124*349cc55cSDimitry Andric Res = CSKYMCExpr::create(Res, Kind, getContext()); 1125*349cc55cSDimitry Andric 1126*349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1127*349cc55cSDimitry Andric return MatchOperand_Success; 1128*349cc55cSDimitry Andric case AsmToken::Plus: 1129*349cc55cSDimitry Andric Opcode = MCBinaryExpr::Add; 1130*349cc55cSDimitry Andric break; 1131*349cc55cSDimitry Andric case AsmToken::Minus: 1132*349cc55cSDimitry Andric Opcode = MCBinaryExpr::Sub; 1133*349cc55cSDimitry Andric break; 1134*349cc55cSDimitry Andric } 1135*349cc55cSDimitry Andric 1136*349cc55cSDimitry Andric getLexer().Lex(); // eat + or - 1137*349cc55cSDimitry Andric 1138*349cc55cSDimitry Andric const MCExpr *Expr; 1139*349cc55cSDimitry Andric if (getParser().parseExpression(Expr)) { 1140*349cc55cSDimitry Andric Error(getLoc(), "unknown expression"); 1141*349cc55cSDimitry Andric return MatchOperand_ParseFail; 1142*349cc55cSDimitry Andric } 1143*349cc55cSDimitry Andric 1144*349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::RBrac) { 1145*349cc55cSDimitry Andric Error(getLoc(), "expected ']'"); 1146*349cc55cSDimitry Andric return MatchOperand_ParseFail; 1147*349cc55cSDimitry Andric } 1148*349cc55cSDimitry Andric 1149*349cc55cSDimitry Andric getLexer().Lex(); // Eat ']'. 1150*349cc55cSDimitry Andric 1151*349cc55cSDimitry Andric Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1152*349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1153*349cc55cSDimitry Andric return MatchOperand_Success; 1154fe6060f1SDimitry Andric } 1155fe6060f1SDimitry Andric 1156fe6060f1SDimitry Andric OperandMatchResultTy 1157fe6060f1SDimitry Andric CSKYAsmParser::parseConstpoolSymbol(OperandVector &Operands) { 1158fe6060f1SDimitry Andric SMLoc S = getLoc(); 1159fe6060f1SDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1160*349cc55cSDimitry Andric const MCExpr *Res; 1161fe6060f1SDimitry Andric 1162fe6060f1SDimitry Andric if (getLexer().getKind() != AsmToken::LBrac) 1163fe6060f1SDimitry Andric return MatchOperand_NoMatch; 1164fe6060f1SDimitry Andric 1165fe6060f1SDimitry Andric getLexer().Lex(); // Eat '['. 1166fe6060f1SDimitry Andric 1167*349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::Identifier) { 1168*349cc55cSDimitry Andric const MCExpr *Expr; 1169*349cc55cSDimitry Andric if (getParser().parseExpression(Expr)) { 1170*349cc55cSDimitry Andric Error(getLoc(), "unknown expression"); 1171fe6060f1SDimitry Andric return MatchOperand_ParseFail; 1172*349cc55cSDimitry Andric } 1173fe6060f1SDimitry Andric 1174*349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::RBrac) { 1175*349cc55cSDimitry Andric Error(getLoc(), "expected ']'"); 1176*349cc55cSDimitry Andric return MatchOperand_ParseFail; 1177*349cc55cSDimitry Andric } 1178fe6060f1SDimitry Andric 1179fe6060f1SDimitry Andric getLexer().Lex(); // Eat ']'. 1180fe6060f1SDimitry Andric 1181*349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E)); 1182*349cc55cSDimitry Andric return MatchOperand_Success; 1183*349cc55cSDimitry Andric } 1184*349cc55cSDimitry Andric 1185*349cc55cSDimitry Andric AsmToken Tok = getLexer().getTok(); 1186*349cc55cSDimitry Andric StringRef Identifier; 1187*349cc55cSDimitry Andric 1188*349cc55cSDimitry Andric if (getParser().parseIdentifier(Identifier)) { 1189*349cc55cSDimitry Andric Error(getLoc(), "unknown identifier"); 1190*349cc55cSDimitry Andric return MatchOperand_ParseFail; 1191*349cc55cSDimitry Andric } 1192*349cc55cSDimitry Andric 1193*349cc55cSDimitry Andric MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier); 1194*349cc55cSDimitry Andric 1195*349cc55cSDimitry Andric if (!Sym) 1196*349cc55cSDimitry Andric Sym = getContext().getOrCreateSymbol(Identifier); 1197*349cc55cSDimitry Andric 1198*349cc55cSDimitry Andric if (Sym->isVariable()) { 1199*349cc55cSDimitry Andric const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1200*349cc55cSDimitry Andric if (!isa<MCSymbolRefExpr>(V)) { 1201*349cc55cSDimitry Andric getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1202*349cc55cSDimitry Andric Error(getLoc(), "unknown symbol"); 1203*349cc55cSDimitry Andric return MatchOperand_ParseFail; 1204*349cc55cSDimitry Andric } 1205*349cc55cSDimitry Andric Res = V; 1206*349cc55cSDimitry Andric } else { 1207*349cc55cSDimitry Andric Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1208*349cc55cSDimitry Andric } 1209*349cc55cSDimitry Andric 1210*349cc55cSDimitry Andric MCBinaryExpr::Opcode Opcode; 1211*349cc55cSDimitry Andric switch (getLexer().getKind()) { 1212*349cc55cSDimitry Andric default: 1213*349cc55cSDimitry Andric Error(getLoc(), "unknown symbol"); 1214*349cc55cSDimitry Andric return MatchOperand_ParseFail; 1215*349cc55cSDimitry Andric case AsmToken::RBrac: 1216*349cc55cSDimitry Andric 1217*349cc55cSDimitry Andric getLexer().Lex(); // Eat ']'. 1218*349cc55cSDimitry Andric 1219*349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1220*349cc55cSDimitry Andric return MatchOperand_Success; 1221*349cc55cSDimitry Andric case AsmToken::Plus: 1222*349cc55cSDimitry Andric Opcode = MCBinaryExpr::Add; 1223*349cc55cSDimitry Andric break; 1224*349cc55cSDimitry Andric case AsmToken::Minus: 1225*349cc55cSDimitry Andric Opcode = MCBinaryExpr::Sub; 1226*349cc55cSDimitry Andric break; 1227*349cc55cSDimitry Andric } 1228*349cc55cSDimitry Andric 1229*349cc55cSDimitry Andric getLexer().Lex(); // eat + or - 1230*349cc55cSDimitry Andric 1231*349cc55cSDimitry Andric const MCExpr *Expr; 1232*349cc55cSDimitry Andric if (getParser().parseExpression(Expr)) { 1233*349cc55cSDimitry Andric Error(getLoc(), "unknown expression"); 1234*349cc55cSDimitry Andric return MatchOperand_ParseFail; 1235*349cc55cSDimitry Andric } 1236*349cc55cSDimitry Andric 1237*349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::RBrac) { 1238*349cc55cSDimitry Andric Error(getLoc(), "expected ']'"); 1239*349cc55cSDimitry Andric return MatchOperand_ParseFail; 1240*349cc55cSDimitry Andric } 1241*349cc55cSDimitry Andric 1242*349cc55cSDimitry Andric getLexer().Lex(); // Eat ']'. 1243*349cc55cSDimitry Andric 1244*349cc55cSDimitry Andric Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1245*349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1246*349cc55cSDimitry Andric return MatchOperand_Success; 1247*349cc55cSDimitry Andric } 1248*349cc55cSDimitry Andric 1249*349cc55cSDimitry Andric OperandMatchResultTy CSKYAsmParser::parsePSRFlag(OperandVector &Operands) { 1250*349cc55cSDimitry Andric SMLoc S = getLoc(); 1251*349cc55cSDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1252*349cc55cSDimitry Andric 1253*349cc55cSDimitry Andric unsigned Flag = 0; 1254*349cc55cSDimitry Andric 1255*349cc55cSDimitry Andric while (getLexer().isNot(AsmToken::EndOfStatement)) { 1256*349cc55cSDimitry Andric StringRef Identifier; 1257*349cc55cSDimitry Andric if (getParser().parseIdentifier(Identifier)) { 1258*349cc55cSDimitry Andric Error(getLoc(), "unknown identifier " + Identifier); 1259*349cc55cSDimitry Andric return MatchOperand_ParseFail; 1260*349cc55cSDimitry Andric } 1261*349cc55cSDimitry Andric 1262*349cc55cSDimitry Andric if (Identifier == "sie") 1263*349cc55cSDimitry Andric Flag = (1 << 4) | Flag; 1264*349cc55cSDimitry Andric else if (Identifier == "ee") 1265*349cc55cSDimitry Andric Flag = (1 << 3) | Flag; 1266*349cc55cSDimitry Andric else if (Identifier == "ie") 1267*349cc55cSDimitry Andric Flag = (1 << 2) | Flag; 1268*349cc55cSDimitry Andric else if (Identifier == "fe") 1269*349cc55cSDimitry Andric Flag = (1 << 1) | Flag; 1270*349cc55cSDimitry Andric else if (Identifier == "af") 1271*349cc55cSDimitry Andric Flag = (1 << 0) | Flag; 1272*349cc55cSDimitry Andric else { 1273*349cc55cSDimitry Andric Error(getLoc(), "expected " + Identifier); 1274*349cc55cSDimitry Andric return MatchOperand_ParseFail; 1275*349cc55cSDimitry Andric } 1276*349cc55cSDimitry Andric 1277*349cc55cSDimitry Andric if (getLexer().is(AsmToken::EndOfStatement)) 1278*349cc55cSDimitry Andric break; 1279*349cc55cSDimitry Andric 1280*349cc55cSDimitry Andric if (getLexer().is(AsmToken::Comma)) { 1281*349cc55cSDimitry Andric getLexer().Lex(); // eat ',' 1282*349cc55cSDimitry Andric } else { 1283*349cc55cSDimitry Andric Error(getLoc(), "expected ,"); 1284*349cc55cSDimitry Andric return MatchOperand_ParseFail; 1285*349cc55cSDimitry Andric } 1286*349cc55cSDimitry Andric } 1287*349cc55cSDimitry Andric 1288*349cc55cSDimitry Andric Operands.push_back( 1289*349cc55cSDimitry Andric CSKYOperand::createImm(MCConstantExpr::create(Flag, getContext()), S, E)); 1290*349cc55cSDimitry Andric return MatchOperand_Success; 1291*349cc55cSDimitry Andric } 1292*349cc55cSDimitry Andric 1293*349cc55cSDimitry Andric OperandMatchResultTy CSKYAsmParser::parseRegSeq(OperandVector &Operands) { 1294*349cc55cSDimitry Andric SMLoc S = getLoc(); 1295*349cc55cSDimitry Andric 1296*349cc55cSDimitry Andric if (parseRegister(Operands) != MatchOperand_Success) 1297*349cc55cSDimitry Andric return MatchOperand_NoMatch; 1298*349cc55cSDimitry Andric 1299*349cc55cSDimitry Andric auto Ry = Operands.back()->getReg(); 1300*349cc55cSDimitry Andric Operands.pop_back(); 1301*349cc55cSDimitry Andric 1302*349cc55cSDimitry Andric if (getLexer().isNot(AsmToken::Minus)) { 1303*349cc55cSDimitry Andric Error(getLoc(), "expected '-'"); 1304*349cc55cSDimitry Andric return MatchOperand_ParseFail; 1305*349cc55cSDimitry Andric } 1306*349cc55cSDimitry Andric 1307*349cc55cSDimitry Andric getLexer().Lex(); // eat '-' 1308*349cc55cSDimitry Andric 1309*349cc55cSDimitry Andric if (parseRegister(Operands) != MatchOperand_Success) { 1310*349cc55cSDimitry Andric Error(getLoc(), "invalid register"); 1311*349cc55cSDimitry Andric return MatchOperand_ParseFail; 1312*349cc55cSDimitry Andric } 1313*349cc55cSDimitry Andric 1314*349cc55cSDimitry Andric auto Rz = Operands.back()->getReg(); 1315*349cc55cSDimitry Andric Operands.pop_back(); 1316*349cc55cSDimitry Andric 1317*349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createRegSeq(Ry, Rz, S)); 1318*349cc55cSDimitry Andric return MatchOperand_Success; 1319*349cc55cSDimitry Andric } 1320*349cc55cSDimitry Andric 1321*349cc55cSDimitry Andric OperandMatchResultTy CSKYAsmParser::parseRegList(OperandVector &Operands) { 1322*349cc55cSDimitry Andric SMLoc S = getLoc(); 1323*349cc55cSDimitry Andric 1324*349cc55cSDimitry Andric SmallVector<unsigned, 4> reglist; 1325*349cc55cSDimitry Andric 1326*349cc55cSDimitry Andric while (true) { 1327*349cc55cSDimitry Andric 1328*349cc55cSDimitry Andric if (parseRegister(Operands) != MatchOperand_Success) { 1329*349cc55cSDimitry Andric Error(getLoc(), "invalid register"); 1330*349cc55cSDimitry Andric return MatchOperand_ParseFail; 1331*349cc55cSDimitry Andric } 1332*349cc55cSDimitry Andric 1333*349cc55cSDimitry Andric auto Ry = Operands.back()->getReg(); 1334*349cc55cSDimitry Andric Operands.pop_back(); 1335*349cc55cSDimitry Andric 1336*349cc55cSDimitry Andric if (getLexer().is(AsmToken::Minus)) { 1337*349cc55cSDimitry Andric getLexer().Lex(); // eat '-' 1338*349cc55cSDimitry Andric 1339*349cc55cSDimitry Andric if (parseRegister(Operands) != MatchOperand_Success) { 1340*349cc55cSDimitry Andric Error(getLoc(), "invalid register"); 1341*349cc55cSDimitry Andric return MatchOperand_ParseFail; 1342*349cc55cSDimitry Andric } 1343*349cc55cSDimitry Andric 1344*349cc55cSDimitry Andric auto Rz = Operands.back()->getReg(); 1345*349cc55cSDimitry Andric Operands.pop_back(); 1346*349cc55cSDimitry Andric 1347*349cc55cSDimitry Andric reglist.push_back(Ry); 1348*349cc55cSDimitry Andric reglist.push_back(Rz); 1349*349cc55cSDimitry Andric 1350*349cc55cSDimitry Andric if (getLexer().is(AsmToken::Comma)) 1351*349cc55cSDimitry Andric getLexer().Lex(); // eat ',' 1352*349cc55cSDimitry Andric else if (getLexer().is(AsmToken::EndOfStatement)) 1353*349cc55cSDimitry Andric break; 1354*349cc55cSDimitry Andric 1355*349cc55cSDimitry Andric } else if (getLexer().is(AsmToken::Comma)) { 1356*349cc55cSDimitry Andric reglist.push_back(Ry); 1357*349cc55cSDimitry Andric reglist.push_back(Ry); 1358*349cc55cSDimitry Andric 1359*349cc55cSDimitry Andric getLexer().Lex(); // eat ',' 1360*349cc55cSDimitry Andric } else if (getLexer().is(AsmToken::EndOfStatement)) { 1361*349cc55cSDimitry Andric reglist.push_back(Ry); 1362*349cc55cSDimitry Andric reglist.push_back(Ry); 1363*349cc55cSDimitry Andric break; 1364*349cc55cSDimitry Andric } else { 1365*349cc55cSDimitry Andric Error(getLoc(), "invalid register list"); 1366*349cc55cSDimitry Andric return MatchOperand_ParseFail; 1367*349cc55cSDimitry Andric } 1368*349cc55cSDimitry Andric } 1369*349cc55cSDimitry Andric 1370*349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createRegList(reglist, S)); 1371fe6060f1SDimitry Andric return MatchOperand_Success; 1372fe6060f1SDimitry Andric } 1373fe6060f1SDimitry Andric 1374fe6060f1SDimitry Andric bool CSKYAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 1375fe6060f1SDimitry Andric SMLoc NameLoc, OperandVector &Operands) { 1376fe6060f1SDimitry Andric // First operand is token for instruction. 1377fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createToken(Name, NameLoc)); 1378fe6060f1SDimitry Andric 1379fe6060f1SDimitry Andric // If there are no more operands, then finish. 1380fe6060f1SDimitry Andric if (getLexer().is(AsmToken::EndOfStatement)) 1381fe6060f1SDimitry Andric return false; 1382fe6060f1SDimitry Andric 1383fe6060f1SDimitry Andric // Parse first operand. 1384fe6060f1SDimitry Andric if (parseOperand(Operands, Name)) 1385fe6060f1SDimitry Andric return true; 1386fe6060f1SDimitry Andric 1387fe6060f1SDimitry Andric // Parse until end of statement, consuming commas between operands. 1388fe6060f1SDimitry Andric while (getLexer().is(AsmToken::Comma)) { 1389fe6060f1SDimitry Andric // Consume comma token. 1390fe6060f1SDimitry Andric getLexer().Lex(); 1391fe6060f1SDimitry Andric 1392fe6060f1SDimitry Andric // Parse next operand. 1393fe6060f1SDimitry Andric if (parseOperand(Operands, Name)) 1394fe6060f1SDimitry Andric return true; 1395fe6060f1SDimitry Andric } 1396fe6060f1SDimitry Andric 1397fe6060f1SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) { 1398fe6060f1SDimitry Andric SMLoc Loc = getLexer().getLoc(); 1399fe6060f1SDimitry Andric getParser().eatToEndOfStatement(); 1400fe6060f1SDimitry Andric return Error(Loc, "unexpected token"); 1401fe6060f1SDimitry Andric } 1402fe6060f1SDimitry Andric 1403fe6060f1SDimitry Andric getParser().Lex(); // Consume the EndOfStatement. 1404fe6060f1SDimitry Andric return false; 1405fe6060f1SDimitry Andric } 1406fe6060f1SDimitry Andric 1407fe6060f1SDimitry Andric OperandMatchResultTy CSKYAsmParser::tryParseRegister(unsigned &RegNo, 1408fe6060f1SDimitry Andric SMLoc &StartLoc, 1409fe6060f1SDimitry Andric SMLoc &EndLoc) { 1410fe6060f1SDimitry Andric const AsmToken &Tok = getParser().getTok(); 1411fe6060f1SDimitry Andric StartLoc = Tok.getLoc(); 1412fe6060f1SDimitry Andric EndLoc = Tok.getEndLoc(); 1413fe6060f1SDimitry Andric 1414fe6060f1SDimitry Andric StringRef Name = getLexer().getTok().getIdentifier(); 1415fe6060f1SDimitry Andric 1416*349cc55cSDimitry Andric if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) 1417fe6060f1SDimitry Andric return MatchOperand_NoMatch; 1418fe6060f1SDimitry Andric 1419fe6060f1SDimitry Andric getParser().Lex(); // Eat identifier token. 1420fe6060f1SDimitry Andric return MatchOperand_Success; 1421fe6060f1SDimitry Andric } 1422fe6060f1SDimitry Andric 1423fe6060f1SDimitry Andric bool CSKYAsmParser::ParseDirective(AsmToken DirectiveID) { return true; } 1424fe6060f1SDimitry Andric 1425fe6060f1SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYAsmParser() { 1426fe6060f1SDimitry Andric RegisterMCAsmParser<CSKYAsmParser> X(getTheCSKYTarget()); 1427fe6060f1SDimitry Andric } 1428