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