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