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