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 bool isRegSeqV1() const { 307 return isRegSeqTemplate<CSKY::F0_32, CSKY::F15_32>(); 308 } 309 310 bool isRegSeqV2() const { 311 return isRegSeqTemplate<CSKY::F0_32, CSKY::F31_32>(); 312 } 313 314 static bool isLegalRegList(unsigned from, unsigned to) { 315 if (from == 0 && to == 0) 316 return true; 317 318 if (from == to) { 319 if (from != CSKY::R4 && from != CSKY::R15 && from != CSKY::R16 && 320 from != CSKY::R28) 321 return false; 322 323 return true; 324 } else { 325 if (from != CSKY::R4 && from != CSKY::R16) 326 return false; 327 328 if (from == CSKY::R4 && to > CSKY::R4 && to < CSKY::R12) 329 return true; 330 else if (from == CSKY::R16 && to > CSKY::R16 && to < CSKY::R18) 331 return true; 332 else 333 return false; 334 } 335 } 336 337 bool isRegList() const { 338 if (!isRegisterList()) 339 return false; 340 341 auto regList = getRegList(); 342 343 if (!isLegalRegList(regList.List1From, regList.List1To)) 344 return false; 345 if (!isLegalRegList(regList.List2From, regList.List2To)) 346 return false; 347 if (!isLegalRegList(regList.List3From, regList.List3To)) 348 return false; 349 if (!isLegalRegList(regList.List4From, regList.List4To)) 350 return false; 351 352 return true; 353 } 354 355 bool isExtImm6() { 356 if (!isImm()) 357 return false; 358 359 int64_t Imm; 360 bool IsConstantImm = evaluateConstantImm(getImm(), Imm); 361 if (!IsConstantImm) 362 return false; 363 364 int uimm4 = Imm & 0xf; 365 366 return isShiftedUInt<6, 0>(Imm) && uimm4 >= 0 && uimm4 <= 14; 367 } 368 369 /// Gets location of the first token of this operand. 370 SMLoc getStartLoc() const override { return StartLoc; } 371 /// Gets location of the last token of this operand. 372 SMLoc getEndLoc() const override { return EndLoc; } 373 374 unsigned getReg() const override { 375 assert(Kind == Register && "Invalid type access!"); 376 return Reg.RegNum; 377 } 378 379 std::pair<unsigned, unsigned> getRegSeq() const { 380 assert(Kind == RegisterSeq && "Invalid type access!"); 381 return std::pair<unsigned, unsigned>(RegSeq.RegNumFrom, RegSeq.RegNumTo); 382 } 383 384 RegListOp getRegList() const { 385 assert(Kind == RegisterList && "Invalid type access!"); 386 return RegList; 387 } 388 389 const MCExpr *getImm() const { 390 assert(Kind == Immediate && "Invalid type access!"); 391 return Imm.Val; 392 } 393 394 const MCExpr *getConstpoolOp() const { 395 assert(Kind == CPOP && "Invalid type access!"); 396 return CPool.Val; 397 } 398 399 StringRef getToken() const { 400 assert(Kind == Token && "Invalid type access!"); 401 return Tok; 402 } 403 404 void print(raw_ostream &OS) const override { 405 auto RegName = [](unsigned Reg) { 406 if (Reg) 407 return CSKYInstPrinter::getRegisterName(Reg); 408 else 409 return "noreg"; 410 }; 411 412 switch (Kind) { 413 case CPOP: 414 OS << *getConstpoolOp(); 415 break; 416 case Immediate: 417 OS << *getImm(); 418 break; 419 case KindTy::Register: 420 OS << "<register " << RegName(getReg()) << ">"; 421 break; 422 case RegisterSeq: 423 OS << "<register-seq "; 424 OS << RegName(getRegSeq().first) << "-" << RegName(getRegSeq().second) 425 << ">"; 426 break; 427 case RegisterList: 428 OS << "<register-list "; 429 OS << RegName(getRegList().List1From) << "-" 430 << RegName(getRegList().List1To) << ","; 431 OS << RegName(getRegList().List2From) << "-" 432 << RegName(getRegList().List2To) << ","; 433 OS << RegName(getRegList().List3From) << "-" 434 << RegName(getRegList().List3To) << ","; 435 OS << RegName(getRegList().List4From) << "-" 436 << RegName(getRegList().List4To); 437 break; 438 case Token: 439 OS << "'" << getToken() << "'"; 440 break; 441 } 442 } 443 444 static std::unique_ptr<CSKYOperand> createToken(StringRef Str, SMLoc S) { 445 auto Op = std::make_unique<CSKYOperand>(Token); 446 Op->Tok = Str; 447 Op->StartLoc = S; 448 Op->EndLoc = S; 449 return Op; 450 } 451 452 static std::unique_ptr<CSKYOperand> createReg(unsigned RegNo, SMLoc S, 453 SMLoc E) { 454 auto Op = std::make_unique<CSKYOperand>(Register); 455 Op->Reg.RegNum = RegNo; 456 Op->StartLoc = S; 457 Op->EndLoc = E; 458 return Op; 459 } 460 461 static std::unique_ptr<CSKYOperand> createRegSeq(unsigned RegNoFrom, 462 unsigned RegNoTo, SMLoc S) { 463 auto Op = std::make_unique<CSKYOperand>(RegisterSeq); 464 Op->RegSeq.RegNumFrom = RegNoFrom; 465 Op->RegSeq.RegNumTo = RegNoTo; 466 Op->StartLoc = S; 467 Op->EndLoc = S; 468 return Op; 469 } 470 471 static std::unique_ptr<CSKYOperand> 472 createRegList(SmallVector<unsigned, 4> reglist, SMLoc S) { 473 auto Op = std::make_unique<CSKYOperand>(RegisterList); 474 Op->RegList.List1From = 0; 475 Op->RegList.List1To = 0; 476 Op->RegList.List2From = 0; 477 Op->RegList.List2To = 0; 478 Op->RegList.List3From = 0; 479 Op->RegList.List3To = 0; 480 Op->RegList.List4From = 0; 481 Op->RegList.List4To = 0; 482 483 for (unsigned i = 0; i < reglist.size(); i += 2) { 484 if (Op->RegList.List1From == 0) { 485 Op->RegList.List1From = reglist[i]; 486 Op->RegList.List1To = reglist[i + 1]; 487 } else if (Op->RegList.List2From == 0) { 488 Op->RegList.List2From = reglist[i]; 489 Op->RegList.List2To = reglist[i + 1]; 490 } else if (Op->RegList.List3From == 0) { 491 Op->RegList.List3From = reglist[i]; 492 Op->RegList.List3To = reglist[i + 1]; 493 } else if (Op->RegList.List4From == 0) { 494 Op->RegList.List4From = reglist[i]; 495 Op->RegList.List4To = reglist[i + 1]; 496 } else { 497 assert(0); 498 } 499 } 500 501 Op->StartLoc = S; 502 Op->EndLoc = S; 503 return Op; 504 } 505 506 static std::unique_ptr<CSKYOperand> createImm(const MCExpr *Val, SMLoc S, 507 SMLoc E) { 508 auto Op = std::make_unique<CSKYOperand>(Immediate); 509 Op->Imm.Val = Val; 510 Op->StartLoc = S; 511 Op->EndLoc = E; 512 return Op; 513 } 514 515 static std::unique_ptr<CSKYOperand> createConstpoolOp(const MCExpr *Val, 516 SMLoc S, SMLoc E) { 517 auto Op = std::make_unique<CSKYOperand>(CPOP); 518 Op->CPool.Val = Val; 519 Op->StartLoc = S; 520 Op->EndLoc = E; 521 return Op; 522 } 523 524 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 525 assert(Expr && "Expr shouldn't be null!"); 526 if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) 527 Inst.addOperand(MCOperand::createImm(CE->getValue())); 528 else 529 Inst.addOperand(MCOperand::createExpr(Expr)); 530 } 531 532 // Used by the TableGen Code. 533 void addRegOperands(MCInst &Inst, unsigned N) const { 534 assert(N == 1 && "Invalid number of operands!"); 535 Inst.addOperand(MCOperand::createReg(getReg())); 536 } 537 538 void addImmOperands(MCInst &Inst, unsigned N) const { 539 assert(N == 1 && "Invalid number of operands!"); 540 addExpr(Inst, getImm()); 541 } 542 543 void addConstpoolOperands(MCInst &Inst, unsigned N) const { 544 assert(N == 1 && "Invalid number of operands!"); 545 Inst.addOperand(MCOperand::createExpr(getConstpoolOp())); 546 } 547 548 void addRegSeqOperands(MCInst &Inst, unsigned N) const { 549 assert(N == 2 && "Invalid number of operands!"); 550 auto regSeq = getRegSeq(); 551 552 Inst.addOperand(MCOperand::createReg(regSeq.first)); 553 Inst.addOperand(MCOperand::createReg(regSeq.second)); 554 } 555 556 static unsigned getListValue(unsigned ListFrom, unsigned ListTo) { 557 if (ListFrom == ListTo && ListFrom == CSKY::R15) 558 return (1 << 4); 559 else if (ListFrom == ListTo && ListFrom == CSKY::R28) 560 return (1 << 8); 561 else if (ListFrom == CSKY::R4) 562 return ListTo - ListFrom + 1; 563 else if (ListFrom == CSKY::R16) 564 return ((ListTo - ListFrom + 1) << 5); 565 else 566 return 0; 567 } 568 569 void addRegListOperands(MCInst &Inst, unsigned N) const { 570 assert(N == 1 && "Invalid number of operands!"); 571 auto regList = getRegList(); 572 573 unsigned V = 0; 574 575 unsigned T = getListValue(regList.List1From, regList.List1To); 576 if (T != 0) 577 V = V | T; 578 579 T = getListValue(regList.List2From, regList.List2To); 580 if (T != 0) 581 V = V | T; 582 583 T = getListValue(regList.List3From, regList.List3To); 584 if (T != 0) 585 V = V | T; 586 587 T = getListValue(regList.List4From, regList.List4To); 588 if (T != 0) 589 V = V | T; 590 591 Inst.addOperand(MCOperand::createImm(V)); 592 } 593 594 bool isValidForTie(const CSKYOperand &Other) const { 595 if (Kind != Other.Kind) 596 return false; 597 598 switch (Kind) { 599 default: 600 llvm_unreachable("Unexpected kind"); 601 return false; 602 case Register: 603 return Reg.RegNum == Other.Reg.RegNum; 604 } 605 } 606 }; 607 } // end anonymous namespace. 608 609 #define GET_REGISTER_MATCHER 610 #define GET_SUBTARGET_FEATURE_NAME 611 #define GET_MATCHER_IMPLEMENTATION 612 #define GET_MNEMONIC_SPELL_CHECKER 613 #include "CSKYGenAsmMatcher.inc" 614 615 static std::string CSKYMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, 616 unsigned VariantID = 0); 617 618 bool CSKYAsmParser::generateImmOutOfRangeError( 619 OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper, 620 Twine Msg = "immediate must be an integer in the range") { 621 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 622 return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]"); 623 } 624 625 bool CSKYAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 626 OperandVector &Operands, 627 MCStreamer &Out, 628 uint64_t &ErrorInfo, 629 bool MatchingInlineAsm) { 630 MCInst Inst; 631 FeatureBitset MissingFeatures; 632 633 auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures, 634 MatchingInlineAsm); 635 switch (Result) { 636 default: 637 break; 638 case Match_Success: 639 return processInstruction(Inst, IDLoc, Operands, Out); 640 case Match_MissingFeature: { 641 assert(MissingFeatures.any() && "Unknown missing features!"); 642 ListSeparator LS; 643 std::string Msg = "instruction requires the following: "; 644 for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) { 645 if (MissingFeatures[i]) { 646 Msg += LS; 647 Msg += getSubtargetFeatureName(i); 648 } 649 } 650 return Error(IDLoc, Msg); 651 } 652 case Match_MnemonicFail: { 653 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits()); 654 std::string Suggestion = 655 CSKYMnemonicSpellCheck(((CSKYOperand &)*Operands[0]).getToken(), FBS); 656 return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion); 657 } 658 case Match_InvalidTiedOperand: 659 case Match_InvalidOperand: { 660 SMLoc ErrorLoc = IDLoc; 661 if (ErrorInfo != ~0U) { 662 if (ErrorInfo >= Operands.size()) 663 return Error(ErrorLoc, "too few operands for instruction"); 664 665 ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 666 if (ErrorLoc == SMLoc()) 667 ErrorLoc = IDLoc; 668 } 669 return Error(ErrorLoc, "invalid operand for instruction"); 670 } 671 } 672 673 // Handle the case when the error message is of specific type 674 // other than the generic Match_InvalidOperand, and the 675 // corresponding operand is missing. 676 if (Result > FIRST_TARGET_MATCH_RESULT_TY) { 677 SMLoc ErrorLoc = IDLoc; 678 if (ErrorInfo != ~0U && ErrorInfo >= Operands.size()) 679 return Error(ErrorLoc, "too few operands for instruction"); 680 } 681 682 switch (Result) { 683 default: 684 break; 685 case Match_InvalidSImm8: 686 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7), 687 (1 << 7) - 1); 688 case Match_InvalidOImm3: 689 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 3)); 690 case Match_InvalidOImm4: 691 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4)); 692 case Match_InvalidOImm5: 693 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5)); 694 case Match_InvalidOImm6: 695 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6)); 696 case Match_InvalidOImm8: 697 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 8)); 698 case Match_InvalidOImm12: 699 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 12)); 700 case Match_InvalidOImm16: 701 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16)); 702 case Match_InvalidUImm1: 703 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1); 704 case Match_InvalidUImm2: 705 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1); 706 case Match_InvalidUImm3: 707 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1); 708 case Match_InvalidUImm4: 709 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1); 710 case Match_InvalidUImm5: 711 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 712 case Match_InvalidUImm6: 713 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); 714 case Match_InvalidUImm7: 715 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1); 716 case Match_InvalidUImm8: 717 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1); 718 case Match_InvalidUImm12: 719 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1); 720 case Match_InvalidUImm16: 721 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 16) - 1); 722 case Match_InvalidUImm5Shift1: 723 return generateImmOutOfRangeError( 724 Operands, ErrorInfo, 0, (1 << 5) - 2, 725 "immediate must be a multiple of 2 bytes in the range"); 726 case Match_InvalidUImm12Shift1: 727 return generateImmOutOfRangeError( 728 Operands, ErrorInfo, 0, (1 << 12) - 2, 729 "immediate must be a multiple of 2 bytes in the range"); 730 case Match_InvalidUImm5Shift2: 731 return generateImmOutOfRangeError( 732 Operands, ErrorInfo, 0, (1 << 5) - 4, 733 "immediate must be a multiple of 4 bytes in the range"); 734 case Match_InvalidUImm7Shift1: 735 return generateImmOutOfRangeError( 736 Operands, ErrorInfo, 0, (1 << 7) - 2, 737 "immediate must be a multiple of 2 bytes in the range"); 738 case Match_InvalidUImm7Shift2: 739 return generateImmOutOfRangeError( 740 Operands, ErrorInfo, 0, (1 << 7) - 4, 741 "immediate must be a multiple of 4 bytes in the range"); 742 case Match_InvalidUImm8Shift2: 743 return generateImmOutOfRangeError( 744 Operands, ErrorInfo, 0, (1 << 8) - 4, 745 "immediate must be a multiple of 4 bytes in the range"); 746 case Match_InvalidUImm8Shift3: 747 return generateImmOutOfRangeError( 748 Operands, ErrorInfo, 0, (1 << 8) - 8, 749 "immediate must be a multiple of 8 bytes in the range"); 750 case Match_InvalidUImm8Shift8: 751 return generateImmOutOfRangeError( 752 Operands, ErrorInfo, 0, (1 << 8) - 256, 753 "immediate must be a multiple of 256 bytes in the range"); 754 case Match_InvalidUImm12Shift2: 755 return generateImmOutOfRangeError( 756 Operands, ErrorInfo, 0, (1 << 12) - 4, 757 "immediate must be a multiple of 4 bytes in the range"); 758 case Match_InvalidCSKYSymbol: { 759 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 760 return Error(ErrorLoc, "operand must be a symbol name"); 761 } 762 case Match_InvalidConstpool: { 763 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 764 return Error(ErrorLoc, "operand must be a constpool symbol name"); 765 } 766 case Match_InvalidPSRFlag: { 767 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 768 return Error(ErrorLoc, "psrset operand is not valid"); 769 } 770 case Match_InvalidRegSeq: { 771 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 772 return Error(ErrorLoc, "Register sequence is not valid"); 773 } 774 case Match_InvalidRegOutOfRange: { 775 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 776 return Error(ErrorLoc, "register is out of range"); 777 } 778 case Match_RequiresSameSrcAndDst: { 779 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 780 return Error(ErrorLoc, "src and dst operand must be same"); 781 } 782 case Match_InvalidRegList: { 783 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); 784 return Error(ErrorLoc, "invalid register list"); 785 } 786 } 787 LLVM_DEBUG(dbgs() << "Result = " << Result); 788 llvm_unreachable("Unknown match type detected!"); 789 } 790 791 bool CSKYAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 792 OperandVector &Operands, 793 MCStreamer &Out) { 794 795 switch (Inst.getOpcode()) { 796 default: 797 break; 798 case CSKY::LDQ32: 799 case CSKY::STQ32: 800 if (Inst.getOperand(1).getReg() != CSKY::R4 || 801 Inst.getOperand(2).getReg() != CSKY::R7) { 802 return Error(IDLoc, "Register sequence is not valid. 'r4-r7' expected"); 803 } 804 Inst.setOpcode(Inst.getOpcode() == CSKY::LDQ32 ? CSKY::LDM32 : CSKY::STM32); 805 break; 806 case CSKY::SEXT32: 807 case CSKY::ZEXT32: 808 if (Inst.getOperand(2).getImm() < Inst.getOperand(3).getImm()) 809 return Error(IDLoc, "msb must be greater or equal to lsb"); 810 break; 811 case CSKY::INS32: 812 if (Inst.getOperand(3).getImm() < Inst.getOperand(4).getImm()) 813 return Error(IDLoc, "msb must be greater or equal to lsb"); 814 break; 815 case CSKY::IDLY32: 816 if (Inst.getOperand(0).getImm() > 32 || Inst.getOperand(0).getImm() < 0) 817 return Error(IDLoc, "n must be in range [0,32]"); 818 break; 819 case CSKY::ADDC32: 820 case CSKY::SUBC32: 821 case CSKY::ADDC16: 822 case CSKY::SUBC16: 823 Inst.erase(std::next(Inst.begin())); 824 Inst.erase(std::prev(Inst.end())); 825 Inst.insert(std::next(Inst.begin()), MCOperand::createReg(CSKY::C)); 826 Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C)); 827 break; 828 case CSKY::CMPNEI32: 829 case CSKY::CMPNEI16: 830 case CSKY::CMPNE32: 831 case CSKY::CMPNE16: 832 case CSKY::CMPHSI32: 833 case CSKY::CMPHSI16: 834 case CSKY::CMPHS32: 835 case CSKY::CMPHS16: 836 case CSKY::CMPLTI32: 837 case CSKY::CMPLTI16: 838 case CSKY::CMPLT32: 839 case CSKY::CMPLT16: 840 case CSKY::BTSTI32: 841 Inst.erase(Inst.begin()); 842 Inst.insert(Inst.begin(), MCOperand::createReg(CSKY::C)); 843 break; 844 case CSKY::MVCV32: 845 Inst.erase(std::next(Inst.begin())); 846 Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C)); 847 break; 848 } 849 850 emitToStreamer(Out, Inst); 851 return false; 852 } 853 854 // Attempts to match Name as a register (either using the default name or 855 // alternative ABI names), setting RegNo to the matching register. Upon 856 // failure, returns true and sets RegNo to 0. 857 static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, 858 MCRegister &RegNo, StringRef Name) { 859 RegNo = MatchRegisterName(Name); 860 861 if (RegNo == CSKY::NoRegister) 862 RegNo = MatchRegisterAltName(Name); 863 864 return RegNo == CSKY::NoRegister; 865 } 866 867 bool CSKYAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 868 SMLoc &EndLoc) { 869 const AsmToken &Tok = getParser().getTok(); 870 StartLoc = Tok.getLoc(); 871 EndLoc = Tok.getEndLoc(); 872 StringRef Name = getLexer().getTok().getIdentifier(); 873 874 if (!matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) { 875 getParser().Lex(); // Eat identifier token. 876 return false; 877 } 878 879 return MatchOperand_NoMatch; 880 } 881 882 OperandMatchResultTy CSKYAsmParser::parseRegister(OperandVector &Operands) { 883 SMLoc S = getLoc(); 884 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 885 886 switch (getLexer().getKind()) { 887 default: 888 return MatchOperand_NoMatch; 889 case AsmToken::Identifier: { 890 StringRef Name = getLexer().getTok().getIdentifier(); 891 MCRegister RegNo; 892 893 if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) 894 return MatchOperand_NoMatch; 895 896 getLexer().Lex(); 897 Operands.push_back(CSKYOperand::createReg(RegNo, S, E)); 898 899 return MatchOperand_Success; 900 } 901 } 902 } 903 904 OperandMatchResultTy CSKYAsmParser::parseBaseRegImm(OperandVector &Operands) { 905 assert(getLexer().is(AsmToken::LParen)); 906 907 Operands.push_back(CSKYOperand::createToken("(", getLoc())); 908 909 auto Tok = getParser().Lex(); // Eat '(' 910 911 if (parseRegister(Operands) != MatchOperand_Success) { 912 getLexer().UnLex(Tok); 913 Operands.pop_back(); 914 return MatchOperand_NoMatch; 915 } 916 917 if (getLexer().is(AsmToken::RParen)) { 918 Operands.push_back(CSKYOperand::createToken(")", getLoc())); 919 getParser().Lex(); // Eat ')' 920 return MatchOperand_Success; 921 } 922 923 if (getLexer().isNot(AsmToken::Comma)) { 924 Error(getLoc(), "expected ','"); 925 return MatchOperand_ParseFail; 926 } 927 928 getParser().Lex(); // Eat ',' 929 930 if (parseRegister(Operands) == MatchOperand_Success) { 931 if (getLexer().isNot(AsmToken::LessLess)) { 932 Error(getLoc(), "expected '<<'"); 933 return MatchOperand_ParseFail; 934 } 935 936 Operands.push_back(CSKYOperand::createToken("<<", getLoc())); 937 938 getParser().Lex(); // Eat '<<' 939 940 if (parseImmediate(Operands) != MatchOperand_Success) { 941 Error(getLoc(), "expected imm"); 942 return MatchOperand_ParseFail; 943 } 944 945 } else if (parseImmediate(Operands) != MatchOperand_Success) { 946 Error(getLoc(), "expected imm"); 947 return MatchOperand_ParseFail; 948 } 949 950 if (getLexer().isNot(AsmToken::RParen)) { 951 Error(getLoc(), "expected ')'"); 952 return MatchOperand_ParseFail; 953 } 954 955 Operands.push_back(CSKYOperand::createToken(")", getLoc())); 956 957 getParser().Lex(); // Eat ')' 958 959 return MatchOperand_Success; 960 } 961 962 OperandMatchResultTy CSKYAsmParser::parseImmediate(OperandVector &Operands) { 963 switch (getLexer().getKind()) { 964 default: 965 return MatchOperand_NoMatch; 966 case AsmToken::LParen: 967 case AsmToken::Minus: 968 case AsmToken::Plus: 969 case AsmToken::Integer: 970 case AsmToken::String: 971 break; 972 } 973 974 const MCExpr *IdVal; 975 SMLoc S = getLoc(); 976 if (getParser().parseExpression(IdVal)) { 977 Error(getLoc(), "unknown expression"); 978 return MatchOperand_ParseFail; 979 } 980 981 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 982 Operands.push_back(CSKYOperand::createImm(IdVal, S, E)); 983 return MatchOperand_Success; 984 } 985 986 /// Looks at a token type and creates the relevant operand from this 987 /// information, adding to Operands. If operand was parsed, returns false, else 988 /// true. 989 bool CSKYAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 990 // Check if the current operand has a custom associated parser, if so, try to 991 // custom parse the operand, or fallback to the general approach. 992 OperandMatchResultTy Result = 993 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true); 994 if (Result == MatchOperand_Success) 995 return false; 996 if (Result == MatchOperand_ParseFail) 997 return true; 998 999 // Attempt to parse token as register 1000 auto Res = parseRegister(Operands); 1001 if (Res == MatchOperand_Success) 1002 return false; 1003 else if (Res == MatchOperand_ParseFail) 1004 return true; 1005 1006 // Attempt to parse token as (register, imm) 1007 if (getLexer().is(AsmToken::LParen)) { 1008 Res = parseBaseRegImm(Operands); 1009 if (Res == MatchOperand_Success) 1010 return false; 1011 else if (Res == MatchOperand_ParseFail) 1012 return true; 1013 } 1014 1015 Res = parseImmediate(Operands); 1016 if (Res == MatchOperand_Success) 1017 return false; 1018 else if (Res == MatchOperand_ParseFail) 1019 return true; 1020 1021 // Finally we have exhausted all options and must declare defeat. 1022 Error(getLoc(), "unknown operand"); 1023 return true; 1024 } 1025 1026 OperandMatchResultTy CSKYAsmParser::parseCSKYSymbol(OperandVector &Operands) { 1027 SMLoc S = getLoc(); 1028 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1029 const MCExpr *Res; 1030 1031 if (getLexer().getKind() != AsmToken::Identifier) 1032 return MatchOperand_NoMatch; 1033 1034 StringRef Identifier; 1035 AsmToken Tok = getLexer().getTok(); 1036 1037 if (getParser().parseIdentifier(Identifier)) { 1038 Error(getLoc(), "unknown identifier"); 1039 return MatchOperand_ParseFail; 1040 } 1041 1042 CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None; 1043 if (Identifier.consume_back("@GOT")) 1044 Kind = CSKYMCExpr::VK_CSKY_GOT; 1045 else if (Identifier.consume_back("@GOTOFF")) 1046 Kind = CSKYMCExpr::VK_CSKY_GOTOFF; 1047 else if (Identifier.consume_back("@PLT")) 1048 Kind = CSKYMCExpr::VK_CSKY_PLT; 1049 else if (Identifier.consume_back("@GOTPC")) 1050 Kind = CSKYMCExpr::VK_CSKY_GOTPC; 1051 else if (Identifier.consume_back("@TLSGD32")) 1052 Kind = CSKYMCExpr::VK_CSKY_TLSGD; 1053 else if (Identifier.consume_back("@GOTTPOFF")) 1054 Kind = CSKYMCExpr::VK_CSKY_TLSIE; 1055 else if (Identifier.consume_back("@TPOFF")) 1056 Kind = CSKYMCExpr::VK_CSKY_TLSLE; 1057 else if (Identifier.consume_back("@TLSLDM32")) 1058 Kind = CSKYMCExpr::VK_CSKY_TLSLDM; 1059 else if (Identifier.consume_back("@TLSLDO32")) 1060 Kind = CSKYMCExpr::VK_CSKY_TLSLDO; 1061 1062 MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier); 1063 1064 if (!Sym) 1065 Sym = getContext().getOrCreateSymbol(Identifier); 1066 1067 if (Sym->isVariable()) { 1068 const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1069 if (!isa<MCSymbolRefExpr>(V)) { 1070 getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1071 Error(getLoc(), "unknown symbol"); 1072 return MatchOperand_ParseFail; 1073 } 1074 Res = V; 1075 } else 1076 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1077 1078 MCBinaryExpr::Opcode Opcode; 1079 switch (getLexer().getKind()) { 1080 default: 1081 if (Kind != CSKYMCExpr::VK_CSKY_None) 1082 Res = CSKYMCExpr::create(Res, Kind, getContext()); 1083 1084 Operands.push_back(CSKYOperand::createImm(Res, S, E)); 1085 return MatchOperand_Success; 1086 case AsmToken::Plus: 1087 Opcode = MCBinaryExpr::Add; 1088 break; 1089 case AsmToken::Minus: 1090 Opcode = MCBinaryExpr::Sub; 1091 break; 1092 } 1093 1094 getLexer().Lex(); // eat + or - 1095 1096 const MCExpr *Expr; 1097 if (getParser().parseExpression(Expr)) { 1098 Error(getLoc(), "unknown expression"); 1099 return MatchOperand_ParseFail; 1100 } 1101 Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1102 Operands.push_back(CSKYOperand::createImm(Res, S, E)); 1103 return MatchOperand_Success; 1104 } 1105 1106 OperandMatchResultTy CSKYAsmParser::parseDataSymbol(OperandVector &Operands) { 1107 SMLoc S = getLoc(); 1108 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1109 const MCExpr *Res; 1110 1111 if (getLexer().getKind() != AsmToken::LBrac) 1112 return MatchOperand_NoMatch; 1113 1114 getLexer().Lex(); // Eat '['. 1115 1116 if (getLexer().getKind() != AsmToken::Identifier) { 1117 const MCExpr *Expr; 1118 if (getParser().parseExpression(Expr)) { 1119 Error(getLoc(), "unknown expression"); 1120 return MatchOperand_ParseFail; 1121 } 1122 1123 if (getLexer().getKind() != AsmToken::RBrac) { 1124 Error(getLoc(), "expected ]"); 1125 return MatchOperand_ParseFail; 1126 } 1127 1128 getLexer().Lex(); // Eat ']'. 1129 1130 Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E)); 1131 return MatchOperand_Success; 1132 } 1133 1134 AsmToken Tok = getLexer().getTok(); 1135 StringRef Identifier; 1136 1137 if (getParser().parseIdentifier(Identifier)) { 1138 Error(getLoc(), "unknown identifier " + Identifier); 1139 return MatchOperand_ParseFail; 1140 } 1141 1142 CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None; 1143 if (Identifier.consume_back("@GOT")) 1144 Kind = CSKYMCExpr::VK_CSKY_GOT_IMM18_BY4; 1145 else if (Identifier.consume_back("@PLT")) 1146 Kind = CSKYMCExpr::VK_CSKY_PLT_IMM18_BY4; 1147 1148 MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier); 1149 1150 if (!Sym) 1151 Sym = getContext().getOrCreateSymbol(Identifier); 1152 1153 if (Sym->isVariable()) { 1154 const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1155 if (!isa<MCSymbolRefExpr>(V)) { 1156 getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1157 Error(getLoc(), "unknown symbol"); 1158 return MatchOperand_ParseFail; 1159 } 1160 Res = V; 1161 } else { 1162 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1163 } 1164 1165 MCBinaryExpr::Opcode Opcode; 1166 switch (getLexer().getKind()) { 1167 default: 1168 Error(getLoc(), "unknown symbol"); 1169 return MatchOperand_ParseFail; 1170 case AsmToken::RBrac: 1171 1172 getLexer().Lex(); // Eat ']'. 1173 1174 if (Kind != CSKYMCExpr::VK_CSKY_None) 1175 Res = CSKYMCExpr::create(Res, Kind, getContext()); 1176 1177 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1178 return MatchOperand_Success; 1179 case AsmToken::Plus: 1180 Opcode = MCBinaryExpr::Add; 1181 break; 1182 case AsmToken::Minus: 1183 Opcode = MCBinaryExpr::Sub; 1184 break; 1185 } 1186 1187 getLexer().Lex(); // eat + or - 1188 1189 const MCExpr *Expr; 1190 if (getParser().parseExpression(Expr)) { 1191 Error(getLoc(), "unknown expression"); 1192 return MatchOperand_ParseFail; 1193 } 1194 1195 if (getLexer().getKind() != AsmToken::RBrac) { 1196 Error(getLoc(), "expected ']'"); 1197 return MatchOperand_ParseFail; 1198 } 1199 1200 getLexer().Lex(); // Eat ']'. 1201 1202 Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1203 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1204 return MatchOperand_Success; 1205 } 1206 1207 OperandMatchResultTy 1208 CSKYAsmParser::parseConstpoolSymbol(OperandVector &Operands) { 1209 SMLoc S = getLoc(); 1210 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1211 const MCExpr *Res; 1212 1213 if (getLexer().getKind() != AsmToken::LBrac) 1214 return MatchOperand_NoMatch; 1215 1216 getLexer().Lex(); // Eat '['. 1217 1218 if (getLexer().getKind() != AsmToken::Identifier) { 1219 const MCExpr *Expr; 1220 if (getParser().parseExpression(Expr)) { 1221 Error(getLoc(), "unknown expression"); 1222 return MatchOperand_ParseFail; 1223 } 1224 1225 if (getLexer().getKind() != AsmToken::RBrac) { 1226 Error(getLoc(), "expected ']'"); 1227 return MatchOperand_ParseFail; 1228 } 1229 1230 getLexer().Lex(); // Eat ']'. 1231 1232 Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E)); 1233 return MatchOperand_Success; 1234 } 1235 1236 AsmToken Tok = getLexer().getTok(); 1237 StringRef Identifier; 1238 1239 if (getParser().parseIdentifier(Identifier)) { 1240 Error(getLoc(), "unknown identifier"); 1241 return MatchOperand_ParseFail; 1242 } 1243 1244 MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier); 1245 1246 if (!Sym) 1247 Sym = getContext().getOrCreateSymbol(Identifier); 1248 1249 if (Sym->isVariable()) { 1250 const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1251 if (!isa<MCSymbolRefExpr>(V)) { 1252 getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1253 Error(getLoc(), "unknown symbol"); 1254 return MatchOperand_ParseFail; 1255 } 1256 Res = V; 1257 } else { 1258 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1259 } 1260 1261 MCBinaryExpr::Opcode Opcode; 1262 switch (getLexer().getKind()) { 1263 default: 1264 Error(getLoc(), "unknown symbol"); 1265 return MatchOperand_ParseFail; 1266 case AsmToken::RBrac: 1267 1268 getLexer().Lex(); // Eat ']'. 1269 1270 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1271 return MatchOperand_Success; 1272 case AsmToken::Plus: 1273 Opcode = MCBinaryExpr::Add; 1274 break; 1275 case AsmToken::Minus: 1276 Opcode = MCBinaryExpr::Sub; 1277 break; 1278 } 1279 1280 getLexer().Lex(); // eat + or - 1281 1282 const MCExpr *Expr; 1283 if (getParser().parseExpression(Expr)) { 1284 Error(getLoc(), "unknown expression"); 1285 return MatchOperand_ParseFail; 1286 } 1287 1288 if (getLexer().getKind() != AsmToken::RBrac) { 1289 Error(getLoc(), "expected ']'"); 1290 return MatchOperand_ParseFail; 1291 } 1292 1293 getLexer().Lex(); // Eat ']'. 1294 1295 Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1296 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); 1297 return MatchOperand_Success; 1298 } 1299 1300 OperandMatchResultTy CSKYAsmParser::parsePSRFlag(OperandVector &Operands) { 1301 SMLoc S = getLoc(); 1302 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1303 1304 unsigned Flag = 0; 1305 1306 while (getLexer().isNot(AsmToken::EndOfStatement)) { 1307 StringRef Identifier; 1308 if (getParser().parseIdentifier(Identifier)) { 1309 Error(getLoc(), "unknown identifier " + Identifier); 1310 return MatchOperand_ParseFail; 1311 } 1312 1313 if (Identifier == "sie") 1314 Flag = (1 << 4) | Flag; 1315 else if (Identifier == "ee") 1316 Flag = (1 << 3) | Flag; 1317 else if (Identifier == "ie") 1318 Flag = (1 << 2) | Flag; 1319 else if (Identifier == "fe") 1320 Flag = (1 << 1) | Flag; 1321 else if (Identifier == "af") 1322 Flag = (1 << 0) | Flag; 1323 else { 1324 Error(getLoc(), "expected " + Identifier); 1325 return MatchOperand_ParseFail; 1326 } 1327 1328 if (getLexer().is(AsmToken::EndOfStatement)) 1329 break; 1330 1331 if (getLexer().is(AsmToken::Comma)) { 1332 getLexer().Lex(); // eat ',' 1333 } else { 1334 Error(getLoc(), "expected ,"); 1335 return MatchOperand_ParseFail; 1336 } 1337 } 1338 1339 Operands.push_back( 1340 CSKYOperand::createImm(MCConstantExpr::create(Flag, getContext()), S, E)); 1341 return MatchOperand_Success; 1342 } 1343 1344 OperandMatchResultTy CSKYAsmParser::parseRegSeq(OperandVector &Operands) { 1345 SMLoc S = getLoc(); 1346 1347 if (parseRegister(Operands) != MatchOperand_Success) 1348 return MatchOperand_NoMatch; 1349 1350 auto Ry = Operands.back()->getReg(); 1351 Operands.pop_back(); 1352 1353 if (getLexer().isNot(AsmToken::Minus)) { 1354 Error(getLoc(), "expected '-'"); 1355 return MatchOperand_ParseFail; 1356 } 1357 1358 getLexer().Lex(); // eat '-' 1359 1360 if (parseRegister(Operands) != MatchOperand_Success) { 1361 Error(getLoc(), "invalid register"); 1362 return MatchOperand_ParseFail; 1363 } 1364 1365 auto Rz = Operands.back()->getReg(); 1366 Operands.pop_back(); 1367 1368 Operands.push_back(CSKYOperand::createRegSeq(Ry, Rz, S)); 1369 return MatchOperand_Success; 1370 } 1371 1372 OperandMatchResultTy CSKYAsmParser::parseRegList(OperandVector &Operands) { 1373 SMLoc S = getLoc(); 1374 1375 SmallVector<unsigned, 4> reglist; 1376 1377 while (true) { 1378 1379 if (parseRegister(Operands) != MatchOperand_Success) { 1380 Error(getLoc(), "invalid register"); 1381 return MatchOperand_ParseFail; 1382 } 1383 1384 auto Ry = Operands.back()->getReg(); 1385 Operands.pop_back(); 1386 1387 if (getLexer().is(AsmToken::Minus)) { 1388 getLexer().Lex(); // eat '-' 1389 1390 if (parseRegister(Operands) != MatchOperand_Success) { 1391 Error(getLoc(), "invalid register"); 1392 return MatchOperand_ParseFail; 1393 } 1394 1395 auto Rz = Operands.back()->getReg(); 1396 Operands.pop_back(); 1397 1398 reglist.push_back(Ry); 1399 reglist.push_back(Rz); 1400 1401 if (getLexer().is(AsmToken::Comma)) 1402 getLexer().Lex(); // eat ',' 1403 else if (getLexer().is(AsmToken::EndOfStatement)) 1404 break; 1405 1406 } else if (getLexer().is(AsmToken::Comma)) { 1407 reglist.push_back(Ry); 1408 reglist.push_back(Ry); 1409 1410 getLexer().Lex(); // eat ',' 1411 } else if (getLexer().is(AsmToken::EndOfStatement)) { 1412 reglist.push_back(Ry); 1413 reglist.push_back(Ry); 1414 break; 1415 } else { 1416 Error(getLoc(), "invalid register list"); 1417 return MatchOperand_ParseFail; 1418 } 1419 } 1420 1421 Operands.push_back(CSKYOperand::createRegList(reglist, S)); 1422 return MatchOperand_Success; 1423 } 1424 1425 bool CSKYAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 1426 SMLoc NameLoc, OperandVector &Operands) { 1427 // First operand is token for instruction. 1428 Operands.push_back(CSKYOperand::createToken(Name, NameLoc)); 1429 1430 // If there are no more operands, then finish. 1431 if (getLexer().is(AsmToken::EndOfStatement)) 1432 return false; 1433 1434 // Parse first operand. 1435 if (parseOperand(Operands, Name)) 1436 return true; 1437 1438 // Parse until end of statement, consuming commas between operands. 1439 while (getLexer().is(AsmToken::Comma)) { 1440 // Consume comma token. 1441 getLexer().Lex(); 1442 1443 // Parse next operand. 1444 if (parseOperand(Operands, Name)) 1445 return true; 1446 } 1447 1448 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1449 SMLoc Loc = getLexer().getLoc(); 1450 getParser().eatToEndOfStatement(); 1451 return Error(Loc, "unexpected token"); 1452 } 1453 1454 getParser().Lex(); // Consume the EndOfStatement. 1455 return false; 1456 } 1457 1458 OperandMatchResultTy CSKYAsmParser::tryParseRegister(unsigned &RegNo, 1459 SMLoc &StartLoc, 1460 SMLoc &EndLoc) { 1461 const AsmToken &Tok = getParser().getTok(); 1462 StartLoc = Tok.getLoc(); 1463 EndLoc = Tok.getEndLoc(); 1464 1465 StringRef Name = getLexer().getTok().getIdentifier(); 1466 1467 if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) 1468 return MatchOperand_NoMatch; 1469 1470 getParser().Lex(); // Eat identifier token. 1471 return MatchOperand_Success; 1472 } 1473 1474 bool CSKYAsmParser::ParseDirective(AsmToken DirectiveID) { return true; } 1475 1476 void CSKYAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) { 1477 MCInst CInst; 1478 bool Res = false; 1479 if (EnableCompressedInst) 1480 Res = compressInst(CInst, Inst, getSTI(), S.getContext()); 1481 if (Res) 1482 ++CSKYNumInstrsCompressed; 1483 S.emitInstruction((Res ? CInst : Inst), getSTI()); 1484 } 1485 1486 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYAsmParser() { 1487 RegisterMCAsmParser<CSKYAsmParser> X(getTheCSKYTarget()); 1488 } 1489