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