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