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