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