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