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_RequiresSameSrcAndDst: { 759 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 760 return Error(ErrorLoc, "src and dst operand must be same"); 761 } 762 case Match_InvalidRegList: { 763 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 764 return Error(ErrorLoc, "invalid register list"); 765 } 766 } 767 LLVM_DEBUG(dbgs() << "Result = " << Result); 768 llvm_unreachable("Unknown match type detected!"); 769 } 770 771 bool CSKYAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 772 OperandVector &Operands, 773 MCStreamer &Out) { 774 775 if (Inst.getOpcode() == CSKY::LDQ32 || Inst.getOpcode() == CSKY::STQ32) { 776 if (Inst.getOperand(1).getReg() != CSKY::R4 || 777 Inst.getOperand(2).getReg() != CSKY::R7) { 778 return Error(IDLoc, "Register sequence is not valid. 'r4-r7' expected"); 779 } 780 Inst.setOpcode(Inst.getOpcode() == CSKY::LDQ32 ? CSKY::LDM32 : CSKY::STM32); 781 Out.emitInstruction(Inst, getSTI()); 782 return false; 783 } else if (Inst.getOpcode() == CSKY::SEXT32 || 784 Inst.getOpcode() == CSKY::ZEXT32) { 785 if (Inst.getOperand(2).getImm() < Inst.getOperand(3).getImm()) 786 return Error(IDLoc, "msb must be greater or equal to lsb"); 787 } else if (Inst.getOpcode() == CSKY::INS32) { 788 if (Inst.getOperand(3).getImm() < Inst.getOperand(4).getImm()) 789 return Error(IDLoc, "msb must be greater or equal to lsb"); 790 } else if (Inst.getOpcode() == CSKY::IDLY32) { 791 if (Inst.getOperand(0).getImm() > 32 || Inst.getOperand(0).getImm() < 0) 792 return Error(IDLoc, "n must be in range [0,32]"); 793 } 794 795 Out.emitInstruction(Inst, getSTI()); 796 return false; 797 } 798 799 // Attempts to match Name as a register (either using the default name or 800 // alternative ABI names), setting RegNo to the matching register. Upon 801 // failure, returns true and sets RegNo to 0. 802 static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, 803 MCRegister &RegNo, StringRef Name) { 804 RegNo = MatchRegisterName(Name); 805 806 if (RegNo == CSKY::NoRegister) 807 RegNo = MatchRegisterAltName(Name); 808 809 return RegNo == CSKY::NoRegister; 810 } 811 812 bool CSKYAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 813 SMLoc &EndLoc) { 814 const AsmToken &Tok = getParser().getTok(); 815 StartLoc = Tok.getLoc(); 816 EndLoc = Tok.getEndLoc(); 817 StringRef Name = getLexer().getTok().getIdentifier(); 818 819 if (!matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) { 820 getParser().Lex(); // Eat identifier token. 821 return false; 822 } 823 824 return MatchOperand_NoMatch; 825 } 826 827 OperandMatchResultTy CSKYAsmParser::parseRegister(OperandVector &Operands) { 828 SMLoc S = getLoc(); 829 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 830 831 switch (getLexer().getKind()) { 832 default: 833 return MatchOperand_NoMatch; 834 case AsmToken::Identifier: { 835 StringRef Name = getLexer().getTok().getIdentifier(); 836 MCRegister RegNo; 837 838 if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) 839 return MatchOperand_NoMatch; 840 841 getLexer().Lex(); 842 Operands.push_back(CSKYOperand::createReg(RegNo, S, E)); 843 844 return MatchOperand_Success; 845 } 846 } 847 } 848 849 OperandMatchResultTy CSKYAsmParser::parseBaseRegImm(OperandVector &Operands) { 850 assert(getLexer().is(AsmToken::LParen)); 851 852 Operands.push_back(CSKYOperand::createToken("(", getLoc())); 853 854 auto Tok = getParser().Lex(); // Eat '(' 855 856 if (parseRegister(Operands) != MatchOperand_Success) { 857 getLexer().UnLex(Tok); 858 Operands.pop_back(); 859 return MatchOperand_NoMatch; 860 } 861 862 if (getLexer().is(AsmToken::RParen)) { 863 Operands.push_back(CSKYOperand::createToken(")", getLoc())); 864 getParser().Lex(); // Eat ')' 865 return MatchOperand_Success; 866 } 867 868 if (getLexer().isNot(AsmToken::Comma)) { 869 Error(getLoc(), "expected ','"); 870 return MatchOperand_ParseFail; 871 } 872 873 getParser().Lex(); // Eat ',' 874 875 if (parseRegister(Operands) == MatchOperand_Success) { 876 if (getLexer().isNot(AsmToken::LessLess)) { 877 Error(getLoc(), "expected '<<'"); 878 return MatchOperand_ParseFail; 879 } 880 881 Operands.push_back(CSKYOperand::createToken("<<", getLoc())); 882 883 getParser().Lex(); // Eat '<<' 884 885 if (parseImmediate(Operands) != MatchOperand_Success) { 886 Error(getLoc(), "expected imm"); 887 return MatchOperand_ParseFail; 888 } 889 890 } else if (parseImmediate(Operands) != MatchOperand_Success) { 891 Error(getLoc(), "expected imm"); 892 return MatchOperand_ParseFail; 893 } 894 895 if (getLexer().isNot(AsmToken::RParen)) { 896 Error(getLoc(), "expected ')'"); 897 return MatchOperand_ParseFail; 898 } 899 900 Operands.push_back(CSKYOperand::createToken(")", getLoc())); 901 902 getParser().Lex(); // Eat ')' 903 904 return MatchOperand_Success; 905 } 906 907 OperandMatchResultTy CSKYAsmParser::parseImmediate(OperandVector &Operands) { 908 switch (getLexer().getKind()) { 909 default: 910 return MatchOperand_NoMatch; 911 case AsmToken::LParen: 912 case AsmToken::Minus: 913 case AsmToken::Plus: 914 case AsmToken::Integer: 915 case AsmToken::String: 916 break; 917 } 918 919 const MCExpr *IdVal; 920 SMLoc S = getLoc(); 921 if (getParser().parseExpression(IdVal)) { 922 Error(getLoc(), "unknown expression"); 923 return MatchOperand_ParseFail; 924 } 925 926 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 927 Operands.push_back(CSKYOperand::createImm(IdVal, S, E)); 928 return MatchOperand_Success; 929 } 930 931 /// Looks at a token type and creates the relevant operand from this 932 /// information, adding to Operands. If operand was parsed, returns false, else 933 /// true. 934 bool CSKYAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 935 // Check if the current operand has a custom associated parser, if so, try to 936 // custom parse the operand, or fallback to the general approach. 937 OperandMatchResultTy Result = 938 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true); 939 if (Result == MatchOperand_Success) 940 return false; 941 if (Result == MatchOperand_ParseFail) 942 return true; 943 944 // Attempt to parse token as register 945 auto Res = parseRegister(Operands); 946 if (Res == MatchOperand_Success) 947 return false; 948 else if (Res == MatchOperand_ParseFail) 949 return true; 950 951 // Attempt to parse token as (register, imm) 952 if (getLexer().is(AsmToken::LParen)) { 953 Res = parseBaseRegImm(Operands); 954 if (Res == MatchOperand_Success) 955 return false; 956 else if (Res == MatchOperand_ParseFail) 957 return true; 958 } 959 960 Res = parseImmediate(Operands); 961 if (Res == MatchOperand_Success) 962 return false; 963 else if (Res == MatchOperand_ParseFail) 964 return true; 965 966 // Finally we have exhausted all options and must declare defeat. 967 Error(getLoc(), "unknown operand"); 968 return true; 969 } 970 971 OperandMatchResultTy CSKYAsmParser::parseCSKYSymbol(OperandVector &Operands) { 972 SMLoc S = getLoc(); 973 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 974 const MCExpr *Res; 975 976 if (getLexer().getKind() != AsmToken::Identifier) 977 return MatchOperand_NoMatch; 978 979 StringRef Identifier; 980 AsmToken Tok = getLexer().getTok(); 981 982 if (getParser().parseIdentifier(Identifier)) { 983 Error(getLoc(), "unknown identifier"); 984 return MatchOperand_ParseFail; 985 } 986 987 CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None; 988 if (Identifier.consume_back("@GOT")) 989 Kind = CSKYMCExpr::VK_CSKY_GOT; 990 else if (Identifier.consume_back("@GOTOFF")) 991 Kind = CSKYMCExpr::VK_CSKY_GOTOFF; 992 else if (Identifier.consume_back("@PLT")) 993 Kind = CSKYMCExpr::VK_CSKY_PLT; 994 else if (Identifier.consume_back("@GOTPC")) 995 Kind = CSKYMCExpr::VK_CSKY_GOTPC; 996 else if (Identifier.consume_back("@TLSGD32")) 997 Kind = CSKYMCExpr::VK_CSKY_TLSGD; 998 else if (Identifier.consume_back("@GOTTPOFF")) 999 Kind = CSKYMCExpr::VK_CSKY_TLSIE; 1000 else if (Identifier.consume_back("@TPOFF")) 1001 Kind = CSKYMCExpr::VK_CSKY_TLSLE; 1002 else if (Identifier.consume_back("@TLSLDM32")) 1003 Kind = CSKYMCExpr::VK_CSKY_TLSLDM; 1004 else if (Identifier.consume_back("@TLSLDO32")) 1005 Kind = CSKYMCExpr::VK_CSKY_TLSLDO; 1006 1007 MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier); 1008 1009 if (!Sym) 1010 Sym = getContext().getOrCreateSymbol(Identifier); 1011 1012 if (Sym->isVariable()) { 1013 const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1014 if (!isa<MCSymbolRefExpr>(V)) { 1015 getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1016 Error(getLoc(), "unknown symbol"); 1017 return MatchOperand_ParseFail; 1018 } 1019 Res = V; 1020 } else 1021 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1022 1023 MCBinaryExpr::Opcode Opcode; 1024 switch (getLexer().getKind()) { 1025 default: 1026 if (Kind != CSKYMCExpr::VK_CSKY_None) 1027 Res = CSKYMCExpr::create(Res, Kind, getContext()); 1028 1029 Operands.push_back(CSKYOperand::createImm(Res, S, E)); 1030 return MatchOperand_Success; 1031 case AsmToken::Plus: 1032 Opcode = MCBinaryExpr::Add; 1033 break; 1034 case AsmToken::Minus: 1035 Opcode = MCBinaryExpr::Sub; 1036 break; 1037 } 1038 1039 getLexer().Lex(); // eat + or - 1040 1041 const MCExpr *Expr; 1042 if (getParser().parseExpression(Expr)) { 1043 Error(getLoc(), "unknown expression"); 1044 return MatchOperand_ParseFail; 1045 } 1046 Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1047 Operands.push_back(CSKYOperand::createImm(Res, S, E)); 1048 return MatchOperand_Success; 1049 } 1050 1051 OperandMatchResultTy CSKYAsmParser::parseDataSymbol(OperandVector &Operands) { 1052 SMLoc S = getLoc(); 1053 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1054 const MCExpr *Res; 1055 1056 if (getLexer().getKind() != AsmToken::LBrac) 1057 return MatchOperand_NoMatch; 1058 1059 getLexer().Lex(); // Eat '['. 1060 1061 if (getLexer().getKind() != AsmToken::Identifier) { 1062 const MCExpr *Expr; 1063 if (getParser().parseExpression(Expr)) { 1064 Error(getLoc(), "unknown expression"); 1065 return MatchOperand_ParseFail; 1066 } 1067 1068 if (getLexer().getKind() != AsmToken::RBrac) { 1069 Error(getLoc(), "expected ]"); 1070 return MatchOperand_ParseFail; 1071 } 1072 1073 getLexer().Lex(); // Eat ']'. 1074 1075 Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E)); 1076 return MatchOperand_Success; 1077 } 1078 1079 AsmToken Tok = getLexer().getTok(); 1080 StringRef Identifier; 1081 1082 if (getParser().parseIdentifier(Identifier)) { 1083 Error(getLoc(), "unknown identifier " + Identifier); 1084 return MatchOperand_ParseFail; 1085 } 1086 1087 CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None; 1088 if (Identifier.consume_back("@GOT")) 1089 Kind = CSKYMCExpr::VK_CSKY_GOT_IMM18_BY4; 1090 else if (Identifier.consume_back("@PLT")) 1091 Kind = CSKYMCExpr::VK_CSKY_PLT_IMM18_BY4; 1092 1093 MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier); 1094 1095 if (!Sym) 1096 Sym = getContext().getOrCreateSymbol(Identifier); 1097 1098 if (Sym->isVariable()) { 1099 const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1100 if (!isa<MCSymbolRefExpr>(V)) { 1101 getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1102 Error(getLoc(), "unknown symbol"); 1103 return MatchOperand_ParseFail; 1104 } 1105 Res = V; 1106 } else { 1107 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1108 } 1109 1110 MCBinaryExpr::Opcode Opcode; 1111 switch (getLexer().getKind()) { 1112 default: 1113 Error(getLoc(), "unknown symbol"); 1114 return MatchOperand_ParseFail; 1115 case AsmToken::RBrac: 1116 1117 getLexer().Lex(); // Eat ']'. 1118 1119 if (Kind != CSKYMCExpr::VK_CSKY_None) 1120 Res = CSKYMCExpr::create(Res, Kind, getContext()); 1121 1122 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1123 return MatchOperand_Success; 1124 case AsmToken::Plus: 1125 Opcode = MCBinaryExpr::Add; 1126 break; 1127 case AsmToken::Minus: 1128 Opcode = MCBinaryExpr::Sub; 1129 break; 1130 } 1131 1132 getLexer().Lex(); // eat + or - 1133 1134 const MCExpr *Expr; 1135 if (getParser().parseExpression(Expr)) { 1136 Error(getLoc(), "unknown expression"); 1137 return MatchOperand_ParseFail; 1138 } 1139 1140 if (getLexer().getKind() != AsmToken::RBrac) { 1141 Error(getLoc(), "expected ']'"); 1142 return MatchOperand_ParseFail; 1143 } 1144 1145 getLexer().Lex(); // Eat ']'. 1146 1147 Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1148 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1149 return MatchOperand_Success; 1150 } 1151 1152 OperandMatchResultTy 1153 CSKYAsmParser::parseConstpoolSymbol(OperandVector &Operands) { 1154 SMLoc S = getLoc(); 1155 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1156 const MCExpr *Res; 1157 1158 if (getLexer().getKind() != AsmToken::LBrac) 1159 return MatchOperand_NoMatch; 1160 1161 getLexer().Lex(); // Eat '['. 1162 1163 if (getLexer().getKind() != AsmToken::Identifier) { 1164 const MCExpr *Expr; 1165 if (getParser().parseExpression(Expr)) { 1166 Error(getLoc(), "unknown expression"); 1167 return MatchOperand_ParseFail; 1168 } 1169 1170 if (getLexer().getKind() != AsmToken::RBrac) { 1171 Error(getLoc(), "expected ']'"); 1172 return MatchOperand_ParseFail; 1173 } 1174 1175 getLexer().Lex(); // Eat ']'. 1176 1177 Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E)); 1178 return MatchOperand_Success; 1179 } 1180 1181 AsmToken Tok = getLexer().getTok(); 1182 StringRef Identifier; 1183 1184 if (getParser().parseIdentifier(Identifier)) { 1185 Error(getLoc(), "unknown identifier"); 1186 return MatchOperand_ParseFail; 1187 } 1188 1189 MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier); 1190 1191 if (!Sym) 1192 Sym = getContext().getOrCreateSymbol(Identifier); 1193 1194 if (Sym->isVariable()) { 1195 const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1196 if (!isa<MCSymbolRefExpr>(V)) { 1197 getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1198 Error(getLoc(), "unknown symbol"); 1199 return MatchOperand_ParseFail; 1200 } 1201 Res = V; 1202 } else { 1203 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1204 } 1205 1206 MCBinaryExpr::Opcode Opcode; 1207 switch (getLexer().getKind()) { 1208 default: 1209 Error(getLoc(), "unknown symbol"); 1210 return MatchOperand_ParseFail; 1211 case AsmToken::RBrac: 1212 1213 getLexer().Lex(); // Eat ']'. 1214 1215 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1216 return MatchOperand_Success; 1217 case AsmToken::Plus: 1218 Opcode = MCBinaryExpr::Add; 1219 break; 1220 case AsmToken::Minus: 1221 Opcode = MCBinaryExpr::Sub; 1222 break; 1223 } 1224 1225 getLexer().Lex(); // eat + or - 1226 1227 const MCExpr *Expr; 1228 if (getParser().parseExpression(Expr)) { 1229 Error(getLoc(), "unknown expression"); 1230 return MatchOperand_ParseFail; 1231 } 1232 1233 if (getLexer().getKind() != AsmToken::RBrac) { 1234 Error(getLoc(), "expected ']'"); 1235 return MatchOperand_ParseFail; 1236 } 1237 1238 getLexer().Lex(); // Eat ']'. 1239 1240 Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1241 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1242 return MatchOperand_Success; 1243 } 1244 1245 OperandMatchResultTy CSKYAsmParser::parsePSRFlag(OperandVector &Operands) { 1246 SMLoc S = getLoc(); 1247 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1248 1249 unsigned Flag = 0; 1250 1251 while (getLexer().isNot(AsmToken::EndOfStatement)) { 1252 StringRef Identifier; 1253 if (getParser().parseIdentifier(Identifier)) { 1254 Error(getLoc(), "unknown identifier " + Identifier); 1255 return MatchOperand_ParseFail; 1256 } 1257 1258 if (Identifier == "sie") 1259 Flag = (1 << 4) | Flag; 1260 else if (Identifier == "ee") 1261 Flag = (1 << 3) | Flag; 1262 else if (Identifier == "ie") 1263 Flag = (1 << 2) | Flag; 1264 else if (Identifier == "fe") 1265 Flag = (1 << 1) | Flag; 1266 else if (Identifier == "af") 1267 Flag = (1 << 0) | Flag; 1268 else { 1269 Error(getLoc(), "expected " + Identifier); 1270 return MatchOperand_ParseFail; 1271 } 1272 1273 if (getLexer().is(AsmToken::EndOfStatement)) 1274 break; 1275 1276 if (getLexer().is(AsmToken::Comma)) { 1277 getLexer().Lex(); // eat ',' 1278 } else { 1279 Error(getLoc(), "expected ,"); 1280 return MatchOperand_ParseFail; 1281 } 1282 } 1283 1284 Operands.push_back( 1285 CSKYOperand::createImm(MCConstantExpr::create(Flag, getContext()), S, E)); 1286 return MatchOperand_Success; 1287 } 1288 1289 OperandMatchResultTy CSKYAsmParser::parseRegSeq(OperandVector &Operands) { 1290 SMLoc S = getLoc(); 1291 1292 if (parseRegister(Operands) != MatchOperand_Success) 1293 return MatchOperand_NoMatch; 1294 1295 auto Ry = Operands.back()->getReg(); 1296 Operands.pop_back(); 1297 1298 if (getLexer().isNot(AsmToken::Minus)) { 1299 Error(getLoc(), "expected '-'"); 1300 return MatchOperand_ParseFail; 1301 } 1302 1303 getLexer().Lex(); // eat '-' 1304 1305 if (parseRegister(Operands) != MatchOperand_Success) { 1306 Error(getLoc(), "invalid register"); 1307 return MatchOperand_ParseFail; 1308 } 1309 1310 auto Rz = Operands.back()->getReg(); 1311 Operands.pop_back(); 1312 1313 Operands.push_back(CSKYOperand::createRegSeq(Ry, Rz, S)); 1314 return MatchOperand_Success; 1315 } 1316 1317 OperandMatchResultTy CSKYAsmParser::parseRegList(OperandVector &Operands) { 1318 SMLoc S = getLoc(); 1319 1320 SmallVector<unsigned, 4> reglist; 1321 1322 while (true) { 1323 1324 if (parseRegister(Operands) != MatchOperand_Success) { 1325 Error(getLoc(), "invalid register"); 1326 return MatchOperand_ParseFail; 1327 } 1328 1329 auto Ry = Operands.back()->getReg(); 1330 Operands.pop_back(); 1331 1332 if (getLexer().is(AsmToken::Minus)) { 1333 getLexer().Lex(); // eat '-' 1334 1335 if (parseRegister(Operands) != MatchOperand_Success) { 1336 Error(getLoc(), "invalid register"); 1337 return MatchOperand_ParseFail; 1338 } 1339 1340 auto Rz = Operands.back()->getReg(); 1341 Operands.pop_back(); 1342 1343 reglist.push_back(Ry); 1344 reglist.push_back(Rz); 1345 1346 if (getLexer().is(AsmToken::Comma)) 1347 getLexer().Lex(); // eat ',' 1348 else if (getLexer().is(AsmToken::EndOfStatement)) 1349 break; 1350 1351 } else if (getLexer().is(AsmToken::Comma)) { 1352 reglist.push_back(Ry); 1353 reglist.push_back(Ry); 1354 1355 getLexer().Lex(); // eat ',' 1356 } else if (getLexer().is(AsmToken::EndOfStatement)) { 1357 reglist.push_back(Ry); 1358 reglist.push_back(Ry); 1359 break; 1360 } else { 1361 Error(getLoc(), "invalid register list"); 1362 return MatchOperand_ParseFail; 1363 } 1364 } 1365 1366 Operands.push_back(CSKYOperand::createRegList(reglist, S)); 1367 return MatchOperand_Success; 1368 } 1369 1370 bool CSKYAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 1371 SMLoc NameLoc, OperandVector &Operands) { 1372 // First operand is token for instruction. 1373 Operands.push_back(CSKYOperand::createToken(Name, NameLoc)); 1374 1375 // If there are no more operands, then finish. 1376 if (getLexer().is(AsmToken::EndOfStatement)) 1377 return false; 1378 1379 // Parse first operand. 1380 if (parseOperand(Operands, Name)) 1381 return true; 1382 1383 // Parse until end of statement, consuming commas between operands. 1384 while (getLexer().is(AsmToken::Comma)) { 1385 // Consume comma token. 1386 getLexer().Lex(); 1387 1388 // Parse next operand. 1389 if (parseOperand(Operands, Name)) 1390 return true; 1391 } 1392 1393 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1394 SMLoc Loc = getLexer().getLoc(); 1395 getParser().eatToEndOfStatement(); 1396 return Error(Loc, "unexpected token"); 1397 } 1398 1399 getParser().Lex(); // Consume the EndOfStatement. 1400 return false; 1401 } 1402 1403 OperandMatchResultTy CSKYAsmParser::tryParseRegister(unsigned &RegNo, 1404 SMLoc &StartLoc, 1405 SMLoc &EndLoc) { 1406 const AsmToken &Tok = getParser().getTok(); 1407 StartLoc = Tok.getLoc(); 1408 EndLoc = Tok.getEndLoc(); 1409 1410 StringRef Name = getLexer().getTok().getIdentifier(); 1411 1412 if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) 1413 return MatchOperand_NoMatch; 1414 1415 getParser().Lex(); // Eat identifier token. 1416 return MatchOperand_Success; 1417 } 1418 1419 bool CSKYAsmParser::ParseDirective(AsmToken DirectiveID) { return true; } 1420 1421 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYAsmParser() { 1422 RegisterMCAsmParser<CSKYAsmParser> X(getTheCSKYTarget()); 1423 } 1424