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