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