1 //==- AArch64AsmParser.cpp - Parse AArch64 assembly to MCInst instructions -==// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "MCTargetDesc/AArch64AddressingModes.h" 11 #include "MCTargetDesc/AArch64MCExpr.h" 12 #include "MCTargetDesc/AArch64TargetStreamer.h" 13 #include "Utils/AArch64BaseInfo.h" 14 #include "llvm/ADT/APInt.h" 15 #include "llvm/ADT/STLExtras.h" 16 #include "llvm/ADT/SmallString.h" 17 #include "llvm/ADT/SmallVector.h" 18 #include "llvm/ADT/StringSwitch.h" 19 #include "llvm/ADT/Twine.h" 20 #include "llvm/MC/MCContext.h" 21 #include "llvm/MC/MCExpr.h" 22 #include "llvm/MC/MCInst.h" 23 #include "llvm/MC/MCObjectFileInfo.h" 24 #include "llvm/MC/MCParser/MCAsmLexer.h" 25 #include "llvm/MC/MCParser/MCAsmParser.h" 26 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 27 #include "llvm/MC/MCRegisterInfo.h" 28 #include "llvm/MC/MCStreamer.h" 29 #include "llvm/MC/MCSubtargetInfo.h" 30 #include "llvm/MC/MCSymbol.h" 31 #include "llvm/MC/MCTargetAsmParser.h" 32 #include "llvm/Support/ErrorHandling.h" 33 #include "llvm/Support/SourceMgr.h" 34 #include "llvm/Support/TargetRegistry.h" 35 #include "llvm/Support/raw_ostream.h" 36 #include <cstdio> 37 using namespace llvm; 38 39 namespace { 40 41 class AArch64Operand; 42 43 class AArch64AsmParser : public MCTargetAsmParser { 44 private: 45 StringRef Mnemonic; ///< Instruction mnemonic. 46 47 // Map of register aliases registers via the .req directive. 48 StringMap<std::pair<bool, unsigned> > RegisterReqs; 49 50 AArch64TargetStreamer &getTargetStreamer() { 51 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); 52 return static_cast<AArch64TargetStreamer &>(TS); 53 } 54 55 SMLoc getLoc() const { return getParser().getTok().getLoc(); } 56 57 bool parseSysAlias(StringRef Name, SMLoc NameLoc, OperandVector &Operands); 58 AArch64CC::CondCode parseCondCodeString(StringRef Cond); 59 bool parseCondCode(OperandVector &Operands, bool invertCondCode); 60 unsigned matchRegisterNameAlias(StringRef Name, bool isVector); 61 int tryParseRegister(); 62 int tryMatchVectorRegister(StringRef &Kind, bool expected); 63 bool parseRegister(OperandVector &Operands); 64 bool parseSymbolicImmVal(const MCExpr *&ImmVal); 65 bool parseVectorList(OperandVector &Operands); 66 bool parseOperand(OperandVector &Operands, bool isCondCode, 67 bool invertCondCode); 68 69 void Warning(SMLoc L, const Twine &Msg) { getParser().Warning(L, Msg); } 70 bool Error(SMLoc L, const Twine &Msg) { return getParser().Error(L, Msg); } 71 bool showMatchError(SMLoc Loc, unsigned ErrCode); 72 73 bool parseDirectiveWord(unsigned Size, SMLoc L); 74 bool parseDirectiveInst(SMLoc L); 75 76 bool parseDirectiveTLSDescCall(SMLoc L); 77 78 bool parseDirectiveLOH(StringRef LOH, SMLoc L); 79 bool parseDirectiveLtorg(SMLoc L); 80 81 bool parseDirectiveReq(StringRef Name, SMLoc L); 82 bool parseDirectiveUnreq(SMLoc L); 83 84 bool validateInstruction(MCInst &Inst, SmallVectorImpl<SMLoc> &Loc); 85 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 86 OperandVector &Operands, MCStreamer &Out, 87 uint64_t &ErrorInfo, 88 bool MatchingInlineAsm) override; 89 /// @name Auto-generated Match Functions 90 /// { 91 92 #define GET_ASSEMBLER_HEADER 93 #include "AArch64GenAsmMatcher.inc" 94 95 /// } 96 97 OperandMatchResultTy tryParseOptionalShiftExtend(OperandVector &Operands); 98 OperandMatchResultTy tryParseBarrierOperand(OperandVector &Operands); 99 OperandMatchResultTy tryParseMRSSystemRegister(OperandVector &Operands); 100 OperandMatchResultTy tryParseSysReg(OperandVector &Operands); 101 OperandMatchResultTy tryParseSysCROperand(OperandVector &Operands); 102 OperandMatchResultTy tryParsePrefetch(OperandVector &Operands); 103 OperandMatchResultTy tryParsePSBHint(OperandVector &Operands); 104 OperandMatchResultTy tryParseAdrpLabel(OperandVector &Operands); 105 OperandMatchResultTy tryParseAdrLabel(OperandVector &Operands); 106 OperandMatchResultTy tryParseFPImm(OperandVector &Operands); 107 OperandMatchResultTy tryParseAddSubImm(OperandVector &Operands); 108 OperandMatchResultTy tryParseGPR64sp0Operand(OperandVector &Operands); 109 bool tryParseVectorRegister(OperandVector &Operands); 110 OperandMatchResultTy tryParseGPRSeqPair(OperandVector &Operands); 111 112 public: 113 enum AArch64MatchResultTy { 114 Match_InvalidSuffix = FIRST_TARGET_MATCH_RESULT_TY, 115 #define GET_OPERAND_DIAGNOSTIC_TYPES 116 #include "AArch64GenAsmMatcher.inc" 117 }; 118 AArch64AsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, 119 const MCInstrInfo &MII, const MCTargetOptions &Options) 120 : MCTargetAsmParser(Options, STI) { 121 MCAsmParserExtension::Initialize(Parser); 122 MCStreamer &S = getParser().getStreamer(); 123 if (S.getTargetStreamer() == nullptr) 124 new AArch64TargetStreamer(S); 125 126 // Initialize the set of available features. 127 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits())); 128 } 129 130 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 131 SMLoc NameLoc, OperandVector &Operands) override; 132 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 133 bool ParseDirective(AsmToken DirectiveID) override; 134 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 135 unsigned Kind) override; 136 137 static bool classifySymbolRef(const MCExpr *Expr, 138 AArch64MCExpr::VariantKind &ELFRefKind, 139 MCSymbolRefExpr::VariantKind &DarwinRefKind, 140 int64_t &Addend); 141 }; 142 } // end anonymous namespace 143 144 namespace { 145 146 /// AArch64Operand - Instances of this class represent a parsed AArch64 machine 147 /// instruction. 148 class AArch64Operand : public MCParsedAsmOperand { 149 private: 150 enum KindTy { 151 k_Immediate, 152 k_ShiftedImm, 153 k_CondCode, 154 k_Register, 155 k_VectorList, 156 k_VectorIndex, 157 k_Token, 158 k_SysReg, 159 k_SysCR, 160 k_Prefetch, 161 k_ShiftExtend, 162 k_FPImm, 163 k_Barrier, 164 k_PSBHint, 165 } Kind; 166 167 SMLoc StartLoc, EndLoc; 168 169 struct TokOp { 170 const char *Data; 171 unsigned Length; 172 bool IsSuffix; // Is the operand actually a suffix on the mnemonic. 173 }; 174 175 struct RegOp { 176 unsigned RegNum; 177 bool isVector; 178 }; 179 180 struct VectorListOp { 181 unsigned RegNum; 182 unsigned Count; 183 unsigned NumElements; 184 unsigned ElementKind; 185 }; 186 187 struct VectorIndexOp { 188 unsigned Val; 189 }; 190 191 struct ImmOp { 192 const MCExpr *Val; 193 }; 194 195 struct ShiftedImmOp { 196 const MCExpr *Val; 197 unsigned ShiftAmount; 198 }; 199 200 struct CondCodeOp { 201 AArch64CC::CondCode Code; 202 }; 203 204 struct FPImmOp { 205 unsigned Val; // Encoded 8-bit representation. 206 }; 207 208 struct BarrierOp { 209 unsigned Val; // Not the enum since not all values have names. 210 const char *Data; 211 unsigned Length; 212 }; 213 214 struct SysRegOp { 215 const char *Data; 216 unsigned Length; 217 uint32_t MRSReg; 218 uint32_t MSRReg; 219 uint32_t PStateField; 220 }; 221 222 struct SysCRImmOp { 223 unsigned Val; 224 }; 225 226 struct PrefetchOp { 227 unsigned Val; 228 const char *Data; 229 unsigned Length; 230 }; 231 232 struct PSBHintOp { 233 unsigned Val; 234 const char *Data; 235 unsigned Length; 236 }; 237 238 struct ShiftExtendOp { 239 AArch64_AM::ShiftExtendType Type; 240 unsigned Amount; 241 bool HasExplicitAmount; 242 }; 243 244 struct ExtendOp { 245 unsigned Val; 246 }; 247 248 union { 249 struct TokOp Tok; 250 struct RegOp Reg; 251 struct VectorListOp VectorList; 252 struct VectorIndexOp VectorIndex; 253 struct ImmOp Imm; 254 struct ShiftedImmOp ShiftedImm; 255 struct CondCodeOp CondCode; 256 struct FPImmOp FPImm; 257 struct BarrierOp Barrier; 258 struct SysRegOp SysReg; 259 struct SysCRImmOp SysCRImm; 260 struct PrefetchOp Prefetch; 261 struct PSBHintOp PSBHint; 262 struct ShiftExtendOp ShiftExtend; 263 }; 264 265 // Keep the MCContext around as the MCExprs may need manipulated during 266 // the add<>Operands() calls. 267 MCContext &Ctx; 268 269 public: 270 AArch64Operand(KindTy K, MCContext &Ctx) : Kind(K), Ctx(Ctx) {} 271 272 AArch64Operand(const AArch64Operand &o) : MCParsedAsmOperand(), Ctx(o.Ctx) { 273 Kind = o.Kind; 274 StartLoc = o.StartLoc; 275 EndLoc = o.EndLoc; 276 switch (Kind) { 277 case k_Token: 278 Tok = o.Tok; 279 break; 280 case k_Immediate: 281 Imm = o.Imm; 282 break; 283 case k_ShiftedImm: 284 ShiftedImm = o.ShiftedImm; 285 break; 286 case k_CondCode: 287 CondCode = o.CondCode; 288 break; 289 case k_FPImm: 290 FPImm = o.FPImm; 291 break; 292 case k_Barrier: 293 Barrier = o.Barrier; 294 break; 295 case k_Register: 296 Reg = o.Reg; 297 break; 298 case k_VectorList: 299 VectorList = o.VectorList; 300 break; 301 case k_VectorIndex: 302 VectorIndex = o.VectorIndex; 303 break; 304 case k_SysReg: 305 SysReg = o.SysReg; 306 break; 307 case k_SysCR: 308 SysCRImm = o.SysCRImm; 309 break; 310 case k_Prefetch: 311 Prefetch = o.Prefetch; 312 break; 313 case k_PSBHint: 314 PSBHint = o.PSBHint; 315 break; 316 case k_ShiftExtend: 317 ShiftExtend = o.ShiftExtend; 318 break; 319 } 320 } 321 322 /// getStartLoc - Get the location of the first token of this operand. 323 SMLoc getStartLoc() const override { return StartLoc; } 324 /// getEndLoc - Get the location of the last token of this operand. 325 SMLoc getEndLoc() const override { return EndLoc; } 326 327 StringRef getToken() const { 328 assert(Kind == k_Token && "Invalid access!"); 329 return StringRef(Tok.Data, Tok.Length); 330 } 331 332 bool isTokenSuffix() const { 333 assert(Kind == k_Token && "Invalid access!"); 334 return Tok.IsSuffix; 335 } 336 337 const MCExpr *getImm() const { 338 assert(Kind == k_Immediate && "Invalid access!"); 339 return Imm.Val; 340 } 341 342 const MCExpr *getShiftedImmVal() const { 343 assert(Kind == k_ShiftedImm && "Invalid access!"); 344 return ShiftedImm.Val; 345 } 346 347 unsigned getShiftedImmShift() const { 348 assert(Kind == k_ShiftedImm && "Invalid access!"); 349 return ShiftedImm.ShiftAmount; 350 } 351 352 AArch64CC::CondCode getCondCode() const { 353 assert(Kind == k_CondCode && "Invalid access!"); 354 return CondCode.Code; 355 } 356 357 unsigned getFPImm() const { 358 assert(Kind == k_FPImm && "Invalid access!"); 359 return FPImm.Val; 360 } 361 362 unsigned getBarrier() const { 363 assert(Kind == k_Barrier && "Invalid access!"); 364 return Barrier.Val; 365 } 366 367 StringRef getBarrierName() const { 368 assert(Kind == k_Barrier && "Invalid access!"); 369 return StringRef(Barrier.Data, Barrier.Length); 370 } 371 372 unsigned getReg() const override { 373 assert(Kind == k_Register && "Invalid access!"); 374 return Reg.RegNum; 375 } 376 377 unsigned getVectorListStart() const { 378 assert(Kind == k_VectorList && "Invalid access!"); 379 return VectorList.RegNum; 380 } 381 382 unsigned getVectorListCount() const { 383 assert(Kind == k_VectorList && "Invalid access!"); 384 return VectorList.Count; 385 } 386 387 unsigned getVectorIndex() const { 388 assert(Kind == k_VectorIndex && "Invalid access!"); 389 return VectorIndex.Val; 390 } 391 392 StringRef getSysReg() const { 393 assert(Kind == k_SysReg && "Invalid access!"); 394 return StringRef(SysReg.Data, SysReg.Length); 395 } 396 397 unsigned getSysCR() const { 398 assert(Kind == k_SysCR && "Invalid access!"); 399 return SysCRImm.Val; 400 } 401 402 unsigned getPrefetch() const { 403 assert(Kind == k_Prefetch && "Invalid access!"); 404 return Prefetch.Val; 405 } 406 407 unsigned getPSBHint() const { 408 assert(Kind == k_PSBHint && "Invalid access!"); 409 return PSBHint.Val; 410 } 411 412 StringRef getPSBHintName() const { 413 assert(Kind == k_PSBHint && "Invalid access!"); 414 return StringRef(PSBHint.Data, PSBHint.Length); 415 } 416 417 StringRef getPrefetchName() const { 418 assert(Kind == k_Prefetch && "Invalid access!"); 419 return StringRef(Prefetch.Data, Prefetch.Length); 420 } 421 422 AArch64_AM::ShiftExtendType getShiftExtendType() const { 423 assert(Kind == k_ShiftExtend && "Invalid access!"); 424 return ShiftExtend.Type; 425 } 426 427 unsigned getShiftExtendAmount() const { 428 assert(Kind == k_ShiftExtend && "Invalid access!"); 429 return ShiftExtend.Amount; 430 } 431 432 bool hasShiftExtendAmount() const { 433 assert(Kind == k_ShiftExtend && "Invalid access!"); 434 return ShiftExtend.HasExplicitAmount; 435 } 436 437 bool isImm() const override { return Kind == k_Immediate; } 438 bool isMem() const override { return false; } 439 bool isSImm9() const { 440 if (!isImm()) 441 return false; 442 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 443 if (!MCE) 444 return false; 445 int64_t Val = MCE->getValue(); 446 return (Val >= -256 && Val < 256); 447 } 448 bool isSImm7s4() const { 449 if (!isImm()) 450 return false; 451 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 452 if (!MCE) 453 return false; 454 int64_t Val = MCE->getValue(); 455 return (Val >= -256 && Val <= 252 && (Val & 3) == 0); 456 } 457 bool isSImm7s8() const { 458 if (!isImm()) 459 return false; 460 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 461 if (!MCE) 462 return false; 463 int64_t Val = MCE->getValue(); 464 return (Val >= -512 && Val <= 504 && (Val & 7) == 0); 465 } 466 bool isSImm7s16() const { 467 if (!isImm()) 468 return false; 469 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 470 if (!MCE) 471 return false; 472 int64_t Val = MCE->getValue(); 473 return (Val >= -1024 && Val <= 1008 && (Val & 15) == 0); 474 } 475 476 bool isSymbolicUImm12Offset(const MCExpr *Expr, unsigned Scale) const { 477 AArch64MCExpr::VariantKind ELFRefKind; 478 MCSymbolRefExpr::VariantKind DarwinRefKind; 479 int64_t Addend; 480 if (!AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, 481 Addend)) { 482 // If we don't understand the expression, assume the best and 483 // let the fixup and relocation code deal with it. 484 return true; 485 } 486 487 if (DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF || 488 ELFRefKind == AArch64MCExpr::VK_LO12 || 489 ELFRefKind == AArch64MCExpr::VK_GOT_LO12 || 490 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 || 491 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC || 492 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 || 493 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC || 494 ELFRefKind == AArch64MCExpr::VK_GOTTPREL_LO12_NC || 495 ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12) { 496 // Note that we don't range-check the addend. It's adjusted modulo page 497 // size when converted, so there is no "out of range" condition when using 498 // @pageoff. 499 return Addend >= 0 && (Addend % Scale) == 0; 500 } else if (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF || 501 DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) { 502 // @gotpageoff/@tlvppageoff can only be used directly, not with an addend. 503 return Addend == 0; 504 } 505 506 return false; 507 } 508 509 template <int Scale> bool isUImm12Offset() const { 510 if (!isImm()) 511 return false; 512 513 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 514 if (!MCE) 515 return isSymbolicUImm12Offset(getImm(), Scale); 516 517 int64_t Val = MCE->getValue(); 518 return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000; 519 } 520 521 bool isImm0_1() const { 522 if (!isImm()) 523 return false; 524 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 525 if (!MCE) 526 return false; 527 int64_t Val = MCE->getValue(); 528 return (Val >= 0 && Val < 2); 529 } 530 bool isImm0_7() const { 531 if (!isImm()) 532 return false; 533 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 534 if (!MCE) 535 return false; 536 int64_t Val = MCE->getValue(); 537 return (Val >= 0 && Val < 8); 538 } 539 bool isImm1_8() const { 540 if (!isImm()) 541 return false; 542 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 543 if (!MCE) 544 return false; 545 int64_t Val = MCE->getValue(); 546 return (Val > 0 && Val < 9); 547 } 548 bool isImm0_15() const { 549 if (!isImm()) 550 return false; 551 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 552 if (!MCE) 553 return false; 554 int64_t Val = MCE->getValue(); 555 return (Val >= 0 && Val < 16); 556 } 557 bool isImm1_16() const { 558 if (!isImm()) 559 return false; 560 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 561 if (!MCE) 562 return false; 563 int64_t Val = MCE->getValue(); 564 return (Val > 0 && Val < 17); 565 } 566 bool isImm0_31() const { 567 if (!isImm()) 568 return false; 569 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 570 if (!MCE) 571 return false; 572 int64_t Val = MCE->getValue(); 573 return (Val >= 0 && Val < 32); 574 } 575 bool isImm1_31() const { 576 if (!isImm()) 577 return false; 578 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 579 if (!MCE) 580 return false; 581 int64_t Val = MCE->getValue(); 582 return (Val >= 1 && Val < 32); 583 } 584 bool isImm1_32() const { 585 if (!isImm()) 586 return false; 587 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 588 if (!MCE) 589 return false; 590 int64_t Val = MCE->getValue(); 591 return (Val >= 1 && Val < 33); 592 } 593 bool isImm0_63() const { 594 if (!isImm()) 595 return false; 596 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 597 if (!MCE) 598 return false; 599 int64_t Val = MCE->getValue(); 600 return (Val >= 0 && Val < 64); 601 } 602 bool isImm1_63() const { 603 if (!isImm()) 604 return false; 605 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 606 if (!MCE) 607 return false; 608 int64_t Val = MCE->getValue(); 609 return (Val >= 1 && Val < 64); 610 } 611 bool isImm1_64() const { 612 if (!isImm()) 613 return false; 614 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 615 if (!MCE) 616 return false; 617 int64_t Val = MCE->getValue(); 618 return (Val >= 1 && Val < 65); 619 } 620 bool isImm0_127() const { 621 if (!isImm()) 622 return false; 623 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 624 if (!MCE) 625 return false; 626 int64_t Val = MCE->getValue(); 627 return (Val >= 0 && Val < 128); 628 } 629 bool isImm0_255() const { 630 if (!isImm()) 631 return false; 632 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 633 if (!MCE) 634 return false; 635 int64_t Val = MCE->getValue(); 636 return (Val >= 0 && Val < 256); 637 } 638 bool isImm0_65535() const { 639 if (!isImm()) 640 return false; 641 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 642 if (!MCE) 643 return false; 644 int64_t Val = MCE->getValue(); 645 return (Val >= 0 && Val < 65536); 646 } 647 bool isImm32_63() const { 648 if (!isImm()) 649 return false; 650 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 651 if (!MCE) 652 return false; 653 int64_t Val = MCE->getValue(); 654 return (Val >= 32 && Val < 64); 655 } 656 bool isLogicalImm32() const { 657 if (!isImm()) 658 return false; 659 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 660 if (!MCE) 661 return false; 662 int64_t Val = MCE->getValue(); 663 if (Val >> 32 != 0 && Val >> 32 != ~0LL) 664 return false; 665 Val &= 0xFFFFFFFF; 666 return AArch64_AM::isLogicalImmediate(Val, 32); 667 } 668 bool isLogicalImm64() const { 669 if (!isImm()) 670 return false; 671 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 672 if (!MCE) 673 return false; 674 return AArch64_AM::isLogicalImmediate(MCE->getValue(), 64); 675 } 676 bool isLogicalImm32Not() const { 677 if (!isImm()) 678 return false; 679 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 680 if (!MCE) 681 return false; 682 int64_t Val = ~MCE->getValue() & 0xFFFFFFFF; 683 return AArch64_AM::isLogicalImmediate(Val, 32); 684 } 685 bool isLogicalImm64Not() const { 686 if (!isImm()) 687 return false; 688 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 689 if (!MCE) 690 return false; 691 return AArch64_AM::isLogicalImmediate(~MCE->getValue(), 64); 692 } 693 bool isShiftedImm() const { return Kind == k_ShiftedImm; } 694 bool isAddSubImm() const { 695 if (!isShiftedImm() && !isImm()) 696 return false; 697 698 const MCExpr *Expr; 699 700 // An ADD/SUB shifter is either 'lsl #0' or 'lsl #12'. 701 if (isShiftedImm()) { 702 unsigned Shift = ShiftedImm.ShiftAmount; 703 Expr = ShiftedImm.Val; 704 if (Shift != 0 && Shift != 12) 705 return false; 706 } else { 707 Expr = getImm(); 708 } 709 710 AArch64MCExpr::VariantKind ELFRefKind; 711 MCSymbolRefExpr::VariantKind DarwinRefKind; 712 int64_t Addend; 713 if (AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind, 714 DarwinRefKind, Addend)) { 715 return DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF 716 || DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF 717 || (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF && Addend == 0) 718 || ELFRefKind == AArch64MCExpr::VK_LO12 719 || ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 720 || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 721 || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC 722 || ELFRefKind == AArch64MCExpr::VK_TPREL_HI12 723 || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 724 || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC 725 || ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12; 726 } 727 728 // Otherwise it should be a real immediate in range: 729 const MCConstantExpr *CE = cast<MCConstantExpr>(Expr); 730 return CE->getValue() >= 0 && CE->getValue() <= 0xfff; 731 } 732 bool isAddSubImmNeg() const { 733 if (!isShiftedImm() && !isImm()) 734 return false; 735 736 const MCExpr *Expr; 737 738 // An ADD/SUB shifter is either 'lsl #0' or 'lsl #12'. 739 if (isShiftedImm()) { 740 unsigned Shift = ShiftedImm.ShiftAmount; 741 Expr = ShiftedImm.Val; 742 if (Shift != 0 && Shift != 12) 743 return false; 744 } else 745 Expr = getImm(); 746 747 // Otherwise it should be a real negative immediate in range: 748 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 749 return CE != nullptr && CE->getValue() < 0 && -CE->getValue() <= 0xfff; 750 } 751 bool isCondCode() const { return Kind == k_CondCode; } 752 bool isSIMDImmType10() const { 753 if (!isImm()) 754 return false; 755 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 756 if (!MCE) 757 return false; 758 return AArch64_AM::isAdvSIMDModImmType10(MCE->getValue()); 759 } 760 bool isBranchTarget26() const { 761 if (!isImm()) 762 return false; 763 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 764 if (!MCE) 765 return true; 766 int64_t Val = MCE->getValue(); 767 if (Val & 0x3) 768 return false; 769 return (Val >= -(0x2000000 << 2) && Val <= (0x1ffffff << 2)); 770 } 771 bool isPCRelLabel19() const { 772 if (!isImm()) 773 return false; 774 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 775 if (!MCE) 776 return true; 777 int64_t Val = MCE->getValue(); 778 if (Val & 0x3) 779 return false; 780 return (Val >= -(0x40000 << 2) && Val <= (0x3ffff << 2)); 781 } 782 bool isBranchTarget14() const { 783 if (!isImm()) 784 return false; 785 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 786 if (!MCE) 787 return true; 788 int64_t Val = MCE->getValue(); 789 if (Val & 0x3) 790 return false; 791 return (Val >= -(0x2000 << 2) && Val <= (0x1fff << 2)); 792 } 793 794 bool 795 isMovWSymbol(ArrayRef<AArch64MCExpr::VariantKind> AllowedModifiers) const { 796 if (!isImm()) 797 return false; 798 799 AArch64MCExpr::VariantKind ELFRefKind; 800 MCSymbolRefExpr::VariantKind DarwinRefKind; 801 int64_t Addend; 802 if (!AArch64AsmParser::classifySymbolRef(getImm(), ELFRefKind, 803 DarwinRefKind, Addend)) { 804 return false; 805 } 806 if (DarwinRefKind != MCSymbolRefExpr::VK_None) 807 return false; 808 809 for (unsigned i = 0; i != AllowedModifiers.size(); ++i) { 810 if (ELFRefKind == AllowedModifiers[i]) 811 return Addend == 0; 812 } 813 814 return false; 815 } 816 817 bool isMovZSymbolG3() const { 818 return isMovWSymbol(AArch64MCExpr::VK_ABS_G3); 819 } 820 821 bool isMovZSymbolG2() const { 822 return isMovWSymbol({AArch64MCExpr::VK_ABS_G2, AArch64MCExpr::VK_ABS_G2_S, 823 AArch64MCExpr::VK_TPREL_G2, 824 AArch64MCExpr::VK_DTPREL_G2}); 825 } 826 827 bool isMovZSymbolG1() const { 828 return isMovWSymbol({ 829 AArch64MCExpr::VK_ABS_G1, AArch64MCExpr::VK_ABS_G1_S, 830 AArch64MCExpr::VK_GOTTPREL_G1, AArch64MCExpr::VK_TPREL_G1, 831 AArch64MCExpr::VK_DTPREL_G1, 832 }); 833 } 834 835 bool isMovZSymbolG0() const { 836 return isMovWSymbol({AArch64MCExpr::VK_ABS_G0, AArch64MCExpr::VK_ABS_G0_S, 837 AArch64MCExpr::VK_TPREL_G0, 838 AArch64MCExpr::VK_DTPREL_G0}); 839 } 840 841 bool isMovKSymbolG3() const { 842 return isMovWSymbol(AArch64MCExpr::VK_ABS_G3); 843 } 844 845 bool isMovKSymbolG2() const { 846 return isMovWSymbol(AArch64MCExpr::VK_ABS_G2_NC); 847 } 848 849 bool isMovKSymbolG1() const { 850 return isMovWSymbol({AArch64MCExpr::VK_ABS_G1_NC, 851 AArch64MCExpr::VK_TPREL_G1_NC, 852 AArch64MCExpr::VK_DTPREL_G1_NC}); 853 } 854 855 bool isMovKSymbolG0() const { 856 return isMovWSymbol( 857 {AArch64MCExpr::VK_ABS_G0_NC, AArch64MCExpr::VK_GOTTPREL_G0_NC, 858 AArch64MCExpr::VK_TPREL_G0_NC, AArch64MCExpr::VK_DTPREL_G0_NC}); 859 } 860 861 template<int RegWidth, int Shift> 862 bool isMOVZMovAlias() const { 863 if (!isImm()) return false; 864 865 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 866 if (!CE) return false; 867 uint64_t Value = CE->getValue(); 868 869 if (RegWidth == 32) 870 Value &= 0xffffffffULL; 871 872 // "lsl #0" takes precedence: in practice this only affects "#0, lsl #0". 873 if (Value == 0 && Shift != 0) 874 return false; 875 876 return (Value & ~(0xffffULL << Shift)) == 0; 877 } 878 879 template<int RegWidth, int Shift> 880 bool isMOVNMovAlias() const { 881 if (!isImm()) return false; 882 883 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 884 if (!CE) return false; 885 uint64_t Value = CE->getValue(); 886 887 // MOVZ takes precedence over MOVN. 888 for (int MOVZShift = 0; MOVZShift <= 48; MOVZShift += 16) 889 if ((Value & ~(0xffffULL << MOVZShift)) == 0) 890 return false; 891 892 Value = ~Value; 893 if (RegWidth == 32) 894 Value &= 0xffffffffULL; 895 896 return (Value & ~(0xffffULL << Shift)) == 0; 897 } 898 899 bool isFPImm() const { return Kind == k_FPImm; } 900 bool isBarrier() const { return Kind == k_Barrier; } 901 bool isSysReg() const { return Kind == k_SysReg; } 902 bool isMRSSystemRegister() const { 903 if (!isSysReg()) return false; 904 905 return SysReg.MRSReg != -1U; 906 } 907 bool isMSRSystemRegister() const { 908 if (!isSysReg()) return false; 909 return SysReg.MSRReg != -1U; 910 } 911 bool isSystemPStateFieldWithImm0_1() const { 912 if (!isSysReg()) return false; 913 return (SysReg.PStateField == AArch64PState::PAN || 914 SysReg.PStateField == AArch64PState::UAO); 915 } 916 bool isSystemPStateFieldWithImm0_15() const { 917 if (!isSysReg() || isSystemPStateFieldWithImm0_1()) return false; 918 return SysReg.PStateField != -1U; 919 } 920 bool isReg() const override { return Kind == k_Register && !Reg.isVector; } 921 bool isVectorReg() const { return Kind == k_Register && Reg.isVector; } 922 bool isVectorRegLo() const { 923 return Kind == k_Register && Reg.isVector && 924 AArch64MCRegisterClasses[AArch64::FPR128_loRegClassID].contains( 925 Reg.RegNum); 926 } 927 bool isGPR32as64() const { 928 return Kind == k_Register && !Reg.isVector && 929 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(Reg.RegNum); 930 } 931 bool isWSeqPair() const { 932 return Kind == k_Register && !Reg.isVector && 933 AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID].contains( 934 Reg.RegNum); 935 } 936 bool isXSeqPair() const { 937 return Kind == k_Register && !Reg.isVector && 938 AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID].contains( 939 Reg.RegNum); 940 } 941 942 bool isGPR64sp0() const { 943 return Kind == k_Register && !Reg.isVector && 944 AArch64MCRegisterClasses[AArch64::GPR64spRegClassID].contains(Reg.RegNum); 945 } 946 947 /// Is this a vector list with the type implicit (presumably attached to the 948 /// instruction itself)? 949 template <unsigned NumRegs> bool isImplicitlyTypedVectorList() const { 950 return Kind == k_VectorList && VectorList.Count == NumRegs && 951 !VectorList.ElementKind; 952 } 953 954 template <unsigned NumRegs, unsigned NumElements, char ElementKind> 955 bool isTypedVectorList() const { 956 if (Kind != k_VectorList) 957 return false; 958 if (VectorList.Count != NumRegs) 959 return false; 960 if (VectorList.ElementKind != ElementKind) 961 return false; 962 return VectorList.NumElements == NumElements; 963 } 964 965 bool isVectorIndex1() const { 966 return Kind == k_VectorIndex && VectorIndex.Val == 1; 967 } 968 bool isVectorIndexB() const { 969 return Kind == k_VectorIndex && VectorIndex.Val < 16; 970 } 971 bool isVectorIndexH() const { 972 return Kind == k_VectorIndex && VectorIndex.Val < 8; 973 } 974 bool isVectorIndexS() const { 975 return Kind == k_VectorIndex && VectorIndex.Val < 4; 976 } 977 bool isVectorIndexD() const { 978 return Kind == k_VectorIndex && VectorIndex.Val < 2; 979 } 980 bool isToken() const override { return Kind == k_Token; } 981 bool isTokenEqual(StringRef Str) const { 982 return Kind == k_Token && getToken() == Str; 983 } 984 bool isSysCR() const { return Kind == k_SysCR; } 985 bool isPrefetch() const { return Kind == k_Prefetch; } 986 bool isPSBHint() const { return Kind == k_PSBHint; } 987 bool isShiftExtend() const { return Kind == k_ShiftExtend; } 988 bool isShifter() const { 989 if (!isShiftExtend()) 990 return false; 991 992 AArch64_AM::ShiftExtendType ST = getShiftExtendType(); 993 return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR || 994 ST == AArch64_AM::ASR || ST == AArch64_AM::ROR || 995 ST == AArch64_AM::MSL); 996 } 997 bool isExtend() const { 998 if (!isShiftExtend()) 999 return false; 1000 1001 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 1002 return (ET == AArch64_AM::UXTB || ET == AArch64_AM::SXTB || 1003 ET == AArch64_AM::UXTH || ET == AArch64_AM::SXTH || 1004 ET == AArch64_AM::UXTW || ET == AArch64_AM::SXTW || 1005 ET == AArch64_AM::UXTX || ET == AArch64_AM::SXTX || 1006 ET == AArch64_AM::LSL) && 1007 getShiftExtendAmount() <= 4; 1008 } 1009 1010 bool isExtend64() const { 1011 if (!isExtend()) 1012 return false; 1013 // UXTX and SXTX require a 64-bit source register (the ExtendLSL64 class). 1014 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 1015 return ET != AArch64_AM::UXTX && ET != AArch64_AM::SXTX; 1016 } 1017 bool isExtendLSL64() const { 1018 if (!isExtend()) 1019 return false; 1020 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 1021 return (ET == AArch64_AM::UXTX || ET == AArch64_AM::SXTX || 1022 ET == AArch64_AM::LSL) && 1023 getShiftExtendAmount() <= 4; 1024 } 1025 1026 template<int Width> bool isMemXExtend() const { 1027 if (!isExtend()) 1028 return false; 1029 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 1030 return (ET == AArch64_AM::LSL || ET == AArch64_AM::SXTX) && 1031 (getShiftExtendAmount() == Log2_32(Width / 8) || 1032 getShiftExtendAmount() == 0); 1033 } 1034 1035 template<int Width> bool isMemWExtend() const { 1036 if (!isExtend()) 1037 return false; 1038 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 1039 return (ET == AArch64_AM::UXTW || ET == AArch64_AM::SXTW) && 1040 (getShiftExtendAmount() == Log2_32(Width / 8) || 1041 getShiftExtendAmount() == 0); 1042 } 1043 1044 template <unsigned width> 1045 bool isArithmeticShifter() const { 1046 if (!isShifter()) 1047 return false; 1048 1049 // An arithmetic shifter is LSL, LSR, or ASR. 1050 AArch64_AM::ShiftExtendType ST = getShiftExtendType(); 1051 return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR || 1052 ST == AArch64_AM::ASR) && getShiftExtendAmount() < width; 1053 } 1054 1055 template <unsigned width> 1056 bool isLogicalShifter() const { 1057 if (!isShifter()) 1058 return false; 1059 1060 // A logical shifter is LSL, LSR, ASR or ROR. 1061 AArch64_AM::ShiftExtendType ST = getShiftExtendType(); 1062 return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR || 1063 ST == AArch64_AM::ASR || ST == AArch64_AM::ROR) && 1064 getShiftExtendAmount() < width; 1065 } 1066 1067 bool isMovImm32Shifter() const { 1068 if (!isShifter()) 1069 return false; 1070 1071 // A MOVi shifter is LSL of 0, 16, 32, or 48. 1072 AArch64_AM::ShiftExtendType ST = getShiftExtendType(); 1073 if (ST != AArch64_AM::LSL) 1074 return false; 1075 uint64_t Val = getShiftExtendAmount(); 1076 return (Val == 0 || Val == 16); 1077 } 1078 1079 bool isMovImm64Shifter() const { 1080 if (!isShifter()) 1081 return false; 1082 1083 // A MOVi shifter is LSL of 0 or 16. 1084 AArch64_AM::ShiftExtendType ST = getShiftExtendType(); 1085 if (ST != AArch64_AM::LSL) 1086 return false; 1087 uint64_t Val = getShiftExtendAmount(); 1088 return (Val == 0 || Val == 16 || Val == 32 || Val == 48); 1089 } 1090 1091 bool isLogicalVecShifter() const { 1092 if (!isShifter()) 1093 return false; 1094 1095 // A logical vector shifter is a left shift by 0, 8, 16, or 24. 1096 unsigned Shift = getShiftExtendAmount(); 1097 return getShiftExtendType() == AArch64_AM::LSL && 1098 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24); 1099 } 1100 1101 bool isLogicalVecHalfWordShifter() const { 1102 if (!isLogicalVecShifter()) 1103 return false; 1104 1105 // A logical vector shifter is a left shift by 0 or 8. 1106 unsigned Shift = getShiftExtendAmount(); 1107 return getShiftExtendType() == AArch64_AM::LSL && 1108 (Shift == 0 || Shift == 8); 1109 } 1110 1111 bool isMoveVecShifter() const { 1112 if (!isShiftExtend()) 1113 return false; 1114 1115 // A logical vector shifter is a left shift by 8 or 16. 1116 unsigned Shift = getShiftExtendAmount(); 1117 return getShiftExtendType() == AArch64_AM::MSL && 1118 (Shift == 8 || Shift == 16); 1119 } 1120 1121 // Fallback unscaled operands are for aliases of LDR/STR that fall back 1122 // to LDUR/STUR when the offset is not legal for the former but is for 1123 // the latter. As such, in addition to checking for being a legal unscaled 1124 // address, also check that it is not a legal scaled address. This avoids 1125 // ambiguity in the matcher. 1126 template<int Width> 1127 bool isSImm9OffsetFB() const { 1128 return isSImm9() && !isUImm12Offset<Width / 8>(); 1129 } 1130 1131 bool isAdrpLabel() const { 1132 // Validation was handled during parsing, so we just sanity check that 1133 // something didn't go haywire. 1134 if (!isImm()) 1135 return false; 1136 1137 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) { 1138 int64_t Val = CE->getValue(); 1139 int64_t Min = - (4096 * (1LL << (21 - 1))); 1140 int64_t Max = 4096 * ((1LL << (21 - 1)) - 1); 1141 return (Val % 4096) == 0 && Val >= Min && Val <= Max; 1142 } 1143 1144 return true; 1145 } 1146 1147 bool isAdrLabel() const { 1148 // Validation was handled during parsing, so we just sanity check that 1149 // something didn't go haywire. 1150 if (!isImm()) 1151 return false; 1152 1153 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) { 1154 int64_t Val = CE->getValue(); 1155 int64_t Min = - (1LL << (21 - 1)); 1156 int64_t Max = ((1LL << (21 - 1)) - 1); 1157 return Val >= Min && Val <= Max; 1158 } 1159 1160 return true; 1161 } 1162 1163 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 1164 // Add as immediates when possible. Null MCExpr = 0. 1165 if (!Expr) 1166 Inst.addOperand(MCOperand::createImm(0)); 1167 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 1168 Inst.addOperand(MCOperand::createImm(CE->getValue())); 1169 else 1170 Inst.addOperand(MCOperand::createExpr(Expr)); 1171 } 1172 1173 void addRegOperands(MCInst &Inst, unsigned N) const { 1174 assert(N == 1 && "Invalid number of operands!"); 1175 Inst.addOperand(MCOperand::createReg(getReg())); 1176 } 1177 1178 void addGPR32as64Operands(MCInst &Inst, unsigned N) const { 1179 assert(N == 1 && "Invalid number of operands!"); 1180 assert( 1181 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(getReg())); 1182 1183 const MCRegisterInfo *RI = Ctx.getRegisterInfo(); 1184 uint32_t Reg = RI->getRegClass(AArch64::GPR32RegClassID).getRegister( 1185 RI->getEncodingValue(getReg())); 1186 1187 Inst.addOperand(MCOperand::createReg(Reg)); 1188 } 1189 1190 void addVectorReg64Operands(MCInst &Inst, unsigned N) const { 1191 assert(N == 1 && "Invalid number of operands!"); 1192 assert( 1193 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains(getReg())); 1194 Inst.addOperand(MCOperand::createReg(AArch64::D0 + getReg() - AArch64::Q0)); 1195 } 1196 1197 void addVectorReg128Operands(MCInst &Inst, unsigned N) const { 1198 assert(N == 1 && "Invalid number of operands!"); 1199 assert( 1200 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains(getReg())); 1201 Inst.addOperand(MCOperand::createReg(getReg())); 1202 } 1203 1204 void addVectorRegLoOperands(MCInst &Inst, unsigned N) const { 1205 assert(N == 1 && "Invalid number of operands!"); 1206 Inst.addOperand(MCOperand::createReg(getReg())); 1207 } 1208 1209 template <unsigned NumRegs> 1210 void addVectorList64Operands(MCInst &Inst, unsigned N) const { 1211 assert(N == 1 && "Invalid number of operands!"); 1212 static const unsigned FirstRegs[] = { AArch64::D0, 1213 AArch64::D0_D1, 1214 AArch64::D0_D1_D2, 1215 AArch64::D0_D1_D2_D3 }; 1216 unsigned FirstReg = FirstRegs[NumRegs - 1]; 1217 1218 Inst.addOperand( 1219 MCOperand::createReg(FirstReg + getVectorListStart() - AArch64::Q0)); 1220 } 1221 1222 template <unsigned NumRegs> 1223 void addVectorList128Operands(MCInst &Inst, unsigned N) const { 1224 assert(N == 1 && "Invalid number of operands!"); 1225 static const unsigned FirstRegs[] = { AArch64::Q0, 1226 AArch64::Q0_Q1, 1227 AArch64::Q0_Q1_Q2, 1228 AArch64::Q0_Q1_Q2_Q3 }; 1229 unsigned FirstReg = FirstRegs[NumRegs - 1]; 1230 1231 Inst.addOperand( 1232 MCOperand::createReg(FirstReg + getVectorListStart() - AArch64::Q0)); 1233 } 1234 1235 void addVectorIndex1Operands(MCInst &Inst, unsigned N) const { 1236 assert(N == 1 && "Invalid number of operands!"); 1237 Inst.addOperand(MCOperand::createImm(getVectorIndex())); 1238 } 1239 1240 void addVectorIndexBOperands(MCInst &Inst, unsigned N) const { 1241 assert(N == 1 && "Invalid number of operands!"); 1242 Inst.addOperand(MCOperand::createImm(getVectorIndex())); 1243 } 1244 1245 void addVectorIndexHOperands(MCInst &Inst, unsigned N) const { 1246 assert(N == 1 && "Invalid number of operands!"); 1247 Inst.addOperand(MCOperand::createImm(getVectorIndex())); 1248 } 1249 1250 void addVectorIndexSOperands(MCInst &Inst, unsigned N) const { 1251 assert(N == 1 && "Invalid number of operands!"); 1252 Inst.addOperand(MCOperand::createImm(getVectorIndex())); 1253 } 1254 1255 void addVectorIndexDOperands(MCInst &Inst, unsigned N) const { 1256 assert(N == 1 && "Invalid number of operands!"); 1257 Inst.addOperand(MCOperand::createImm(getVectorIndex())); 1258 } 1259 1260 void addImmOperands(MCInst &Inst, unsigned N) const { 1261 assert(N == 1 && "Invalid number of operands!"); 1262 // If this is a pageoff symrefexpr with an addend, adjust the addend 1263 // to be only the page-offset portion. Otherwise, just add the expr 1264 // as-is. 1265 addExpr(Inst, getImm()); 1266 } 1267 1268 void addAddSubImmOperands(MCInst &Inst, unsigned N) const { 1269 assert(N == 2 && "Invalid number of operands!"); 1270 if (isShiftedImm()) { 1271 addExpr(Inst, getShiftedImmVal()); 1272 Inst.addOperand(MCOperand::createImm(getShiftedImmShift())); 1273 } else { 1274 addExpr(Inst, getImm()); 1275 Inst.addOperand(MCOperand::createImm(0)); 1276 } 1277 } 1278 1279 void addAddSubImmNegOperands(MCInst &Inst, unsigned N) const { 1280 assert(N == 2 && "Invalid number of operands!"); 1281 1282 const MCExpr *MCE = isShiftedImm() ? getShiftedImmVal() : getImm(); 1283 const MCConstantExpr *CE = cast<MCConstantExpr>(MCE); 1284 int64_t Val = -CE->getValue(); 1285 unsigned ShiftAmt = isShiftedImm() ? ShiftedImm.ShiftAmount : 0; 1286 1287 Inst.addOperand(MCOperand::createImm(Val)); 1288 Inst.addOperand(MCOperand::createImm(ShiftAmt)); 1289 } 1290 1291 void addCondCodeOperands(MCInst &Inst, unsigned N) const { 1292 assert(N == 1 && "Invalid number of operands!"); 1293 Inst.addOperand(MCOperand::createImm(getCondCode())); 1294 } 1295 1296 void addAdrpLabelOperands(MCInst &Inst, unsigned N) const { 1297 assert(N == 1 && "Invalid number of operands!"); 1298 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 1299 if (!MCE) 1300 addExpr(Inst, getImm()); 1301 else 1302 Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 12)); 1303 } 1304 1305 void addAdrLabelOperands(MCInst &Inst, unsigned N) const { 1306 addImmOperands(Inst, N); 1307 } 1308 1309 template<int Scale> 1310 void addUImm12OffsetOperands(MCInst &Inst, unsigned N) const { 1311 assert(N == 1 && "Invalid number of operands!"); 1312 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 1313 1314 if (!MCE) { 1315 Inst.addOperand(MCOperand::createExpr(getImm())); 1316 return; 1317 } 1318 Inst.addOperand(MCOperand::createImm(MCE->getValue() / Scale)); 1319 } 1320 1321 void addSImm9Operands(MCInst &Inst, unsigned N) const { 1322 assert(N == 1 && "Invalid number of operands!"); 1323 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1324 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1325 } 1326 1327 void addSImm7s4Operands(MCInst &Inst, unsigned N) const { 1328 assert(N == 1 && "Invalid number of operands!"); 1329 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1330 Inst.addOperand(MCOperand::createImm(MCE->getValue() / 4)); 1331 } 1332 1333 void addSImm7s8Operands(MCInst &Inst, unsigned N) const { 1334 assert(N == 1 && "Invalid number of operands!"); 1335 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1336 Inst.addOperand(MCOperand::createImm(MCE->getValue() / 8)); 1337 } 1338 1339 void addSImm7s16Operands(MCInst &Inst, unsigned N) const { 1340 assert(N == 1 && "Invalid number of operands!"); 1341 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1342 Inst.addOperand(MCOperand::createImm(MCE->getValue() / 16)); 1343 } 1344 1345 void addImm0_1Operands(MCInst &Inst, unsigned N) const { 1346 assert(N == 1 && "Invalid number of operands!"); 1347 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1348 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1349 } 1350 1351 void addImm0_7Operands(MCInst &Inst, unsigned N) const { 1352 assert(N == 1 && "Invalid number of operands!"); 1353 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1354 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1355 } 1356 1357 void addImm1_8Operands(MCInst &Inst, unsigned N) const { 1358 assert(N == 1 && "Invalid number of operands!"); 1359 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1360 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1361 } 1362 1363 void addImm0_15Operands(MCInst &Inst, unsigned N) const { 1364 assert(N == 1 && "Invalid number of operands!"); 1365 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1366 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1367 } 1368 1369 void addImm1_16Operands(MCInst &Inst, unsigned N) const { 1370 assert(N == 1 && "Invalid number of operands!"); 1371 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1372 assert(MCE && "Invalid constant immediate operand!"); 1373 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1374 } 1375 1376 void addImm0_31Operands(MCInst &Inst, unsigned N) const { 1377 assert(N == 1 && "Invalid number of operands!"); 1378 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1379 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1380 } 1381 1382 void addImm1_31Operands(MCInst &Inst, unsigned N) const { 1383 assert(N == 1 && "Invalid number of operands!"); 1384 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1385 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1386 } 1387 1388 void addImm1_32Operands(MCInst &Inst, unsigned N) const { 1389 assert(N == 1 && "Invalid number of operands!"); 1390 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1391 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1392 } 1393 1394 void addImm0_63Operands(MCInst &Inst, unsigned N) const { 1395 assert(N == 1 && "Invalid number of operands!"); 1396 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1397 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1398 } 1399 1400 void addImm1_63Operands(MCInst &Inst, unsigned N) const { 1401 assert(N == 1 && "Invalid number of operands!"); 1402 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1403 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1404 } 1405 1406 void addImm1_64Operands(MCInst &Inst, unsigned N) const { 1407 assert(N == 1 && "Invalid number of operands!"); 1408 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1409 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1410 } 1411 1412 void addImm0_127Operands(MCInst &Inst, unsigned N) const { 1413 assert(N == 1 && "Invalid number of operands!"); 1414 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1415 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1416 } 1417 1418 void addImm0_255Operands(MCInst &Inst, unsigned N) const { 1419 assert(N == 1 && "Invalid number of operands!"); 1420 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1421 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1422 } 1423 1424 void addImm0_65535Operands(MCInst &Inst, unsigned N) const { 1425 assert(N == 1 && "Invalid number of operands!"); 1426 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1427 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1428 } 1429 1430 void addImm32_63Operands(MCInst &Inst, unsigned N) const { 1431 assert(N == 1 && "Invalid number of operands!"); 1432 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1433 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1434 } 1435 1436 void addLogicalImm32Operands(MCInst &Inst, unsigned N) const { 1437 assert(N == 1 && "Invalid number of operands!"); 1438 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1439 uint64_t encoding = 1440 AArch64_AM::encodeLogicalImmediate(MCE->getValue() & 0xFFFFFFFF, 32); 1441 Inst.addOperand(MCOperand::createImm(encoding)); 1442 } 1443 1444 void addLogicalImm64Operands(MCInst &Inst, unsigned N) const { 1445 assert(N == 1 && "Invalid number of operands!"); 1446 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1447 uint64_t encoding = AArch64_AM::encodeLogicalImmediate(MCE->getValue(), 64); 1448 Inst.addOperand(MCOperand::createImm(encoding)); 1449 } 1450 1451 void addLogicalImm32NotOperands(MCInst &Inst, unsigned N) const { 1452 assert(N == 1 && "Invalid number of operands!"); 1453 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1454 int64_t Val = ~MCE->getValue() & 0xFFFFFFFF; 1455 uint64_t encoding = AArch64_AM::encodeLogicalImmediate(Val, 32); 1456 Inst.addOperand(MCOperand::createImm(encoding)); 1457 } 1458 1459 void addLogicalImm64NotOperands(MCInst &Inst, unsigned N) const { 1460 assert(N == 1 && "Invalid number of operands!"); 1461 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1462 uint64_t encoding = 1463 AArch64_AM::encodeLogicalImmediate(~MCE->getValue(), 64); 1464 Inst.addOperand(MCOperand::createImm(encoding)); 1465 } 1466 1467 void addSIMDImmType10Operands(MCInst &Inst, unsigned N) const { 1468 assert(N == 1 && "Invalid number of operands!"); 1469 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1470 uint64_t encoding = AArch64_AM::encodeAdvSIMDModImmType10(MCE->getValue()); 1471 Inst.addOperand(MCOperand::createImm(encoding)); 1472 } 1473 1474 void addBranchTarget26Operands(MCInst &Inst, unsigned N) const { 1475 // Branch operands don't encode the low bits, so shift them off 1476 // here. If it's a label, however, just put it on directly as there's 1477 // not enough information now to do anything. 1478 assert(N == 1 && "Invalid number of operands!"); 1479 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 1480 if (!MCE) { 1481 addExpr(Inst, getImm()); 1482 return; 1483 } 1484 assert(MCE && "Invalid constant immediate operand!"); 1485 Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2)); 1486 } 1487 1488 void addPCRelLabel19Operands(MCInst &Inst, unsigned N) const { 1489 // Branch operands don't encode the low bits, so shift them off 1490 // here. If it's a label, however, just put it on directly as there's 1491 // not enough information now to do anything. 1492 assert(N == 1 && "Invalid number of operands!"); 1493 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 1494 if (!MCE) { 1495 addExpr(Inst, getImm()); 1496 return; 1497 } 1498 assert(MCE && "Invalid constant immediate operand!"); 1499 Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2)); 1500 } 1501 1502 void addBranchTarget14Operands(MCInst &Inst, unsigned N) const { 1503 // Branch operands don't encode the low bits, so shift them off 1504 // here. If it's a label, however, just put it on directly as there's 1505 // not enough information now to do anything. 1506 assert(N == 1 && "Invalid number of operands!"); 1507 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 1508 if (!MCE) { 1509 addExpr(Inst, getImm()); 1510 return; 1511 } 1512 assert(MCE && "Invalid constant immediate operand!"); 1513 Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2)); 1514 } 1515 1516 void addFPImmOperands(MCInst &Inst, unsigned N) const { 1517 assert(N == 1 && "Invalid number of operands!"); 1518 Inst.addOperand(MCOperand::createImm(getFPImm())); 1519 } 1520 1521 void addBarrierOperands(MCInst &Inst, unsigned N) const { 1522 assert(N == 1 && "Invalid number of operands!"); 1523 Inst.addOperand(MCOperand::createImm(getBarrier())); 1524 } 1525 1526 void addMRSSystemRegisterOperands(MCInst &Inst, unsigned N) const { 1527 assert(N == 1 && "Invalid number of operands!"); 1528 1529 Inst.addOperand(MCOperand::createImm(SysReg.MRSReg)); 1530 } 1531 1532 void addMSRSystemRegisterOperands(MCInst &Inst, unsigned N) const { 1533 assert(N == 1 && "Invalid number of operands!"); 1534 1535 Inst.addOperand(MCOperand::createImm(SysReg.MSRReg)); 1536 } 1537 1538 void addSystemPStateFieldWithImm0_1Operands(MCInst &Inst, unsigned N) const { 1539 assert(N == 1 && "Invalid number of operands!"); 1540 1541 Inst.addOperand(MCOperand::createImm(SysReg.PStateField)); 1542 } 1543 1544 void addSystemPStateFieldWithImm0_15Operands(MCInst &Inst, unsigned N) const { 1545 assert(N == 1 && "Invalid number of operands!"); 1546 1547 Inst.addOperand(MCOperand::createImm(SysReg.PStateField)); 1548 } 1549 1550 void addSysCROperands(MCInst &Inst, unsigned N) const { 1551 assert(N == 1 && "Invalid number of operands!"); 1552 Inst.addOperand(MCOperand::createImm(getSysCR())); 1553 } 1554 1555 void addPrefetchOperands(MCInst &Inst, unsigned N) const { 1556 assert(N == 1 && "Invalid number of operands!"); 1557 Inst.addOperand(MCOperand::createImm(getPrefetch())); 1558 } 1559 1560 void addPSBHintOperands(MCInst &Inst, unsigned N) const { 1561 assert(N == 1 && "Invalid number of operands!"); 1562 Inst.addOperand(MCOperand::createImm(getPSBHint())); 1563 } 1564 1565 void addShifterOperands(MCInst &Inst, unsigned N) const { 1566 assert(N == 1 && "Invalid number of operands!"); 1567 unsigned Imm = 1568 AArch64_AM::getShifterImm(getShiftExtendType(), getShiftExtendAmount()); 1569 Inst.addOperand(MCOperand::createImm(Imm)); 1570 } 1571 1572 void addExtendOperands(MCInst &Inst, unsigned N) const { 1573 assert(N == 1 && "Invalid number of operands!"); 1574 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 1575 if (ET == AArch64_AM::LSL) ET = AArch64_AM::UXTW; 1576 unsigned Imm = AArch64_AM::getArithExtendImm(ET, getShiftExtendAmount()); 1577 Inst.addOperand(MCOperand::createImm(Imm)); 1578 } 1579 1580 void addExtend64Operands(MCInst &Inst, unsigned N) const { 1581 assert(N == 1 && "Invalid number of operands!"); 1582 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 1583 if (ET == AArch64_AM::LSL) ET = AArch64_AM::UXTX; 1584 unsigned Imm = AArch64_AM::getArithExtendImm(ET, getShiftExtendAmount()); 1585 Inst.addOperand(MCOperand::createImm(Imm)); 1586 } 1587 1588 void addMemExtendOperands(MCInst &Inst, unsigned N) const { 1589 assert(N == 2 && "Invalid number of operands!"); 1590 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 1591 bool IsSigned = ET == AArch64_AM::SXTW || ET == AArch64_AM::SXTX; 1592 Inst.addOperand(MCOperand::createImm(IsSigned)); 1593 Inst.addOperand(MCOperand::createImm(getShiftExtendAmount() != 0)); 1594 } 1595 1596 // For 8-bit load/store instructions with a register offset, both the 1597 // "DoShift" and "NoShift" variants have a shift of 0. Because of this, 1598 // they're disambiguated by whether the shift was explicit or implicit rather 1599 // than its size. 1600 void addMemExtend8Operands(MCInst &Inst, unsigned N) const { 1601 assert(N == 2 && "Invalid number of operands!"); 1602 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 1603 bool IsSigned = ET == AArch64_AM::SXTW || ET == AArch64_AM::SXTX; 1604 Inst.addOperand(MCOperand::createImm(IsSigned)); 1605 Inst.addOperand(MCOperand::createImm(hasShiftExtendAmount())); 1606 } 1607 1608 template<int Shift> 1609 void addMOVZMovAliasOperands(MCInst &Inst, unsigned N) const { 1610 assert(N == 1 && "Invalid number of operands!"); 1611 1612 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 1613 uint64_t Value = CE->getValue(); 1614 Inst.addOperand(MCOperand::createImm((Value >> Shift) & 0xffff)); 1615 } 1616 1617 template<int Shift> 1618 void addMOVNMovAliasOperands(MCInst &Inst, unsigned N) const { 1619 assert(N == 1 && "Invalid number of operands!"); 1620 1621 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 1622 uint64_t Value = CE->getValue(); 1623 Inst.addOperand(MCOperand::createImm((~Value >> Shift) & 0xffff)); 1624 } 1625 1626 void print(raw_ostream &OS) const override; 1627 1628 static std::unique_ptr<AArch64Operand> 1629 CreateToken(StringRef Str, bool IsSuffix, SMLoc S, MCContext &Ctx) { 1630 auto Op = make_unique<AArch64Operand>(k_Token, Ctx); 1631 Op->Tok.Data = Str.data(); 1632 Op->Tok.Length = Str.size(); 1633 Op->Tok.IsSuffix = IsSuffix; 1634 Op->StartLoc = S; 1635 Op->EndLoc = S; 1636 return Op; 1637 } 1638 1639 static std::unique_ptr<AArch64Operand> 1640 CreateReg(unsigned RegNum, bool isVector, SMLoc S, SMLoc E, MCContext &Ctx) { 1641 auto Op = make_unique<AArch64Operand>(k_Register, Ctx); 1642 Op->Reg.RegNum = RegNum; 1643 Op->Reg.isVector = isVector; 1644 Op->StartLoc = S; 1645 Op->EndLoc = E; 1646 return Op; 1647 } 1648 1649 static std::unique_ptr<AArch64Operand> 1650 CreateVectorList(unsigned RegNum, unsigned Count, unsigned NumElements, 1651 char ElementKind, SMLoc S, SMLoc E, MCContext &Ctx) { 1652 auto Op = make_unique<AArch64Operand>(k_VectorList, Ctx); 1653 Op->VectorList.RegNum = RegNum; 1654 Op->VectorList.Count = Count; 1655 Op->VectorList.NumElements = NumElements; 1656 Op->VectorList.ElementKind = ElementKind; 1657 Op->StartLoc = S; 1658 Op->EndLoc = E; 1659 return Op; 1660 } 1661 1662 static std::unique_ptr<AArch64Operand> 1663 CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, MCContext &Ctx) { 1664 auto Op = make_unique<AArch64Operand>(k_VectorIndex, Ctx); 1665 Op->VectorIndex.Val = Idx; 1666 Op->StartLoc = S; 1667 Op->EndLoc = E; 1668 return Op; 1669 } 1670 1671 static std::unique_ptr<AArch64Operand> CreateImm(const MCExpr *Val, SMLoc S, 1672 SMLoc E, MCContext &Ctx) { 1673 auto Op = make_unique<AArch64Operand>(k_Immediate, Ctx); 1674 Op->Imm.Val = Val; 1675 Op->StartLoc = S; 1676 Op->EndLoc = E; 1677 return Op; 1678 } 1679 1680 static std::unique_ptr<AArch64Operand> CreateShiftedImm(const MCExpr *Val, 1681 unsigned ShiftAmount, 1682 SMLoc S, SMLoc E, 1683 MCContext &Ctx) { 1684 auto Op = make_unique<AArch64Operand>(k_ShiftedImm, Ctx); 1685 Op->ShiftedImm .Val = Val; 1686 Op->ShiftedImm.ShiftAmount = ShiftAmount; 1687 Op->StartLoc = S; 1688 Op->EndLoc = E; 1689 return Op; 1690 } 1691 1692 static std::unique_ptr<AArch64Operand> 1693 CreateCondCode(AArch64CC::CondCode Code, SMLoc S, SMLoc E, MCContext &Ctx) { 1694 auto Op = make_unique<AArch64Operand>(k_CondCode, Ctx); 1695 Op->CondCode.Code = Code; 1696 Op->StartLoc = S; 1697 Op->EndLoc = E; 1698 return Op; 1699 } 1700 1701 static std::unique_ptr<AArch64Operand> CreateFPImm(unsigned Val, SMLoc S, 1702 MCContext &Ctx) { 1703 auto Op = make_unique<AArch64Operand>(k_FPImm, Ctx); 1704 Op->FPImm.Val = Val; 1705 Op->StartLoc = S; 1706 Op->EndLoc = S; 1707 return Op; 1708 } 1709 1710 static std::unique_ptr<AArch64Operand> CreateBarrier(unsigned Val, 1711 StringRef Str, 1712 SMLoc S, 1713 MCContext &Ctx) { 1714 auto Op = make_unique<AArch64Operand>(k_Barrier, Ctx); 1715 Op->Barrier.Val = Val; 1716 Op->Barrier.Data = Str.data(); 1717 Op->Barrier.Length = Str.size(); 1718 Op->StartLoc = S; 1719 Op->EndLoc = S; 1720 return Op; 1721 } 1722 1723 static std::unique_ptr<AArch64Operand> CreateSysReg(StringRef Str, SMLoc S, 1724 uint32_t MRSReg, 1725 uint32_t MSRReg, 1726 uint32_t PStateField, 1727 MCContext &Ctx) { 1728 auto Op = make_unique<AArch64Operand>(k_SysReg, Ctx); 1729 Op->SysReg.Data = Str.data(); 1730 Op->SysReg.Length = Str.size(); 1731 Op->SysReg.MRSReg = MRSReg; 1732 Op->SysReg.MSRReg = MSRReg; 1733 Op->SysReg.PStateField = PStateField; 1734 Op->StartLoc = S; 1735 Op->EndLoc = S; 1736 return Op; 1737 } 1738 1739 static std::unique_ptr<AArch64Operand> CreateSysCR(unsigned Val, SMLoc S, 1740 SMLoc E, MCContext &Ctx) { 1741 auto Op = make_unique<AArch64Operand>(k_SysCR, Ctx); 1742 Op->SysCRImm.Val = Val; 1743 Op->StartLoc = S; 1744 Op->EndLoc = E; 1745 return Op; 1746 } 1747 1748 static std::unique_ptr<AArch64Operand> CreatePrefetch(unsigned Val, 1749 StringRef Str, 1750 SMLoc S, 1751 MCContext &Ctx) { 1752 auto Op = make_unique<AArch64Operand>(k_Prefetch, Ctx); 1753 Op->Prefetch.Val = Val; 1754 Op->Barrier.Data = Str.data(); 1755 Op->Barrier.Length = Str.size(); 1756 Op->StartLoc = S; 1757 Op->EndLoc = S; 1758 return Op; 1759 } 1760 1761 static std::unique_ptr<AArch64Operand> CreatePSBHint(unsigned Val, 1762 StringRef Str, 1763 SMLoc S, 1764 MCContext &Ctx) { 1765 auto Op = make_unique<AArch64Operand>(k_PSBHint, Ctx); 1766 Op->PSBHint.Val = Val; 1767 Op->PSBHint.Data = Str.data(); 1768 Op->PSBHint.Length = Str.size(); 1769 Op->StartLoc = S; 1770 Op->EndLoc = S; 1771 return Op; 1772 } 1773 1774 static std::unique_ptr<AArch64Operand> 1775 CreateShiftExtend(AArch64_AM::ShiftExtendType ShOp, unsigned Val, 1776 bool HasExplicitAmount, SMLoc S, SMLoc E, MCContext &Ctx) { 1777 auto Op = make_unique<AArch64Operand>(k_ShiftExtend, Ctx); 1778 Op->ShiftExtend.Type = ShOp; 1779 Op->ShiftExtend.Amount = Val; 1780 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount; 1781 Op->StartLoc = S; 1782 Op->EndLoc = E; 1783 return Op; 1784 } 1785 }; 1786 1787 } // end anonymous namespace. 1788 1789 void AArch64Operand::print(raw_ostream &OS) const { 1790 switch (Kind) { 1791 case k_FPImm: 1792 OS << "<fpimm " << getFPImm() << "(" 1793 << AArch64_AM::getFPImmFloat(getFPImm()) << ") >"; 1794 break; 1795 case k_Barrier: { 1796 StringRef Name = getBarrierName(); 1797 if (!Name.empty()) 1798 OS << "<barrier " << Name << ">"; 1799 else 1800 OS << "<barrier invalid #" << getBarrier() << ">"; 1801 break; 1802 } 1803 case k_Immediate: 1804 OS << *getImm(); 1805 break; 1806 case k_ShiftedImm: { 1807 unsigned Shift = getShiftedImmShift(); 1808 OS << "<shiftedimm "; 1809 OS << *getShiftedImmVal(); 1810 OS << ", lsl #" << AArch64_AM::getShiftValue(Shift) << ">"; 1811 break; 1812 } 1813 case k_CondCode: 1814 OS << "<condcode " << getCondCode() << ">"; 1815 break; 1816 case k_Register: 1817 OS << "<register " << getReg() << ">"; 1818 break; 1819 case k_VectorList: { 1820 OS << "<vectorlist "; 1821 unsigned Reg = getVectorListStart(); 1822 for (unsigned i = 0, e = getVectorListCount(); i != e; ++i) 1823 OS << Reg + i << " "; 1824 OS << ">"; 1825 break; 1826 } 1827 case k_VectorIndex: 1828 OS << "<vectorindex " << getVectorIndex() << ">"; 1829 break; 1830 case k_SysReg: 1831 OS << "<sysreg: " << getSysReg() << '>'; 1832 break; 1833 case k_Token: 1834 OS << "'" << getToken() << "'"; 1835 break; 1836 case k_SysCR: 1837 OS << "c" << getSysCR(); 1838 break; 1839 case k_Prefetch: { 1840 StringRef Name = getPrefetchName(); 1841 if (!Name.empty()) 1842 OS << "<prfop " << Name << ">"; 1843 else 1844 OS << "<prfop invalid #" << getPrefetch() << ">"; 1845 break; 1846 } 1847 case k_PSBHint: { 1848 OS << getPSBHintName(); 1849 break; 1850 } 1851 case k_ShiftExtend: { 1852 OS << "<" << AArch64_AM::getShiftExtendName(getShiftExtendType()) << " #" 1853 << getShiftExtendAmount(); 1854 if (!hasShiftExtendAmount()) 1855 OS << "<imp>"; 1856 OS << '>'; 1857 break; 1858 } 1859 } 1860 } 1861 1862 /// @name Auto-generated Match Functions 1863 /// { 1864 1865 static unsigned MatchRegisterName(StringRef Name); 1866 1867 /// } 1868 1869 static unsigned matchVectorRegName(StringRef Name) { 1870 return StringSwitch<unsigned>(Name.lower()) 1871 .Case("v0", AArch64::Q0) 1872 .Case("v1", AArch64::Q1) 1873 .Case("v2", AArch64::Q2) 1874 .Case("v3", AArch64::Q3) 1875 .Case("v4", AArch64::Q4) 1876 .Case("v5", AArch64::Q5) 1877 .Case("v6", AArch64::Q6) 1878 .Case("v7", AArch64::Q7) 1879 .Case("v8", AArch64::Q8) 1880 .Case("v9", AArch64::Q9) 1881 .Case("v10", AArch64::Q10) 1882 .Case("v11", AArch64::Q11) 1883 .Case("v12", AArch64::Q12) 1884 .Case("v13", AArch64::Q13) 1885 .Case("v14", AArch64::Q14) 1886 .Case("v15", AArch64::Q15) 1887 .Case("v16", AArch64::Q16) 1888 .Case("v17", AArch64::Q17) 1889 .Case("v18", AArch64::Q18) 1890 .Case("v19", AArch64::Q19) 1891 .Case("v20", AArch64::Q20) 1892 .Case("v21", AArch64::Q21) 1893 .Case("v22", AArch64::Q22) 1894 .Case("v23", AArch64::Q23) 1895 .Case("v24", AArch64::Q24) 1896 .Case("v25", AArch64::Q25) 1897 .Case("v26", AArch64::Q26) 1898 .Case("v27", AArch64::Q27) 1899 .Case("v28", AArch64::Q28) 1900 .Case("v29", AArch64::Q29) 1901 .Case("v30", AArch64::Q30) 1902 .Case("v31", AArch64::Q31) 1903 .Default(0); 1904 } 1905 1906 static bool isValidVectorKind(StringRef Name) { 1907 return StringSwitch<bool>(Name.lower()) 1908 .Case(".8b", true) 1909 .Case(".16b", true) 1910 .Case(".4h", true) 1911 .Case(".8h", true) 1912 .Case(".2s", true) 1913 .Case(".4s", true) 1914 .Case(".1d", true) 1915 .Case(".2d", true) 1916 .Case(".1q", true) 1917 // Accept the width neutral ones, too, for verbose syntax. If those 1918 // aren't used in the right places, the token operand won't match so 1919 // all will work out. 1920 .Case(".b", true) 1921 .Case(".h", true) 1922 .Case(".s", true) 1923 .Case(".d", true) 1924 .Default(false); 1925 } 1926 1927 static void parseValidVectorKind(StringRef Name, unsigned &NumElements, 1928 char &ElementKind) { 1929 assert(isValidVectorKind(Name)); 1930 1931 ElementKind = Name.lower()[Name.size() - 1]; 1932 NumElements = 0; 1933 1934 if (Name.size() == 2) 1935 return; 1936 1937 // Parse the lane count 1938 Name = Name.drop_front(); 1939 while (isdigit(Name.front())) { 1940 NumElements = 10 * NumElements + (Name.front() - '0'); 1941 Name = Name.drop_front(); 1942 } 1943 } 1944 1945 bool AArch64AsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 1946 SMLoc &EndLoc) { 1947 StartLoc = getLoc(); 1948 RegNo = tryParseRegister(); 1949 EndLoc = SMLoc::getFromPointer(getLoc().getPointer() - 1); 1950 return (RegNo == (unsigned)-1); 1951 } 1952 1953 // Matches a register name or register alias previously defined by '.req' 1954 unsigned AArch64AsmParser::matchRegisterNameAlias(StringRef Name, 1955 bool isVector) { 1956 unsigned RegNum = isVector ? matchVectorRegName(Name) 1957 : MatchRegisterName(Name); 1958 1959 if (RegNum == 0) { 1960 // Check for aliases registered via .req. Canonicalize to lower case. 1961 // That's more consistent since register names are case insensitive, and 1962 // it's how the original entry was passed in from MC/MCParser/AsmParser. 1963 auto Entry = RegisterReqs.find(Name.lower()); 1964 if (Entry == RegisterReqs.end()) 1965 return 0; 1966 // set RegNum if the match is the right kind of register 1967 if (isVector == Entry->getValue().first) 1968 RegNum = Entry->getValue().second; 1969 } 1970 return RegNum; 1971 } 1972 1973 /// tryParseRegister - Try to parse a register name. The token must be an 1974 /// Identifier when called, and if it is a register name the token is eaten and 1975 /// the register is added to the operand list. 1976 int AArch64AsmParser::tryParseRegister() { 1977 MCAsmParser &Parser = getParser(); 1978 const AsmToken &Tok = Parser.getTok(); 1979 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1980 1981 std::string lowerCase = Tok.getString().lower(); 1982 unsigned RegNum = matchRegisterNameAlias(lowerCase, false); 1983 // Also handle a few aliases of registers. 1984 if (RegNum == 0) 1985 RegNum = StringSwitch<unsigned>(lowerCase) 1986 .Case("fp", AArch64::FP) 1987 .Case("lr", AArch64::LR) 1988 .Case("x31", AArch64::XZR) 1989 .Case("w31", AArch64::WZR) 1990 .Default(0); 1991 1992 if (RegNum == 0) 1993 return -1; 1994 1995 Parser.Lex(); // Eat identifier token. 1996 return RegNum; 1997 } 1998 1999 /// tryMatchVectorRegister - Try to parse a vector register name with optional 2000 /// kind specifier. If it is a register specifier, eat the token and return it. 2001 int AArch64AsmParser::tryMatchVectorRegister(StringRef &Kind, bool expected) { 2002 MCAsmParser &Parser = getParser(); 2003 if (Parser.getTok().isNot(AsmToken::Identifier)) { 2004 TokError("vector register expected"); 2005 return -1; 2006 } 2007 2008 StringRef Name = Parser.getTok().getString(); 2009 // If there is a kind specifier, it's separated from the register name by 2010 // a '.'. 2011 size_t Start = 0, Next = Name.find('.'); 2012 StringRef Head = Name.slice(Start, Next); 2013 unsigned RegNum = matchRegisterNameAlias(Head, true); 2014 2015 if (RegNum) { 2016 if (Next != StringRef::npos) { 2017 Kind = Name.slice(Next, StringRef::npos); 2018 if (!isValidVectorKind(Kind)) { 2019 TokError("invalid vector kind qualifier"); 2020 return -1; 2021 } 2022 } 2023 Parser.Lex(); // Eat the register token. 2024 return RegNum; 2025 } 2026 2027 if (expected) 2028 TokError("vector register expected"); 2029 return -1; 2030 } 2031 2032 /// tryParseSysCROperand - Try to parse a system instruction CR operand name. 2033 AArch64AsmParser::OperandMatchResultTy 2034 AArch64AsmParser::tryParseSysCROperand(OperandVector &Operands) { 2035 MCAsmParser &Parser = getParser(); 2036 SMLoc S = getLoc(); 2037 2038 if (Parser.getTok().isNot(AsmToken::Identifier)) { 2039 Error(S, "Expected cN operand where 0 <= N <= 15"); 2040 return MatchOperand_ParseFail; 2041 } 2042 2043 StringRef Tok = Parser.getTok().getIdentifier(); 2044 if (Tok[0] != 'c' && Tok[0] != 'C') { 2045 Error(S, "Expected cN operand where 0 <= N <= 15"); 2046 return MatchOperand_ParseFail; 2047 } 2048 2049 uint32_t CRNum; 2050 bool BadNum = Tok.drop_front().getAsInteger(10, CRNum); 2051 if (BadNum || CRNum > 15) { 2052 Error(S, "Expected cN operand where 0 <= N <= 15"); 2053 return MatchOperand_ParseFail; 2054 } 2055 2056 Parser.Lex(); // Eat identifier token. 2057 Operands.push_back( 2058 AArch64Operand::CreateSysCR(CRNum, S, getLoc(), getContext())); 2059 return MatchOperand_Success; 2060 } 2061 2062 /// tryParsePrefetch - Try to parse a prefetch operand. 2063 AArch64AsmParser::OperandMatchResultTy 2064 AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) { 2065 MCAsmParser &Parser = getParser(); 2066 SMLoc S = getLoc(); 2067 const AsmToken &Tok = Parser.getTok(); 2068 // Either an identifier for named values or a 5-bit immediate. 2069 bool Hash = Tok.is(AsmToken::Hash); 2070 if (Hash || Tok.is(AsmToken::Integer)) { 2071 if (Hash) 2072 Parser.Lex(); // Eat hash token. 2073 const MCExpr *ImmVal; 2074 if (getParser().parseExpression(ImmVal)) 2075 return MatchOperand_ParseFail; 2076 2077 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 2078 if (!MCE) { 2079 TokError("immediate value expected for prefetch operand"); 2080 return MatchOperand_ParseFail; 2081 } 2082 unsigned prfop = MCE->getValue(); 2083 if (prfop > 31) { 2084 TokError("prefetch operand out of range, [0,31] expected"); 2085 return MatchOperand_ParseFail; 2086 } 2087 2088 bool Valid; 2089 auto Mapper = AArch64PRFM::PRFMMapper(); 2090 StringRef Name = 2091 Mapper.toString(MCE->getValue(), getSTI().getFeatureBits(), Valid); 2092 Operands.push_back(AArch64Operand::CreatePrefetch(prfop, Name, 2093 S, getContext())); 2094 return MatchOperand_Success; 2095 } 2096 2097 if (Tok.isNot(AsmToken::Identifier)) { 2098 TokError("pre-fetch hint expected"); 2099 return MatchOperand_ParseFail; 2100 } 2101 2102 bool Valid; 2103 auto Mapper = AArch64PRFM::PRFMMapper(); 2104 unsigned prfop = 2105 Mapper.fromString(Tok.getString(), getSTI().getFeatureBits(), Valid); 2106 if (!Valid) { 2107 TokError("pre-fetch hint expected"); 2108 return MatchOperand_ParseFail; 2109 } 2110 2111 Parser.Lex(); // Eat identifier token. 2112 Operands.push_back(AArch64Operand::CreatePrefetch(prfop, Tok.getString(), 2113 S, getContext())); 2114 return MatchOperand_Success; 2115 } 2116 2117 /// tryParsePSBHint - Try to parse a PSB operand, mapped to Hint command 2118 AArch64AsmParser::OperandMatchResultTy 2119 AArch64AsmParser::tryParsePSBHint(OperandVector &Operands) { 2120 MCAsmParser &Parser = getParser(); 2121 SMLoc S = getLoc(); 2122 const AsmToken &Tok = Parser.getTok(); 2123 if (Tok.isNot(AsmToken::Identifier)) { 2124 TokError("invalid operand for instruction"); 2125 return MatchOperand_ParseFail; 2126 } 2127 2128 bool Valid; 2129 auto Mapper = AArch64PSBHint::PSBHintMapper(); 2130 unsigned psbhint = 2131 Mapper.fromString(Tok.getString(), getSTI().getFeatureBits(), Valid); 2132 if (!Valid) { 2133 TokError("invalid operand for instruction"); 2134 return MatchOperand_ParseFail; 2135 } 2136 2137 Parser.Lex(); // Eat identifier token. 2138 Operands.push_back(AArch64Operand::CreatePSBHint(psbhint, Tok.getString(), 2139 S, getContext())); 2140 return MatchOperand_Success; 2141 } 2142 2143 /// tryParseAdrpLabel - Parse and validate a source label for the ADRP 2144 /// instruction. 2145 AArch64AsmParser::OperandMatchResultTy 2146 AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) { 2147 MCAsmParser &Parser = getParser(); 2148 SMLoc S = getLoc(); 2149 const MCExpr *Expr; 2150 2151 if (Parser.getTok().is(AsmToken::Hash)) { 2152 Parser.Lex(); // Eat hash token. 2153 } 2154 2155 if (parseSymbolicImmVal(Expr)) 2156 return MatchOperand_ParseFail; 2157 2158 AArch64MCExpr::VariantKind ELFRefKind; 2159 MCSymbolRefExpr::VariantKind DarwinRefKind; 2160 int64_t Addend; 2161 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) { 2162 if (DarwinRefKind == MCSymbolRefExpr::VK_None && 2163 ELFRefKind == AArch64MCExpr::VK_INVALID) { 2164 // No modifier was specified at all; this is the syntax for an ELF basic 2165 // ADRP relocation (unfortunately). 2166 Expr = 2167 AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS_PAGE, getContext()); 2168 } else if ((DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGE || 2169 DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGE) && 2170 Addend != 0) { 2171 Error(S, "gotpage label reference not allowed an addend"); 2172 return MatchOperand_ParseFail; 2173 } else if (DarwinRefKind != MCSymbolRefExpr::VK_PAGE && 2174 DarwinRefKind != MCSymbolRefExpr::VK_GOTPAGE && 2175 DarwinRefKind != MCSymbolRefExpr::VK_TLVPPAGE && 2176 ELFRefKind != AArch64MCExpr::VK_GOT_PAGE && 2177 ELFRefKind != AArch64MCExpr::VK_GOTTPREL_PAGE && 2178 ELFRefKind != AArch64MCExpr::VK_TLSDESC_PAGE) { 2179 // The operand must be an @page or @gotpage qualified symbolref. 2180 Error(S, "page or gotpage label reference expected"); 2181 return MatchOperand_ParseFail; 2182 } 2183 } 2184 2185 // We have either a label reference possibly with addend or an immediate. The 2186 // addend is a raw value here. The linker will adjust it to only reference the 2187 // page. 2188 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1); 2189 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext())); 2190 2191 return MatchOperand_Success; 2192 } 2193 2194 /// tryParseAdrLabel - Parse and validate a source label for the ADR 2195 /// instruction. 2196 AArch64AsmParser::OperandMatchResultTy 2197 AArch64AsmParser::tryParseAdrLabel(OperandVector &Operands) { 2198 MCAsmParser &Parser = getParser(); 2199 SMLoc S = getLoc(); 2200 const MCExpr *Expr; 2201 2202 if (Parser.getTok().is(AsmToken::Hash)) { 2203 Parser.Lex(); // Eat hash token. 2204 } 2205 2206 if (getParser().parseExpression(Expr)) 2207 return MatchOperand_ParseFail; 2208 2209 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1); 2210 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext())); 2211 2212 return MatchOperand_Success; 2213 } 2214 2215 /// tryParseFPImm - A floating point immediate expression operand. 2216 AArch64AsmParser::OperandMatchResultTy 2217 AArch64AsmParser::tryParseFPImm(OperandVector &Operands) { 2218 MCAsmParser &Parser = getParser(); 2219 SMLoc S = getLoc(); 2220 2221 bool Hash = false; 2222 if (Parser.getTok().is(AsmToken::Hash)) { 2223 Parser.Lex(); // Eat '#' 2224 Hash = true; 2225 } 2226 2227 // Handle negation, as that still comes through as a separate token. 2228 bool isNegative = false; 2229 if (Parser.getTok().is(AsmToken::Minus)) { 2230 isNegative = true; 2231 Parser.Lex(); 2232 } 2233 const AsmToken &Tok = Parser.getTok(); 2234 if (Tok.is(AsmToken::Real)) { 2235 APFloat RealVal(APFloat::IEEEdouble, Tok.getString()); 2236 if (isNegative) 2237 RealVal.changeSign(); 2238 2239 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 2240 int Val = AArch64_AM::getFP64Imm(APInt(64, IntVal)); 2241 Parser.Lex(); // Eat the token. 2242 // Check for out of range values. As an exception, we let Zero through, 2243 // as we handle that special case in post-processing before matching in 2244 // order to use the zero register for it. 2245 if (Val == -1 && !RealVal.isPosZero()) { 2246 TokError("expected compatible register or floating-point constant"); 2247 return MatchOperand_ParseFail; 2248 } 2249 Operands.push_back(AArch64Operand::CreateFPImm(Val, S, getContext())); 2250 return MatchOperand_Success; 2251 } 2252 if (Tok.is(AsmToken::Integer)) { 2253 int64_t Val; 2254 if (!isNegative && Tok.getString().startswith("0x")) { 2255 Val = Tok.getIntVal(); 2256 if (Val > 255 || Val < 0) { 2257 TokError("encoded floating point value out of range"); 2258 return MatchOperand_ParseFail; 2259 } 2260 } else { 2261 APFloat RealVal(APFloat::IEEEdouble, Tok.getString()); 2262 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 2263 // If we had a '-' in front, toggle the sign bit. 2264 IntVal ^= (uint64_t)isNegative << 63; 2265 Val = AArch64_AM::getFP64Imm(APInt(64, IntVal)); 2266 } 2267 Parser.Lex(); // Eat the token. 2268 Operands.push_back(AArch64Operand::CreateFPImm(Val, S, getContext())); 2269 return MatchOperand_Success; 2270 } 2271 2272 if (!Hash) 2273 return MatchOperand_NoMatch; 2274 2275 TokError("invalid floating point immediate"); 2276 return MatchOperand_ParseFail; 2277 } 2278 2279 /// tryParseAddSubImm - Parse ADD/SUB shifted immediate operand 2280 AArch64AsmParser::OperandMatchResultTy 2281 AArch64AsmParser::tryParseAddSubImm(OperandVector &Operands) { 2282 MCAsmParser &Parser = getParser(); 2283 SMLoc S = getLoc(); 2284 2285 if (Parser.getTok().is(AsmToken::Hash)) 2286 Parser.Lex(); // Eat '#' 2287 else if (Parser.getTok().isNot(AsmToken::Integer)) 2288 // Operand should start from # or should be integer, emit error otherwise. 2289 return MatchOperand_NoMatch; 2290 2291 const MCExpr *Imm; 2292 if (parseSymbolicImmVal(Imm)) 2293 return MatchOperand_ParseFail; 2294 else if (Parser.getTok().isNot(AsmToken::Comma)) { 2295 uint64_t ShiftAmount = 0; 2296 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Imm); 2297 if (MCE) { 2298 int64_t Val = MCE->getValue(); 2299 if (Val > 0xfff && (Val & 0xfff) == 0) { 2300 Imm = MCConstantExpr::create(Val >> 12, getContext()); 2301 ShiftAmount = 12; 2302 } 2303 } 2304 SMLoc E = Parser.getTok().getLoc(); 2305 Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S, E, 2306 getContext())); 2307 return MatchOperand_Success; 2308 } 2309 2310 // Eat ',' 2311 Parser.Lex(); 2312 2313 // The optional operand must be "lsl #N" where N is non-negative. 2314 if (!Parser.getTok().is(AsmToken::Identifier) || 2315 !Parser.getTok().getIdentifier().equals_lower("lsl")) { 2316 Error(Parser.getTok().getLoc(), "only 'lsl #+N' valid after immediate"); 2317 return MatchOperand_ParseFail; 2318 } 2319 2320 // Eat 'lsl' 2321 Parser.Lex(); 2322 2323 if (Parser.getTok().is(AsmToken::Hash)) { 2324 Parser.Lex(); 2325 } 2326 2327 if (Parser.getTok().isNot(AsmToken::Integer)) { 2328 Error(Parser.getTok().getLoc(), "only 'lsl #+N' valid after immediate"); 2329 return MatchOperand_ParseFail; 2330 } 2331 2332 int64_t ShiftAmount = Parser.getTok().getIntVal(); 2333 2334 if (ShiftAmount < 0) { 2335 Error(Parser.getTok().getLoc(), "positive shift amount required"); 2336 return MatchOperand_ParseFail; 2337 } 2338 Parser.Lex(); // Eat the number 2339 2340 SMLoc E = Parser.getTok().getLoc(); 2341 Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, 2342 S, E, getContext())); 2343 return MatchOperand_Success; 2344 } 2345 2346 /// parseCondCodeString - Parse a Condition Code string. 2347 AArch64CC::CondCode AArch64AsmParser::parseCondCodeString(StringRef Cond) { 2348 AArch64CC::CondCode CC = StringSwitch<AArch64CC::CondCode>(Cond.lower()) 2349 .Case("eq", AArch64CC::EQ) 2350 .Case("ne", AArch64CC::NE) 2351 .Case("cs", AArch64CC::HS) 2352 .Case("hs", AArch64CC::HS) 2353 .Case("cc", AArch64CC::LO) 2354 .Case("lo", AArch64CC::LO) 2355 .Case("mi", AArch64CC::MI) 2356 .Case("pl", AArch64CC::PL) 2357 .Case("vs", AArch64CC::VS) 2358 .Case("vc", AArch64CC::VC) 2359 .Case("hi", AArch64CC::HI) 2360 .Case("ls", AArch64CC::LS) 2361 .Case("ge", AArch64CC::GE) 2362 .Case("lt", AArch64CC::LT) 2363 .Case("gt", AArch64CC::GT) 2364 .Case("le", AArch64CC::LE) 2365 .Case("al", AArch64CC::AL) 2366 .Case("nv", AArch64CC::NV) 2367 .Default(AArch64CC::Invalid); 2368 return CC; 2369 } 2370 2371 /// parseCondCode - Parse a Condition Code operand. 2372 bool AArch64AsmParser::parseCondCode(OperandVector &Operands, 2373 bool invertCondCode) { 2374 MCAsmParser &Parser = getParser(); 2375 SMLoc S = getLoc(); 2376 const AsmToken &Tok = Parser.getTok(); 2377 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2378 2379 StringRef Cond = Tok.getString(); 2380 AArch64CC::CondCode CC = parseCondCodeString(Cond); 2381 if (CC == AArch64CC::Invalid) 2382 return TokError("invalid condition code"); 2383 Parser.Lex(); // Eat identifier token. 2384 2385 if (invertCondCode) { 2386 if (CC == AArch64CC::AL || CC == AArch64CC::NV) 2387 return TokError("condition codes AL and NV are invalid for this instruction"); 2388 CC = AArch64CC::getInvertedCondCode(AArch64CC::CondCode(CC)); 2389 } 2390 2391 Operands.push_back( 2392 AArch64Operand::CreateCondCode(CC, S, getLoc(), getContext())); 2393 return false; 2394 } 2395 2396 /// tryParseOptionalShift - Some operands take an optional shift argument. Parse 2397 /// them if present. 2398 AArch64AsmParser::OperandMatchResultTy 2399 AArch64AsmParser::tryParseOptionalShiftExtend(OperandVector &Operands) { 2400 MCAsmParser &Parser = getParser(); 2401 const AsmToken &Tok = Parser.getTok(); 2402 std::string LowerID = Tok.getString().lower(); 2403 AArch64_AM::ShiftExtendType ShOp = 2404 StringSwitch<AArch64_AM::ShiftExtendType>(LowerID) 2405 .Case("lsl", AArch64_AM::LSL) 2406 .Case("lsr", AArch64_AM::LSR) 2407 .Case("asr", AArch64_AM::ASR) 2408 .Case("ror", AArch64_AM::ROR) 2409 .Case("msl", AArch64_AM::MSL) 2410 .Case("uxtb", AArch64_AM::UXTB) 2411 .Case("uxth", AArch64_AM::UXTH) 2412 .Case("uxtw", AArch64_AM::UXTW) 2413 .Case("uxtx", AArch64_AM::UXTX) 2414 .Case("sxtb", AArch64_AM::SXTB) 2415 .Case("sxth", AArch64_AM::SXTH) 2416 .Case("sxtw", AArch64_AM::SXTW) 2417 .Case("sxtx", AArch64_AM::SXTX) 2418 .Default(AArch64_AM::InvalidShiftExtend); 2419 2420 if (ShOp == AArch64_AM::InvalidShiftExtend) 2421 return MatchOperand_NoMatch; 2422 2423 SMLoc S = Tok.getLoc(); 2424 Parser.Lex(); 2425 2426 bool Hash = getLexer().is(AsmToken::Hash); 2427 if (!Hash && getLexer().isNot(AsmToken::Integer)) { 2428 if (ShOp == AArch64_AM::LSL || ShOp == AArch64_AM::LSR || 2429 ShOp == AArch64_AM::ASR || ShOp == AArch64_AM::ROR || 2430 ShOp == AArch64_AM::MSL) { 2431 // We expect a number here. 2432 TokError("expected #imm after shift specifier"); 2433 return MatchOperand_ParseFail; 2434 } 2435 2436 // "extend" type operatoins don't need an immediate, #0 is implicit. 2437 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1); 2438 Operands.push_back( 2439 AArch64Operand::CreateShiftExtend(ShOp, 0, false, S, E, getContext())); 2440 return MatchOperand_Success; 2441 } 2442 2443 if (Hash) 2444 Parser.Lex(); // Eat the '#'. 2445 2446 // Make sure we do actually have a number or a parenthesized expression. 2447 SMLoc E = Parser.getTok().getLoc(); 2448 if (!Parser.getTok().is(AsmToken::Integer) && 2449 !Parser.getTok().is(AsmToken::LParen)) { 2450 Error(E, "expected integer shift amount"); 2451 return MatchOperand_ParseFail; 2452 } 2453 2454 const MCExpr *ImmVal; 2455 if (getParser().parseExpression(ImmVal)) 2456 return MatchOperand_ParseFail; 2457 2458 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 2459 if (!MCE) { 2460 Error(E, "expected constant '#imm' after shift specifier"); 2461 return MatchOperand_ParseFail; 2462 } 2463 2464 E = SMLoc::getFromPointer(getLoc().getPointer() - 1); 2465 Operands.push_back(AArch64Operand::CreateShiftExtend( 2466 ShOp, MCE->getValue(), true, S, E, getContext())); 2467 return MatchOperand_Success; 2468 } 2469 2470 /// parseSysAlias - The IC, DC, AT, and TLBI instructions are simple aliases for 2471 /// the SYS instruction. Parse them specially so that we create a SYS MCInst. 2472 bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc, 2473 OperandVector &Operands) { 2474 if (Name.find('.') != StringRef::npos) 2475 return TokError("invalid operand"); 2476 2477 Mnemonic = Name; 2478 Operands.push_back( 2479 AArch64Operand::CreateToken("sys", false, NameLoc, getContext())); 2480 2481 MCAsmParser &Parser = getParser(); 2482 const AsmToken &Tok = Parser.getTok(); 2483 StringRef Op = Tok.getString(); 2484 SMLoc S = Tok.getLoc(); 2485 2486 const MCExpr *Expr = nullptr; 2487 2488 #define SYS_ALIAS(op1, Cn, Cm, op2) \ 2489 do { \ 2490 Expr = MCConstantExpr::create(op1, getContext()); \ 2491 Operands.push_back( \ 2492 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext())); \ 2493 Operands.push_back( \ 2494 AArch64Operand::CreateSysCR(Cn, S, getLoc(), getContext())); \ 2495 Operands.push_back( \ 2496 AArch64Operand::CreateSysCR(Cm, S, getLoc(), getContext())); \ 2497 Expr = MCConstantExpr::create(op2, getContext()); \ 2498 Operands.push_back( \ 2499 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext())); \ 2500 } while (0) 2501 2502 if (Mnemonic == "ic") { 2503 if (!Op.compare_lower("ialluis")) { 2504 // SYS #0, C7, C1, #0 2505 SYS_ALIAS(0, 7, 1, 0); 2506 } else if (!Op.compare_lower("iallu")) { 2507 // SYS #0, C7, C5, #0 2508 SYS_ALIAS(0, 7, 5, 0); 2509 } else if (!Op.compare_lower("ivau")) { 2510 // SYS #3, C7, C5, #1 2511 SYS_ALIAS(3, 7, 5, 1); 2512 } else { 2513 return TokError("invalid operand for IC instruction"); 2514 } 2515 } else if (Mnemonic == "dc") { 2516 if (!Op.compare_lower("zva")) { 2517 // SYS #3, C7, C4, #1 2518 SYS_ALIAS(3, 7, 4, 1); 2519 } else if (!Op.compare_lower("ivac")) { 2520 // SYS #3, C7, C6, #1 2521 SYS_ALIAS(0, 7, 6, 1); 2522 } else if (!Op.compare_lower("isw")) { 2523 // SYS #0, C7, C6, #2 2524 SYS_ALIAS(0, 7, 6, 2); 2525 } else if (!Op.compare_lower("cvac")) { 2526 // SYS #3, C7, C10, #1 2527 SYS_ALIAS(3, 7, 10, 1); 2528 } else if (!Op.compare_lower("csw")) { 2529 // SYS #0, C7, C10, #2 2530 SYS_ALIAS(0, 7, 10, 2); 2531 } else if (!Op.compare_lower("cvau")) { 2532 // SYS #3, C7, C11, #1 2533 SYS_ALIAS(3, 7, 11, 1); 2534 } else if (!Op.compare_lower("civac")) { 2535 // SYS #3, C7, C14, #1 2536 SYS_ALIAS(3, 7, 14, 1); 2537 } else if (!Op.compare_lower("cisw")) { 2538 // SYS #0, C7, C14, #2 2539 SYS_ALIAS(0, 7, 14, 2); 2540 } else if (!Op.compare_lower("cvap")) { 2541 if (getSTI().getFeatureBits()[AArch64::HasV8_2aOps]) { 2542 // SYS #3, C7, C12, #1 2543 SYS_ALIAS(3, 7, 12, 1); 2544 } else { 2545 return TokError("DC CVAP requires ARMv8.2a"); 2546 } 2547 } else { 2548 return TokError("invalid operand for DC instruction"); 2549 } 2550 } else if (Mnemonic == "at") { 2551 if (!Op.compare_lower("s1e1r")) { 2552 // SYS #0, C7, C8, #0 2553 SYS_ALIAS(0, 7, 8, 0); 2554 } else if (!Op.compare_lower("s1e2r")) { 2555 // SYS #4, C7, C8, #0 2556 SYS_ALIAS(4, 7, 8, 0); 2557 } else if (!Op.compare_lower("s1e3r")) { 2558 // SYS #6, C7, C8, #0 2559 SYS_ALIAS(6, 7, 8, 0); 2560 } else if (!Op.compare_lower("s1e1w")) { 2561 // SYS #0, C7, C8, #1 2562 SYS_ALIAS(0, 7, 8, 1); 2563 } else if (!Op.compare_lower("s1e2w")) { 2564 // SYS #4, C7, C8, #1 2565 SYS_ALIAS(4, 7, 8, 1); 2566 } else if (!Op.compare_lower("s1e3w")) { 2567 // SYS #6, C7, C8, #1 2568 SYS_ALIAS(6, 7, 8, 1); 2569 } else if (!Op.compare_lower("s1e0r")) { 2570 // SYS #0, C7, C8, #3 2571 SYS_ALIAS(0, 7, 8, 2); 2572 } else if (!Op.compare_lower("s1e0w")) { 2573 // SYS #0, C7, C8, #3 2574 SYS_ALIAS(0, 7, 8, 3); 2575 } else if (!Op.compare_lower("s12e1r")) { 2576 // SYS #4, C7, C8, #4 2577 SYS_ALIAS(4, 7, 8, 4); 2578 } else if (!Op.compare_lower("s12e1w")) { 2579 // SYS #4, C7, C8, #5 2580 SYS_ALIAS(4, 7, 8, 5); 2581 } else if (!Op.compare_lower("s12e0r")) { 2582 // SYS #4, C7, C8, #6 2583 SYS_ALIAS(4, 7, 8, 6); 2584 } else if (!Op.compare_lower("s12e0w")) { 2585 // SYS #4, C7, C8, #7 2586 SYS_ALIAS(4, 7, 8, 7); 2587 } else if (!Op.compare_lower("s1e1rp")) { 2588 if (getSTI().getFeatureBits()[AArch64::HasV8_2aOps]) { 2589 // SYS #0, C7, C9, #0 2590 SYS_ALIAS(0, 7, 9, 0); 2591 } else { 2592 return TokError("AT S1E1RP requires ARMv8.2a"); 2593 } 2594 } else if (!Op.compare_lower("s1e1wp")) { 2595 if (getSTI().getFeatureBits()[AArch64::HasV8_2aOps]) { 2596 // SYS #0, C7, C9, #1 2597 SYS_ALIAS(0, 7, 9, 1); 2598 } else { 2599 return TokError("AT S1E1WP requires ARMv8.2a"); 2600 } 2601 } else { 2602 return TokError("invalid operand for AT instruction"); 2603 } 2604 } else if (Mnemonic == "tlbi") { 2605 if (!Op.compare_lower("vmalle1is")) { 2606 // SYS #0, C8, C3, #0 2607 SYS_ALIAS(0, 8, 3, 0); 2608 } else if (!Op.compare_lower("alle2is")) { 2609 // SYS #4, C8, C3, #0 2610 SYS_ALIAS(4, 8, 3, 0); 2611 } else if (!Op.compare_lower("alle3is")) { 2612 // SYS #6, C8, C3, #0 2613 SYS_ALIAS(6, 8, 3, 0); 2614 } else if (!Op.compare_lower("vae1is")) { 2615 // SYS #0, C8, C3, #1 2616 SYS_ALIAS(0, 8, 3, 1); 2617 } else if (!Op.compare_lower("vae2is")) { 2618 // SYS #4, C8, C3, #1 2619 SYS_ALIAS(4, 8, 3, 1); 2620 } else if (!Op.compare_lower("vae3is")) { 2621 // SYS #6, C8, C3, #1 2622 SYS_ALIAS(6, 8, 3, 1); 2623 } else if (!Op.compare_lower("aside1is")) { 2624 // SYS #0, C8, C3, #2 2625 SYS_ALIAS(0, 8, 3, 2); 2626 } else if (!Op.compare_lower("vaae1is")) { 2627 // SYS #0, C8, C3, #3 2628 SYS_ALIAS(0, 8, 3, 3); 2629 } else if (!Op.compare_lower("alle1is")) { 2630 // SYS #4, C8, C3, #4 2631 SYS_ALIAS(4, 8, 3, 4); 2632 } else if (!Op.compare_lower("vale1is")) { 2633 // SYS #0, C8, C3, #5 2634 SYS_ALIAS(0, 8, 3, 5); 2635 } else if (!Op.compare_lower("vaale1is")) { 2636 // SYS #0, C8, C3, #7 2637 SYS_ALIAS(0, 8, 3, 7); 2638 } else if (!Op.compare_lower("vmalle1")) { 2639 // SYS #0, C8, C7, #0 2640 SYS_ALIAS(0, 8, 7, 0); 2641 } else if (!Op.compare_lower("alle2")) { 2642 // SYS #4, C8, C7, #0 2643 SYS_ALIAS(4, 8, 7, 0); 2644 } else if (!Op.compare_lower("vale2is")) { 2645 // SYS #4, C8, C3, #5 2646 SYS_ALIAS(4, 8, 3, 5); 2647 } else if (!Op.compare_lower("vale3is")) { 2648 // SYS #6, C8, C3, #5 2649 SYS_ALIAS(6, 8, 3, 5); 2650 } else if (!Op.compare_lower("alle3")) { 2651 // SYS #6, C8, C7, #0 2652 SYS_ALIAS(6, 8, 7, 0); 2653 } else if (!Op.compare_lower("vae1")) { 2654 // SYS #0, C8, C7, #1 2655 SYS_ALIAS(0, 8, 7, 1); 2656 } else if (!Op.compare_lower("vae2")) { 2657 // SYS #4, C8, C7, #1 2658 SYS_ALIAS(4, 8, 7, 1); 2659 } else if (!Op.compare_lower("vae3")) { 2660 // SYS #6, C8, C7, #1 2661 SYS_ALIAS(6, 8, 7, 1); 2662 } else if (!Op.compare_lower("aside1")) { 2663 // SYS #0, C8, C7, #2 2664 SYS_ALIAS(0, 8, 7, 2); 2665 } else if (!Op.compare_lower("vaae1")) { 2666 // SYS #0, C8, C7, #3 2667 SYS_ALIAS(0, 8, 7, 3); 2668 } else if (!Op.compare_lower("alle1")) { 2669 // SYS #4, C8, C7, #4 2670 SYS_ALIAS(4, 8, 7, 4); 2671 } else if (!Op.compare_lower("vale1")) { 2672 // SYS #0, C8, C7, #5 2673 SYS_ALIAS(0, 8, 7, 5); 2674 } else if (!Op.compare_lower("vale2")) { 2675 // SYS #4, C8, C7, #5 2676 SYS_ALIAS(4, 8, 7, 5); 2677 } else if (!Op.compare_lower("vale3")) { 2678 // SYS #6, C8, C7, #5 2679 SYS_ALIAS(6, 8, 7, 5); 2680 } else if (!Op.compare_lower("vaale1")) { 2681 // SYS #0, C8, C7, #7 2682 SYS_ALIAS(0, 8, 7, 7); 2683 } else if (!Op.compare_lower("ipas2e1")) { 2684 // SYS #4, C8, C4, #1 2685 SYS_ALIAS(4, 8, 4, 1); 2686 } else if (!Op.compare_lower("ipas2le1")) { 2687 // SYS #4, C8, C4, #5 2688 SYS_ALIAS(4, 8, 4, 5); 2689 } else if (!Op.compare_lower("ipas2e1is")) { 2690 // SYS #4, C8, C4, #1 2691 SYS_ALIAS(4, 8, 0, 1); 2692 } else if (!Op.compare_lower("ipas2le1is")) { 2693 // SYS #4, C8, C4, #5 2694 SYS_ALIAS(4, 8, 0, 5); 2695 } else if (!Op.compare_lower("vmalls12e1")) { 2696 // SYS #4, C8, C7, #6 2697 SYS_ALIAS(4, 8, 7, 6); 2698 } else if (!Op.compare_lower("vmalls12e1is")) { 2699 // SYS #4, C8, C3, #6 2700 SYS_ALIAS(4, 8, 3, 6); 2701 } else { 2702 return TokError("invalid operand for TLBI instruction"); 2703 } 2704 } 2705 2706 #undef SYS_ALIAS 2707 2708 Parser.Lex(); // Eat operand. 2709 2710 bool ExpectRegister = (Op.lower().find("all") == StringRef::npos); 2711 bool HasRegister = false; 2712 2713 // Check for the optional register operand. 2714 if (getLexer().is(AsmToken::Comma)) { 2715 Parser.Lex(); // Eat comma. 2716 2717 if (Tok.isNot(AsmToken::Identifier) || parseRegister(Operands)) 2718 return TokError("expected register operand"); 2719 2720 HasRegister = true; 2721 } 2722 2723 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2724 Parser.eatToEndOfStatement(); 2725 return TokError("unexpected token in argument list"); 2726 } 2727 2728 if (ExpectRegister && !HasRegister) { 2729 return TokError("specified " + Mnemonic + " op requires a register"); 2730 } 2731 else if (!ExpectRegister && HasRegister) { 2732 return TokError("specified " + Mnemonic + " op does not use a register"); 2733 } 2734 2735 Parser.Lex(); // Consume the EndOfStatement 2736 return false; 2737 } 2738 2739 AArch64AsmParser::OperandMatchResultTy 2740 AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) { 2741 MCAsmParser &Parser = getParser(); 2742 const AsmToken &Tok = Parser.getTok(); 2743 2744 // Can be either a #imm style literal or an option name 2745 bool Hash = Tok.is(AsmToken::Hash); 2746 if (Hash || Tok.is(AsmToken::Integer)) { 2747 // Immediate operand. 2748 if (Hash) 2749 Parser.Lex(); // Eat the '#' 2750 const MCExpr *ImmVal; 2751 SMLoc ExprLoc = getLoc(); 2752 if (getParser().parseExpression(ImmVal)) 2753 return MatchOperand_ParseFail; 2754 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 2755 if (!MCE) { 2756 Error(ExprLoc, "immediate value expected for barrier operand"); 2757 return MatchOperand_ParseFail; 2758 } 2759 if (MCE->getValue() < 0 || MCE->getValue() > 15) { 2760 Error(ExprLoc, "barrier operand out of range"); 2761 return MatchOperand_ParseFail; 2762 } 2763 bool Valid; 2764 auto Mapper = AArch64DB::DBarrierMapper(); 2765 StringRef Name = 2766 Mapper.toString(MCE->getValue(), getSTI().getFeatureBits(), Valid); 2767 Operands.push_back( AArch64Operand::CreateBarrier(MCE->getValue(), Name, 2768 ExprLoc, getContext())); 2769 return MatchOperand_Success; 2770 } 2771 2772 if (Tok.isNot(AsmToken::Identifier)) { 2773 TokError("invalid operand for instruction"); 2774 return MatchOperand_ParseFail; 2775 } 2776 2777 bool Valid; 2778 auto Mapper = AArch64DB::DBarrierMapper(); 2779 unsigned Opt = 2780 Mapper.fromString(Tok.getString(), getSTI().getFeatureBits(), Valid); 2781 if (!Valid) { 2782 TokError("invalid barrier option name"); 2783 return MatchOperand_ParseFail; 2784 } 2785 2786 // The only valid named option for ISB is 'sy' 2787 if (Mnemonic == "isb" && Opt != AArch64DB::SY) { 2788 TokError("'sy' or #imm operand expected"); 2789 return MatchOperand_ParseFail; 2790 } 2791 2792 Operands.push_back( AArch64Operand::CreateBarrier(Opt, Tok.getString(), 2793 getLoc(), getContext())); 2794 Parser.Lex(); // Consume the option 2795 2796 return MatchOperand_Success; 2797 } 2798 2799 AArch64AsmParser::OperandMatchResultTy 2800 AArch64AsmParser::tryParseSysReg(OperandVector &Operands) { 2801 MCAsmParser &Parser = getParser(); 2802 const AsmToken &Tok = Parser.getTok(); 2803 2804 if (Tok.isNot(AsmToken::Identifier)) 2805 return MatchOperand_NoMatch; 2806 2807 bool IsKnown; 2808 auto MRSMapper = AArch64SysReg::MRSMapper(); 2809 uint32_t MRSReg = MRSMapper.fromString(Tok.getString(), 2810 getSTI().getFeatureBits(), IsKnown); 2811 assert(IsKnown == (MRSReg != -1U) && 2812 "register should be -1 if and only if it's unknown"); 2813 2814 auto MSRMapper = AArch64SysReg::MSRMapper(); 2815 uint32_t MSRReg = MSRMapper.fromString(Tok.getString(), 2816 getSTI().getFeatureBits(), IsKnown); 2817 assert(IsKnown == (MSRReg != -1U) && 2818 "register should be -1 if and only if it's unknown"); 2819 2820 auto PStateMapper = AArch64PState::PStateMapper(); 2821 uint32_t PStateField = 2822 PStateMapper.fromString(Tok.getString(), 2823 getSTI().getFeatureBits(), IsKnown); 2824 assert(IsKnown == (PStateField != -1U) && 2825 "register should be -1 if and only if it's unknown"); 2826 2827 Operands.push_back(AArch64Operand::CreateSysReg( 2828 Tok.getString(), getLoc(), MRSReg, MSRReg, PStateField, getContext())); 2829 Parser.Lex(); // Eat identifier 2830 2831 return MatchOperand_Success; 2832 } 2833 2834 /// tryParseVectorRegister - Parse a vector register operand. 2835 bool AArch64AsmParser::tryParseVectorRegister(OperandVector &Operands) { 2836 MCAsmParser &Parser = getParser(); 2837 if (Parser.getTok().isNot(AsmToken::Identifier)) 2838 return true; 2839 2840 SMLoc S = getLoc(); 2841 // Check for a vector register specifier first. 2842 StringRef Kind; 2843 int64_t Reg = tryMatchVectorRegister(Kind, false); 2844 if (Reg == -1) 2845 return true; 2846 Operands.push_back( 2847 AArch64Operand::CreateReg(Reg, true, S, getLoc(), getContext())); 2848 // If there was an explicit qualifier, that goes on as a literal text 2849 // operand. 2850 if (!Kind.empty()) 2851 Operands.push_back( 2852 AArch64Operand::CreateToken(Kind, false, S, getContext())); 2853 2854 // If there is an index specifier following the register, parse that too. 2855 if (Parser.getTok().is(AsmToken::LBrac)) { 2856 SMLoc SIdx = getLoc(); 2857 Parser.Lex(); // Eat left bracket token. 2858 2859 const MCExpr *ImmVal; 2860 if (getParser().parseExpression(ImmVal)) 2861 return false; 2862 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 2863 if (!MCE) { 2864 TokError("immediate value expected for vector index"); 2865 return false; 2866 } 2867 2868 SMLoc E = getLoc(); 2869 if (Parser.getTok().isNot(AsmToken::RBrac)) { 2870 Error(E, "']' expected"); 2871 return false; 2872 } 2873 2874 Parser.Lex(); // Eat right bracket token. 2875 2876 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx, 2877 E, getContext())); 2878 } 2879 2880 return false; 2881 } 2882 2883 /// parseRegister - Parse a non-vector register operand. 2884 bool AArch64AsmParser::parseRegister(OperandVector &Operands) { 2885 MCAsmParser &Parser = getParser(); 2886 SMLoc S = getLoc(); 2887 // Try for a vector register. 2888 if (!tryParseVectorRegister(Operands)) 2889 return false; 2890 2891 // Try for a scalar register. 2892 int64_t Reg = tryParseRegister(); 2893 if (Reg == -1) 2894 return true; 2895 Operands.push_back( 2896 AArch64Operand::CreateReg(Reg, false, S, getLoc(), getContext())); 2897 2898 // A small number of instructions (FMOVXDhighr, for example) have "[1]" 2899 // as a string token in the instruction itself. 2900 if (getLexer().getKind() == AsmToken::LBrac) { 2901 SMLoc LBracS = getLoc(); 2902 Parser.Lex(); 2903 const AsmToken &Tok = Parser.getTok(); 2904 if (Tok.is(AsmToken::Integer)) { 2905 SMLoc IntS = getLoc(); 2906 int64_t Val = Tok.getIntVal(); 2907 if (Val == 1) { 2908 Parser.Lex(); 2909 if (getLexer().getKind() == AsmToken::RBrac) { 2910 SMLoc RBracS = getLoc(); 2911 Parser.Lex(); 2912 Operands.push_back( 2913 AArch64Operand::CreateToken("[", false, LBracS, getContext())); 2914 Operands.push_back( 2915 AArch64Operand::CreateToken("1", false, IntS, getContext())); 2916 Operands.push_back( 2917 AArch64Operand::CreateToken("]", false, RBracS, getContext())); 2918 return false; 2919 } 2920 } 2921 } 2922 } 2923 2924 return false; 2925 } 2926 2927 bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) { 2928 MCAsmParser &Parser = getParser(); 2929 bool HasELFModifier = false; 2930 AArch64MCExpr::VariantKind RefKind; 2931 2932 if (Parser.getTok().is(AsmToken::Colon)) { 2933 Parser.Lex(); // Eat ':" 2934 HasELFModifier = true; 2935 2936 if (Parser.getTok().isNot(AsmToken::Identifier)) { 2937 Error(Parser.getTok().getLoc(), 2938 "expect relocation specifier in operand after ':'"); 2939 return true; 2940 } 2941 2942 std::string LowerCase = Parser.getTok().getIdentifier().lower(); 2943 RefKind = StringSwitch<AArch64MCExpr::VariantKind>(LowerCase) 2944 .Case("lo12", AArch64MCExpr::VK_LO12) 2945 .Case("abs_g3", AArch64MCExpr::VK_ABS_G3) 2946 .Case("abs_g2", AArch64MCExpr::VK_ABS_G2) 2947 .Case("abs_g2_s", AArch64MCExpr::VK_ABS_G2_S) 2948 .Case("abs_g2_nc", AArch64MCExpr::VK_ABS_G2_NC) 2949 .Case("abs_g1", AArch64MCExpr::VK_ABS_G1) 2950 .Case("abs_g1_s", AArch64MCExpr::VK_ABS_G1_S) 2951 .Case("abs_g1_nc", AArch64MCExpr::VK_ABS_G1_NC) 2952 .Case("abs_g0", AArch64MCExpr::VK_ABS_G0) 2953 .Case("abs_g0_s", AArch64MCExpr::VK_ABS_G0_S) 2954 .Case("abs_g0_nc", AArch64MCExpr::VK_ABS_G0_NC) 2955 .Case("dtprel_g2", AArch64MCExpr::VK_DTPREL_G2) 2956 .Case("dtprel_g1", AArch64MCExpr::VK_DTPREL_G1) 2957 .Case("dtprel_g1_nc", AArch64MCExpr::VK_DTPREL_G1_NC) 2958 .Case("dtprel_g0", AArch64MCExpr::VK_DTPREL_G0) 2959 .Case("dtprel_g0_nc", AArch64MCExpr::VK_DTPREL_G0_NC) 2960 .Case("dtprel_hi12", AArch64MCExpr::VK_DTPREL_HI12) 2961 .Case("dtprel_lo12", AArch64MCExpr::VK_DTPREL_LO12) 2962 .Case("dtprel_lo12_nc", AArch64MCExpr::VK_DTPREL_LO12_NC) 2963 .Case("tprel_g2", AArch64MCExpr::VK_TPREL_G2) 2964 .Case("tprel_g1", AArch64MCExpr::VK_TPREL_G1) 2965 .Case("tprel_g1_nc", AArch64MCExpr::VK_TPREL_G1_NC) 2966 .Case("tprel_g0", AArch64MCExpr::VK_TPREL_G0) 2967 .Case("tprel_g0_nc", AArch64MCExpr::VK_TPREL_G0_NC) 2968 .Case("tprel_hi12", AArch64MCExpr::VK_TPREL_HI12) 2969 .Case("tprel_lo12", AArch64MCExpr::VK_TPREL_LO12) 2970 .Case("tprel_lo12_nc", AArch64MCExpr::VK_TPREL_LO12_NC) 2971 .Case("tlsdesc_lo12", AArch64MCExpr::VK_TLSDESC_LO12) 2972 .Case("got", AArch64MCExpr::VK_GOT_PAGE) 2973 .Case("got_lo12", AArch64MCExpr::VK_GOT_LO12) 2974 .Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE) 2975 .Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC) 2976 .Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1) 2977 .Case("gottprel_g0_nc", AArch64MCExpr::VK_GOTTPREL_G0_NC) 2978 .Case("tlsdesc", AArch64MCExpr::VK_TLSDESC_PAGE) 2979 .Default(AArch64MCExpr::VK_INVALID); 2980 2981 if (RefKind == AArch64MCExpr::VK_INVALID) { 2982 Error(Parser.getTok().getLoc(), 2983 "expect relocation specifier in operand after ':'"); 2984 return true; 2985 } 2986 2987 Parser.Lex(); // Eat identifier 2988 2989 if (Parser.getTok().isNot(AsmToken::Colon)) { 2990 Error(Parser.getTok().getLoc(), "expect ':' after relocation specifier"); 2991 return true; 2992 } 2993 Parser.Lex(); // Eat ':' 2994 } 2995 2996 if (getParser().parseExpression(ImmVal)) 2997 return true; 2998 2999 if (HasELFModifier) 3000 ImmVal = AArch64MCExpr::create(ImmVal, RefKind, getContext()); 3001 3002 return false; 3003 } 3004 3005 /// parseVectorList - Parse a vector list operand for AdvSIMD instructions. 3006 bool AArch64AsmParser::parseVectorList(OperandVector &Operands) { 3007 MCAsmParser &Parser = getParser(); 3008 assert(Parser.getTok().is(AsmToken::LCurly) && "Token is not a Left Bracket"); 3009 SMLoc S = getLoc(); 3010 Parser.Lex(); // Eat left bracket token. 3011 StringRef Kind; 3012 int64_t FirstReg = tryMatchVectorRegister(Kind, true); 3013 if (FirstReg == -1) 3014 return true; 3015 int64_t PrevReg = FirstReg; 3016 unsigned Count = 1; 3017 3018 if (Parser.getTok().is(AsmToken::Minus)) { 3019 Parser.Lex(); // Eat the minus. 3020 3021 SMLoc Loc = getLoc(); 3022 StringRef NextKind; 3023 int64_t Reg = tryMatchVectorRegister(NextKind, true); 3024 if (Reg == -1) 3025 return true; 3026 // Any Kind suffices must match on all regs in the list. 3027 if (Kind != NextKind) 3028 return Error(Loc, "mismatched register size suffix"); 3029 3030 unsigned Space = (PrevReg < Reg) ? (Reg - PrevReg) : (Reg + 32 - PrevReg); 3031 3032 if (Space == 0 || Space > 3) { 3033 return Error(Loc, "invalid number of vectors"); 3034 } 3035 3036 Count += Space; 3037 } 3038 else { 3039 while (Parser.getTok().is(AsmToken::Comma)) { 3040 Parser.Lex(); // Eat the comma token. 3041 3042 SMLoc Loc = getLoc(); 3043 StringRef NextKind; 3044 int64_t Reg = tryMatchVectorRegister(NextKind, true); 3045 if (Reg == -1) 3046 return true; 3047 // Any Kind suffices must match on all regs in the list. 3048 if (Kind != NextKind) 3049 return Error(Loc, "mismatched register size suffix"); 3050 3051 // Registers must be incremental (with wraparound at 31) 3052 if (getContext().getRegisterInfo()->getEncodingValue(Reg) != 3053 (getContext().getRegisterInfo()->getEncodingValue(PrevReg) + 1) % 32) 3054 return Error(Loc, "registers must be sequential"); 3055 3056 PrevReg = Reg; 3057 ++Count; 3058 } 3059 } 3060 3061 if (Parser.getTok().isNot(AsmToken::RCurly)) 3062 return Error(getLoc(), "'}' expected"); 3063 Parser.Lex(); // Eat the '}' token. 3064 3065 if (Count > 4) 3066 return Error(S, "invalid number of vectors"); 3067 3068 unsigned NumElements = 0; 3069 char ElementKind = 0; 3070 if (!Kind.empty()) 3071 parseValidVectorKind(Kind, NumElements, ElementKind); 3072 3073 Operands.push_back(AArch64Operand::CreateVectorList( 3074 FirstReg, Count, NumElements, ElementKind, S, getLoc(), getContext())); 3075 3076 // If there is an index specifier following the list, parse that too. 3077 if (Parser.getTok().is(AsmToken::LBrac)) { 3078 SMLoc SIdx = getLoc(); 3079 Parser.Lex(); // Eat left bracket token. 3080 3081 const MCExpr *ImmVal; 3082 if (getParser().parseExpression(ImmVal)) 3083 return false; 3084 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 3085 if (!MCE) { 3086 TokError("immediate value expected for vector index"); 3087 return false; 3088 } 3089 3090 SMLoc E = getLoc(); 3091 if (Parser.getTok().isNot(AsmToken::RBrac)) { 3092 Error(E, "']' expected"); 3093 return false; 3094 } 3095 3096 Parser.Lex(); // Eat right bracket token. 3097 3098 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx, 3099 E, getContext())); 3100 } 3101 return false; 3102 } 3103 3104 AArch64AsmParser::OperandMatchResultTy 3105 AArch64AsmParser::tryParseGPR64sp0Operand(OperandVector &Operands) { 3106 MCAsmParser &Parser = getParser(); 3107 const AsmToken &Tok = Parser.getTok(); 3108 if (!Tok.is(AsmToken::Identifier)) 3109 return MatchOperand_NoMatch; 3110 3111 unsigned RegNum = matchRegisterNameAlias(Tok.getString().lower(), false); 3112 3113 MCContext &Ctx = getContext(); 3114 const MCRegisterInfo *RI = Ctx.getRegisterInfo(); 3115 if (!RI->getRegClass(AArch64::GPR64spRegClassID).contains(RegNum)) 3116 return MatchOperand_NoMatch; 3117 3118 SMLoc S = getLoc(); 3119 Parser.Lex(); // Eat register 3120 3121 if (Parser.getTok().isNot(AsmToken::Comma)) { 3122 Operands.push_back( 3123 AArch64Operand::CreateReg(RegNum, false, S, getLoc(), Ctx)); 3124 return MatchOperand_Success; 3125 } 3126 Parser.Lex(); // Eat comma. 3127 3128 if (Parser.getTok().is(AsmToken::Hash)) 3129 Parser.Lex(); // Eat hash 3130 3131 if (Parser.getTok().isNot(AsmToken::Integer)) { 3132 Error(getLoc(), "index must be absent or #0"); 3133 return MatchOperand_ParseFail; 3134 } 3135 3136 const MCExpr *ImmVal; 3137 if (Parser.parseExpression(ImmVal) || !isa<MCConstantExpr>(ImmVal) || 3138 cast<MCConstantExpr>(ImmVal)->getValue() != 0) { 3139 Error(getLoc(), "index must be absent or #0"); 3140 return MatchOperand_ParseFail; 3141 } 3142 3143 Operands.push_back( 3144 AArch64Operand::CreateReg(RegNum, false, S, getLoc(), Ctx)); 3145 return MatchOperand_Success; 3146 } 3147 3148 /// parseOperand - Parse a arm instruction operand. For now this parses the 3149 /// operand regardless of the mnemonic. 3150 bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode, 3151 bool invertCondCode) { 3152 MCAsmParser &Parser = getParser(); 3153 // Check if the current operand has a custom associated parser, if so, try to 3154 // custom parse the operand, or fallback to the general approach. 3155 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 3156 if (ResTy == MatchOperand_Success) 3157 return false; 3158 // If there wasn't a custom match, try the generic matcher below. Otherwise, 3159 // there was a match, but an error occurred, in which case, just return that 3160 // the operand parsing failed. 3161 if (ResTy == MatchOperand_ParseFail) 3162 return true; 3163 3164 // Nothing custom, so do general case parsing. 3165 SMLoc S, E; 3166 switch (getLexer().getKind()) { 3167 default: { 3168 SMLoc S = getLoc(); 3169 const MCExpr *Expr; 3170 if (parseSymbolicImmVal(Expr)) 3171 return Error(S, "invalid operand"); 3172 3173 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1); 3174 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext())); 3175 return false; 3176 } 3177 case AsmToken::LBrac: { 3178 SMLoc Loc = Parser.getTok().getLoc(); 3179 Operands.push_back(AArch64Operand::CreateToken("[", false, Loc, 3180 getContext())); 3181 Parser.Lex(); // Eat '[' 3182 3183 // There's no comma after a '[', so we can parse the next operand 3184 // immediately. 3185 return parseOperand(Operands, false, false); 3186 } 3187 case AsmToken::LCurly: 3188 return parseVectorList(Operands); 3189 case AsmToken::Identifier: { 3190 // If we're expecting a Condition Code operand, then just parse that. 3191 if (isCondCode) 3192 return parseCondCode(Operands, invertCondCode); 3193 3194 // If it's a register name, parse it. 3195 if (!parseRegister(Operands)) 3196 return false; 3197 3198 // This could be an optional "shift" or "extend" operand. 3199 OperandMatchResultTy GotShift = tryParseOptionalShiftExtend(Operands); 3200 // We can only continue if no tokens were eaten. 3201 if (GotShift != MatchOperand_NoMatch) 3202 return GotShift; 3203 3204 // This was not a register so parse other operands that start with an 3205 // identifier (like labels) as expressions and create them as immediates. 3206 const MCExpr *IdVal; 3207 S = getLoc(); 3208 if (getParser().parseExpression(IdVal)) 3209 return true; 3210 3211 E = SMLoc::getFromPointer(getLoc().getPointer() - 1); 3212 Operands.push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext())); 3213 return false; 3214 } 3215 case AsmToken::Integer: 3216 case AsmToken::Real: 3217 case AsmToken::Hash: { 3218 // #42 -> immediate. 3219 S = getLoc(); 3220 if (getLexer().is(AsmToken::Hash)) 3221 Parser.Lex(); 3222 3223 // Parse a negative sign 3224 bool isNegative = false; 3225 if (Parser.getTok().is(AsmToken::Minus)) { 3226 isNegative = true; 3227 // We need to consume this token only when we have a Real, otherwise 3228 // we let parseSymbolicImmVal take care of it 3229 if (Parser.getLexer().peekTok().is(AsmToken::Real)) 3230 Parser.Lex(); 3231 } 3232 3233 // The only Real that should come through here is a literal #0.0 for 3234 // the fcmp[e] r, #0.0 instructions. They expect raw token operands, 3235 // so convert the value. 3236 const AsmToken &Tok = Parser.getTok(); 3237 if (Tok.is(AsmToken::Real)) { 3238 APFloat RealVal(APFloat::IEEEdouble, Tok.getString()); 3239 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 3240 if (Mnemonic != "fcmp" && Mnemonic != "fcmpe" && Mnemonic != "fcmeq" && 3241 Mnemonic != "fcmge" && Mnemonic != "fcmgt" && Mnemonic != "fcmle" && 3242 Mnemonic != "fcmlt") 3243 return TokError("unexpected floating point literal"); 3244 else if (IntVal != 0 || isNegative) 3245 return TokError("expected floating-point constant #0.0"); 3246 Parser.Lex(); // Eat the token. 3247 3248 Operands.push_back( 3249 AArch64Operand::CreateToken("#0", false, S, getContext())); 3250 Operands.push_back( 3251 AArch64Operand::CreateToken(".0", false, S, getContext())); 3252 return false; 3253 } 3254 3255 const MCExpr *ImmVal; 3256 if (parseSymbolicImmVal(ImmVal)) 3257 return true; 3258 3259 E = SMLoc::getFromPointer(getLoc().getPointer() - 1); 3260 Operands.push_back(AArch64Operand::CreateImm(ImmVal, S, E, getContext())); 3261 return false; 3262 } 3263 case AsmToken::Equal: { 3264 SMLoc Loc = Parser.getTok().getLoc(); 3265 if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val) 3266 return Error(Loc, "unexpected token in operand"); 3267 Parser.Lex(); // Eat '=' 3268 const MCExpr *SubExprVal; 3269 if (getParser().parseExpression(SubExprVal)) 3270 return true; 3271 3272 if (Operands.size() < 2 || 3273 !static_cast<AArch64Operand &>(*Operands[1]).isReg()) 3274 return Error(Loc, "Only valid when first operand is register"); 3275 3276 bool IsXReg = 3277 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( 3278 Operands[1]->getReg()); 3279 3280 MCContext& Ctx = getContext(); 3281 E = SMLoc::getFromPointer(Loc.getPointer() - 1); 3282 // If the op is an imm and can be fit into a mov, then replace ldr with mov. 3283 if (isa<MCConstantExpr>(SubExprVal)) { 3284 uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue(); 3285 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16; 3286 while(Imm > 0xFFFF && countTrailingZeros(Imm) >= 16) { 3287 ShiftAmt += 16; 3288 Imm >>= 16; 3289 } 3290 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) { 3291 Operands[0] = AArch64Operand::CreateToken("movz", false, Loc, Ctx); 3292 Operands.push_back(AArch64Operand::CreateImm( 3293 MCConstantExpr::create(Imm, Ctx), S, E, Ctx)); 3294 if (ShiftAmt) 3295 Operands.push_back(AArch64Operand::CreateShiftExtend(AArch64_AM::LSL, 3296 ShiftAmt, true, S, E, Ctx)); 3297 return false; 3298 } 3299 APInt Simm = APInt(64, Imm << ShiftAmt); 3300 // check if the immediate is an unsigned or signed 32-bit int for W regs 3301 if (!IsXReg && !(Simm.isIntN(32) || Simm.isSignedIntN(32))) 3302 return Error(Loc, "Immediate too large for register"); 3303 } 3304 // If it is a label or an imm that cannot fit in a movz, put it into CP. 3305 const MCExpr *CPLoc = 3306 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc); 3307 Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx)); 3308 return false; 3309 } 3310 } 3311 } 3312 3313 /// ParseInstruction - Parse an AArch64 instruction mnemonic followed by its 3314 /// operands. 3315 bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info, 3316 StringRef Name, SMLoc NameLoc, 3317 OperandVector &Operands) { 3318 MCAsmParser &Parser = getParser(); 3319 Name = StringSwitch<StringRef>(Name.lower()) 3320 .Case("beq", "b.eq") 3321 .Case("bne", "b.ne") 3322 .Case("bhs", "b.hs") 3323 .Case("bcs", "b.cs") 3324 .Case("blo", "b.lo") 3325 .Case("bcc", "b.cc") 3326 .Case("bmi", "b.mi") 3327 .Case("bpl", "b.pl") 3328 .Case("bvs", "b.vs") 3329 .Case("bvc", "b.vc") 3330 .Case("bhi", "b.hi") 3331 .Case("bls", "b.ls") 3332 .Case("bge", "b.ge") 3333 .Case("blt", "b.lt") 3334 .Case("bgt", "b.gt") 3335 .Case("ble", "b.le") 3336 .Case("bal", "b.al") 3337 .Case("bnv", "b.nv") 3338 .Default(Name); 3339 3340 // First check for the AArch64-specific .req directive. 3341 if (Parser.getTok().is(AsmToken::Identifier) && 3342 Parser.getTok().getIdentifier() == ".req") { 3343 parseDirectiveReq(Name, NameLoc); 3344 // We always return 'error' for this, as we're done with this 3345 // statement and don't need to match the 'instruction." 3346 return true; 3347 } 3348 3349 // Create the leading tokens for the mnemonic, split by '.' characters. 3350 size_t Start = 0, Next = Name.find('.'); 3351 StringRef Head = Name.slice(Start, Next); 3352 3353 // IC, DC, AT, and TLBI instructions are aliases for the SYS instruction. 3354 if (Head == "ic" || Head == "dc" || Head == "at" || Head == "tlbi") { 3355 bool IsError = parseSysAlias(Head, NameLoc, Operands); 3356 if (IsError && getLexer().isNot(AsmToken::EndOfStatement)) 3357 Parser.eatToEndOfStatement(); 3358 return IsError; 3359 } 3360 3361 Operands.push_back( 3362 AArch64Operand::CreateToken(Head, false, NameLoc, getContext())); 3363 Mnemonic = Head; 3364 3365 // Handle condition codes for a branch mnemonic 3366 if (Head == "b" && Next != StringRef::npos) { 3367 Start = Next; 3368 Next = Name.find('.', Start + 1); 3369 Head = Name.slice(Start + 1, Next); 3370 3371 SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() + 3372 (Head.data() - Name.data())); 3373 AArch64CC::CondCode CC = parseCondCodeString(Head); 3374 if (CC == AArch64CC::Invalid) 3375 return Error(SuffixLoc, "invalid condition code"); 3376 Operands.push_back( 3377 AArch64Operand::CreateToken(".", true, SuffixLoc, getContext())); 3378 Operands.push_back( 3379 AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc, getContext())); 3380 } 3381 3382 // Add the remaining tokens in the mnemonic. 3383 while (Next != StringRef::npos) { 3384 Start = Next; 3385 Next = Name.find('.', Start + 1); 3386 Head = Name.slice(Start, Next); 3387 SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() + 3388 (Head.data() - Name.data()) + 1); 3389 Operands.push_back( 3390 AArch64Operand::CreateToken(Head, true, SuffixLoc, getContext())); 3391 } 3392 3393 // Conditional compare instructions have a Condition Code operand, which needs 3394 // to be parsed and an immediate operand created. 3395 bool condCodeFourthOperand = 3396 (Head == "ccmp" || Head == "ccmn" || Head == "fccmp" || 3397 Head == "fccmpe" || Head == "fcsel" || Head == "csel" || 3398 Head == "csinc" || Head == "csinv" || Head == "csneg"); 3399 3400 // These instructions are aliases to some of the conditional select 3401 // instructions. However, the condition code is inverted in the aliased 3402 // instruction. 3403 // 3404 // FIXME: Is this the correct way to handle these? Or should the parser 3405 // generate the aliased instructions directly? 3406 bool condCodeSecondOperand = (Head == "cset" || Head == "csetm"); 3407 bool condCodeThirdOperand = 3408 (Head == "cinc" || Head == "cinv" || Head == "cneg"); 3409 3410 // Read the remaining operands. 3411 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3412 // Read the first operand. 3413 if (parseOperand(Operands, false, false)) { 3414 Parser.eatToEndOfStatement(); 3415 return true; 3416 } 3417 3418 unsigned N = 2; 3419 while (getLexer().is(AsmToken::Comma)) { 3420 Parser.Lex(); // Eat the comma. 3421 3422 // Parse and remember the operand. 3423 if (parseOperand(Operands, (N == 4 && condCodeFourthOperand) || 3424 (N == 3 && condCodeThirdOperand) || 3425 (N == 2 && condCodeSecondOperand), 3426 condCodeSecondOperand || condCodeThirdOperand)) { 3427 Parser.eatToEndOfStatement(); 3428 return true; 3429 } 3430 3431 // After successfully parsing some operands there are two special cases to 3432 // consider (i.e. notional operands not separated by commas). Both are due 3433 // to memory specifiers: 3434 // + An RBrac will end an address for load/store/prefetch 3435 // + An '!' will indicate a pre-indexed operation. 3436 // 3437 // It's someone else's responsibility to make sure these tokens are sane 3438 // in the given context! 3439 if (Parser.getTok().is(AsmToken::RBrac)) { 3440 SMLoc Loc = Parser.getTok().getLoc(); 3441 Operands.push_back(AArch64Operand::CreateToken("]", false, Loc, 3442 getContext())); 3443 Parser.Lex(); 3444 } 3445 3446 if (Parser.getTok().is(AsmToken::Exclaim)) { 3447 SMLoc Loc = Parser.getTok().getLoc(); 3448 Operands.push_back(AArch64Operand::CreateToken("!", false, Loc, 3449 getContext())); 3450 Parser.Lex(); 3451 } 3452 3453 ++N; 3454 } 3455 } 3456 3457 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3458 SMLoc Loc = Parser.getTok().getLoc(); 3459 Parser.eatToEndOfStatement(); 3460 return Error(Loc, "unexpected token in argument list"); 3461 } 3462 3463 Parser.Lex(); // Consume the EndOfStatement 3464 return false; 3465 } 3466 3467 // FIXME: This entire function is a giant hack to provide us with decent 3468 // operand range validation/diagnostics until TableGen/MC can be extended 3469 // to support autogeneration of this kind of validation. 3470 bool AArch64AsmParser::validateInstruction(MCInst &Inst, 3471 SmallVectorImpl<SMLoc> &Loc) { 3472 const MCRegisterInfo *RI = getContext().getRegisterInfo(); 3473 // Check for indexed addressing modes w/ the base register being the 3474 // same as a destination/source register or pair load where 3475 // the Rt == Rt2. All of those are undefined behaviour. 3476 switch (Inst.getOpcode()) { 3477 case AArch64::LDPSWpre: 3478 case AArch64::LDPWpost: 3479 case AArch64::LDPWpre: 3480 case AArch64::LDPXpost: 3481 case AArch64::LDPXpre: { 3482 unsigned Rt = Inst.getOperand(1).getReg(); 3483 unsigned Rt2 = Inst.getOperand(2).getReg(); 3484 unsigned Rn = Inst.getOperand(3).getReg(); 3485 if (RI->isSubRegisterEq(Rn, Rt)) 3486 return Error(Loc[0], "unpredictable LDP instruction, writeback base " 3487 "is also a destination"); 3488 if (RI->isSubRegisterEq(Rn, Rt2)) 3489 return Error(Loc[1], "unpredictable LDP instruction, writeback base " 3490 "is also a destination"); 3491 // FALLTHROUGH 3492 } 3493 case AArch64::LDPDi: 3494 case AArch64::LDPQi: 3495 case AArch64::LDPSi: 3496 case AArch64::LDPSWi: 3497 case AArch64::LDPWi: 3498 case AArch64::LDPXi: { 3499 unsigned Rt = Inst.getOperand(0).getReg(); 3500 unsigned Rt2 = Inst.getOperand(1).getReg(); 3501 if (Rt == Rt2) 3502 return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt"); 3503 break; 3504 } 3505 case AArch64::LDPDpost: 3506 case AArch64::LDPDpre: 3507 case AArch64::LDPQpost: 3508 case AArch64::LDPQpre: 3509 case AArch64::LDPSpost: 3510 case AArch64::LDPSpre: 3511 case AArch64::LDPSWpost: { 3512 unsigned Rt = Inst.getOperand(1).getReg(); 3513 unsigned Rt2 = Inst.getOperand(2).getReg(); 3514 if (Rt == Rt2) 3515 return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt"); 3516 break; 3517 } 3518 case AArch64::STPDpost: 3519 case AArch64::STPDpre: 3520 case AArch64::STPQpost: 3521 case AArch64::STPQpre: 3522 case AArch64::STPSpost: 3523 case AArch64::STPSpre: 3524 case AArch64::STPWpost: 3525 case AArch64::STPWpre: 3526 case AArch64::STPXpost: 3527 case AArch64::STPXpre: { 3528 unsigned Rt = Inst.getOperand(1).getReg(); 3529 unsigned Rt2 = Inst.getOperand(2).getReg(); 3530 unsigned Rn = Inst.getOperand(3).getReg(); 3531 if (RI->isSubRegisterEq(Rn, Rt)) 3532 return Error(Loc[0], "unpredictable STP instruction, writeback base " 3533 "is also a source"); 3534 if (RI->isSubRegisterEq(Rn, Rt2)) 3535 return Error(Loc[1], "unpredictable STP instruction, writeback base " 3536 "is also a source"); 3537 break; 3538 } 3539 case AArch64::LDRBBpre: 3540 case AArch64::LDRBpre: 3541 case AArch64::LDRHHpre: 3542 case AArch64::LDRHpre: 3543 case AArch64::LDRSBWpre: 3544 case AArch64::LDRSBXpre: 3545 case AArch64::LDRSHWpre: 3546 case AArch64::LDRSHXpre: 3547 case AArch64::LDRSWpre: 3548 case AArch64::LDRWpre: 3549 case AArch64::LDRXpre: 3550 case AArch64::LDRBBpost: 3551 case AArch64::LDRBpost: 3552 case AArch64::LDRHHpost: 3553 case AArch64::LDRHpost: 3554 case AArch64::LDRSBWpost: 3555 case AArch64::LDRSBXpost: 3556 case AArch64::LDRSHWpost: 3557 case AArch64::LDRSHXpost: 3558 case AArch64::LDRSWpost: 3559 case AArch64::LDRWpost: 3560 case AArch64::LDRXpost: { 3561 unsigned Rt = Inst.getOperand(1).getReg(); 3562 unsigned Rn = Inst.getOperand(2).getReg(); 3563 if (RI->isSubRegisterEq(Rn, Rt)) 3564 return Error(Loc[0], "unpredictable LDR instruction, writeback base " 3565 "is also a source"); 3566 break; 3567 } 3568 case AArch64::STRBBpost: 3569 case AArch64::STRBpost: 3570 case AArch64::STRHHpost: 3571 case AArch64::STRHpost: 3572 case AArch64::STRWpost: 3573 case AArch64::STRXpost: 3574 case AArch64::STRBBpre: 3575 case AArch64::STRBpre: 3576 case AArch64::STRHHpre: 3577 case AArch64::STRHpre: 3578 case AArch64::STRWpre: 3579 case AArch64::STRXpre: { 3580 unsigned Rt = Inst.getOperand(1).getReg(); 3581 unsigned Rn = Inst.getOperand(2).getReg(); 3582 if (RI->isSubRegisterEq(Rn, Rt)) 3583 return Error(Loc[0], "unpredictable STR instruction, writeback base " 3584 "is also a source"); 3585 break; 3586 } 3587 } 3588 3589 // Now check immediate ranges. Separate from the above as there is overlap 3590 // in the instructions being checked and this keeps the nested conditionals 3591 // to a minimum. 3592 switch (Inst.getOpcode()) { 3593 case AArch64::ADDSWri: 3594 case AArch64::ADDSXri: 3595 case AArch64::ADDWri: 3596 case AArch64::ADDXri: 3597 case AArch64::SUBSWri: 3598 case AArch64::SUBSXri: 3599 case AArch64::SUBWri: 3600 case AArch64::SUBXri: { 3601 // Annoyingly we can't do this in the isAddSubImm predicate, so there is 3602 // some slight duplication here. 3603 if (Inst.getOperand(2).isExpr()) { 3604 const MCExpr *Expr = Inst.getOperand(2).getExpr(); 3605 AArch64MCExpr::VariantKind ELFRefKind; 3606 MCSymbolRefExpr::VariantKind DarwinRefKind; 3607 int64_t Addend; 3608 if (!classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) { 3609 return Error(Loc[2], "invalid immediate expression"); 3610 } 3611 3612 // Only allow these with ADDXri. 3613 if ((DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF || 3614 DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) && 3615 Inst.getOpcode() == AArch64::ADDXri) 3616 return false; 3617 3618 // Only allow these with ADDXri/ADDWri 3619 if ((ELFRefKind == AArch64MCExpr::VK_LO12 || 3620 ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 || 3621 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 || 3622 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC || 3623 ELFRefKind == AArch64MCExpr::VK_TPREL_HI12 || 3624 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 || 3625 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC || 3626 ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12) && 3627 (Inst.getOpcode() == AArch64::ADDXri || 3628 Inst.getOpcode() == AArch64::ADDWri)) 3629 return false; 3630 3631 // Don't allow expressions in the immediate field otherwise 3632 return Error(Loc[2], "invalid immediate expression"); 3633 } 3634 return false; 3635 } 3636 default: 3637 return false; 3638 } 3639 } 3640 3641 bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode) { 3642 switch (ErrCode) { 3643 case Match_MissingFeature: 3644 return Error(Loc, 3645 "instruction requires a CPU feature not currently enabled"); 3646 case Match_InvalidOperand: 3647 return Error(Loc, "invalid operand for instruction"); 3648 case Match_InvalidSuffix: 3649 return Error(Loc, "invalid type suffix for instruction"); 3650 case Match_InvalidCondCode: 3651 return Error(Loc, "expected AArch64 condition code"); 3652 case Match_AddSubRegExtendSmall: 3653 return Error(Loc, 3654 "expected '[su]xt[bhw]' or 'lsl' with optional integer in range [0, 4]"); 3655 case Match_AddSubRegExtendLarge: 3656 return Error(Loc, 3657 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]"); 3658 case Match_AddSubSecondSource: 3659 return Error(Loc, 3660 "expected compatible register, symbol or integer in range [0, 4095]"); 3661 case Match_LogicalSecondSource: 3662 return Error(Loc, "expected compatible register or logical immediate"); 3663 case Match_InvalidMovImm32Shift: 3664 return Error(Loc, "expected 'lsl' with optional integer 0 or 16"); 3665 case Match_InvalidMovImm64Shift: 3666 return Error(Loc, "expected 'lsl' with optional integer 0, 16, 32 or 48"); 3667 case Match_AddSubRegShift32: 3668 return Error(Loc, 3669 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]"); 3670 case Match_AddSubRegShift64: 3671 return Error(Loc, 3672 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]"); 3673 case Match_InvalidFPImm: 3674 return Error(Loc, 3675 "expected compatible register or floating-point constant"); 3676 case Match_InvalidMemoryIndexedSImm9: 3677 return Error(Loc, "index must be an integer in range [-256, 255]."); 3678 case Match_InvalidMemoryIndexed4SImm7: 3679 return Error(Loc, "index must be a multiple of 4 in range [-256, 252]."); 3680 case Match_InvalidMemoryIndexed8SImm7: 3681 return Error(Loc, "index must be a multiple of 8 in range [-512, 504]."); 3682 case Match_InvalidMemoryIndexed16SImm7: 3683 return Error(Loc, "index must be a multiple of 16 in range [-1024, 1008]."); 3684 case Match_InvalidMemoryWExtend8: 3685 return Error(Loc, 3686 "expected 'uxtw' or 'sxtw' with optional shift of #0"); 3687 case Match_InvalidMemoryWExtend16: 3688 return Error(Loc, 3689 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1"); 3690 case Match_InvalidMemoryWExtend32: 3691 return Error(Loc, 3692 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2"); 3693 case Match_InvalidMemoryWExtend64: 3694 return Error(Loc, 3695 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3"); 3696 case Match_InvalidMemoryWExtend128: 3697 return Error(Loc, 3698 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4"); 3699 case Match_InvalidMemoryXExtend8: 3700 return Error(Loc, 3701 "expected 'lsl' or 'sxtx' with optional shift of #0"); 3702 case Match_InvalidMemoryXExtend16: 3703 return Error(Loc, 3704 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1"); 3705 case Match_InvalidMemoryXExtend32: 3706 return Error(Loc, 3707 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2"); 3708 case Match_InvalidMemoryXExtend64: 3709 return Error(Loc, 3710 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3"); 3711 case Match_InvalidMemoryXExtend128: 3712 return Error(Loc, 3713 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4"); 3714 case Match_InvalidMemoryIndexed1: 3715 return Error(Loc, "index must be an integer in range [0, 4095]."); 3716 case Match_InvalidMemoryIndexed2: 3717 return Error(Loc, "index must be a multiple of 2 in range [0, 8190]."); 3718 case Match_InvalidMemoryIndexed4: 3719 return Error(Loc, "index must be a multiple of 4 in range [0, 16380]."); 3720 case Match_InvalidMemoryIndexed8: 3721 return Error(Loc, "index must be a multiple of 8 in range [0, 32760]."); 3722 case Match_InvalidMemoryIndexed16: 3723 return Error(Loc, "index must be a multiple of 16 in range [0, 65520]."); 3724 case Match_InvalidImm0_1: 3725 return Error(Loc, "immediate must be an integer in range [0, 1]."); 3726 case Match_InvalidImm0_7: 3727 return Error(Loc, "immediate must be an integer in range [0, 7]."); 3728 case Match_InvalidImm0_15: 3729 return Error(Loc, "immediate must be an integer in range [0, 15]."); 3730 case Match_InvalidImm0_31: 3731 return Error(Loc, "immediate must be an integer in range [0, 31]."); 3732 case Match_InvalidImm0_63: 3733 return Error(Loc, "immediate must be an integer in range [0, 63]."); 3734 case Match_InvalidImm0_127: 3735 return Error(Loc, "immediate must be an integer in range [0, 127]."); 3736 case Match_InvalidImm0_65535: 3737 return Error(Loc, "immediate must be an integer in range [0, 65535]."); 3738 case Match_InvalidImm1_8: 3739 return Error(Loc, "immediate must be an integer in range [1, 8]."); 3740 case Match_InvalidImm1_16: 3741 return Error(Loc, "immediate must be an integer in range [1, 16]."); 3742 case Match_InvalidImm1_32: 3743 return Error(Loc, "immediate must be an integer in range [1, 32]."); 3744 case Match_InvalidImm1_64: 3745 return Error(Loc, "immediate must be an integer in range [1, 64]."); 3746 case Match_InvalidIndex1: 3747 return Error(Loc, "expected lane specifier '[1]'"); 3748 case Match_InvalidIndexB: 3749 return Error(Loc, "vector lane must be an integer in range [0, 15]."); 3750 case Match_InvalidIndexH: 3751 return Error(Loc, "vector lane must be an integer in range [0, 7]."); 3752 case Match_InvalidIndexS: 3753 return Error(Loc, "vector lane must be an integer in range [0, 3]."); 3754 case Match_InvalidIndexD: 3755 return Error(Loc, "vector lane must be an integer in range [0, 1]."); 3756 case Match_InvalidLabel: 3757 return Error(Loc, "expected label or encodable integer pc offset"); 3758 case Match_MRS: 3759 return Error(Loc, "expected readable system register"); 3760 case Match_MSR: 3761 return Error(Loc, "expected writable system register or pstate"); 3762 case Match_MnemonicFail: 3763 return Error(Loc, "unrecognized instruction mnemonic"); 3764 default: 3765 llvm_unreachable("unexpected error code!"); 3766 } 3767 } 3768 3769 static const char *getSubtargetFeatureName(uint64_t Val); 3770 3771 bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 3772 OperandVector &Operands, 3773 MCStreamer &Out, 3774 uint64_t &ErrorInfo, 3775 bool MatchingInlineAsm) { 3776 assert(!Operands.empty() && "Unexpect empty operand list!"); 3777 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[0]); 3778 assert(Op.isToken() && "Leading operand should always be a mnemonic!"); 3779 3780 StringRef Tok = Op.getToken(); 3781 unsigned NumOperands = Operands.size(); 3782 3783 if (NumOperands == 4 && Tok == "lsl") { 3784 AArch64Operand &Op2 = static_cast<AArch64Operand &>(*Operands[2]); 3785 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]); 3786 if (Op2.isReg() && Op3.isImm()) { 3787 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm()); 3788 if (Op3CE) { 3789 uint64_t Op3Val = Op3CE->getValue(); 3790 uint64_t NewOp3Val = 0; 3791 uint64_t NewOp4Val = 0; 3792 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].contains( 3793 Op2.getReg())) { 3794 NewOp3Val = (32 - Op3Val) & 0x1f; 3795 NewOp4Val = 31 - Op3Val; 3796 } else { 3797 NewOp3Val = (64 - Op3Val) & 0x3f; 3798 NewOp4Val = 63 - Op3Val; 3799 } 3800 3801 const MCExpr *NewOp3 = MCConstantExpr::create(NewOp3Val, getContext()); 3802 const MCExpr *NewOp4 = MCConstantExpr::create(NewOp4Val, getContext()); 3803 3804 Operands[0] = AArch64Operand::CreateToken( 3805 "ubfm", false, Op.getStartLoc(), getContext()); 3806 Operands.push_back(AArch64Operand::CreateImm( 3807 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext())); 3808 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(), 3809 Op3.getEndLoc(), getContext()); 3810 } 3811 } 3812 } else if (NumOperands == 4 && Tok == "bfc") { 3813 // FIXME: Horrible hack to handle BFC->BFM alias. 3814 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]); 3815 AArch64Operand LSBOp = static_cast<AArch64Operand &>(*Operands[2]); 3816 AArch64Operand WidthOp = static_cast<AArch64Operand &>(*Operands[3]); 3817 3818 if (Op1.isReg() && LSBOp.isImm() && WidthOp.isImm()) { 3819 const MCConstantExpr *LSBCE = dyn_cast<MCConstantExpr>(LSBOp.getImm()); 3820 const MCConstantExpr *WidthCE = dyn_cast<MCConstantExpr>(WidthOp.getImm()); 3821 3822 if (LSBCE && WidthCE) { 3823 uint64_t LSB = LSBCE->getValue(); 3824 uint64_t Width = WidthCE->getValue(); 3825 3826 uint64_t RegWidth = 0; 3827 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( 3828 Op1.getReg())) 3829 RegWidth = 64; 3830 else 3831 RegWidth = 32; 3832 3833 if (LSB >= RegWidth) 3834 return Error(LSBOp.getStartLoc(), 3835 "expected integer in range [0, 31]"); 3836 if (Width < 1 || Width > RegWidth) 3837 return Error(WidthOp.getStartLoc(), 3838 "expected integer in range [1, 32]"); 3839 3840 uint64_t ImmR = 0; 3841 if (RegWidth == 32) 3842 ImmR = (32 - LSB) & 0x1f; 3843 else 3844 ImmR = (64 - LSB) & 0x3f; 3845 3846 uint64_t ImmS = Width - 1; 3847 3848 if (ImmR != 0 && ImmS >= ImmR) 3849 return Error(WidthOp.getStartLoc(), 3850 "requested insert overflows register"); 3851 3852 const MCExpr *ImmRExpr = MCConstantExpr::create(ImmR, getContext()); 3853 const MCExpr *ImmSExpr = MCConstantExpr::create(ImmS, getContext()); 3854 Operands[0] = AArch64Operand::CreateToken( 3855 "bfm", false, Op.getStartLoc(), getContext()); 3856 Operands[2] = AArch64Operand::CreateReg( 3857 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, false, SMLoc(), 3858 SMLoc(), getContext()); 3859 Operands[3] = AArch64Operand::CreateImm( 3860 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(), getContext()); 3861 Operands.emplace_back( 3862 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(), 3863 WidthOp.getEndLoc(), getContext())); 3864 } 3865 } 3866 } else if (NumOperands == 5) { 3867 // FIXME: Horrible hack to handle the BFI -> BFM, SBFIZ->SBFM, and 3868 // UBFIZ -> UBFM aliases. 3869 if (Tok == "bfi" || Tok == "sbfiz" || Tok == "ubfiz") { 3870 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]); 3871 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]); 3872 AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]); 3873 3874 if (Op1.isReg() && Op3.isImm() && Op4.isImm()) { 3875 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm()); 3876 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm()); 3877 3878 if (Op3CE && Op4CE) { 3879 uint64_t Op3Val = Op3CE->getValue(); 3880 uint64_t Op4Val = Op4CE->getValue(); 3881 3882 uint64_t RegWidth = 0; 3883 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( 3884 Op1.getReg())) 3885 RegWidth = 64; 3886 else 3887 RegWidth = 32; 3888 3889 if (Op3Val >= RegWidth) 3890 return Error(Op3.getStartLoc(), 3891 "expected integer in range [0, 31]"); 3892 if (Op4Val < 1 || Op4Val > RegWidth) 3893 return Error(Op4.getStartLoc(), 3894 "expected integer in range [1, 32]"); 3895 3896 uint64_t NewOp3Val = 0; 3897 if (RegWidth == 32) 3898 NewOp3Val = (32 - Op3Val) & 0x1f; 3899 else 3900 NewOp3Val = (64 - Op3Val) & 0x3f; 3901 3902 uint64_t NewOp4Val = Op4Val - 1; 3903 3904 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val) 3905 return Error(Op4.getStartLoc(), 3906 "requested insert overflows register"); 3907 3908 const MCExpr *NewOp3 = 3909 MCConstantExpr::create(NewOp3Val, getContext()); 3910 const MCExpr *NewOp4 = 3911 MCConstantExpr::create(NewOp4Val, getContext()); 3912 Operands[3] = AArch64Operand::CreateImm( 3913 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext()); 3914 Operands[4] = AArch64Operand::CreateImm( 3915 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext()); 3916 if (Tok == "bfi") 3917 Operands[0] = AArch64Operand::CreateToken( 3918 "bfm", false, Op.getStartLoc(), getContext()); 3919 else if (Tok == "sbfiz") 3920 Operands[0] = AArch64Operand::CreateToken( 3921 "sbfm", false, Op.getStartLoc(), getContext()); 3922 else if (Tok == "ubfiz") 3923 Operands[0] = AArch64Operand::CreateToken( 3924 "ubfm", false, Op.getStartLoc(), getContext()); 3925 else 3926 llvm_unreachable("No valid mnemonic for alias?"); 3927 } 3928 } 3929 3930 // FIXME: Horrible hack to handle the BFXIL->BFM, SBFX->SBFM, and 3931 // UBFX -> UBFM aliases. 3932 } else if (NumOperands == 5 && 3933 (Tok == "bfxil" || Tok == "sbfx" || Tok == "ubfx")) { 3934 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]); 3935 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]); 3936 AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]); 3937 3938 if (Op1.isReg() && Op3.isImm() && Op4.isImm()) { 3939 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm()); 3940 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm()); 3941 3942 if (Op3CE && Op4CE) { 3943 uint64_t Op3Val = Op3CE->getValue(); 3944 uint64_t Op4Val = Op4CE->getValue(); 3945 3946 uint64_t RegWidth = 0; 3947 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( 3948 Op1.getReg())) 3949 RegWidth = 64; 3950 else 3951 RegWidth = 32; 3952 3953 if (Op3Val >= RegWidth) 3954 return Error(Op3.getStartLoc(), 3955 "expected integer in range [0, 31]"); 3956 if (Op4Val < 1 || Op4Val > RegWidth) 3957 return Error(Op4.getStartLoc(), 3958 "expected integer in range [1, 32]"); 3959 3960 uint64_t NewOp4Val = Op3Val + Op4Val - 1; 3961 3962 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val) 3963 return Error(Op4.getStartLoc(), 3964 "requested extract overflows register"); 3965 3966 const MCExpr *NewOp4 = 3967 MCConstantExpr::create(NewOp4Val, getContext()); 3968 Operands[4] = AArch64Operand::CreateImm( 3969 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext()); 3970 if (Tok == "bfxil") 3971 Operands[0] = AArch64Operand::CreateToken( 3972 "bfm", false, Op.getStartLoc(), getContext()); 3973 else if (Tok == "sbfx") 3974 Operands[0] = AArch64Operand::CreateToken( 3975 "sbfm", false, Op.getStartLoc(), getContext()); 3976 else if (Tok == "ubfx") 3977 Operands[0] = AArch64Operand::CreateToken( 3978 "ubfm", false, Op.getStartLoc(), getContext()); 3979 else 3980 llvm_unreachable("No valid mnemonic for alias?"); 3981 } 3982 } 3983 } 3984 } 3985 // FIXME: Horrible hack for sxtw and uxtw with Wn src and Xd dst operands. 3986 // InstAlias can't quite handle this since the reg classes aren't 3987 // subclasses. 3988 if (NumOperands == 3 && (Tok == "sxtw" || Tok == "uxtw")) { 3989 // The source register can be Wn here, but the matcher expects a 3990 // GPR64. Twiddle it here if necessary. 3991 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]); 3992 if (Op.isReg()) { 3993 unsigned Reg = getXRegFromWReg(Op.getReg()); 3994 Operands[2] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(), 3995 Op.getEndLoc(), getContext()); 3996 } 3997 } 3998 // FIXME: Likewise for sxt[bh] with a Xd dst operand 3999 else if (NumOperands == 3 && (Tok == "sxtb" || Tok == "sxth")) { 4000 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]); 4001 if (Op.isReg() && 4002 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( 4003 Op.getReg())) { 4004 // The source register can be Wn here, but the matcher expects a 4005 // GPR64. Twiddle it here if necessary. 4006 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]); 4007 if (Op.isReg()) { 4008 unsigned Reg = getXRegFromWReg(Op.getReg()); 4009 Operands[2] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(), 4010 Op.getEndLoc(), getContext()); 4011 } 4012 } 4013 } 4014 // FIXME: Likewise for uxt[bh] with a Xd dst operand 4015 else if (NumOperands == 3 && (Tok == "uxtb" || Tok == "uxth")) { 4016 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]); 4017 if (Op.isReg() && 4018 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( 4019 Op.getReg())) { 4020 // The source register can be Wn here, but the matcher expects a 4021 // GPR32. Twiddle it here if necessary. 4022 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]); 4023 if (Op.isReg()) { 4024 unsigned Reg = getWRegFromXReg(Op.getReg()); 4025 Operands[1] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(), 4026 Op.getEndLoc(), getContext()); 4027 } 4028 } 4029 } 4030 4031 // Yet another horrible hack to handle FMOV Rd, #0.0 using [WX]ZR. 4032 if (NumOperands == 3 && Tok == "fmov") { 4033 AArch64Operand &RegOp = static_cast<AArch64Operand &>(*Operands[1]); 4034 AArch64Operand &ImmOp = static_cast<AArch64Operand &>(*Operands[2]); 4035 if (RegOp.isReg() && ImmOp.isFPImm() && ImmOp.getFPImm() == (unsigned)-1) { 4036 unsigned zreg = 4037 !AArch64MCRegisterClasses[AArch64::FPR64RegClassID].contains( 4038 RegOp.getReg()) 4039 ? AArch64::WZR 4040 : AArch64::XZR; 4041 Operands[2] = AArch64Operand::CreateReg(zreg, false, Op.getStartLoc(), 4042 Op.getEndLoc(), getContext()); 4043 } 4044 } 4045 4046 MCInst Inst; 4047 // First try to match against the secondary set of tables containing the 4048 // short-form NEON instructions (e.g. "fadd.2s v0, v1, v2"). 4049 unsigned MatchResult = 4050 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 1); 4051 4052 // If that fails, try against the alternate table containing long-form NEON: 4053 // "fadd v0.2s, v1.2s, v2.2s" 4054 if (MatchResult != Match_Success) { 4055 // But first, save the short-form match result: we can use it in case the 4056 // long-form match also fails. 4057 auto ShortFormNEONErrorInfo = ErrorInfo; 4058 auto ShortFormNEONMatchResult = MatchResult; 4059 4060 MatchResult = 4061 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 0); 4062 4063 // Now, both matches failed, and the long-form match failed on the mnemonic 4064 // suffix token operand. The short-form match failure is probably more 4065 // relevant: use it instead. 4066 if (MatchResult == Match_InvalidOperand && ErrorInfo == 1 && 4067 Operands.size() > 1 && ((AArch64Operand &)*Operands[1]).isToken() && 4068 ((AArch64Operand &)*Operands[1]).isTokenSuffix()) { 4069 MatchResult = ShortFormNEONMatchResult; 4070 ErrorInfo = ShortFormNEONErrorInfo; 4071 } 4072 } 4073 4074 4075 switch (MatchResult) { 4076 case Match_Success: { 4077 // Perform range checking and other semantic validations 4078 SmallVector<SMLoc, 8> OperandLocs; 4079 NumOperands = Operands.size(); 4080 for (unsigned i = 1; i < NumOperands; ++i) 4081 OperandLocs.push_back(Operands[i]->getStartLoc()); 4082 if (validateInstruction(Inst, OperandLocs)) 4083 return true; 4084 4085 Inst.setLoc(IDLoc); 4086 Out.EmitInstruction(Inst, getSTI()); 4087 return false; 4088 } 4089 case Match_MissingFeature: { 4090 assert(ErrorInfo && "Unknown missing feature!"); 4091 // Special case the error message for the very common case where only 4092 // a single subtarget feature is missing (neon, e.g.). 4093 std::string Msg = "instruction requires:"; 4094 uint64_t Mask = 1; 4095 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) { 4096 if (ErrorInfo & Mask) { 4097 Msg += " "; 4098 Msg += getSubtargetFeatureName(ErrorInfo & Mask); 4099 } 4100 Mask <<= 1; 4101 } 4102 return Error(IDLoc, Msg); 4103 } 4104 case Match_MnemonicFail: 4105 return showMatchError(IDLoc, MatchResult); 4106 case Match_InvalidOperand: { 4107 SMLoc ErrorLoc = IDLoc; 4108 4109 if (ErrorInfo != ~0ULL) { 4110 if (ErrorInfo >= Operands.size()) 4111 return Error(IDLoc, "too few operands for instruction"); 4112 4113 ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc(); 4114 if (ErrorLoc == SMLoc()) 4115 ErrorLoc = IDLoc; 4116 } 4117 // If the match failed on a suffix token operand, tweak the diagnostic 4118 // accordingly. 4119 if (((AArch64Operand &)*Operands[ErrorInfo]).isToken() && 4120 ((AArch64Operand &)*Operands[ErrorInfo]).isTokenSuffix()) 4121 MatchResult = Match_InvalidSuffix; 4122 4123 return showMatchError(ErrorLoc, MatchResult); 4124 } 4125 case Match_InvalidMemoryIndexed1: 4126 case Match_InvalidMemoryIndexed2: 4127 case Match_InvalidMemoryIndexed4: 4128 case Match_InvalidMemoryIndexed8: 4129 case Match_InvalidMemoryIndexed16: 4130 case Match_InvalidCondCode: 4131 case Match_AddSubRegExtendSmall: 4132 case Match_AddSubRegExtendLarge: 4133 case Match_AddSubSecondSource: 4134 case Match_LogicalSecondSource: 4135 case Match_AddSubRegShift32: 4136 case Match_AddSubRegShift64: 4137 case Match_InvalidMovImm32Shift: 4138 case Match_InvalidMovImm64Shift: 4139 case Match_InvalidFPImm: 4140 case Match_InvalidMemoryWExtend8: 4141 case Match_InvalidMemoryWExtend16: 4142 case Match_InvalidMemoryWExtend32: 4143 case Match_InvalidMemoryWExtend64: 4144 case Match_InvalidMemoryWExtend128: 4145 case Match_InvalidMemoryXExtend8: 4146 case Match_InvalidMemoryXExtend16: 4147 case Match_InvalidMemoryXExtend32: 4148 case Match_InvalidMemoryXExtend64: 4149 case Match_InvalidMemoryXExtend128: 4150 case Match_InvalidMemoryIndexed4SImm7: 4151 case Match_InvalidMemoryIndexed8SImm7: 4152 case Match_InvalidMemoryIndexed16SImm7: 4153 case Match_InvalidMemoryIndexedSImm9: 4154 case Match_InvalidImm0_1: 4155 case Match_InvalidImm0_7: 4156 case Match_InvalidImm0_15: 4157 case Match_InvalidImm0_31: 4158 case Match_InvalidImm0_63: 4159 case Match_InvalidImm0_127: 4160 case Match_InvalidImm0_65535: 4161 case Match_InvalidImm1_8: 4162 case Match_InvalidImm1_16: 4163 case Match_InvalidImm1_32: 4164 case Match_InvalidImm1_64: 4165 case Match_InvalidIndex1: 4166 case Match_InvalidIndexB: 4167 case Match_InvalidIndexH: 4168 case Match_InvalidIndexS: 4169 case Match_InvalidIndexD: 4170 case Match_InvalidLabel: 4171 case Match_MSR: 4172 case Match_MRS: { 4173 if (ErrorInfo >= Operands.size()) 4174 return Error(IDLoc, "too few operands for instruction"); 4175 // Any time we get here, there's nothing fancy to do. Just get the 4176 // operand SMLoc and display the diagnostic. 4177 SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc(); 4178 if (ErrorLoc == SMLoc()) 4179 ErrorLoc = IDLoc; 4180 return showMatchError(ErrorLoc, MatchResult); 4181 } 4182 } 4183 4184 llvm_unreachable("Implement any new match types added!"); 4185 } 4186 4187 /// ParseDirective parses the arm specific directives 4188 bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) { 4189 const MCObjectFileInfo::Environment Format = 4190 getContext().getObjectFileInfo()->getObjectFileType(); 4191 bool IsMachO = Format == MCObjectFileInfo::IsMachO; 4192 bool IsCOFF = Format == MCObjectFileInfo::IsCOFF; 4193 4194 StringRef IDVal = DirectiveID.getIdentifier(); 4195 SMLoc Loc = DirectiveID.getLoc(); 4196 if (IDVal == ".hword") 4197 return parseDirectiveWord(2, Loc); 4198 if (IDVal == ".word") 4199 return parseDirectiveWord(4, Loc); 4200 if (IDVal == ".xword") 4201 return parseDirectiveWord(8, Loc); 4202 if (IDVal == ".tlsdesccall") 4203 return parseDirectiveTLSDescCall(Loc); 4204 if (IDVal == ".ltorg" || IDVal == ".pool") 4205 return parseDirectiveLtorg(Loc); 4206 if (IDVal == ".unreq") 4207 return parseDirectiveUnreq(Loc); 4208 4209 if (!IsMachO && !IsCOFF) { 4210 if (IDVal == ".inst") 4211 return parseDirectiveInst(Loc); 4212 } 4213 4214 return parseDirectiveLOH(IDVal, Loc); 4215 } 4216 4217 /// parseDirectiveWord 4218 /// ::= .word [ expression (, expression)* ] 4219 bool AArch64AsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 4220 MCAsmParser &Parser = getParser(); 4221 if (getLexer().isNot(AsmToken::EndOfStatement)) { 4222 for (;;) { 4223 const MCExpr *Value; 4224 if (getParser().parseExpression(Value)) 4225 return true; 4226 4227 getParser().getStreamer().EmitValue(Value, Size, L); 4228 4229 if (getLexer().is(AsmToken::EndOfStatement)) 4230 break; 4231 4232 // FIXME: Improve diagnostic. 4233 if (getLexer().isNot(AsmToken::Comma)) 4234 return Error(L, "unexpected token in directive"); 4235 Parser.Lex(); 4236 } 4237 } 4238 4239 Parser.Lex(); 4240 return false; 4241 } 4242 4243 /// parseDirectiveInst 4244 /// ::= .inst opcode [, ...] 4245 bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) { 4246 MCAsmParser &Parser = getParser(); 4247 if (getLexer().is(AsmToken::EndOfStatement)) { 4248 Parser.eatToEndOfStatement(); 4249 Error(Loc, "expected expression following directive"); 4250 return false; 4251 } 4252 4253 for (;;) { 4254 const MCExpr *Expr; 4255 4256 if (getParser().parseExpression(Expr)) { 4257 Error(Loc, "expected expression"); 4258 return false; 4259 } 4260 4261 const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr); 4262 if (!Value) { 4263 Error(Loc, "expected constant expression"); 4264 return false; 4265 } 4266 4267 getTargetStreamer().emitInst(Value->getValue()); 4268 4269 if (getLexer().is(AsmToken::EndOfStatement)) 4270 break; 4271 4272 if (getLexer().isNot(AsmToken::Comma)) { 4273 Error(Loc, "unexpected token in directive"); 4274 return false; 4275 } 4276 4277 Parser.Lex(); // Eat comma. 4278 } 4279 4280 Parser.Lex(); 4281 return false; 4282 } 4283 4284 // parseDirectiveTLSDescCall: 4285 // ::= .tlsdesccall symbol 4286 bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) { 4287 StringRef Name; 4288 if (getParser().parseIdentifier(Name)) 4289 return Error(L, "expected symbol after directive"); 4290 4291 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 4292 const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext()); 4293 Expr = AArch64MCExpr::create(Expr, AArch64MCExpr::VK_TLSDESC, getContext()); 4294 4295 MCInst Inst; 4296 Inst.setOpcode(AArch64::TLSDESCCALL); 4297 Inst.addOperand(MCOperand::createExpr(Expr)); 4298 4299 getParser().getStreamer().EmitInstruction(Inst, getSTI()); 4300 return false; 4301 } 4302 4303 /// ::= .loh <lohName | lohId> label1, ..., labelN 4304 /// The number of arguments depends on the loh identifier. 4305 bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) { 4306 if (IDVal != MCLOHDirectiveName()) 4307 return true; 4308 MCLOHType Kind; 4309 if (getParser().getTok().isNot(AsmToken::Identifier)) { 4310 if (getParser().getTok().isNot(AsmToken::Integer)) 4311 return TokError("expected an identifier or a number in directive"); 4312 // We successfully get a numeric value for the identifier. 4313 // Check if it is valid. 4314 int64_t Id = getParser().getTok().getIntVal(); 4315 if (Id <= -1U && !isValidMCLOHType(Id)) 4316 return TokError("invalid numeric identifier in directive"); 4317 Kind = (MCLOHType)Id; 4318 } else { 4319 StringRef Name = getTok().getIdentifier(); 4320 // We successfully parse an identifier. 4321 // Check if it is a recognized one. 4322 int Id = MCLOHNameToId(Name); 4323 4324 if (Id == -1) 4325 return TokError("invalid identifier in directive"); 4326 Kind = (MCLOHType)Id; 4327 } 4328 // Consume the identifier. 4329 Lex(); 4330 // Get the number of arguments of this LOH. 4331 int NbArgs = MCLOHIdToNbArgs(Kind); 4332 4333 assert(NbArgs != -1 && "Invalid number of arguments"); 4334 4335 SmallVector<MCSymbol *, 3> Args; 4336 for (int Idx = 0; Idx < NbArgs; ++Idx) { 4337 StringRef Name; 4338 if (getParser().parseIdentifier(Name)) 4339 return TokError("expected identifier in directive"); 4340 Args.push_back(getContext().getOrCreateSymbol(Name)); 4341 4342 if (Idx + 1 == NbArgs) 4343 break; 4344 if (getLexer().isNot(AsmToken::Comma)) 4345 return TokError("unexpected token in '" + Twine(IDVal) + "' directive"); 4346 Lex(); 4347 } 4348 if (getLexer().isNot(AsmToken::EndOfStatement)) 4349 return TokError("unexpected token in '" + Twine(IDVal) + "' directive"); 4350 4351 getStreamer().EmitLOHDirective((MCLOHType)Kind, Args); 4352 return false; 4353 } 4354 4355 /// parseDirectiveLtorg 4356 /// ::= .ltorg | .pool 4357 bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) { 4358 getTargetStreamer().emitCurrentConstantPool(); 4359 return false; 4360 } 4361 4362 /// parseDirectiveReq 4363 /// ::= name .req registername 4364 bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) { 4365 MCAsmParser &Parser = getParser(); 4366 Parser.Lex(); // Eat the '.req' token. 4367 SMLoc SRegLoc = getLoc(); 4368 unsigned RegNum = tryParseRegister(); 4369 bool IsVector = false; 4370 4371 if (RegNum == static_cast<unsigned>(-1)) { 4372 StringRef Kind; 4373 RegNum = tryMatchVectorRegister(Kind, false); 4374 if (!Kind.empty()) { 4375 Error(SRegLoc, "vector register without type specifier expected"); 4376 return false; 4377 } 4378 IsVector = true; 4379 } 4380 4381 if (RegNum == static_cast<unsigned>(-1)) { 4382 Parser.eatToEndOfStatement(); 4383 Error(SRegLoc, "register name or alias expected"); 4384 return false; 4385 } 4386 4387 // Shouldn't be anything else. 4388 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 4389 Error(Parser.getTok().getLoc(), "unexpected input in .req directive"); 4390 Parser.eatToEndOfStatement(); 4391 return false; 4392 } 4393 4394 Parser.Lex(); // Consume the EndOfStatement 4395 4396 auto pair = std::make_pair(IsVector, RegNum); 4397 if (RegisterReqs.insert(std::make_pair(Name, pair)).first->second != pair) 4398 Warning(L, "ignoring redefinition of register alias '" + Name + "'"); 4399 4400 return true; 4401 } 4402 4403 /// parseDirectiveUneq 4404 /// ::= .unreq registername 4405 bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) { 4406 MCAsmParser &Parser = getParser(); 4407 if (Parser.getTok().isNot(AsmToken::Identifier)) { 4408 Error(Parser.getTok().getLoc(), "unexpected input in .unreq directive."); 4409 Parser.eatToEndOfStatement(); 4410 return false; 4411 } 4412 RegisterReqs.erase(Parser.getTok().getIdentifier().lower()); 4413 Parser.Lex(); // Eat the identifier. 4414 return false; 4415 } 4416 4417 bool 4418 AArch64AsmParser::classifySymbolRef(const MCExpr *Expr, 4419 AArch64MCExpr::VariantKind &ELFRefKind, 4420 MCSymbolRefExpr::VariantKind &DarwinRefKind, 4421 int64_t &Addend) { 4422 ELFRefKind = AArch64MCExpr::VK_INVALID; 4423 DarwinRefKind = MCSymbolRefExpr::VK_None; 4424 Addend = 0; 4425 4426 if (const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) { 4427 ELFRefKind = AE->getKind(); 4428 Expr = AE->getSubExpr(); 4429 } 4430 4431 const MCSymbolRefExpr *SE = dyn_cast<MCSymbolRefExpr>(Expr); 4432 if (SE) { 4433 // It's a simple symbol reference with no addend. 4434 DarwinRefKind = SE->getKind(); 4435 return true; 4436 } 4437 4438 const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr); 4439 if (!BE) 4440 return false; 4441 4442 SE = dyn_cast<MCSymbolRefExpr>(BE->getLHS()); 4443 if (!SE) 4444 return false; 4445 DarwinRefKind = SE->getKind(); 4446 4447 if (BE->getOpcode() != MCBinaryExpr::Add && 4448 BE->getOpcode() != MCBinaryExpr::Sub) 4449 return false; 4450 4451 // See if the addend is is a constant, otherwise there's more going 4452 // on here than we can deal with. 4453 auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS()); 4454 if (!AddendExpr) 4455 return false; 4456 4457 Addend = AddendExpr->getValue(); 4458 if (BE->getOpcode() == MCBinaryExpr::Sub) 4459 Addend = -Addend; 4460 4461 // It's some symbol reference + a constant addend, but really 4462 // shouldn't use both Darwin and ELF syntax. 4463 return ELFRefKind == AArch64MCExpr::VK_INVALID || 4464 DarwinRefKind == MCSymbolRefExpr::VK_None; 4465 } 4466 4467 /// Force static initialization. 4468 extern "C" void LLVMInitializeAArch64AsmParser() { 4469 RegisterMCAsmParser<AArch64AsmParser> X(TheAArch64leTarget); 4470 RegisterMCAsmParser<AArch64AsmParser> Y(TheAArch64beTarget); 4471 RegisterMCAsmParser<AArch64AsmParser> Z(TheARM64Target); 4472 } 4473 4474 #define GET_REGISTER_MATCHER 4475 #define GET_SUBTARGET_FEATURE_NAME 4476 #define GET_MATCHER_IMPLEMENTATION 4477 #include "AArch64GenAsmMatcher.inc" 4478 4479 // Define this matcher function after the auto-generated include so we 4480 // have the match class enum definitions. 4481 unsigned AArch64AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, 4482 unsigned Kind) { 4483 AArch64Operand &Op = static_cast<AArch64Operand &>(AsmOp); 4484 // If the kind is a token for a literal immediate, check if our asm 4485 // operand matches. This is for InstAliases which have a fixed-value 4486 // immediate in the syntax. 4487 int64_t ExpectedVal; 4488 switch (Kind) { 4489 default: 4490 return Match_InvalidOperand; 4491 case MCK__35_0: 4492 ExpectedVal = 0; 4493 break; 4494 case MCK__35_1: 4495 ExpectedVal = 1; 4496 break; 4497 case MCK__35_12: 4498 ExpectedVal = 12; 4499 break; 4500 case MCK__35_16: 4501 ExpectedVal = 16; 4502 break; 4503 case MCK__35_2: 4504 ExpectedVal = 2; 4505 break; 4506 case MCK__35_24: 4507 ExpectedVal = 24; 4508 break; 4509 case MCK__35_3: 4510 ExpectedVal = 3; 4511 break; 4512 case MCK__35_32: 4513 ExpectedVal = 32; 4514 break; 4515 case MCK__35_4: 4516 ExpectedVal = 4; 4517 break; 4518 case MCK__35_48: 4519 ExpectedVal = 48; 4520 break; 4521 case MCK__35_6: 4522 ExpectedVal = 6; 4523 break; 4524 case MCK__35_64: 4525 ExpectedVal = 64; 4526 break; 4527 case MCK__35_8: 4528 ExpectedVal = 8; 4529 break; 4530 } 4531 if (!Op.isImm()) 4532 return Match_InvalidOperand; 4533 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm()); 4534 if (!CE) 4535 return Match_InvalidOperand; 4536 if (CE->getValue() == ExpectedVal) 4537 return Match_Success; 4538 return Match_InvalidOperand; 4539 } 4540 4541 4542 AArch64AsmParser::OperandMatchResultTy 4543 AArch64AsmParser::tryParseGPRSeqPair(OperandVector &Operands) { 4544 4545 SMLoc S = getLoc(); 4546 4547 if (getParser().getTok().isNot(AsmToken::Identifier)) { 4548 Error(S, "expected register"); 4549 return MatchOperand_ParseFail; 4550 } 4551 4552 int FirstReg = tryParseRegister(); 4553 if (FirstReg == -1) { 4554 return MatchOperand_ParseFail; 4555 } 4556 const MCRegisterClass &WRegClass = 4557 AArch64MCRegisterClasses[AArch64::GPR32RegClassID]; 4558 const MCRegisterClass &XRegClass = 4559 AArch64MCRegisterClasses[AArch64::GPR64RegClassID]; 4560 4561 bool isXReg = XRegClass.contains(FirstReg), 4562 isWReg = WRegClass.contains(FirstReg); 4563 if (!isXReg && !isWReg) { 4564 Error(S, "expected first even register of a " 4565 "consecutive same-size even/odd register pair"); 4566 return MatchOperand_ParseFail; 4567 } 4568 4569 const MCRegisterInfo *RI = getContext().getRegisterInfo(); 4570 unsigned FirstEncoding = RI->getEncodingValue(FirstReg); 4571 4572 if (FirstEncoding & 0x1) { 4573 Error(S, "expected first even register of a " 4574 "consecutive same-size even/odd register pair"); 4575 return MatchOperand_ParseFail; 4576 } 4577 4578 SMLoc M = getLoc(); 4579 if (getParser().getTok().isNot(AsmToken::Comma)) { 4580 Error(M, "expected comma"); 4581 return MatchOperand_ParseFail; 4582 } 4583 // Eat the comma 4584 getParser().Lex(); 4585 4586 SMLoc E = getLoc(); 4587 int SecondReg = tryParseRegister(); 4588 if (SecondReg ==-1) { 4589 return MatchOperand_ParseFail; 4590 } 4591 4592 if (RI->getEncodingValue(SecondReg) != FirstEncoding + 1 || 4593 (isXReg && !XRegClass.contains(SecondReg)) || 4594 (isWReg && !WRegClass.contains(SecondReg))) { 4595 Error(E,"expected second odd register of a " 4596 "consecutive same-size even/odd register pair"); 4597 return MatchOperand_ParseFail; 4598 } 4599 4600 unsigned Pair = 0; 4601 if(isXReg) { 4602 Pair = RI->getMatchingSuperReg(FirstReg, AArch64::sube64, 4603 &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]); 4604 } else { 4605 Pair = RI->getMatchingSuperReg(FirstReg, AArch64::sube32, 4606 &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]); 4607 } 4608 4609 Operands.push_back(AArch64Operand::CreateReg(Pair, false, S, getLoc(), 4610 getContext())); 4611 4612 return MatchOperand_Success; 4613 } 4614