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