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