1 //==- AArch64AsmParser.cpp - Parse AArch64 assembly to MCInst instructions -==// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "MCTargetDesc/AArch64AddressingModes.h" 10 #include "MCTargetDesc/AArch64MCExpr.h" 11 #include "MCTargetDesc/AArch64MCTargetDesc.h" 12 #include "MCTargetDesc/AArch64TargetStreamer.h" 13 #include "TargetInfo/AArch64TargetInfo.h" 14 #include "AArch64InstrInfo.h" 15 #include "Utils/AArch64BaseInfo.h" 16 #include "llvm/ADT/APFloat.h" 17 #include "llvm/ADT/APInt.h" 18 #include "llvm/ADT/ArrayRef.h" 19 #include "llvm/ADT/STLExtras.h" 20 #include "llvm/ADT/SmallVector.h" 21 #include "llvm/ADT/StringExtras.h" 22 #include "llvm/ADT/StringMap.h" 23 #include "llvm/ADT/StringRef.h" 24 #include "llvm/ADT/StringSwitch.h" 25 #include "llvm/ADT/Twine.h" 26 #include "llvm/MC/MCContext.h" 27 #include "llvm/MC/MCExpr.h" 28 #include "llvm/MC/MCInst.h" 29 #include "llvm/MC/MCLinkerOptimizationHint.h" 30 #include "llvm/MC/MCObjectFileInfo.h" 31 #include "llvm/MC/MCParser/MCAsmLexer.h" 32 #include "llvm/MC/MCParser/MCAsmParser.h" 33 #include "llvm/MC/MCParser/MCAsmParserExtension.h" 34 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 35 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 36 #include "llvm/MC/MCRegisterInfo.h" 37 #include "llvm/MC/MCStreamer.h" 38 #include "llvm/MC/MCSubtargetInfo.h" 39 #include "llvm/MC/MCSymbol.h" 40 #include "llvm/MC/MCTargetOptions.h" 41 #include "llvm/MC/SubtargetFeature.h" 42 #include "llvm/MC/MCValue.h" 43 #include "llvm/Support/Casting.h" 44 #include "llvm/Support/Compiler.h" 45 #include "llvm/Support/ErrorHandling.h" 46 #include "llvm/Support/MathExtras.h" 47 #include "llvm/Support/SMLoc.h" 48 #include "llvm/Support/TargetParser.h" 49 #include "llvm/Support/TargetRegistry.h" 50 #include "llvm/Support/raw_ostream.h" 51 #include <cassert> 52 #include <cctype> 53 #include <cstdint> 54 #include <cstdio> 55 #include <string> 56 #include <tuple> 57 #include <utility> 58 #include <vector> 59 60 using namespace llvm; 61 62 namespace { 63 64 enum class RegKind { 65 Scalar, 66 NeonVector, 67 SVEDataVector, 68 SVEPredicateVector 69 }; 70 71 enum RegConstraintEqualityTy { 72 EqualsReg, 73 EqualsSuperReg, 74 EqualsSubReg 75 }; 76 77 class AArch64AsmParser : public MCTargetAsmParser { 78 private: 79 StringRef Mnemonic; ///< Instruction mnemonic. 80 81 // Map of register aliases registers via the .req directive. 82 StringMap<std::pair<RegKind, unsigned>> RegisterReqs; 83 84 class PrefixInfo { 85 public: 86 static PrefixInfo CreateFromInst(const MCInst &Inst, uint64_t TSFlags) { 87 PrefixInfo Prefix; 88 switch (Inst.getOpcode()) { 89 case AArch64::MOVPRFX_ZZ: 90 Prefix.Active = true; 91 Prefix.Dst = Inst.getOperand(0).getReg(); 92 break; 93 case AArch64::MOVPRFX_ZPmZ_B: 94 case AArch64::MOVPRFX_ZPmZ_H: 95 case AArch64::MOVPRFX_ZPmZ_S: 96 case AArch64::MOVPRFX_ZPmZ_D: 97 Prefix.Active = true; 98 Prefix.Predicated = true; 99 Prefix.ElementSize = TSFlags & AArch64::ElementSizeMask; 100 assert(Prefix.ElementSize != AArch64::ElementSizeNone && 101 "No destructive element size set for movprfx"); 102 Prefix.Dst = Inst.getOperand(0).getReg(); 103 Prefix.Pg = Inst.getOperand(2).getReg(); 104 break; 105 case AArch64::MOVPRFX_ZPzZ_B: 106 case AArch64::MOVPRFX_ZPzZ_H: 107 case AArch64::MOVPRFX_ZPzZ_S: 108 case AArch64::MOVPRFX_ZPzZ_D: 109 Prefix.Active = true; 110 Prefix.Predicated = true; 111 Prefix.ElementSize = TSFlags & AArch64::ElementSizeMask; 112 assert(Prefix.ElementSize != AArch64::ElementSizeNone && 113 "No destructive element size set for movprfx"); 114 Prefix.Dst = Inst.getOperand(0).getReg(); 115 Prefix.Pg = Inst.getOperand(1).getReg(); 116 break; 117 default: 118 break; 119 } 120 121 return Prefix; 122 } 123 124 PrefixInfo() : Active(false), Predicated(false) {} 125 bool isActive() const { return Active; } 126 bool isPredicated() const { return Predicated; } 127 unsigned getElementSize() const { 128 assert(Predicated); 129 return ElementSize; 130 } 131 unsigned getDstReg() const { return Dst; } 132 unsigned getPgReg() const { 133 assert(Predicated); 134 return Pg; 135 } 136 137 private: 138 bool Active; 139 bool Predicated; 140 unsigned ElementSize; 141 unsigned Dst; 142 unsigned Pg; 143 } NextPrefix; 144 145 AArch64TargetStreamer &getTargetStreamer() { 146 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); 147 return static_cast<AArch64TargetStreamer &>(TS); 148 } 149 150 SMLoc getLoc() const { return getParser().getTok().getLoc(); } 151 152 bool parseSysAlias(StringRef Name, SMLoc NameLoc, OperandVector &Operands); 153 void createSysAlias(uint16_t Encoding, OperandVector &Operands, SMLoc S); 154 AArch64CC::CondCode parseCondCodeString(StringRef Cond); 155 bool parseCondCode(OperandVector &Operands, bool invertCondCode); 156 unsigned matchRegisterNameAlias(StringRef Name, RegKind Kind); 157 bool parseRegister(OperandVector &Operands); 158 bool parseSymbolicImmVal(const MCExpr *&ImmVal); 159 bool parseNeonVectorList(OperandVector &Operands); 160 bool parseOptionalMulOperand(OperandVector &Operands); 161 bool parseOperand(OperandVector &Operands, bool isCondCode, 162 bool invertCondCode); 163 164 bool showMatchError(SMLoc Loc, unsigned ErrCode, uint64_t ErrorInfo, 165 OperandVector &Operands); 166 167 bool parseDirectiveArch(SMLoc L); 168 bool parseDirectiveArchExtension(SMLoc L); 169 bool parseDirectiveCPU(SMLoc L); 170 bool parseDirectiveInst(SMLoc L); 171 172 bool parseDirectiveTLSDescCall(SMLoc L); 173 174 bool parseDirectiveLOH(StringRef LOH, SMLoc L); 175 bool parseDirectiveLtorg(SMLoc L); 176 177 bool parseDirectiveReq(StringRef Name, SMLoc L); 178 bool parseDirectiveUnreq(SMLoc L); 179 bool parseDirectiveCFINegateRAState(); 180 bool parseDirectiveCFIBKeyFrame(); 181 182 bool validateInstruction(MCInst &Inst, SMLoc &IDLoc, 183 SmallVectorImpl<SMLoc> &Loc); 184 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 185 OperandVector &Operands, MCStreamer &Out, 186 uint64_t &ErrorInfo, 187 bool MatchingInlineAsm) override; 188 /// @name Auto-generated Match Functions 189 /// { 190 191 #define GET_ASSEMBLER_HEADER 192 #include "AArch64GenAsmMatcher.inc" 193 194 /// } 195 196 OperandMatchResultTy tryParseScalarRegister(unsigned &Reg); 197 OperandMatchResultTy tryParseVectorRegister(unsigned &Reg, StringRef &Kind, 198 RegKind MatchKind); 199 OperandMatchResultTy tryParseOptionalShiftExtend(OperandVector &Operands); 200 OperandMatchResultTy tryParseBarrierOperand(OperandVector &Operands); 201 OperandMatchResultTy tryParseMRSSystemRegister(OperandVector &Operands); 202 OperandMatchResultTy tryParseSysReg(OperandVector &Operands); 203 OperandMatchResultTy tryParseSysCROperand(OperandVector &Operands); 204 template <bool IsSVEPrefetch = false> 205 OperandMatchResultTy tryParsePrefetch(OperandVector &Operands); 206 OperandMatchResultTy tryParsePSBHint(OperandVector &Operands); 207 OperandMatchResultTy tryParseBTIHint(OperandVector &Operands); 208 OperandMatchResultTy tryParseAdrpLabel(OperandVector &Operands); 209 OperandMatchResultTy tryParseAdrLabel(OperandVector &Operands); 210 template<bool AddFPZeroAsLiteral> 211 OperandMatchResultTy tryParseFPImm(OperandVector &Operands); 212 OperandMatchResultTy tryParseImmWithOptionalShift(OperandVector &Operands); 213 OperandMatchResultTy tryParseGPR64sp0Operand(OperandVector &Operands); 214 bool tryParseNeonVectorRegister(OperandVector &Operands); 215 OperandMatchResultTy tryParseVectorIndex(OperandVector &Operands); 216 OperandMatchResultTy tryParseGPRSeqPair(OperandVector &Operands); 217 template <bool ParseShiftExtend, 218 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg> 219 OperandMatchResultTy tryParseGPROperand(OperandVector &Operands); 220 template <bool ParseShiftExtend, bool ParseSuffix> 221 OperandMatchResultTy tryParseSVEDataVector(OperandVector &Operands); 222 OperandMatchResultTy tryParseSVEPredicateVector(OperandVector &Operands); 223 template <RegKind VectorKind> 224 OperandMatchResultTy tryParseVectorList(OperandVector &Operands, 225 bool ExpectMatch = false); 226 OperandMatchResultTy tryParseSVEPattern(OperandVector &Operands); 227 228 public: 229 enum AArch64MatchResultTy { 230 Match_InvalidSuffix = FIRST_TARGET_MATCH_RESULT_TY, 231 #define GET_OPERAND_DIAGNOSTIC_TYPES 232 #include "AArch64GenAsmMatcher.inc" 233 }; 234 bool IsILP32; 235 236 AArch64AsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, 237 const MCInstrInfo &MII, const MCTargetOptions &Options) 238 : MCTargetAsmParser(Options, STI, MII) { 239 IsILP32 = Options.getABIName() == "ilp32"; 240 MCAsmParserExtension::Initialize(Parser); 241 MCStreamer &S = getParser().getStreamer(); 242 if (S.getTargetStreamer() == nullptr) 243 new AArch64TargetStreamer(S); 244 245 // Alias .hword/.word/.[dx]word to the target-independent 246 // .2byte/.4byte/.8byte directives as they have the same form and 247 // semantics: 248 /// ::= (.hword | .word | .dword | .xword ) [ expression (, expression)* ] 249 Parser.addAliasForDirective(".hword", ".2byte"); 250 Parser.addAliasForDirective(".word", ".4byte"); 251 Parser.addAliasForDirective(".dword", ".8byte"); 252 Parser.addAliasForDirective(".xword", ".8byte"); 253 254 // Initialize the set of available features. 255 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits())); 256 } 257 258 bool regsEqual(const MCParsedAsmOperand &Op1, 259 const MCParsedAsmOperand &Op2) const override; 260 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 261 SMLoc NameLoc, OperandVector &Operands) override; 262 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 263 OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc, 264 SMLoc &EndLoc) override; 265 bool ParseDirective(AsmToken DirectiveID) override; 266 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 267 unsigned Kind) override; 268 269 static bool classifySymbolRef(const MCExpr *Expr, 270 AArch64MCExpr::VariantKind &ELFRefKind, 271 MCSymbolRefExpr::VariantKind &DarwinRefKind, 272 int64_t &Addend); 273 }; 274 275 /// AArch64Operand - Instances of this class represent a parsed AArch64 machine 276 /// instruction. 277 class AArch64Operand : public MCParsedAsmOperand { 278 private: 279 enum KindTy { 280 k_Immediate, 281 k_ShiftedImm, 282 k_CondCode, 283 k_Register, 284 k_VectorList, 285 k_VectorIndex, 286 k_Token, 287 k_SysReg, 288 k_SysCR, 289 k_Prefetch, 290 k_ShiftExtend, 291 k_FPImm, 292 k_Barrier, 293 k_PSBHint, 294 k_BTIHint, 295 } Kind; 296 297 SMLoc StartLoc, EndLoc; 298 299 struct TokOp { 300 const char *Data; 301 unsigned Length; 302 bool IsSuffix; // Is the operand actually a suffix on the mnemonic. 303 }; 304 305 // Separate shift/extend operand. 306 struct ShiftExtendOp { 307 AArch64_AM::ShiftExtendType Type; 308 unsigned Amount; 309 bool HasExplicitAmount; 310 }; 311 312 struct RegOp { 313 unsigned RegNum; 314 RegKind Kind; 315 int ElementWidth; 316 317 // The register may be allowed as a different register class, 318 // e.g. for GPR64as32 or GPR32as64. 319 RegConstraintEqualityTy EqualityTy; 320 321 // In some cases the shift/extend needs to be explicitly parsed together 322 // with the register, rather than as a separate operand. This is needed 323 // for addressing modes where the instruction as a whole dictates the 324 // scaling/extend, rather than specific bits in the instruction. 325 // By parsing them as a single operand, we avoid the need to pass an 326 // extra operand in all CodeGen patterns (because all operands need to 327 // have an associated value), and we avoid the need to update TableGen to 328 // accept operands that have no associated bits in the instruction. 329 // 330 // An added benefit of parsing them together is that the assembler 331 // can give a sensible diagnostic if the scaling is not correct. 332 // 333 // The default is 'lsl #0' (HasExplicitAmount = false) if no 334 // ShiftExtend is specified. 335 ShiftExtendOp ShiftExtend; 336 }; 337 338 struct VectorListOp { 339 unsigned RegNum; 340 unsigned Count; 341 unsigned NumElements; 342 unsigned ElementWidth; 343 RegKind RegisterKind; 344 }; 345 346 struct VectorIndexOp { 347 unsigned Val; 348 }; 349 350 struct ImmOp { 351 const MCExpr *Val; 352 }; 353 354 struct ShiftedImmOp { 355 const MCExpr *Val; 356 unsigned ShiftAmount; 357 }; 358 359 struct CondCodeOp { 360 AArch64CC::CondCode Code; 361 }; 362 363 struct FPImmOp { 364 uint64_t Val; // APFloat value bitcasted to uint64_t. 365 bool IsExact; // describes whether parsed value was exact. 366 }; 367 368 struct BarrierOp { 369 const char *Data; 370 unsigned Length; 371 unsigned Val; // Not the enum since not all values have names. 372 }; 373 374 struct SysRegOp { 375 const char *Data; 376 unsigned Length; 377 uint32_t MRSReg; 378 uint32_t MSRReg; 379 uint32_t PStateField; 380 }; 381 382 struct SysCRImmOp { 383 unsigned Val; 384 }; 385 386 struct PrefetchOp { 387 const char *Data; 388 unsigned Length; 389 unsigned Val; 390 }; 391 392 struct PSBHintOp { 393 const char *Data; 394 unsigned Length; 395 unsigned Val; 396 }; 397 398 struct BTIHintOp { 399 const char *Data; 400 unsigned Length; 401 unsigned Val; 402 }; 403 404 struct ExtendOp { 405 unsigned Val; 406 }; 407 408 union { 409 struct TokOp Tok; 410 struct RegOp Reg; 411 struct VectorListOp VectorList; 412 struct VectorIndexOp VectorIndex; 413 struct ImmOp Imm; 414 struct ShiftedImmOp ShiftedImm; 415 struct CondCodeOp CondCode; 416 struct FPImmOp FPImm; 417 struct BarrierOp Barrier; 418 struct SysRegOp SysReg; 419 struct SysCRImmOp SysCRImm; 420 struct PrefetchOp Prefetch; 421 struct PSBHintOp PSBHint; 422 struct BTIHintOp BTIHint; 423 struct ShiftExtendOp ShiftExtend; 424 }; 425 426 // Keep the MCContext around as the MCExprs may need manipulated during 427 // the add<>Operands() calls. 428 MCContext &Ctx; 429 430 public: 431 AArch64Operand(KindTy K, MCContext &Ctx) : Kind(K), Ctx(Ctx) {} 432 433 AArch64Operand(const AArch64Operand &o) : MCParsedAsmOperand(), Ctx(o.Ctx) { 434 Kind = o.Kind; 435 StartLoc = o.StartLoc; 436 EndLoc = o.EndLoc; 437 switch (Kind) { 438 case k_Token: 439 Tok = o.Tok; 440 break; 441 case k_Immediate: 442 Imm = o.Imm; 443 break; 444 case k_ShiftedImm: 445 ShiftedImm = o.ShiftedImm; 446 break; 447 case k_CondCode: 448 CondCode = o.CondCode; 449 break; 450 case k_FPImm: 451 FPImm = o.FPImm; 452 break; 453 case k_Barrier: 454 Barrier = o.Barrier; 455 break; 456 case k_Register: 457 Reg = o.Reg; 458 break; 459 case k_VectorList: 460 VectorList = o.VectorList; 461 break; 462 case k_VectorIndex: 463 VectorIndex = o.VectorIndex; 464 break; 465 case k_SysReg: 466 SysReg = o.SysReg; 467 break; 468 case k_SysCR: 469 SysCRImm = o.SysCRImm; 470 break; 471 case k_Prefetch: 472 Prefetch = o.Prefetch; 473 break; 474 case k_PSBHint: 475 PSBHint = o.PSBHint; 476 break; 477 case k_BTIHint: 478 BTIHint = o.BTIHint; 479 break; 480 case k_ShiftExtend: 481 ShiftExtend = o.ShiftExtend; 482 break; 483 } 484 } 485 486 /// getStartLoc - Get the location of the first token of this operand. 487 SMLoc getStartLoc() const override { return StartLoc; } 488 /// getEndLoc - Get the location of the last token of this operand. 489 SMLoc getEndLoc() const override { return EndLoc; } 490 491 StringRef getToken() const { 492 assert(Kind == k_Token && "Invalid access!"); 493 return StringRef(Tok.Data, Tok.Length); 494 } 495 496 bool isTokenSuffix() const { 497 assert(Kind == k_Token && "Invalid access!"); 498 return Tok.IsSuffix; 499 } 500 501 const MCExpr *getImm() const { 502 assert(Kind == k_Immediate && "Invalid access!"); 503 return Imm.Val; 504 } 505 506 const MCExpr *getShiftedImmVal() const { 507 assert(Kind == k_ShiftedImm && "Invalid access!"); 508 return ShiftedImm.Val; 509 } 510 511 unsigned getShiftedImmShift() const { 512 assert(Kind == k_ShiftedImm && "Invalid access!"); 513 return ShiftedImm.ShiftAmount; 514 } 515 516 AArch64CC::CondCode getCondCode() const { 517 assert(Kind == k_CondCode && "Invalid access!"); 518 return CondCode.Code; 519 } 520 521 APFloat getFPImm() const { 522 assert (Kind == k_FPImm && "Invalid access!"); 523 return APFloat(APFloat::IEEEdouble(), APInt(64, FPImm.Val, true)); 524 } 525 526 bool getFPImmIsExact() const { 527 assert (Kind == k_FPImm && "Invalid access!"); 528 return FPImm.IsExact; 529 } 530 531 unsigned getBarrier() const { 532 assert(Kind == k_Barrier && "Invalid access!"); 533 return Barrier.Val; 534 } 535 536 StringRef getBarrierName() const { 537 assert(Kind == k_Barrier && "Invalid access!"); 538 return StringRef(Barrier.Data, Barrier.Length); 539 } 540 541 unsigned getReg() const override { 542 assert(Kind == k_Register && "Invalid access!"); 543 return Reg.RegNum; 544 } 545 546 RegConstraintEqualityTy getRegEqualityTy() const { 547 assert(Kind == k_Register && "Invalid access!"); 548 return Reg.EqualityTy; 549 } 550 551 unsigned getVectorListStart() const { 552 assert(Kind == k_VectorList && "Invalid access!"); 553 return VectorList.RegNum; 554 } 555 556 unsigned getVectorListCount() const { 557 assert(Kind == k_VectorList && "Invalid access!"); 558 return VectorList.Count; 559 } 560 561 unsigned getVectorIndex() const { 562 assert(Kind == k_VectorIndex && "Invalid access!"); 563 return VectorIndex.Val; 564 } 565 566 StringRef getSysReg() const { 567 assert(Kind == k_SysReg && "Invalid access!"); 568 return StringRef(SysReg.Data, SysReg.Length); 569 } 570 571 unsigned getSysCR() const { 572 assert(Kind == k_SysCR && "Invalid access!"); 573 return SysCRImm.Val; 574 } 575 576 unsigned getPrefetch() const { 577 assert(Kind == k_Prefetch && "Invalid access!"); 578 return Prefetch.Val; 579 } 580 581 unsigned getPSBHint() const { 582 assert(Kind == k_PSBHint && "Invalid access!"); 583 return PSBHint.Val; 584 } 585 586 StringRef getPSBHintName() const { 587 assert(Kind == k_PSBHint && "Invalid access!"); 588 return StringRef(PSBHint.Data, PSBHint.Length); 589 } 590 591 unsigned getBTIHint() const { 592 assert(Kind == k_BTIHint && "Invalid access!"); 593 return BTIHint.Val; 594 } 595 596 StringRef getBTIHintName() const { 597 assert(Kind == k_BTIHint && "Invalid access!"); 598 return StringRef(BTIHint.Data, BTIHint.Length); 599 } 600 601 StringRef getPrefetchName() const { 602 assert(Kind == k_Prefetch && "Invalid access!"); 603 return StringRef(Prefetch.Data, Prefetch.Length); 604 } 605 606 AArch64_AM::ShiftExtendType getShiftExtendType() const { 607 if (Kind == k_ShiftExtend) 608 return ShiftExtend.Type; 609 if (Kind == k_Register) 610 return Reg.ShiftExtend.Type; 611 llvm_unreachable("Invalid access!"); 612 } 613 614 unsigned getShiftExtendAmount() const { 615 if (Kind == k_ShiftExtend) 616 return ShiftExtend.Amount; 617 if (Kind == k_Register) 618 return Reg.ShiftExtend.Amount; 619 llvm_unreachable("Invalid access!"); 620 } 621 622 bool hasShiftExtendAmount() const { 623 if (Kind == k_ShiftExtend) 624 return ShiftExtend.HasExplicitAmount; 625 if (Kind == k_Register) 626 return Reg.ShiftExtend.HasExplicitAmount; 627 llvm_unreachable("Invalid access!"); 628 } 629 630 bool isImm() const override { return Kind == k_Immediate; } 631 bool isMem() const override { return false; } 632 633 bool isUImm6() 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 < 64); 641 } 642 643 template <int Width> bool isSImm() const { return isSImmScaled<Width, 1>(); } 644 645 template <int Bits, int Scale> DiagnosticPredicate isSImmScaled() const { 646 return isImmScaled<Bits, Scale>(true); 647 } 648 649 template <int Bits, int Scale> DiagnosticPredicate isUImmScaled() const { 650 return isImmScaled<Bits, Scale>(false); 651 } 652 653 template <int Bits, int Scale> 654 DiagnosticPredicate isImmScaled(bool Signed) const { 655 if (!isImm()) 656 return DiagnosticPredicateTy::NoMatch; 657 658 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 659 if (!MCE) 660 return DiagnosticPredicateTy::NoMatch; 661 662 int64_t MinVal, MaxVal; 663 if (Signed) { 664 int64_t Shift = Bits - 1; 665 MinVal = (int64_t(1) << Shift) * -Scale; 666 MaxVal = ((int64_t(1) << Shift) - 1) * Scale; 667 } else { 668 MinVal = 0; 669 MaxVal = ((int64_t(1) << Bits) - 1) * Scale; 670 } 671 672 int64_t Val = MCE->getValue(); 673 if (Val >= MinVal && Val <= MaxVal && (Val % Scale) == 0) 674 return DiagnosticPredicateTy::Match; 675 676 return DiagnosticPredicateTy::NearMatch; 677 } 678 679 DiagnosticPredicate isSVEPattern() const { 680 if (!isImm()) 681 return DiagnosticPredicateTy::NoMatch; 682 auto *MCE = dyn_cast<MCConstantExpr>(getImm()); 683 if (!MCE) 684 return DiagnosticPredicateTy::NoMatch; 685 int64_t Val = MCE->getValue(); 686 if (Val >= 0 && Val < 32) 687 return DiagnosticPredicateTy::Match; 688 return DiagnosticPredicateTy::NearMatch; 689 } 690 691 bool isSymbolicUImm12Offset(const MCExpr *Expr) const { 692 AArch64MCExpr::VariantKind ELFRefKind; 693 MCSymbolRefExpr::VariantKind DarwinRefKind; 694 int64_t Addend; 695 if (!AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, 696 Addend)) { 697 // If we don't understand the expression, assume the best and 698 // let the fixup and relocation code deal with it. 699 return true; 700 } 701 702 if (DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF || 703 ELFRefKind == AArch64MCExpr::VK_LO12 || 704 ELFRefKind == AArch64MCExpr::VK_GOT_LO12 || 705 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 || 706 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC || 707 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 || 708 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC || 709 ELFRefKind == AArch64MCExpr::VK_GOTTPREL_LO12_NC || 710 ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12 || 711 ELFRefKind == AArch64MCExpr::VK_SECREL_LO12 || 712 ELFRefKind == AArch64MCExpr::VK_SECREL_HI12) { 713 // Note that we don't range-check the addend. It's adjusted modulo page 714 // size when converted, so there is no "out of range" condition when using 715 // @pageoff. 716 return true; 717 } else if (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF || 718 DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) { 719 // @gotpageoff/@tlvppageoff can only be used directly, not with an addend. 720 return Addend == 0; 721 } 722 723 return false; 724 } 725 726 template <int Scale> bool isUImm12Offset() const { 727 if (!isImm()) 728 return false; 729 730 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 731 if (!MCE) 732 return isSymbolicUImm12Offset(getImm()); 733 734 int64_t Val = MCE->getValue(); 735 return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000; 736 } 737 738 template <int N, int M> 739 bool isImmInRange() const { 740 if (!isImm()) 741 return false; 742 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 743 if (!MCE) 744 return false; 745 int64_t Val = MCE->getValue(); 746 return (Val >= N && Val <= M); 747 } 748 749 // NOTE: Also used for isLogicalImmNot as anything that can be represented as 750 // a logical immediate can always be represented when inverted. 751 template <typename T> 752 bool isLogicalImm() const { 753 if (!isImm()) 754 return false; 755 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 756 if (!MCE) 757 return false; 758 759 int64_t Val = MCE->getValue(); 760 // Avoid left shift by 64 directly. 761 uint64_t Upper = UINT64_C(-1) << (sizeof(T) * 4) << (sizeof(T) * 4); 762 // Allow all-0 or all-1 in top bits to permit bitwise NOT. 763 if ((Val & Upper) && (Val & Upper) != Upper) 764 return false; 765 766 return AArch64_AM::isLogicalImmediate(Val & ~Upper, sizeof(T) * 8); 767 } 768 769 bool isShiftedImm() const { return Kind == k_ShiftedImm; } 770 771 /// Returns the immediate value as a pair of (imm, shift) if the immediate is 772 /// a shifted immediate by value 'Shift' or '0', or if it is an unshifted 773 /// immediate that can be shifted by 'Shift'. 774 template <unsigned Width> 775 Optional<std::pair<int64_t, unsigned> > getShiftedVal() const { 776 if (isShiftedImm() && Width == getShiftedImmShift()) 777 if (auto *CE = dyn_cast<MCConstantExpr>(getShiftedImmVal())) 778 return std::make_pair(CE->getValue(), Width); 779 780 if (isImm()) 781 if (auto *CE = dyn_cast<MCConstantExpr>(getImm())) { 782 int64_t Val = CE->getValue(); 783 if ((Val != 0) && (uint64_t(Val >> Width) << Width) == uint64_t(Val)) 784 return std::make_pair(Val >> Width, Width); 785 else 786 return std::make_pair(Val, 0u); 787 } 788 789 return {}; 790 } 791 792 bool isAddSubImm() const { 793 if (!isShiftedImm() && !isImm()) 794 return false; 795 796 const MCExpr *Expr; 797 798 // An ADD/SUB shifter is either 'lsl #0' or 'lsl #12'. 799 if (isShiftedImm()) { 800 unsigned Shift = ShiftedImm.ShiftAmount; 801 Expr = ShiftedImm.Val; 802 if (Shift != 0 && Shift != 12) 803 return false; 804 } else { 805 Expr = getImm(); 806 } 807 808 AArch64MCExpr::VariantKind ELFRefKind; 809 MCSymbolRefExpr::VariantKind DarwinRefKind; 810 int64_t Addend; 811 if (AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind, 812 DarwinRefKind, Addend)) { 813 return DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF 814 || DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF 815 || (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF && Addend == 0) 816 || ELFRefKind == AArch64MCExpr::VK_LO12 817 || ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 818 || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 819 || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC 820 || ELFRefKind == AArch64MCExpr::VK_TPREL_HI12 821 || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 822 || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC 823 || ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12 824 || ELFRefKind == AArch64MCExpr::VK_SECREL_HI12 825 || ELFRefKind == AArch64MCExpr::VK_SECREL_LO12; 826 } 827 828 // If it's a constant, it should be a real immediate in range. 829 if (auto ShiftedVal = getShiftedVal<12>()) 830 return ShiftedVal->first >= 0 && ShiftedVal->first <= 0xfff; 831 832 // If it's an expression, we hope for the best and let the fixup/relocation 833 // code deal with it. 834 return true; 835 } 836 837 bool isAddSubImmNeg() const { 838 if (!isShiftedImm() && !isImm()) 839 return false; 840 841 // Otherwise it should be a real negative immediate in range. 842 if (auto ShiftedVal = getShiftedVal<12>()) 843 return ShiftedVal->first < 0 && -ShiftedVal->first <= 0xfff; 844 845 return false; 846 } 847 848 // Signed value in the range -128 to +127. For element widths of 849 // 16 bits or higher it may also be a signed multiple of 256 in the 850 // range -32768 to +32512. 851 // For element-width of 8 bits a range of -128 to 255 is accepted, 852 // since a copy of a byte can be either signed/unsigned. 853 template <typename T> 854 DiagnosticPredicate isSVECpyImm() const { 855 if (!isShiftedImm() && (!isImm() || !isa<MCConstantExpr>(getImm()))) 856 return DiagnosticPredicateTy::NoMatch; 857 858 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value; 859 if (auto ShiftedImm = getShiftedVal<8>()) 860 if (!(IsByte && ShiftedImm->second) && 861 AArch64_AM::isSVECpyImm<T>(uint64_t(ShiftedImm->first) 862 << ShiftedImm->second)) 863 return DiagnosticPredicateTy::Match; 864 865 return DiagnosticPredicateTy::NearMatch; 866 } 867 868 // Unsigned value in the range 0 to 255. For element widths of 869 // 16 bits or higher it may also be a signed multiple of 256 in the 870 // range 0 to 65280. 871 template <typename T> DiagnosticPredicate isSVEAddSubImm() const { 872 if (!isShiftedImm() && (!isImm() || !isa<MCConstantExpr>(getImm()))) 873 return DiagnosticPredicateTy::NoMatch; 874 875 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value; 876 if (auto ShiftedImm = getShiftedVal<8>()) 877 if (!(IsByte && ShiftedImm->second) && 878 AArch64_AM::isSVEAddSubImm<T>(ShiftedImm->first 879 << ShiftedImm->second)) 880 return DiagnosticPredicateTy::Match; 881 882 return DiagnosticPredicateTy::NearMatch; 883 } 884 885 template <typename T> DiagnosticPredicate isSVEPreferredLogicalImm() const { 886 if (isLogicalImm<T>() && !isSVECpyImm<T>()) 887 return DiagnosticPredicateTy::Match; 888 return DiagnosticPredicateTy::NoMatch; 889 } 890 891 bool isCondCode() const { return Kind == k_CondCode; } 892 893 bool isSIMDImmType10() const { 894 if (!isImm()) 895 return false; 896 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 897 if (!MCE) 898 return false; 899 return AArch64_AM::isAdvSIMDModImmType10(MCE->getValue()); 900 } 901 902 template<int N> 903 bool isBranchTarget() const { 904 if (!isImm()) 905 return false; 906 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 907 if (!MCE) 908 return true; 909 int64_t Val = MCE->getValue(); 910 if (Val & 0x3) 911 return false; 912 assert(N > 0 && "Branch target immediate cannot be 0 bits!"); 913 return (Val >= -((1<<(N-1)) << 2) && Val <= (((1<<(N-1))-1) << 2)); 914 } 915 916 bool 917 isMovWSymbol(ArrayRef<AArch64MCExpr::VariantKind> AllowedModifiers) const { 918 if (!isImm()) 919 return false; 920 921 AArch64MCExpr::VariantKind ELFRefKind; 922 MCSymbolRefExpr::VariantKind DarwinRefKind; 923 int64_t Addend; 924 if (!AArch64AsmParser::classifySymbolRef(getImm(), ELFRefKind, 925 DarwinRefKind, Addend)) { 926 return false; 927 } 928 if (DarwinRefKind != MCSymbolRefExpr::VK_None) 929 return false; 930 931 for (unsigned i = 0; i != AllowedModifiers.size(); ++i) { 932 if (ELFRefKind == AllowedModifiers[i]) 933 return true; 934 } 935 936 return false; 937 } 938 939 bool isMovWSymbolG3() const { 940 return isMovWSymbol({AArch64MCExpr::VK_ABS_G3, AArch64MCExpr::VK_PREL_G3}); 941 } 942 943 bool isMovWSymbolG2() const { 944 return isMovWSymbol( 945 {AArch64MCExpr::VK_ABS_G2, AArch64MCExpr::VK_ABS_G2_S, 946 AArch64MCExpr::VK_ABS_G2_NC, AArch64MCExpr::VK_PREL_G2, 947 AArch64MCExpr::VK_PREL_G2_NC, AArch64MCExpr::VK_TPREL_G2, 948 AArch64MCExpr::VK_DTPREL_G2}); 949 } 950 951 bool isMovWSymbolG1() const { 952 return isMovWSymbol( 953 {AArch64MCExpr::VK_ABS_G1, AArch64MCExpr::VK_ABS_G1_S, 954 AArch64MCExpr::VK_ABS_G1_NC, AArch64MCExpr::VK_PREL_G1, 955 AArch64MCExpr::VK_PREL_G1_NC, AArch64MCExpr::VK_GOTTPREL_G1, 956 AArch64MCExpr::VK_TPREL_G1, AArch64MCExpr::VK_TPREL_G1_NC, 957 AArch64MCExpr::VK_DTPREL_G1, AArch64MCExpr::VK_DTPREL_G1_NC}); 958 } 959 960 bool isMovWSymbolG0() const { 961 return isMovWSymbol( 962 {AArch64MCExpr::VK_ABS_G0, AArch64MCExpr::VK_ABS_G0_S, 963 AArch64MCExpr::VK_ABS_G0_NC, AArch64MCExpr::VK_PREL_G0, 964 AArch64MCExpr::VK_PREL_G0_NC, AArch64MCExpr::VK_GOTTPREL_G0_NC, 965 AArch64MCExpr::VK_TPREL_G0, AArch64MCExpr::VK_TPREL_G0_NC, 966 AArch64MCExpr::VK_DTPREL_G0, AArch64MCExpr::VK_DTPREL_G0_NC}); 967 } 968 969 template<int RegWidth, int Shift> 970 bool isMOVZMovAlias() const { 971 if (!isImm()) return false; 972 973 const MCExpr *E = getImm(); 974 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(E)) { 975 uint64_t Value = CE->getValue(); 976 977 return AArch64_AM::isMOVZMovAlias(Value, Shift, RegWidth); 978 } 979 // Only supports the case of Shift being 0 if an expression is used as an 980 // operand 981 return !Shift && E; 982 } 983 984 template<int RegWidth, int Shift> 985 bool isMOVNMovAlias() const { 986 if (!isImm()) return false; 987 988 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 989 if (!CE) return false; 990 uint64_t Value = CE->getValue(); 991 992 return AArch64_AM::isMOVNMovAlias(Value, Shift, RegWidth); 993 } 994 995 bool isFPImm() const { 996 return Kind == k_FPImm && 997 AArch64_AM::getFP64Imm(getFPImm().bitcastToAPInt()) != -1; 998 } 999 1000 bool isBarrier() const { return Kind == k_Barrier; } 1001 bool isSysReg() const { return Kind == k_SysReg; } 1002 1003 bool isMRSSystemRegister() const { 1004 if (!isSysReg()) return false; 1005 1006 return SysReg.MRSReg != -1U; 1007 } 1008 1009 bool isMSRSystemRegister() const { 1010 if (!isSysReg()) return false; 1011 return SysReg.MSRReg != -1U; 1012 } 1013 1014 bool isSystemPStateFieldWithImm0_1() const { 1015 if (!isSysReg()) return false; 1016 return (SysReg.PStateField == AArch64PState::PAN || 1017 SysReg.PStateField == AArch64PState::DIT || 1018 SysReg.PStateField == AArch64PState::UAO || 1019 SysReg.PStateField == AArch64PState::SSBS); 1020 } 1021 1022 bool isSystemPStateFieldWithImm0_15() const { 1023 if (!isSysReg() || isSystemPStateFieldWithImm0_1()) return false; 1024 return SysReg.PStateField != -1U; 1025 } 1026 1027 bool isReg() const override { 1028 return Kind == k_Register; 1029 } 1030 1031 bool isScalarReg() const { 1032 return Kind == k_Register && Reg.Kind == RegKind::Scalar; 1033 } 1034 1035 bool isNeonVectorReg() const { 1036 return Kind == k_Register && Reg.Kind == RegKind::NeonVector; 1037 } 1038 1039 bool isNeonVectorRegLo() const { 1040 return Kind == k_Register && Reg.Kind == RegKind::NeonVector && 1041 (AArch64MCRegisterClasses[AArch64::FPR128_loRegClassID].contains( 1042 Reg.RegNum) || 1043 AArch64MCRegisterClasses[AArch64::FPR64_loRegClassID].contains( 1044 Reg.RegNum)); 1045 } 1046 1047 template <unsigned Class> bool isSVEVectorReg() const { 1048 RegKind RK; 1049 switch (Class) { 1050 case AArch64::ZPRRegClassID: 1051 case AArch64::ZPR_3bRegClassID: 1052 case AArch64::ZPR_4bRegClassID: 1053 RK = RegKind::SVEDataVector; 1054 break; 1055 case AArch64::PPRRegClassID: 1056 case AArch64::PPR_3bRegClassID: 1057 RK = RegKind::SVEPredicateVector; 1058 break; 1059 default: 1060 llvm_unreachable("Unsupport register class"); 1061 } 1062 1063 return (Kind == k_Register && Reg.Kind == RK) && 1064 AArch64MCRegisterClasses[Class].contains(getReg()); 1065 } 1066 1067 template <unsigned Class> bool isFPRasZPR() const { 1068 return Kind == k_Register && Reg.Kind == RegKind::Scalar && 1069 AArch64MCRegisterClasses[Class].contains(getReg()); 1070 } 1071 1072 template <int ElementWidth, unsigned Class> 1073 DiagnosticPredicate isSVEPredicateVectorRegOfWidth() const { 1074 if (Kind != k_Register || Reg.Kind != RegKind::SVEPredicateVector) 1075 return DiagnosticPredicateTy::NoMatch; 1076 1077 if (isSVEVectorReg<Class>() && (Reg.ElementWidth == ElementWidth)) 1078 return DiagnosticPredicateTy::Match; 1079 1080 return DiagnosticPredicateTy::NearMatch; 1081 } 1082 1083 template <int ElementWidth, unsigned Class> 1084 DiagnosticPredicate isSVEDataVectorRegOfWidth() const { 1085 if (Kind != k_Register || Reg.Kind != RegKind::SVEDataVector) 1086 return DiagnosticPredicateTy::NoMatch; 1087 1088 if (isSVEVectorReg<Class>() && Reg.ElementWidth == ElementWidth) 1089 return DiagnosticPredicateTy::Match; 1090 1091 return DiagnosticPredicateTy::NearMatch; 1092 } 1093 1094 template <int ElementWidth, unsigned Class, 1095 AArch64_AM::ShiftExtendType ShiftExtendTy, int ShiftWidth, 1096 bool ShiftWidthAlwaysSame> 1097 DiagnosticPredicate isSVEDataVectorRegWithShiftExtend() const { 1098 auto VectorMatch = isSVEDataVectorRegOfWidth<ElementWidth, Class>(); 1099 if (!VectorMatch.isMatch()) 1100 return DiagnosticPredicateTy::NoMatch; 1101 1102 // Give a more specific diagnostic when the user has explicitly typed in 1103 // a shift-amount that does not match what is expected, but for which 1104 // there is also an unscaled addressing mode (e.g. sxtw/uxtw). 1105 bool MatchShift = getShiftExtendAmount() == Log2_32(ShiftWidth / 8); 1106 if (!MatchShift && (ShiftExtendTy == AArch64_AM::UXTW || 1107 ShiftExtendTy == AArch64_AM::SXTW) && 1108 !ShiftWidthAlwaysSame && hasShiftExtendAmount() && ShiftWidth == 8) 1109 return DiagnosticPredicateTy::NoMatch; 1110 1111 if (MatchShift && ShiftExtendTy == getShiftExtendType()) 1112 return DiagnosticPredicateTy::Match; 1113 1114 return DiagnosticPredicateTy::NearMatch; 1115 } 1116 1117 bool isGPR32as64() const { 1118 return Kind == k_Register && Reg.Kind == RegKind::Scalar && 1119 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(Reg.RegNum); 1120 } 1121 1122 bool isGPR64as32() const { 1123 return Kind == k_Register && Reg.Kind == RegKind::Scalar && 1124 AArch64MCRegisterClasses[AArch64::GPR32RegClassID].contains(Reg.RegNum); 1125 } 1126 1127 bool isWSeqPair() const { 1128 return Kind == k_Register && Reg.Kind == RegKind::Scalar && 1129 AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID].contains( 1130 Reg.RegNum); 1131 } 1132 1133 bool isXSeqPair() const { 1134 return Kind == k_Register && Reg.Kind == RegKind::Scalar && 1135 AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID].contains( 1136 Reg.RegNum); 1137 } 1138 1139 template<int64_t Angle, int64_t Remainder> 1140 DiagnosticPredicate isComplexRotation() const { 1141 if (!isImm()) return DiagnosticPredicateTy::NoMatch; 1142 1143 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1144 if (!CE) return DiagnosticPredicateTy::NoMatch; 1145 uint64_t Value = CE->getValue(); 1146 1147 if (Value % Angle == Remainder && Value <= 270) 1148 return DiagnosticPredicateTy::Match; 1149 return DiagnosticPredicateTy::NearMatch; 1150 } 1151 1152 template <unsigned RegClassID> bool isGPR64() const { 1153 return Kind == k_Register && Reg.Kind == RegKind::Scalar && 1154 AArch64MCRegisterClasses[RegClassID].contains(getReg()); 1155 } 1156 1157 template <unsigned RegClassID, int ExtWidth> 1158 DiagnosticPredicate isGPR64WithShiftExtend() const { 1159 if (Kind != k_Register || Reg.Kind != RegKind::Scalar) 1160 return DiagnosticPredicateTy::NoMatch; 1161 1162 if (isGPR64<RegClassID>() && getShiftExtendType() == AArch64_AM::LSL && 1163 getShiftExtendAmount() == Log2_32(ExtWidth / 8)) 1164 return DiagnosticPredicateTy::Match; 1165 return DiagnosticPredicateTy::NearMatch; 1166 } 1167 1168 /// Is this a vector list with the type implicit (presumably attached to the 1169 /// instruction itself)? 1170 template <RegKind VectorKind, unsigned NumRegs> 1171 bool isImplicitlyTypedVectorList() const { 1172 return Kind == k_VectorList && VectorList.Count == NumRegs && 1173 VectorList.NumElements == 0 && 1174 VectorList.RegisterKind == VectorKind; 1175 } 1176 1177 template <RegKind VectorKind, unsigned NumRegs, unsigned NumElements, 1178 unsigned ElementWidth> 1179 bool isTypedVectorList() const { 1180 if (Kind != k_VectorList) 1181 return false; 1182 if (VectorList.Count != NumRegs) 1183 return false; 1184 if (VectorList.RegisterKind != VectorKind) 1185 return false; 1186 if (VectorList.ElementWidth != ElementWidth) 1187 return false; 1188 return VectorList.NumElements == NumElements; 1189 } 1190 1191 template <int Min, int Max> 1192 DiagnosticPredicate isVectorIndex() const { 1193 if (Kind != k_VectorIndex) 1194 return DiagnosticPredicateTy::NoMatch; 1195 if (VectorIndex.Val >= Min && VectorIndex.Val <= Max) 1196 return DiagnosticPredicateTy::Match; 1197 return DiagnosticPredicateTy::NearMatch; 1198 } 1199 1200 bool isToken() const override { return Kind == k_Token; } 1201 1202 bool isTokenEqual(StringRef Str) const { 1203 return Kind == k_Token && getToken() == Str; 1204 } 1205 bool isSysCR() const { return Kind == k_SysCR; } 1206 bool isPrefetch() const { return Kind == k_Prefetch; } 1207 bool isPSBHint() const { return Kind == k_PSBHint; } 1208 bool isBTIHint() const { return Kind == k_BTIHint; } 1209 bool isShiftExtend() const { return Kind == k_ShiftExtend; } 1210 bool isShifter() const { 1211 if (!isShiftExtend()) 1212 return false; 1213 1214 AArch64_AM::ShiftExtendType ST = getShiftExtendType(); 1215 return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR || 1216 ST == AArch64_AM::ASR || ST == AArch64_AM::ROR || 1217 ST == AArch64_AM::MSL); 1218 } 1219 1220 template <unsigned ImmEnum> DiagnosticPredicate isExactFPImm() const { 1221 if (Kind != k_FPImm) 1222 return DiagnosticPredicateTy::NoMatch; 1223 1224 if (getFPImmIsExact()) { 1225 // Lookup the immediate from table of supported immediates. 1226 auto *Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmEnum); 1227 assert(Desc && "Unknown enum value"); 1228 1229 // Calculate its FP value. 1230 APFloat RealVal(APFloat::IEEEdouble()); 1231 auto StatusOrErr = 1232 RealVal.convertFromString(Desc->Repr, APFloat::rmTowardZero); 1233 if (errorToBool(StatusOrErr.takeError()) || *StatusOrErr != APFloat::opOK) 1234 llvm_unreachable("FP immediate is not exact"); 1235 1236 if (getFPImm().bitwiseIsEqual(RealVal)) 1237 return DiagnosticPredicateTy::Match; 1238 } 1239 1240 return DiagnosticPredicateTy::NearMatch; 1241 } 1242 1243 template <unsigned ImmA, unsigned ImmB> 1244 DiagnosticPredicate isExactFPImm() const { 1245 DiagnosticPredicate Res = DiagnosticPredicateTy::NoMatch; 1246 if ((Res = isExactFPImm<ImmA>())) 1247 return DiagnosticPredicateTy::Match; 1248 if ((Res = isExactFPImm<ImmB>())) 1249 return DiagnosticPredicateTy::Match; 1250 return Res; 1251 } 1252 1253 bool isExtend() const { 1254 if (!isShiftExtend()) 1255 return false; 1256 1257 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 1258 return (ET == AArch64_AM::UXTB || ET == AArch64_AM::SXTB || 1259 ET == AArch64_AM::UXTH || ET == AArch64_AM::SXTH || 1260 ET == AArch64_AM::UXTW || ET == AArch64_AM::SXTW || 1261 ET == AArch64_AM::UXTX || ET == AArch64_AM::SXTX || 1262 ET == AArch64_AM::LSL) && 1263 getShiftExtendAmount() <= 4; 1264 } 1265 1266 bool isExtend64() const { 1267 if (!isExtend()) 1268 return false; 1269 // Make sure the extend expects a 32-bit source register. 1270 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 1271 return ET == AArch64_AM::UXTB || ET == AArch64_AM::SXTB || 1272 ET == AArch64_AM::UXTH || ET == AArch64_AM::SXTH || 1273 ET == AArch64_AM::UXTW || ET == AArch64_AM::SXTW; 1274 } 1275 1276 bool isExtendLSL64() const { 1277 if (!isExtend()) 1278 return false; 1279 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 1280 return (ET == AArch64_AM::UXTX || ET == AArch64_AM::SXTX || 1281 ET == AArch64_AM::LSL) && 1282 getShiftExtendAmount() <= 4; 1283 } 1284 1285 template<int Width> bool isMemXExtend() const { 1286 if (!isExtend()) 1287 return false; 1288 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 1289 return (ET == AArch64_AM::LSL || ET == AArch64_AM::SXTX) && 1290 (getShiftExtendAmount() == Log2_32(Width / 8) || 1291 getShiftExtendAmount() == 0); 1292 } 1293 1294 template<int Width> bool isMemWExtend() const { 1295 if (!isExtend()) 1296 return false; 1297 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 1298 return (ET == AArch64_AM::UXTW || ET == AArch64_AM::SXTW) && 1299 (getShiftExtendAmount() == Log2_32(Width / 8) || 1300 getShiftExtendAmount() == 0); 1301 } 1302 1303 template <unsigned width> 1304 bool isArithmeticShifter() const { 1305 if (!isShifter()) 1306 return false; 1307 1308 // An arithmetic shifter is LSL, LSR, or ASR. 1309 AArch64_AM::ShiftExtendType ST = getShiftExtendType(); 1310 return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR || 1311 ST == AArch64_AM::ASR) && getShiftExtendAmount() < width; 1312 } 1313 1314 template <unsigned width> 1315 bool isLogicalShifter() const { 1316 if (!isShifter()) 1317 return false; 1318 1319 // A logical shifter is LSL, LSR, ASR or ROR. 1320 AArch64_AM::ShiftExtendType ST = getShiftExtendType(); 1321 return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR || 1322 ST == AArch64_AM::ASR || ST == AArch64_AM::ROR) && 1323 getShiftExtendAmount() < width; 1324 } 1325 1326 bool isMovImm32Shifter() const { 1327 if (!isShifter()) 1328 return false; 1329 1330 // A MOVi shifter is LSL of 0, 16, 32, or 48. 1331 AArch64_AM::ShiftExtendType ST = getShiftExtendType(); 1332 if (ST != AArch64_AM::LSL) 1333 return false; 1334 uint64_t Val = getShiftExtendAmount(); 1335 return (Val == 0 || Val == 16); 1336 } 1337 1338 bool isMovImm64Shifter() const { 1339 if (!isShifter()) 1340 return false; 1341 1342 // A MOVi shifter is LSL of 0 or 16. 1343 AArch64_AM::ShiftExtendType ST = getShiftExtendType(); 1344 if (ST != AArch64_AM::LSL) 1345 return false; 1346 uint64_t Val = getShiftExtendAmount(); 1347 return (Val == 0 || Val == 16 || Val == 32 || Val == 48); 1348 } 1349 1350 bool isLogicalVecShifter() const { 1351 if (!isShifter()) 1352 return false; 1353 1354 // A logical vector shifter is a left shift by 0, 8, 16, or 24. 1355 unsigned Shift = getShiftExtendAmount(); 1356 return getShiftExtendType() == AArch64_AM::LSL && 1357 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24); 1358 } 1359 1360 bool isLogicalVecHalfWordShifter() const { 1361 if (!isLogicalVecShifter()) 1362 return false; 1363 1364 // A logical vector shifter is a left shift by 0 or 8. 1365 unsigned Shift = getShiftExtendAmount(); 1366 return getShiftExtendType() == AArch64_AM::LSL && 1367 (Shift == 0 || Shift == 8); 1368 } 1369 1370 bool isMoveVecShifter() const { 1371 if (!isShiftExtend()) 1372 return false; 1373 1374 // A logical vector shifter is a left shift by 8 or 16. 1375 unsigned Shift = getShiftExtendAmount(); 1376 return getShiftExtendType() == AArch64_AM::MSL && 1377 (Shift == 8 || Shift == 16); 1378 } 1379 1380 // Fallback unscaled operands are for aliases of LDR/STR that fall back 1381 // to LDUR/STUR when the offset is not legal for the former but is for 1382 // the latter. As such, in addition to checking for being a legal unscaled 1383 // address, also check that it is not a legal scaled address. This avoids 1384 // ambiguity in the matcher. 1385 template<int Width> 1386 bool isSImm9OffsetFB() const { 1387 return isSImm<9>() && !isUImm12Offset<Width / 8>(); 1388 } 1389 1390 bool isAdrpLabel() const { 1391 // Validation was handled during parsing, so we just sanity check that 1392 // something didn't go haywire. 1393 if (!isImm()) 1394 return false; 1395 1396 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) { 1397 int64_t Val = CE->getValue(); 1398 int64_t Min = - (4096 * (1LL << (21 - 1))); 1399 int64_t Max = 4096 * ((1LL << (21 - 1)) - 1); 1400 return (Val % 4096) == 0 && Val >= Min && Val <= Max; 1401 } 1402 1403 return true; 1404 } 1405 1406 bool isAdrLabel() const { 1407 // Validation was handled during parsing, so we just sanity check that 1408 // something didn't go haywire. 1409 if (!isImm()) 1410 return false; 1411 1412 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) { 1413 int64_t Val = CE->getValue(); 1414 int64_t Min = - (1LL << (21 - 1)); 1415 int64_t Max = ((1LL << (21 - 1)) - 1); 1416 return Val >= Min && Val <= Max; 1417 } 1418 1419 return true; 1420 } 1421 1422 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 1423 // Add as immediates when possible. Null MCExpr = 0. 1424 if (!Expr) 1425 Inst.addOperand(MCOperand::createImm(0)); 1426 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 1427 Inst.addOperand(MCOperand::createImm(CE->getValue())); 1428 else 1429 Inst.addOperand(MCOperand::createExpr(Expr)); 1430 } 1431 1432 void addRegOperands(MCInst &Inst, unsigned N) const { 1433 assert(N == 1 && "Invalid number of operands!"); 1434 Inst.addOperand(MCOperand::createReg(getReg())); 1435 } 1436 1437 void addGPR32as64Operands(MCInst &Inst, unsigned N) const { 1438 assert(N == 1 && "Invalid number of operands!"); 1439 assert( 1440 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(getReg())); 1441 1442 const MCRegisterInfo *RI = Ctx.getRegisterInfo(); 1443 uint32_t Reg = RI->getRegClass(AArch64::GPR32RegClassID).getRegister( 1444 RI->getEncodingValue(getReg())); 1445 1446 Inst.addOperand(MCOperand::createReg(Reg)); 1447 } 1448 1449 void addGPR64as32Operands(MCInst &Inst, unsigned N) const { 1450 assert(N == 1 && "Invalid number of operands!"); 1451 assert( 1452 AArch64MCRegisterClasses[AArch64::GPR32RegClassID].contains(getReg())); 1453 1454 const MCRegisterInfo *RI = Ctx.getRegisterInfo(); 1455 uint32_t Reg = RI->getRegClass(AArch64::GPR64RegClassID).getRegister( 1456 RI->getEncodingValue(getReg())); 1457 1458 Inst.addOperand(MCOperand::createReg(Reg)); 1459 } 1460 1461 template <int Width> 1462 void addFPRasZPRRegOperands(MCInst &Inst, unsigned N) const { 1463 unsigned Base; 1464 switch (Width) { 1465 case 8: Base = AArch64::B0; break; 1466 case 16: Base = AArch64::H0; break; 1467 case 32: Base = AArch64::S0; break; 1468 case 64: Base = AArch64::D0; break; 1469 case 128: Base = AArch64::Q0; break; 1470 default: 1471 llvm_unreachable("Unsupported width"); 1472 } 1473 Inst.addOperand(MCOperand::createReg(AArch64::Z0 + getReg() - Base)); 1474 } 1475 1476 void addVectorReg64Operands(MCInst &Inst, unsigned N) const { 1477 assert(N == 1 && "Invalid number of operands!"); 1478 assert( 1479 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains(getReg())); 1480 Inst.addOperand(MCOperand::createReg(AArch64::D0 + getReg() - AArch64::Q0)); 1481 } 1482 1483 void addVectorReg128Operands(MCInst &Inst, unsigned N) const { 1484 assert(N == 1 && "Invalid number of operands!"); 1485 assert( 1486 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains(getReg())); 1487 Inst.addOperand(MCOperand::createReg(getReg())); 1488 } 1489 1490 void addVectorRegLoOperands(MCInst &Inst, unsigned N) const { 1491 assert(N == 1 && "Invalid number of operands!"); 1492 Inst.addOperand(MCOperand::createReg(getReg())); 1493 } 1494 1495 enum VecListIndexType { 1496 VecListIdx_DReg = 0, 1497 VecListIdx_QReg = 1, 1498 VecListIdx_ZReg = 2, 1499 }; 1500 1501 template <VecListIndexType RegTy, unsigned NumRegs> 1502 void addVectorListOperands(MCInst &Inst, unsigned N) const { 1503 assert(N == 1 && "Invalid number of operands!"); 1504 static const unsigned FirstRegs[][5] = { 1505 /* DReg */ { AArch64::Q0, 1506 AArch64::D0, AArch64::D0_D1, 1507 AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 }, 1508 /* QReg */ { AArch64::Q0, 1509 AArch64::Q0, AArch64::Q0_Q1, 1510 AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 }, 1511 /* ZReg */ { AArch64::Z0, 1512 AArch64::Z0, AArch64::Z0_Z1, 1513 AArch64::Z0_Z1_Z2, AArch64::Z0_Z1_Z2_Z3 } 1514 }; 1515 1516 assert((RegTy != VecListIdx_ZReg || NumRegs <= 4) && 1517 " NumRegs must be <= 4 for ZRegs"); 1518 1519 unsigned FirstReg = FirstRegs[(unsigned)RegTy][NumRegs]; 1520 Inst.addOperand(MCOperand::createReg(FirstReg + getVectorListStart() - 1521 FirstRegs[(unsigned)RegTy][0])); 1522 } 1523 1524 void addVectorIndexOperands(MCInst &Inst, unsigned N) const { 1525 assert(N == 1 && "Invalid number of operands!"); 1526 Inst.addOperand(MCOperand::createImm(getVectorIndex())); 1527 } 1528 1529 template <unsigned ImmIs0, unsigned ImmIs1> 1530 void addExactFPImmOperands(MCInst &Inst, unsigned N) const { 1531 assert(N == 1 && "Invalid number of operands!"); 1532 assert(bool(isExactFPImm<ImmIs0, ImmIs1>()) && "Invalid operand"); 1533 Inst.addOperand(MCOperand::createImm(bool(isExactFPImm<ImmIs1>()))); 1534 } 1535 1536 void addImmOperands(MCInst &Inst, unsigned N) const { 1537 assert(N == 1 && "Invalid number of operands!"); 1538 // If this is a pageoff symrefexpr with an addend, adjust the addend 1539 // to be only the page-offset portion. Otherwise, just add the expr 1540 // as-is. 1541 addExpr(Inst, getImm()); 1542 } 1543 1544 template <int Shift> 1545 void addImmWithOptionalShiftOperands(MCInst &Inst, unsigned N) const { 1546 assert(N == 2 && "Invalid number of operands!"); 1547 if (auto ShiftedVal = getShiftedVal<Shift>()) { 1548 Inst.addOperand(MCOperand::createImm(ShiftedVal->first)); 1549 Inst.addOperand(MCOperand::createImm(ShiftedVal->second)); 1550 } else if (isShiftedImm()) { 1551 addExpr(Inst, getShiftedImmVal()); 1552 Inst.addOperand(MCOperand::createImm(getShiftedImmShift())); 1553 } else { 1554 addExpr(Inst, getImm()); 1555 Inst.addOperand(MCOperand::createImm(0)); 1556 } 1557 } 1558 1559 template <int Shift> 1560 void addImmNegWithOptionalShiftOperands(MCInst &Inst, unsigned N) const { 1561 assert(N == 2 && "Invalid number of operands!"); 1562 if (auto ShiftedVal = getShiftedVal<Shift>()) { 1563 Inst.addOperand(MCOperand::createImm(-ShiftedVal->first)); 1564 Inst.addOperand(MCOperand::createImm(ShiftedVal->second)); 1565 } else 1566 llvm_unreachable("Not a shifted negative immediate"); 1567 } 1568 1569 void addCondCodeOperands(MCInst &Inst, unsigned N) const { 1570 assert(N == 1 && "Invalid number of operands!"); 1571 Inst.addOperand(MCOperand::createImm(getCondCode())); 1572 } 1573 1574 void addAdrpLabelOperands(MCInst &Inst, unsigned N) const { 1575 assert(N == 1 && "Invalid number of operands!"); 1576 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 1577 if (!MCE) 1578 addExpr(Inst, getImm()); 1579 else 1580 Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 12)); 1581 } 1582 1583 void addAdrLabelOperands(MCInst &Inst, unsigned N) const { 1584 addImmOperands(Inst, N); 1585 } 1586 1587 template<int Scale> 1588 void addUImm12OffsetOperands(MCInst &Inst, unsigned N) const { 1589 assert(N == 1 && "Invalid number of operands!"); 1590 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 1591 1592 if (!MCE) { 1593 Inst.addOperand(MCOperand::createExpr(getImm())); 1594 return; 1595 } 1596 Inst.addOperand(MCOperand::createImm(MCE->getValue() / Scale)); 1597 } 1598 1599 void addUImm6Operands(MCInst &Inst, unsigned N) const { 1600 assert(N == 1 && "Invalid number of operands!"); 1601 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1602 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1603 } 1604 1605 template <int Scale> 1606 void addImmScaledOperands(MCInst &Inst, unsigned N) const { 1607 assert(N == 1 && "Invalid number of operands!"); 1608 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1609 Inst.addOperand(MCOperand::createImm(MCE->getValue() / Scale)); 1610 } 1611 1612 template <typename T> 1613 void addLogicalImmOperands(MCInst &Inst, unsigned N) const { 1614 assert(N == 1 && "Invalid number of operands!"); 1615 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1616 std::make_unsigned_t<T> Val = MCE->getValue(); 1617 uint64_t encoding = AArch64_AM::encodeLogicalImmediate(Val, sizeof(T) * 8); 1618 Inst.addOperand(MCOperand::createImm(encoding)); 1619 } 1620 1621 template <typename T> 1622 void addLogicalImmNotOperands(MCInst &Inst, unsigned N) const { 1623 assert(N == 1 && "Invalid number of operands!"); 1624 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1625 std::make_unsigned_t<T> Val = ~MCE->getValue(); 1626 uint64_t encoding = AArch64_AM::encodeLogicalImmediate(Val, sizeof(T) * 8); 1627 Inst.addOperand(MCOperand::createImm(encoding)); 1628 } 1629 1630 void addSIMDImmType10Operands(MCInst &Inst, unsigned N) const { 1631 assert(N == 1 && "Invalid number of operands!"); 1632 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1633 uint64_t encoding = AArch64_AM::encodeAdvSIMDModImmType10(MCE->getValue()); 1634 Inst.addOperand(MCOperand::createImm(encoding)); 1635 } 1636 1637 void addBranchTarget26Operands(MCInst &Inst, unsigned N) const { 1638 // Branch operands don't encode the low bits, so shift them off 1639 // here. If it's a label, however, just put it on directly as there's 1640 // not enough information now to do anything. 1641 assert(N == 1 && "Invalid number of operands!"); 1642 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 1643 if (!MCE) { 1644 addExpr(Inst, getImm()); 1645 return; 1646 } 1647 assert(MCE && "Invalid constant immediate operand!"); 1648 Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2)); 1649 } 1650 1651 void addPCRelLabel19Operands(MCInst &Inst, unsigned N) const { 1652 // Branch operands don't encode the low bits, so shift them off 1653 // here. If it's a label, however, just put it on directly as there's 1654 // not enough information now to do anything. 1655 assert(N == 1 && "Invalid number of operands!"); 1656 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 1657 if (!MCE) { 1658 addExpr(Inst, getImm()); 1659 return; 1660 } 1661 assert(MCE && "Invalid constant immediate operand!"); 1662 Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2)); 1663 } 1664 1665 void addBranchTarget14Operands(MCInst &Inst, unsigned N) const { 1666 // Branch operands don't encode the low bits, so shift them off 1667 // here. If it's a label, however, just put it on directly as there's 1668 // not enough information now to do anything. 1669 assert(N == 1 && "Invalid number of operands!"); 1670 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 1671 if (!MCE) { 1672 addExpr(Inst, getImm()); 1673 return; 1674 } 1675 assert(MCE && "Invalid constant immediate operand!"); 1676 Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2)); 1677 } 1678 1679 void addFPImmOperands(MCInst &Inst, unsigned N) const { 1680 assert(N == 1 && "Invalid number of operands!"); 1681 Inst.addOperand(MCOperand::createImm( 1682 AArch64_AM::getFP64Imm(getFPImm().bitcastToAPInt()))); 1683 } 1684 1685 void addBarrierOperands(MCInst &Inst, unsigned N) const { 1686 assert(N == 1 && "Invalid number of operands!"); 1687 Inst.addOperand(MCOperand::createImm(getBarrier())); 1688 } 1689 1690 void addMRSSystemRegisterOperands(MCInst &Inst, unsigned N) const { 1691 assert(N == 1 && "Invalid number of operands!"); 1692 1693 Inst.addOperand(MCOperand::createImm(SysReg.MRSReg)); 1694 } 1695 1696 void addMSRSystemRegisterOperands(MCInst &Inst, unsigned N) const { 1697 assert(N == 1 && "Invalid number of operands!"); 1698 1699 Inst.addOperand(MCOperand::createImm(SysReg.MSRReg)); 1700 } 1701 1702 void addSystemPStateFieldWithImm0_1Operands(MCInst &Inst, unsigned N) const { 1703 assert(N == 1 && "Invalid number of operands!"); 1704 1705 Inst.addOperand(MCOperand::createImm(SysReg.PStateField)); 1706 } 1707 1708 void addSystemPStateFieldWithImm0_15Operands(MCInst &Inst, unsigned N) const { 1709 assert(N == 1 && "Invalid number of operands!"); 1710 1711 Inst.addOperand(MCOperand::createImm(SysReg.PStateField)); 1712 } 1713 1714 void addSysCROperands(MCInst &Inst, unsigned N) const { 1715 assert(N == 1 && "Invalid number of operands!"); 1716 Inst.addOperand(MCOperand::createImm(getSysCR())); 1717 } 1718 1719 void addPrefetchOperands(MCInst &Inst, unsigned N) const { 1720 assert(N == 1 && "Invalid number of operands!"); 1721 Inst.addOperand(MCOperand::createImm(getPrefetch())); 1722 } 1723 1724 void addPSBHintOperands(MCInst &Inst, unsigned N) const { 1725 assert(N == 1 && "Invalid number of operands!"); 1726 Inst.addOperand(MCOperand::createImm(getPSBHint())); 1727 } 1728 1729 void addBTIHintOperands(MCInst &Inst, unsigned N) const { 1730 assert(N == 1 && "Invalid number of operands!"); 1731 Inst.addOperand(MCOperand::createImm(getBTIHint())); 1732 } 1733 1734 void addShifterOperands(MCInst &Inst, unsigned N) const { 1735 assert(N == 1 && "Invalid number of operands!"); 1736 unsigned Imm = 1737 AArch64_AM::getShifterImm(getShiftExtendType(), getShiftExtendAmount()); 1738 Inst.addOperand(MCOperand::createImm(Imm)); 1739 } 1740 1741 void addExtendOperands(MCInst &Inst, unsigned N) const { 1742 assert(N == 1 && "Invalid number of operands!"); 1743 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 1744 if (ET == AArch64_AM::LSL) ET = AArch64_AM::UXTW; 1745 unsigned Imm = AArch64_AM::getArithExtendImm(ET, getShiftExtendAmount()); 1746 Inst.addOperand(MCOperand::createImm(Imm)); 1747 } 1748 1749 void addExtend64Operands(MCInst &Inst, unsigned N) const { 1750 assert(N == 1 && "Invalid number of operands!"); 1751 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 1752 if (ET == AArch64_AM::LSL) ET = AArch64_AM::UXTX; 1753 unsigned Imm = AArch64_AM::getArithExtendImm(ET, getShiftExtendAmount()); 1754 Inst.addOperand(MCOperand::createImm(Imm)); 1755 } 1756 1757 void addMemExtendOperands(MCInst &Inst, unsigned N) const { 1758 assert(N == 2 && "Invalid number of operands!"); 1759 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 1760 bool IsSigned = ET == AArch64_AM::SXTW || ET == AArch64_AM::SXTX; 1761 Inst.addOperand(MCOperand::createImm(IsSigned)); 1762 Inst.addOperand(MCOperand::createImm(getShiftExtendAmount() != 0)); 1763 } 1764 1765 // For 8-bit load/store instructions with a register offset, both the 1766 // "DoShift" and "NoShift" variants have a shift of 0. Because of this, 1767 // they're disambiguated by whether the shift was explicit or implicit rather 1768 // than its size. 1769 void addMemExtend8Operands(MCInst &Inst, unsigned N) const { 1770 assert(N == 2 && "Invalid number of operands!"); 1771 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 1772 bool IsSigned = ET == AArch64_AM::SXTW || ET == AArch64_AM::SXTX; 1773 Inst.addOperand(MCOperand::createImm(IsSigned)); 1774 Inst.addOperand(MCOperand::createImm(hasShiftExtendAmount())); 1775 } 1776 1777 template<int Shift> 1778 void addMOVZMovAliasOperands(MCInst &Inst, unsigned N) const { 1779 assert(N == 1 && "Invalid number of operands!"); 1780 1781 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1782 if (CE) { 1783 uint64_t Value = CE->getValue(); 1784 Inst.addOperand(MCOperand::createImm((Value >> Shift) & 0xffff)); 1785 } else { 1786 addExpr(Inst, getImm()); 1787 } 1788 } 1789 1790 template<int Shift> 1791 void addMOVNMovAliasOperands(MCInst &Inst, unsigned N) const { 1792 assert(N == 1 && "Invalid number of operands!"); 1793 1794 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 1795 uint64_t Value = CE->getValue(); 1796 Inst.addOperand(MCOperand::createImm((~Value >> Shift) & 0xffff)); 1797 } 1798 1799 void addComplexRotationEvenOperands(MCInst &Inst, unsigned N) const { 1800 assert(N == 1 && "Invalid number of operands!"); 1801 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1802 Inst.addOperand(MCOperand::createImm(MCE->getValue() / 90)); 1803 } 1804 1805 void addComplexRotationOddOperands(MCInst &Inst, unsigned N) const { 1806 assert(N == 1 && "Invalid number of operands!"); 1807 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1808 Inst.addOperand(MCOperand::createImm((MCE->getValue() - 90) / 180)); 1809 } 1810 1811 void print(raw_ostream &OS) const override; 1812 1813 static std::unique_ptr<AArch64Operand> 1814 CreateToken(StringRef Str, bool IsSuffix, SMLoc S, MCContext &Ctx) { 1815 auto Op = std::make_unique<AArch64Operand>(k_Token, Ctx); 1816 Op->Tok.Data = Str.data(); 1817 Op->Tok.Length = Str.size(); 1818 Op->Tok.IsSuffix = IsSuffix; 1819 Op->StartLoc = S; 1820 Op->EndLoc = S; 1821 return Op; 1822 } 1823 1824 static std::unique_ptr<AArch64Operand> 1825 CreateReg(unsigned RegNum, RegKind Kind, SMLoc S, SMLoc E, MCContext &Ctx, 1826 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg, 1827 AArch64_AM::ShiftExtendType ExtTy = AArch64_AM::LSL, 1828 unsigned ShiftAmount = 0, 1829 unsigned HasExplicitAmount = false) { 1830 auto Op = std::make_unique<AArch64Operand>(k_Register, Ctx); 1831 Op->Reg.RegNum = RegNum; 1832 Op->Reg.Kind = Kind; 1833 Op->Reg.ElementWidth = 0; 1834 Op->Reg.EqualityTy = EqTy; 1835 Op->Reg.ShiftExtend.Type = ExtTy; 1836 Op->Reg.ShiftExtend.Amount = ShiftAmount; 1837 Op->Reg.ShiftExtend.HasExplicitAmount = HasExplicitAmount; 1838 Op->StartLoc = S; 1839 Op->EndLoc = E; 1840 return Op; 1841 } 1842 1843 static std::unique_ptr<AArch64Operand> 1844 CreateVectorReg(unsigned RegNum, RegKind Kind, unsigned ElementWidth, 1845 SMLoc S, SMLoc E, MCContext &Ctx, 1846 AArch64_AM::ShiftExtendType ExtTy = AArch64_AM::LSL, 1847 unsigned ShiftAmount = 0, 1848 unsigned HasExplicitAmount = false) { 1849 assert((Kind == RegKind::NeonVector || Kind == RegKind::SVEDataVector || 1850 Kind == RegKind::SVEPredicateVector) && 1851 "Invalid vector kind"); 1852 auto Op = CreateReg(RegNum, Kind, S, E, Ctx, EqualsReg, ExtTy, ShiftAmount, 1853 HasExplicitAmount); 1854 Op->Reg.ElementWidth = ElementWidth; 1855 return Op; 1856 } 1857 1858 static std::unique_ptr<AArch64Operand> 1859 CreateVectorList(unsigned RegNum, unsigned Count, unsigned NumElements, 1860 unsigned ElementWidth, RegKind RegisterKind, SMLoc S, SMLoc E, 1861 MCContext &Ctx) { 1862 auto Op = std::make_unique<AArch64Operand>(k_VectorList, Ctx); 1863 Op->VectorList.RegNum = RegNum; 1864 Op->VectorList.Count = Count; 1865 Op->VectorList.NumElements = NumElements; 1866 Op->VectorList.ElementWidth = ElementWidth; 1867 Op->VectorList.RegisterKind = RegisterKind; 1868 Op->StartLoc = S; 1869 Op->EndLoc = E; 1870 return Op; 1871 } 1872 1873 static std::unique_ptr<AArch64Operand> 1874 CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, MCContext &Ctx) { 1875 auto Op = std::make_unique<AArch64Operand>(k_VectorIndex, Ctx); 1876 Op->VectorIndex.Val = Idx; 1877 Op->StartLoc = S; 1878 Op->EndLoc = E; 1879 return Op; 1880 } 1881 1882 static std::unique_ptr<AArch64Operand> CreateImm(const MCExpr *Val, SMLoc S, 1883 SMLoc E, MCContext &Ctx) { 1884 auto Op = std::make_unique<AArch64Operand>(k_Immediate, Ctx); 1885 Op->Imm.Val = Val; 1886 Op->StartLoc = S; 1887 Op->EndLoc = E; 1888 return Op; 1889 } 1890 1891 static std::unique_ptr<AArch64Operand> CreateShiftedImm(const MCExpr *Val, 1892 unsigned ShiftAmount, 1893 SMLoc S, SMLoc E, 1894 MCContext &Ctx) { 1895 auto Op = std::make_unique<AArch64Operand>(k_ShiftedImm, Ctx); 1896 Op->ShiftedImm .Val = Val; 1897 Op->ShiftedImm.ShiftAmount = ShiftAmount; 1898 Op->StartLoc = S; 1899 Op->EndLoc = E; 1900 return Op; 1901 } 1902 1903 static std::unique_ptr<AArch64Operand> 1904 CreateCondCode(AArch64CC::CondCode Code, SMLoc S, SMLoc E, MCContext &Ctx) { 1905 auto Op = std::make_unique<AArch64Operand>(k_CondCode, Ctx); 1906 Op->CondCode.Code = Code; 1907 Op->StartLoc = S; 1908 Op->EndLoc = E; 1909 return Op; 1910 } 1911 1912 static std::unique_ptr<AArch64Operand> 1913 CreateFPImm(APFloat Val, bool IsExact, SMLoc S, MCContext &Ctx) { 1914 auto Op = std::make_unique<AArch64Operand>(k_FPImm, Ctx); 1915 Op->FPImm.Val = Val.bitcastToAPInt().getSExtValue(); 1916 Op->FPImm.IsExact = IsExact; 1917 Op->StartLoc = S; 1918 Op->EndLoc = S; 1919 return Op; 1920 } 1921 1922 static std::unique_ptr<AArch64Operand> CreateBarrier(unsigned Val, 1923 StringRef Str, 1924 SMLoc S, 1925 MCContext &Ctx) { 1926 auto Op = std::make_unique<AArch64Operand>(k_Barrier, Ctx); 1927 Op->Barrier.Val = Val; 1928 Op->Barrier.Data = Str.data(); 1929 Op->Barrier.Length = Str.size(); 1930 Op->StartLoc = S; 1931 Op->EndLoc = S; 1932 return Op; 1933 } 1934 1935 static std::unique_ptr<AArch64Operand> CreateSysReg(StringRef Str, SMLoc S, 1936 uint32_t MRSReg, 1937 uint32_t MSRReg, 1938 uint32_t PStateField, 1939 MCContext &Ctx) { 1940 auto Op = std::make_unique<AArch64Operand>(k_SysReg, Ctx); 1941 Op->SysReg.Data = Str.data(); 1942 Op->SysReg.Length = Str.size(); 1943 Op->SysReg.MRSReg = MRSReg; 1944 Op->SysReg.MSRReg = MSRReg; 1945 Op->SysReg.PStateField = PStateField; 1946 Op->StartLoc = S; 1947 Op->EndLoc = S; 1948 return Op; 1949 } 1950 1951 static std::unique_ptr<AArch64Operand> CreateSysCR(unsigned Val, SMLoc S, 1952 SMLoc E, MCContext &Ctx) { 1953 auto Op = std::make_unique<AArch64Operand>(k_SysCR, Ctx); 1954 Op->SysCRImm.Val = Val; 1955 Op->StartLoc = S; 1956 Op->EndLoc = E; 1957 return Op; 1958 } 1959 1960 static std::unique_ptr<AArch64Operand> CreatePrefetch(unsigned Val, 1961 StringRef Str, 1962 SMLoc S, 1963 MCContext &Ctx) { 1964 auto Op = std::make_unique<AArch64Operand>(k_Prefetch, Ctx); 1965 Op->Prefetch.Val = Val; 1966 Op->Barrier.Data = Str.data(); 1967 Op->Barrier.Length = Str.size(); 1968 Op->StartLoc = S; 1969 Op->EndLoc = S; 1970 return Op; 1971 } 1972 1973 static std::unique_ptr<AArch64Operand> CreatePSBHint(unsigned Val, 1974 StringRef Str, 1975 SMLoc S, 1976 MCContext &Ctx) { 1977 auto Op = std::make_unique<AArch64Operand>(k_PSBHint, Ctx); 1978 Op->PSBHint.Val = Val; 1979 Op->PSBHint.Data = Str.data(); 1980 Op->PSBHint.Length = Str.size(); 1981 Op->StartLoc = S; 1982 Op->EndLoc = S; 1983 return Op; 1984 } 1985 1986 static std::unique_ptr<AArch64Operand> CreateBTIHint(unsigned Val, 1987 StringRef Str, 1988 SMLoc S, 1989 MCContext &Ctx) { 1990 auto Op = std::make_unique<AArch64Operand>(k_BTIHint, Ctx); 1991 Op->BTIHint.Val = Val << 1 | 32; 1992 Op->BTIHint.Data = Str.data(); 1993 Op->BTIHint.Length = Str.size(); 1994 Op->StartLoc = S; 1995 Op->EndLoc = S; 1996 return Op; 1997 } 1998 1999 static std::unique_ptr<AArch64Operand> 2000 CreateShiftExtend(AArch64_AM::ShiftExtendType ShOp, unsigned Val, 2001 bool HasExplicitAmount, SMLoc S, SMLoc E, MCContext &Ctx) { 2002 auto Op = std::make_unique<AArch64Operand>(k_ShiftExtend, Ctx); 2003 Op->ShiftExtend.Type = ShOp; 2004 Op->ShiftExtend.Amount = Val; 2005 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount; 2006 Op->StartLoc = S; 2007 Op->EndLoc = E; 2008 return Op; 2009 } 2010 }; 2011 2012 } // end anonymous namespace. 2013 2014 void AArch64Operand::print(raw_ostream &OS) const { 2015 switch (Kind) { 2016 case k_FPImm: 2017 OS << "<fpimm " << getFPImm().bitcastToAPInt().getZExtValue(); 2018 if (!getFPImmIsExact()) 2019 OS << " (inexact)"; 2020 OS << ">"; 2021 break; 2022 case k_Barrier: { 2023 StringRef Name = getBarrierName(); 2024 if (!Name.empty()) 2025 OS << "<barrier " << Name << ">"; 2026 else 2027 OS << "<barrier invalid #" << getBarrier() << ">"; 2028 break; 2029 } 2030 case k_Immediate: 2031 OS << *getImm(); 2032 break; 2033 case k_ShiftedImm: { 2034 unsigned Shift = getShiftedImmShift(); 2035 OS << "<shiftedimm "; 2036 OS << *getShiftedImmVal(); 2037 OS << ", lsl #" << AArch64_AM::getShiftValue(Shift) << ">"; 2038 break; 2039 } 2040 case k_CondCode: 2041 OS << "<condcode " << getCondCode() << ">"; 2042 break; 2043 case k_VectorList: { 2044 OS << "<vectorlist "; 2045 unsigned Reg = getVectorListStart(); 2046 for (unsigned i = 0, e = getVectorListCount(); i != e; ++i) 2047 OS << Reg + i << " "; 2048 OS << ">"; 2049 break; 2050 } 2051 case k_VectorIndex: 2052 OS << "<vectorindex " << getVectorIndex() << ">"; 2053 break; 2054 case k_SysReg: 2055 OS << "<sysreg: " << getSysReg() << '>'; 2056 break; 2057 case k_Token: 2058 OS << "'" << getToken() << "'"; 2059 break; 2060 case k_SysCR: 2061 OS << "c" << getSysCR(); 2062 break; 2063 case k_Prefetch: { 2064 StringRef Name = getPrefetchName(); 2065 if (!Name.empty()) 2066 OS << "<prfop " << Name << ">"; 2067 else 2068 OS << "<prfop invalid #" << getPrefetch() << ">"; 2069 break; 2070 } 2071 case k_PSBHint: 2072 OS << getPSBHintName(); 2073 break; 2074 case k_Register: 2075 OS << "<register " << getReg() << ">"; 2076 if (!getShiftExtendAmount() && !hasShiftExtendAmount()) 2077 break; 2078 LLVM_FALLTHROUGH; 2079 case k_BTIHint: 2080 OS << getBTIHintName(); 2081 break; 2082 case k_ShiftExtend: 2083 OS << "<" << AArch64_AM::getShiftExtendName(getShiftExtendType()) << " #" 2084 << getShiftExtendAmount(); 2085 if (!hasShiftExtendAmount()) 2086 OS << "<imp>"; 2087 OS << '>'; 2088 break; 2089 } 2090 } 2091 2092 /// @name Auto-generated Match Functions 2093 /// { 2094 2095 static unsigned MatchRegisterName(StringRef Name); 2096 2097 /// } 2098 2099 static unsigned MatchNeonVectorRegName(StringRef Name) { 2100 return StringSwitch<unsigned>(Name.lower()) 2101 .Case("v0", AArch64::Q0) 2102 .Case("v1", AArch64::Q1) 2103 .Case("v2", AArch64::Q2) 2104 .Case("v3", AArch64::Q3) 2105 .Case("v4", AArch64::Q4) 2106 .Case("v5", AArch64::Q5) 2107 .Case("v6", AArch64::Q6) 2108 .Case("v7", AArch64::Q7) 2109 .Case("v8", AArch64::Q8) 2110 .Case("v9", AArch64::Q9) 2111 .Case("v10", AArch64::Q10) 2112 .Case("v11", AArch64::Q11) 2113 .Case("v12", AArch64::Q12) 2114 .Case("v13", AArch64::Q13) 2115 .Case("v14", AArch64::Q14) 2116 .Case("v15", AArch64::Q15) 2117 .Case("v16", AArch64::Q16) 2118 .Case("v17", AArch64::Q17) 2119 .Case("v18", AArch64::Q18) 2120 .Case("v19", AArch64::Q19) 2121 .Case("v20", AArch64::Q20) 2122 .Case("v21", AArch64::Q21) 2123 .Case("v22", AArch64::Q22) 2124 .Case("v23", AArch64::Q23) 2125 .Case("v24", AArch64::Q24) 2126 .Case("v25", AArch64::Q25) 2127 .Case("v26", AArch64::Q26) 2128 .Case("v27", AArch64::Q27) 2129 .Case("v28", AArch64::Q28) 2130 .Case("v29", AArch64::Q29) 2131 .Case("v30", AArch64::Q30) 2132 .Case("v31", AArch64::Q31) 2133 .Default(0); 2134 } 2135 2136 /// Returns an optional pair of (#elements, element-width) if Suffix 2137 /// is a valid vector kind. Where the number of elements in a vector 2138 /// or the vector width is implicit or explicitly unknown (but still a 2139 /// valid suffix kind), 0 is used. 2140 static Optional<std::pair<int, int>> parseVectorKind(StringRef Suffix, 2141 RegKind VectorKind) { 2142 std::pair<int, int> Res = {-1, -1}; 2143 2144 switch (VectorKind) { 2145 case RegKind::NeonVector: 2146 Res = 2147 StringSwitch<std::pair<int, int>>(Suffix.lower()) 2148 .Case("", {0, 0}) 2149 .Case(".1d", {1, 64}) 2150 .Case(".1q", {1, 128}) 2151 // '.2h' needed for fp16 scalar pairwise reductions 2152 .Case(".2h", {2, 16}) 2153 .Case(".2s", {2, 32}) 2154 .Case(".2d", {2, 64}) 2155 // '.4b' is another special case for the ARMv8.2a dot product 2156 // operand 2157 .Case(".4b", {4, 8}) 2158 .Case(".4h", {4, 16}) 2159 .Case(".4s", {4, 32}) 2160 .Case(".8b", {8, 8}) 2161 .Case(".8h", {8, 16}) 2162 .Case(".16b", {16, 8}) 2163 // Accept the width neutral ones, too, for verbose syntax. If those 2164 // aren't used in the right places, the token operand won't match so 2165 // all will work out. 2166 .Case(".b", {0, 8}) 2167 .Case(".h", {0, 16}) 2168 .Case(".s", {0, 32}) 2169 .Case(".d", {0, 64}) 2170 .Default({-1, -1}); 2171 break; 2172 case RegKind::SVEPredicateVector: 2173 case RegKind::SVEDataVector: 2174 Res = StringSwitch<std::pair<int, int>>(Suffix.lower()) 2175 .Case("", {0, 0}) 2176 .Case(".b", {0, 8}) 2177 .Case(".h", {0, 16}) 2178 .Case(".s", {0, 32}) 2179 .Case(".d", {0, 64}) 2180 .Case(".q", {0, 128}) 2181 .Default({-1, -1}); 2182 break; 2183 default: 2184 llvm_unreachable("Unsupported RegKind"); 2185 } 2186 2187 if (Res == std::make_pair(-1, -1)) 2188 return Optional<std::pair<int, int>>(); 2189 2190 return Optional<std::pair<int, int>>(Res); 2191 } 2192 2193 static bool isValidVectorKind(StringRef Suffix, RegKind VectorKind) { 2194 return parseVectorKind(Suffix, VectorKind).hasValue(); 2195 } 2196 2197 static unsigned matchSVEDataVectorRegName(StringRef Name) { 2198 return StringSwitch<unsigned>(Name.lower()) 2199 .Case("z0", AArch64::Z0) 2200 .Case("z1", AArch64::Z1) 2201 .Case("z2", AArch64::Z2) 2202 .Case("z3", AArch64::Z3) 2203 .Case("z4", AArch64::Z4) 2204 .Case("z5", AArch64::Z5) 2205 .Case("z6", AArch64::Z6) 2206 .Case("z7", AArch64::Z7) 2207 .Case("z8", AArch64::Z8) 2208 .Case("z9", AArch64::Z9) 2209 .Case("z10", AArch64::Z10) 2210 .Case("z11", AArch64::Z11) 2211 .Case("z12", AArch64::Z12) 2212 .Case("z13", AArch64::Z13) 2213 .Case("z14", AArch64::Z14) 2214 .Case("z15", AArch64::Z15) 2215 .Case("z16", AArch64::Z16) 2216 .Case("z17", AArch64::Z17) 2217 .Case("z18", AArch64::Z18) 2218 .Case("z19", AArch64::Z19) 2219 .Case("z20", AArch64::Z20) 2220 .Case("z21", AArch64::Z21) 2221 .Case("z22", AArch64::Z22) 2222 .Case("z23", AArch64::Z23) 2223 .Case("z24", AArch64::Z24) 2224 .Case("z25", AArch64::Z25) 2225 .Case("z26", AArch64::Z26) 2226 .Case("z27", AArch64::Z27) 2227 .Case("z28", AArch64::Z28) 2228 .Case("z29", AArch64::Z29) 2229 .Case("z30", AArch64::Z30) 2230 .Case("z31", AArch64::Z31) 2231 .Default(0); 2232 } 2233 2234 static unsigned matchSVEPredicateVectorRegName(StringRef Name) { 2235 return StringSwitch<unsigned>(Name.lower()) 2236 .Case("p0", AArch64::P0) 2237 .Case("p1", AArch64::P1) 2238 .Case("p2", AArch64::P2) 2239 .Case("p3", AArch64::P3) 2240 .Case("p4", AArch64::P4) 2241 .Case("p5", AArch64::P5) 2242 .Case("p6", AArch64::P6) 2243 .Case("p7", AArch64::P7) 2244 .Case("p8", AArch64::P8) 2245 .Case("p9", AArch64::P9) 2246 .Case("p10", AArch64::P10) 2247 .Case("p11", AArch64::P11) 2248 .Case("p12", AArch64::P12) 2249 .Case("p13", AArch64::P13) 2250 .Case("p14", AArch64::P14) 2251 .Case("p15", AArch64::P15) 2252 .Default(0); 2253 } 2254 2255 bool AArch64AsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 2256 SMLoc &EndLoc) { 2257 return tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success; 2258 } 2259 2260 OperandMatchResultTy AArch64AsmParser::tryParseRegister(unsigned &RegNo, 2261 SMLoc &StartLoc, 2262 SMLoc &EndLoc) { 2263 StartLoc = getLoc(); 2264 auto Res = tryParseScalarRegister(RegNo); 2265 EndLoc = SMLoc::getFromPointer(getLoc().getPointer() - 1); 2266 return Res; 2267 } 2268 2269 // Matches a register name or register alias previously defined by '.req' 2270 unsigned AArch64AsmParser::matchRegisterNameAlias(StringRef Name, 2271 RegKind Kind) { 2272 unsigned RegNum = 0; 2273 if ((RegNum = matchSVEDataVectorRegName(Name))) 2274 return Kind == RegKind::SVEDataVector ? RegNum : 0; 2275 2276 if ((RegNum = matchSVEPredicateVectorRegName(Name))) 2277 return Kind == RegKind::SVEPredicateVector ? RegNum : 0; 2278 2279 if ((RegNum = MatchNeonVectorRegName(Name))) 2280 return Kind == RegKind::NeonVector ? RegNum : 0; 2281 2282 // The parsed register must be of RegKind Scalar 2283 if ((RegNum = MatchRegisterName(Name))) 2284 return Kind == RegKind::Scalar ? RegNum : 0; 2285 2286 if (!RegNum) { 2287 // Handle a few common aliases of registers. 2288 if (auto RegNum = StringSwitch<unsigned>(Name.lower()) 2289 .Case("fp", AArch64::FP) 2290 .Case("lr", AArch64::LR) 2291 .Case("x31", AArch64::XZR) 2292 .Case("w31", AArch64::WZR) 2293 .Default(0)) 2294 return Kind == RegKind::Scalar ? RegNum : 0; 2295 2296 // Check for aliases registered via .req. Canonicalize to lower case. 2297 // That's more consistent since register names are case insensitive, and 2298 // it's how the original entry was passed in from MC/MCParser/AsmParser. 2299 auto Entry = RegisterReqs.find(Name.lower()); 2300 if (Entry == RegisterReqs.end()) 2301 return 0; 2302 2303 // set RegNum if the match is the right kind of register 2304 if (Kind == Entry->getValue().first) 2305 RegNum = Entry->getValue().second; 2306 } 2307 return RegNum; 2308 } 2309 2310 /// tryParseScalarRegister - Try to parse a register name. The token must be an 2311 /// Identifier when called, and if it is a register name the token is eaten and 2312 /// the register is added to the operand list. 2313 OperandMatchResultTy 2314 AArch64AsmParser::tryParseScalarRegister(unsigned &RegNum) { 2315 MCAsmParser &Parser = getParser(); 2316 const AsmToken &Tok = Parser.getTok(); 2317 if (Tok.isNot(AsmToken::Identifier)) 2318 return MatchOperand_NoMatch; 2319 2320 std::string lowerCase = Tok.getString().lower(); 2321 unsigned Reg = matchRegisterNameAlias(lowerCase, RegKind::Scalar); 2322 if (Reg == 0) 2323 return MatchOperand_NoMatch; 2324 2325 RegNum = Reg; 2326 Parser.Lex(); // Eat identifier token. 2327 return MatchOperand_Success; 2328 } 2329 2330 /// tryParseSysCROperand - Try to parse a system instruction CR operand name. 2331 OperandMatchResultTy 2332 AArch64AsmParser::tryParseSysCROperand(OperandVector &Operands) { 2333 MCAsmParser &Parser = getParser(); 2334 SMLoc S = getLoc(); 2335 2336 if (Parser.getTok().isNot(AsmToken::Identifier)) { 2337 Error(S, "Expected cN operand where 0 <= N <= 15"); 2338 return MatchOperand_ParseFail; 2339 } 2340 2341 StringRef Tok = Parser.getTok().getIdentifier(); 2342 if (Tok[0] != 'c' && Tok[0] != 'C') { 2343 Error(S, "Expected cN operand where 0 <= N <= 15"); 2344 return MatchOperand_ParseFail; 2345 } 2346 2347 uint32_t CRNum; 2348 bool BadNum = Tok.drop_front().getAsInteger(10, CRNum); 2349 if (BadNum || CRNum > 15) { 2350 Error(S, "Expected cN operand where 0 <= N <= 15"); 2351 return MatchOperand_ParseFail; 2352 } 2353 2354 Parser.Lex(); // Eat identifier token. 2355 Operands.push_back( 2356 AArch64Operand::CreateSysCR(CRNum, S, getLoc(), getContext())); 2357 return MatchOperand_Success; 2358 } 2359 2360 /// tryParsePrefetch - Try to parse a prefetch operand. 2361 template <bool IsSVEPrefetch> 2362 OperandMatchResultTy 2363 AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) { 2364 MCAsmParser &Parser = getParser(); 2365 SMLoc S = getLoc(); 2366 const AsmToken &Tok = Parser.getTok(); 2367 2368 auto LookupByName = [](StringRef N) { 2369 if (IsSVEPrefetch) { 2370 if (auto Res = AArch64SVEPRFM::lookupSVEPRFMByName(N)) 2371 return Optional<unsigned>(Res->Encoding); 2372 } else if (auto Res = AArch64PRFM::lookupPRFMByName(N)) 2373 return Optional<unsigned>(Res->Encoding); 2374 return Optional<unsigned>(); 2375 }; 2376 2377 auto LookupByEncoding = [](unsigned E) { 2378 if (IsSVEPrefetch) { 2379 if (auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(E)) 2380 return Optional<StringRef>(Res->Name); 2381 } else if (auto Res = AArch64PRFM::lookupPRFMByEncoding(E)) 2382 return Optional<StringRef>(Res->Name); 2383 return Optional<StringRef>(); 2384 }; 2385 unsigned MaxVal = IsSVEPrefetch ? 15 : 31; 2386 2387 // Either an identifier for named values or a 5-bit immediate. 2388 // Eat optional hash. 2389 if (parseOptionalToken(AsmToken::Hash) || 2390 Tok.is(AsmToken::Integer)) { 2391 const MCExpr *ImmVal; 2392 if (getParser().parseExpression(ImmVal)) 2393 return MatchOperand_ParseFail; 2394 2395 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 2396 if (!MCE) { 2397 TokError("immediate value expected for prefetch operand"); 2398 return MatchOperand_ParseFail; 2399 } 2400 unsigned prfop = MCE->getValue(); 2401 if (prfop > MaxVal) { 2402 TokError("prefetch operand out of range, [0," + utostr(MaxVal) + 2403 "] expected"); 2404 return MatchOperand_ParseFail; 2405 } 2406 2407 auto PRFM = LookupByEncoding(MCE->getValue()); 2408 Operands.push_back(AArch64Operand::CreatePrefetch( 2409 prfop, PRFM.getValueOr(""), S, getContext())); 2410 return MatchOperand_Success; 2411 } 2412 2413 if (Tok.isNot(AsmToken::Identifier)) { 2414 TokError("prefetch hint expected"); 2415 return MatchOperand_ParseFail; 2416 } 2417 2418 auto PRFM = LookupByName(Tok.getString()); 2419 if (!PRFM) { 2420 TokError("prefetch hint expected"); 2421 return MatchOperand_ParseFail; 2422 } 2423 2424 Operands.push_back(AArch64Operand::CreatePrefetch( 2425 *PRFM, Tok.getString(), S, getContext())); 2426 Parser.Lex(); // Eat identifier token. 2427 return MatchOperand_Success; 2428 } 2429 2430 /// tryParsePSBHint - Try to parse a PSB operand, mapped to Hint command 2431 OperandMatchResultTy 2432 AArch64AsmParser::tryParsePSBHint(OperandVector &Operands) { 2433 MCAsmParser &Parser = getParser(); 2434 SMLoc S = getLoc(); 2435 const AsmToken &Tok = Parser.getTok(); 2436 if (Tok.isNot(AsmToken::Identifier)) { 2437 TokError("invalid operand for instruction"); 2438 return MatchOperand_ParseFail; 2439 } 2440 2441 auto PSB = AArch64PSBHint::lookupPSBByName(Tok.getString()); 2442 if (!PSB) { 2443 TokError("invalid operand for instruction"); 2444 return MatchOperand_ParseFail; 2445 } 2446 2447 Operands.push_back(AArch64Operand::CreatePSBHint( 2448 PSB->Encoding, Tok.getString(), S, getContext())); 2449 Parser.Lex(); // Eat identifier token. 2450 return MatchOperand_Success; 2451 } 2452 2453 /// tryParseBTIHint - Try to parse a BTI operand, mapped to Hint command 2454 OperandMatchResultTy 2455 AArch64AsmParser::tryParseBTIHint(OperandVector &Operands) { 2456 MCAsmParser &Parser = getParser(); 2457 SMLoc S = getLoc(); 2458 const AsmToken &Tok = Parser.getTok(); 2459 if (Tok.isNot(AsmToken::Identifier)) { 2460 TokError("invalid operand for instruction"); 2461 return MatchOperand_ParseFail; 2462 } 2463 2464 auto BTI = AArch64BTIHint::lookupBTIByName(Tok.getString()); 2465 if (!BTI) { 2466 TokError("invalid operand for instruction"); 2467 return MatchOperand_ParseFail; 2468 } 2469 2470 Operands.push_back(AArch64Operand::CreateBTIHint( 2471 BTI->Encoding, Tok.getString(), S, getContext())); 2472 Parser.Lex(); // Eat identifier token. 2473 return MatchOperand_Success; 2474 } 2475 2476 /// tryParseAdrpLabel - Parse and validate a source label for the ADRP 2477 /// instruction. 2478 OperandMatchResultTy 2479 AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) { 2480 MCAsmParser &Parser = getParser(); 2481 SMLoc S = getLoc(); 2482 const MCExpr *Expr = nullptr; 2483 2484 if (Parser.getTok().is(AsmToken::Hash)) { 2485 Parser.Lex(); // Eat hash token. 2486 } 2487 2488 if (parseSymbolicImmVal(Expr)) 2489 return MatchOperand_ParseFail; 2490 2491 AArch64MCExpr::VariantKind ELFRefKind; 2492 MCSymbolRefExpr::VariantKind DarwinRefKind; 2493 int64_t Addend; 2494 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) { 2495 if (DarwinRefKind == MCSymbolRefExpr::VK_None && 2496 ELFRefKind == AArch64MCExpr::VK_INVALID) { 2497 // No modifier was specified at all; this is the syntax for an ELF basic 2498 // ADRP relocation (unfortunately). 2499 Expr = 2500 AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS_PAGE, getContext()); 2501 } else if ((DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGE || 2502 DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGE) && 2503 Addend != 0) { 2504 Error(S, "gotpage label reference not allowed an addend"); 2505 return MatchOperand_ParseFail; 2506 } else if (DarwinRefKind != MCSymbolRefExpr::VK_PAGE && 2507 DarwinRefKind != MCSymbolRefExpr::VK_GOTPAGE && 2508 DarwinRefKind != MCSymbolRefExpr::VK_TLVPPAGE && 2509 ELFRefKind != AArch64MCExpr::VK_ABS_PAGE_NC && 2510 ELFRefKind != AArch64MCExpr::VK_GOT_PAGE && 2511 ELFRefKind != AArch64MCExpr::VK_GOTTPREL_PAGE && 2512 ELFRefKind != AArch64MCExpr::VK_TLSDESC_PAGE) { 2513 // The operand must be an @page or @gotpage qualified symbolref. 2514 Error(S, "page or gotpage label reference expected"); 2515 return MatchOperand_ParseFail; 2516 } 2517 } 2518 2519 // We have either a label reference possibly with addend or an immediate. The 2520 // addend is a raw value here. The linker will adjust it to only reference the 2521 // page. 2522 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1); 2523 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext())); 2524 2525 return MatchOperand_Success; 2526 } 2527 2528 /// tryParseAdrLabel - Parse and validate a source label for the ADR 2529 /// instruction. 2530 OperandMatchResultTy 2531 AArch64AsmParser::tryParseAdrLabel(OperandVector &Operands) { 2532 SMLoc S = getLoc(); 2533 const MCExpr *Expr = nullptr; 2534 2535 // Leave anything with a bracket to the default for SVE 2536 if (getParser().getTok().is(AsmToken::LBrac)) 2537 return MatchOperand_NoMatch; 2538 2539 if (getParser().getTok().is(AsmToken::Hash)) 2540 getParser().Lex(); // Eat hash token. 2541 2542 if (parseSymbolicImmVal(Expr)) 2543 return MatchOperand_ParseFail; 2544 2545 AArch64MCExpr::VariantKind ELFRefKind; 2546 MCSymbolRefExpr::VariantKind DarwinRefKind; 2547 int64_t Addend; 2548 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) { 2549 if (DarwinRefKind == MCSymbolRefExpr::VK_None && 2550 ELFRefKind == AArch64MCExpr::VK_INVALID) { 2551 // No modifier was specified at all; this is the syntax for an ELF basic 2552 // ADR relocation (unfortunately). 2553 Expr = AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS, getContext()); 2554 } else { 2555 Error(S, "unexpected adr label"); 2556 return MatchOperand_ParseFail; 2557 } 2558 } 2559 2560 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1); 2561 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext())); 2562 return MatchOperand_Success; 2563 } 2564 2565 /// tryParseFPImm - A floating point immediate expression operand. 2566 template<bool AddFPZeroAsLiteral> 2567 OperandMatchResultTy 2568 AArch64AsmParser::tryParseFPImm(OperandVector &Operands) { 2569 MCAsmParser &Parser = getParser(); 2570 SMLoc S = getLoc(); 2571 2572 bool Hash = parseOptionalToken(AsmToken::Hash); 2573 2574 // Handle negation, as that still comes through as a separate token. 2575 bool isNegative = parseOptionalToken(AsmToken::Minus); 2576 2577 const AsmToken &Tok = Parser.getTok(); 2578 if (!Tok.is(AsmToken::Real) && !Tok.is(AsmToken::Integer)) { 2579 if (!Hash) 2580 return MatchOperand_NoMatch; 2581 TokError("invalid floating point immediate"); 2582 return MatchOperand_ParseFail; 2583 } 2584 2585 // Parse hexadecimal representation. 2586 if (Tok.is(AsmToken::Integer) && Tok.getString().startswith("0x")) { 2587 if (Tok.getIntVal() > 255 || isNegative) { 2588 TokError("encoded floating point value out of range"); 2589 return MatchOperand_ParseFail; 2590 } 2591 2592 APFloat F((double)AArch64_AM::getFPImmFloat(Tok.getIntVal())); 2593 Operands.push_back( 2594 AArch64Operand::CreateFPImm(F, true, S, getContext())); 2595 } else { 2596 // Parse FP representation. 2597 APFloat RealVal(APFloat::IEEEdouble()); 2598 auto StatusOrErr = 2599 RealVal.convertFromString(Tok.getString(), APFloat::rmTowardZero); 2600 if (errorToBool(StatusOrErr.takeError())) { 2601 TokError("invalid floating point representation"); 2602 return MatchOperand_ParseFail; 2603 } 2604 2605 if (isNegative) 2606 RealVal.changeSign(); 2607 2608 if (AddFPZeroAsLiteral && RealVal.isPosZero()) { 2609 Operands.push_back( 2610 AArch64Operand::CreateToken("#0", false, S, getContext())); 2611 Operands.push_back( 2612 AArch64Operand::CreateToken(".0", false, S, getContext())); 2613 } else 2614 Operands.push_back(AArch64Operand::CreateFPImm( 2615 RealVal, *StatusOrErr == APFloat::opOK, S, getContext())); 2616 } 2617 2618 Parser.Lex(); // Eat the token. 2619 2620 return MatchOperand_Success; 2621 } 2622 2623 /// tryParseImmWithOptionalShift - Parse immediate operand, optionally with 2624 /// a shift suffix, for example '#1, lsl #12'. 2625 OperandMatchResultTy 2626 AArch64AsmParser::tryParseImmWithOptionalShift(OperandVector &Operands) { 2627 MCAsmParser &Parser = getParser(); 2628 SMLoc S = getLoc(); 2629 2630 if (Parser.getTok().is(AsmToken::Hash)) 2631 Parser.Lex(); // Eat '#' 2632 else if (Parser.getTok().isNot(AsmToken::Integer)) 2633 // Operand should start from # or should be integer, emit error otherwise. 2634 return MatchOperand_NoMatch; 2635 2636 const MCExpr *Imm = nullptr; 2637 if (parseSymbolicImmVal(Imm)) 2638 return MatchOperand_ParseFail; 2639 else if (Parser.getTok().isNot(AsmToken::Comma)) { 2640 SMLoc E = Parser.getTok().getLoc(); 2641 Operands.push_back( 2642 AArch64Operand::CreateImm(Imm, S, E, getContext())); 2643 return MatchOperand_Success; 2644 } 2645 2646 // Eat ',' 2647 Parser.Lex(); 2648 2649 // The optional operand must be "lsl #N" where N is non-negative. 2650 if (!Parser.getTok().is(AsmToken::Identifier) || 2651 !Parser.getTok().getIdentifier().equals_lower("lsl")) { 2652 Error(Parser.getTok().getLoc(), "only 'lsl #+N' valid after immediate"); 2653 return MatchOperand_ParseFail; 2654 } 2655 2656 // Eat 'lsl' 2657 Parser.Lex(); 2658 2659 parseOptionalToken(AsmToken::Hash); 2660 2661 if (Parser.getTok().isNot(AsmToken::Integer)) { 2662 Error(Parser.getTok().getLoc(), "only 'lsl #+N' valid after immediate"); 2663 return MatchOperand_ParseFail; 2664 } 2665 2666 int64_t ShiftAmount = Parser.getTok().getIntVal(); 2667 2668 if (ShiftAmount < 0) { 2669 Error(Parser.getTok().getLoc(), "positive shift amount required"); 2670 return MatchOperand_ParseFail; 2671 } 2672 Parser.Lex(); // Eat the number 2673 2674 // Just in case the optional lsl #0 is used for immediates other than zero. 2675 if (ShiftAmount == 0 && Imm != nullptr) { 2676 SMLoc E = Parser.getTok().getLoc(); 2677 Operands.push_back(AArch64Operand::CreateImm(Imm, S, E, getContext())); 2678 return MatchOperand_Success; 2679 } 2680 2681 SMLoc E = Parser.getTok().getLoc(); 2682 Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, 2683 S, E, getContext())); 2684 return MatchOperand_Success; 2685 } 2686 2687 /// parseCondCodeString - Parse a Condition Code string. 2688 AArch64CC::CondCode AArch64AsmParser::parseCondCodeString(StringRef Cond) { 2689 AArch64CC::CondCode CC = StringSwitch<AArch64CC::CondCode>(Cond.lower()) 2690 .Case("eq", AArch64CC::EQ) 2691 .Case("ne", AArch64CC::NE) 2692 .Case("cs", AArch64CC::HS) 2693 .Case("hs", AArch64CC::HS) 2694 .Case("cc", AArch64CC::LO) 2695 .Case("lo", AArch64CC::LO) 2696 .Case("mi", AArch64CC::MI) 2697 .Case("pl", AArch64CC::PL) 2698 .Case("vs", AArch64CC::VS) 2699 .Case("vc", AArch64CC::VC) 2700 .Case("hi", AArch64CC::HI) 2701 .Case("ls", AArch64CC::LS) 2702 .Case("ge", AArch64CC::GE) 2703 .Case("lt", AArch64CC::LT) 2704 .Case("gt", AArch64CC::GT) 2705 .Case("le", AArch64CC::LE) 2706 .Case("al", AArch64CC::AL) 2707 .Case("nv", AArch64CC::NV) 2708 .Default(AArch64CC::Invalid); 2709 2710 if (CC == AArch64CC::Invalid && 2711 getSTI().getFeatureBits()[AArch64::FeatureSVE]) 2712 CC = StringSwitch<AArch64CC::CondCode>(Cond.lower()) 2713 .Case("none", AArch64CC::EQ) 2714 .Case("any", AArch64CC::NE) 2715 .Case("nlast", AArch64CC::HS) 2716 .Case("last", AArch64CC::LO) 2717 .Case("first", AArch64CC::MI) 2718 .Case("nfrst", AArch64CC::PL) 2719 .Case("pmore", AArch64CC::HI) 2720 .Case("plast", AArch64CC::LS) 2721 .Case("tcont", AArch64CC::GE) 2722 .Case("tstop", AArch64CC::LT) 2723 .Default(AArch64CC::Invalid); 2724 2725 return CC; 2726 } 2727 2728 /// parseCondCode - Parse a Condition Code operand. 2729 bool AArch64AsmParser::parseCondCode(OperandVector &Operands, 2730 bool invertCondCode) { 2731 MCAsmParser &Parser = getParser(); 2732 SMLoc S = getLoc(); 2733 const AsmToken &Tok = Parser.getTok(); 2734 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2735 2736 StringRef Cond = Tok.getString(); 2737 AArch64CC::CondCode CC = parseCondCodeString(Cond); 2738 if (CC == AArch64CC::Invalid) 2739 return TokError("invalid condition code"); 2740 Parser.Lex(); // Eat identifier token. 2741 2742 if (invertCondCode) { 2743 if (CC == AArch64CC::AL || CC == AArch64CC::NV) 2744 return TokError("condition codes AL and NV are invalid for this instruction"); 2745 CC = AArch64CC::getInvertedCondCode(AArch64CC::CondCode(CC)); 2746 } 2747 2748 Operands.push_back( 2749 AArch64Operand::CreateCondCode(CC, S, getLoc(), getContext())); 2750 return false; 2751 } 2752 2753 /// tryParseOptionalShift - Some operands take an optional shift argument. Parse 2754 /// them if present. 2755 OperandMatchResultTy 2756 AArch64AsmParser::tryParseOptionalShiftExtend(OperandVector &Operands) { 2757 MCAsmParser &Parser = getParser(); 2758 const AsmToken &Tok = Parser.getTok(); 2759 std::string LowerID = Tok.getString().lower(); 2760 AArch64_AM::ShiftExtendType ShOp = 2761 StringSwitch<AArch64_AM::ShiftExtendType>(LowerID) 2762 .Case("lsl", AArch64_AM::LSL) 2763 .Case("lsr", AArch64_AM::LSR) 2764 .Case("asr", AArch64_AM::ASR) 2765 .Case("ror", AArch64_AM::ROR) 2766 .Case("msl", AArch64_AM::MSL) 2767 .Case("uxtb", AArch64_AM::UXTB) 2768 .Case("uxth", AArch64_AM::UXTH) 2769 .Case("uxtw", AArch64_AM::UXTW) 2770 .Case("uxtx", AArch64_AM::UXTX) 2771 .Case("sxtb", AArch64_AM::SXTB) 2772 .Case("sxth", AArch64_AM::SXTH) 2773 .Case("sxtw", AArch64_AM::SXTW) 2774 .Case("sxtx", AArch64_AM::SXTX) 2775 .Default(AArch64_AM::InvalidShiftExtend); 2776 2777 if (ShOp == AArch64_AM::InvalidShiftExtend) 2778 return MatchOperand_NoMatch; 2779 2780 SMLoc S = Tok.getLoc(); 2781 Parser.Lex(); 2782 2783 bool Hash = parseOptionalToken(AsmToken::Hash); 2784 2785 if (!Hash && getLexer().isNot(AsmToken::Integer)) { 2786 if (ShOp == AArch64_AM::LSL || ShOp == AArch64_AM::LSR || 2787 ShOp == AArch64_AM::ASR || ShOp == AArch64_AM::ROR || 2788 ShOp == AArch64_AM::MSL) { 2789 // We expect a number here. 2790 TokError("expected #imm after shift specifier"); 2791 return MatchOperand_ParseFail; 2792 } 2793 2794 // "extend" type operations don't need an immediate, #0 is implicit. 2795 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1); 2796 Operands.push_back( 2797 AArch64Operand::CreateShiftExtend(ShOp, 0, false, S, E, getContext())); 2798 return MatchOperand_Success; 2799 } 2800 2801 // Make sure we do actually have a number, identifier or a parenthesized 2802 // expression. 2803 SMLoc E = Parser.getTok().getLoc(); 2804 if (!Parser.getTok().is(AsmToken::Integer) && 2805 !Parser.getTok().is(AsmToken::LParen) && 2806 !Parser.getTok().is(AsmToken::Identifier)) { 2807 Error(E, "expected integer shift amount"); 2808 return MatchOperand_ParseFail; 2809 } 2810 2811 const MCExpr *ImmVal; 2812 if (getParser().parseExpression(ImmVal)) 2813 return MatchOperand_ParseFail; 2814 2815 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 2816 if (!MCE) { 2817 Error(E, "expected constant '#imm' after shift specifier"); 2818 return MatchOperand_ParseFail; 2819 } 2820 2821 E = SMLoc::getFromPointer(getLoc().getPointer() - 1); 2822 Operands.push_back(AArch64Operand::CreateShiftExtend( 2823 ShOp, MCE->getValue(), true, S, E, getContext())); 2824 return MatchOperand_Success; 2825 } 2826 2827 static const struct Extension { 2828 const char *Name; 2829 const FeatureBitset Features; 2830 } ExtensionMap[] = { 2831 {"crc", {AArch64::FeatureCRC}}, 2832 {"sm4", {AArch64::FeatureSM4}}, 2833 {"sha3", {AArch64::FeatureSHA3}}, 2834 {"sha2", {AArch64::FeatureSHA2}}, 2835 {"aes", {AArch64::FeatureAES}}, 2836 {"crypto", {AArch64::FeatureCrypto}}, 2837 {"fp", {AArch64::FeatureFPARMv8}}, 2838 {"simd", {AArch64::FeatureNEON}}, 2839 {"ras", {AArch64::FeatureRAS}}, 2840 {"lse", {AArch64::FeatureLSE}}, 2841 {"predres", {AArch64::FeaturePredRes}}, 2842 {"ccdp", {AArch64::FeatureCacheDeepPersist}}, 2843 {"mte", {AArch64::FeatureMTE}}, 2844 {"memtag", {AArch64::FeatureMTE}}, 2845 {"tlb-rmi", {AArch64::FeatureTLB_RMI}}, 2846 {"pan-rwv", {AArch64::FeaturePAN_RWV}}, 2847 {"ccpp", {AArch64::FeatureCCPP}}, 2848 {"rcpc", {AArch64::FeatureRCPC}}, 2849 {"sve", {AArch64::FeatureSVE}}, 2850 {"sve2", {AArch64::FeatureSVE2}}, 2851 {"sve2-aes", {AArch64::FeatureSVE2AES}}, 2852 {"sve2-sm4", {AArch64::FeatureSVE2SM4}}, 2853 {"sve2-sha3", {AArch64::FeatureSVE2SHA3}}, 2854 {"sve2-bitperm", {AArch64::FeatureSVE2BitPerm}}, 2855 // FIXME: Unsupported extensions 2856 {"pan", {}}, 2857 {"lor", {}}, 2858 {"rdma", {}}, 2859 {"profile", {}}, 2860 }; 2861 2862 static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str) { 2863 if (FBS[AArch64::HasV8_1aOps]) 2864 Str += "ARMv8.1a"; 2865 else if (FBS[AArch64::HasV8_2aOps]) 2866 Str += "ARMv8.2a"; 2867 else if (FBS[AArch64::HasV8_3aOps]) 2868 Str += "ARMv8.3a"; 2869 else if (FBS[AArch64::HasV8_4aOps]) 2870 Str += "ARMv8.4a"; 2871 else if (FBS[AArch64::HasV8_5aOps]) 2872 Str += "ARMv8.5a"; 2873 else if (FBS[AArch64::HasV8_6aOps]) 2874 Str += "ARMv8.6a"; 2875 else { 2876 auto ext = std::find_if(std::begin(ExtensionMap), 2877 std::end(ExtensionMap), 2878 [&](const Extension& e) 2879 // Use & in case multiple features are enabled 2880 { return (FBS & e.Features) != FeatureBitset(); } 2881 ); 2882 2883 Str += ext != std::end(ExtensionMap) ? ext->Name : "(unknown)"; 2884 } 2885 } 2886 2887 void AArch64AsmParser::createSysAlias(uint16_t Encoding, OperandVector &Operands, 2888 SMLoc S) { 2889 const uint16_t Op2 = Encoding & 7; 2890 const uint16_t Cm = (Encoding & 0x78) >> 3; 2891 const uint16_t Cn = (Encoding & 0x780) >> 7; 2892 const uint16_t Op1 = (Encoding & 0x3800) >> 11; 2893 2894 const MCExpr *Expr = MCConstantExpr::create(Op1, getContext()); 2895 2896 Operands.push_back( 2897 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext())); 2898 Operands.push_back( 2899 AArch64Operand::CreateSysCR(Cn, S, getLoc(), getContext())); 2900 Operands.push_back( 2901 AArch64Operand::CreateSysCR(Cm, S, getLoc(), getContext())); 2902 Expr = MCConstantExpr::create(Op2, getContext()); 2903 Operands.push_back( 2904 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext())); 2905 } 2906 2907 /// parseSysAlias - The IC, DC, AT, and TLBI instructions are simple aliases for 2908 /// the SYS instruction. Parse them specially so that we create a SYS MCInst. 2909 bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc, 2910 OperandVector &Operands) { 2911 if (Name.find('.') != StringRef::npos) 2912 return TokError("invalid operand"); 2913 2914 Mnemonic = Name; 2915 Operands.push_back( 2916 AArch64Operand::CreateToken("sys", false, NameLoc, getContext())); 2917 2918 MCAsmParser &Parser = getParser(); 2919 const AsmToken &Tok = Parser.getTok(); 2920 StringRef Op = Tok.getString(); 2921 SMLoc S = Tok.getLoc(); 2922 2923 if (Mnemonic == "ic") { 2924 const AArch64IC::IC *IC = AArch64IC::lookupICByName(Op); 2925 if (!IC) 2926 return TokError("invalid operand for IC instruction"); 2927 else if (!IC->haveFeatures(getSTI().getFeatureBits())) { 2928 std::string Str("IC " + std::string(IC->Name) + " requires "); 2929 setRequiredFeatureString(IC->getRequiredFeatures(), Str); 2930 return TokError(Str.c_str()); 2931 } 2932 createSysAlias(IC->Encoding, Operands, S); 2933 } else if (Mnemonic == "dc") { 2934 const AArch64DC::DC *DC = AArch64DC::lookupDCByName(Op); 2935 if (!DC) 2936 return TokError("invalid operand for DC instruction"); 2937 else if (!DC->haveFeatures(getSTI().getFeatureBits())) { 2938 std::string Str("DC " + std::string(DC->Name) + " requires "); 2939 setRequiredFeatureString(DC->getRequiredFeatures(), Str); 2940 return TokError(Str.c_str()); 2941 } 2942 createSysAlias(DC->Encoding, Operands, S); 2943 } else if (Mnemonic == "at") { 2944 const AArch64AT::AT *AT = AArch64AT::lookupATByName(Op); 2945 if (!AT) 2946 return TokError("invalid operand for AT instruction"); 2947 else if (!AT->haveFeatures(getSTI().getFeatureBits())) { 2948 std::string Str("AT " + std::string(AT->Name) + " requires "); 2949 setRequiredFeatureString(AT->getRequiredFeatures(), Str); 2950 return TokError(Str.c_str()); 2951 } 2952 createSysAlias(AT->Encoding, Operands, S); 2953 } else if (Mnemonic == "tlbi") { 2954 const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByName(Op); 2955 if (!TLBI) 2956 return TokError("invalid operand for TLBI instruction"); 2957 else if (!TLBI->haveFeatures(getSTI().getFeatureBits())) { 2958 std::string Str("TLBI " + std::string(TLBI->Name) + " requires "); 2959 setRequiredFeatureString(TLBI->getRequiredFeatures(), Str); 2960 return TokError(Str.c_str()); 2961 } 2962 createSysAlias(TLBI->Encoding, Operands, S); 2963 } else if (Mnemonic == "cfp" || Mnemonic == "dvp" || Mnemonic == "cpp") { 2964 const AArch64PRCTX::PRCTX *PRCTX = AArch64PRCTX::lookupPRCTXByName(Op); 2965 if (!PRCTX) 2966 return TokError("invalid operand for prediction restriction instruction"); 2967 else if (!PRCTX->haveFeatures(getSTI().getFeatureBits())) { 2968 std::string Str( 2969 Mnemonic.upper() + std::string(PRCTX->Name) + " requires "); 2970 setRequiredFeatureString(PRCTX->getRequiredFeatures(), Str); 2971 return TokError(Str.c_str()); 2972 } 2973 uint16_t PRCTX_Op2 = 2974 Mnemonic == "cfp" ? 4 : 2975 Mnemonic == "dvp" ? 5 : 2976 Mnemonic == "cpp" ? 7 : 2977 0; 2978 assert(PRCTX_Op2 && "Invalid mnemonic for prediction restriction instruction"); 2979 createSysAlias(PRCTX->Encoding << 3 | PRCTX_Op2 , Operands, S); 2980 } 2981 2982 Parser.Lex(); // Eat operand. 2983 2984 bool ExpectRegister = (Op.lower().find("all") == StringRef::npos); 2985 bool HasRegister = false; 2986 2987 // Check for the optional register operand. 2988 if (parseOptionalToken(AsmToken::Comma)) { 2989 if (Tok.isNot(AsmToken::Identifier) || parseRegister(Operands)) 2990 return TokError("expected register operand"); 2991 HasRegister = true; 2992 } 2993 2994 if (ExpectRegister && !HasRegister) 2995 return TokError("specified " + Mnemonic + " op requires a register"); 2996 else if (!ExpectRegister && HasRegister) 2997 return TokError("specified " + Mnemonic + " op does not use a register"); 2998 2999 if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list")) 3000 return true; 3001 3002 return false; 3003 } 3004 3005 OperandMatchResultTy 3006 AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) { 3007 MCAsmParser &Parser = getParser(); 3008 const AsmToken &Tok = Parser.getTok(); 3009 3010 if (Mnemonic == "tsb" && Tok.isNot(AsmToken::Identifier)) { 3011 TokError("'csync' operand expected"); 3012 return MatchOperand_ParseFail; 3013 // Can be either a #imm style literal or an option name 3014 } else if (parseOptionalToken(AsmToken::Hash) || Tok.is(AsmToken::Integer)) { 3015 // Immediate operand. 3016 const MCExpr *ImmVal; 3017 SMLoc ExprLoc = getLoc(); 3018 if (getParser().parseExpression(ImmVal)) 3019 return MatchOperand_ParseFail; 3020 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 3021 if (!MCE) { 3022 Error(ExprLoc, "immediate value expected for barrier operand"); 3023 return MatchOperand_ParseFail; 3024 } 3025 if (MCE->getValue() < 0 || MCE->getValue() > 15) { 3026 Error(ExprLoc, "barrier operand out of range"); 3027 return MatchOperand_ParseFail; 3028 } 3029 auto DB = AArch64DB::lookupDBByEncoding(MCE->getValue()); 3030 Operands.push_back(AArch64Operand::CreateBarrier( 3031 MCE->getValue(), DB ? DB->Name : "", ExprLoc, getContext())); 3032 return MatchOperand_Success; 3033 } 3034 3035 if (Tok.isNot(AsmToken::Identifier)) { 3036 TokError("invalid operand for instruction"); 3037 return MatchOperand_ParseFail; 3038 } 3039 3040 auto TSB = AArch64TSB::lookupTSBByName(Tok.getString()); 3041 // The only valid named option for ISB is 'sy' 3042 auto DB = AArch64DB::lookupDBByName(Tok.getString()); 3043 if (Mnemonic == "isb" && (!DB || DB->Encoding != AArch64DB::sy)) { 3044 TokError("'sy' or #imm operand expected"); 3045 return MatchOperand_ParseFail; 3046 // The only valid named option for TSB is 'csync' 3047 } else if (Mnemonic == "tsb" && (!TSB || TSB->Encoding != AArch64TSB::csync)) { 3048 TokError("'csync' operand expected"); 3049 return MatchOperand_ParseFail; 3050 } else if (!DB && !TSB) { 3051 TokError("invalid barrier option name"); 3052 return MatchOperand_ParseFail; 3053 } 3054 3055 Operands.push_back(AArch64Operand::CreateBarrier( 3056 DB ? DB->Encoding : TSB->Encoding, Tok.getString(), getLoc(), getContext())); 3057 Parser.Lex(); // Consume the option 3058 3059 return MatchOperand_Success; 3060 } 3061 3062 OperandMatchResultTy 3063 AArch64AsmParser::tryParseSysReg(OperandVector &Operands) { 3064 MCAsmParser &Parser = getParser(); 3065 const AsmToken &Tok = Parser.getTok(); 3066 3067 if (Tok.isNot(AsmToken::Identifier)) 3068 return MatchOperand_NoMatch; 3069 3070 int MRSReg, MSRReg; 3071 auto SysReg = AArch64SysReg::lookupSysRegByName(Tok.getString()); 3072 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) { 3073 MRSReg = SysReg->Readable ? SysReg->Encoding : -1; 3074 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1; 3075 } else 3076 MRSReg = MSRReg = AArch64SysReg::parseGenericRegister(Tok.getString()); 3077 3078 auto PState = AArch64PState::lookupPStateByName(Tok.getString()); 3079 unsigned PStateImm = -1; 3080 if (PState && PState->haveFeatures(getSTI().getFeatureBits())) 3081 PStateImm = PState->Encoding; 3082 3083 Operands.push_back( 3084 AArch64Operand::CreateSysReg(Tok.getString(), getLoc(), MRSReg, MSRReg, 3085 PStateImm, getContext())); 3086 Parser.Lex(); // Eat identifier 3087 3088 return MatchOperand_Success; 3089 } 3090 3091 /// tryParseNeonVectorRegister - Parse a vector register operand. 3092 bool AArch64AsmParser::tryParseNeonVectorRegister(OperandVector &Operands) { 3093 MCAsmParser &Parser = getParser(); 3094 if (Parser.getTok().isNot(AsmToken::Identifier)) 3095 return true; 3096 3097 SMLoc S = getLoc(); 3098 // Check for a vector register specifier first. 3099 StringRef Kind; 3100 unsigned Reg; 3101 OperandMatchResultTy Res = 3102 tryParseVectorRegister(Reg, Kind, RegKind::NeonVector); 3103 if (Res != MatchOperand_Success) 3104 return true; 3105 3106 const auto &KindRes = parseVectorKind(Kind, RegKind::NeonVector); 3107 if (!KindRes) 3108 return true; 3109 3110 unsigned ElementWidth = KindRes->second; 3111 Operands.push_back( 3112 AArch64Operand::CreateVectorReg(Reg, RegKind::NeonVector, ElementWidth, 3113 S, getLoc(), getContext())); 3114 3115 // If there was an explicit qualifier, that goes on as a literal text 3116 // operand. 3117 if (!Kind.empty()) 3118 Operands.push_back( 3119 AArch64Operand::CreateToken(Kind, false, S, getContext())); 3120 3121 return tryParseVectorIndex(Operands) == MatchOperand_ParseFail; 3122 } 3123 3124 OperandMatchResultTy 3125 AArch64AsmParser::tryParseVectorIndex(OperandVector &Operands) { 3126 SMLoc SIdx = getLoc(); 3127 if (parseOptionalToken(AsmToken::LBrac)) { 3128 const MCExpr *ImmVal; 3129 if (getParser().parseExpression(ImmVal)) 3130 return MatchOperand_NoMatch; 3131 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 3132 if (!MCE) { 3133 TokError("immediate value expected for vector index"); 3134 return MatchOperand_ParseFail;; 3135 } 3136 3137 SMLoc E = getLoc(); 3138 3139 if (parseToken(AsmToken::RBrac, "']' expected")) 3140 return MatchOperand_ParseFail;; 3141 3142 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx, 3143 E, getContext())); 3144 return MatchOperand_Success; 3145 } 3146 3147 return MatchOperand_NoMatch; 3148 } 3149 3150 // tryParseVectorRegister - Try to parse a vector register name with 3151 // optional kind specifier. If it is a register specifier, eat the token 3152 // and return it. 3153 OperandMatchResultTy 3154 AArch64AsmParser::tryParseVectorRegister(unsigned &Reg, StringRef &Kind, 3155 RegKind MatchKind) { 3156 MCAsmParser &Parser = getParser(); 3157 const AsmToken &Tok = Parser.getTok(); 3158 3159 if (Tok.isNot(AsmToken::Identifier)) 3160 return MatchOperand_NoMatch; 3161 3162 StringRef Name = Tok.getString(); 3163 // If there is a kind specifier, it's separated from the register name by 3164 // a '.'. 3165 size_t Start = 0, Next = Name.find('.'); 3166 StringRef Head = Name.slice(Start, Next); 3167 unsigned RegNum = matchRegisterNameAlias(Head, MatchKind); 3168 3169 if (RegNum) { 3170 if (Next != StringRef::npos) { 3171 Kind = Name.slice(Next, StringRef::npos); 3172 if (!isValidVectorKind(Kind, MatchKind)) { 3173 TokError("invalid vector kind qualifier"); 3174 return MatchOperand_ParseFail; 3175 } 3176 } 3177 Parser.Lex(); // Eat the register token. 3178 3179 Reg = RegNum; 3180 return MatchOperand_Success; 3181 } 3182 3183 return MatchOperand_NoMatch; 3184 } 3185 3186 /// tryParseSVEPredicateVector - Parse a SVE predicate register operand. 3187 OperandMatchResultTy 3188 AArch64AsmParser::tryParseSVEPredicateVector(OperandVector &Operands) { 3189 // Check for a SVE predicate register specifier first. 3190 const SMLoc S = getLoc(); 3191 StringRef Kind; 3192 unsigned RegNum; 3193 auto Res = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector); 3194 if (Res != MatchOperand_Success) 3195 return Res; 3196 3197 const auto &KindRes = parseVectorKind(Kind, RegKind::SVEPredicateVector); 3198 if (!KindRes) 3199 return MatchOperand_NoMatch; 3200 3201 unsigned ElementWidth = KindRes->second; 3202 Operands.push_back(AArch64Operand::CreateVectorReg( 3203 RegNum, RegKind::SVEPredicateVector, ElementWidth, S, 3204 getLoc(), getContext())); 3205 3206 // Not all predicates are followed by a '/m' or '/z'. 3207 MCAsmParser &Parser = getParser(); 3208 if (Parser.getTok().isNot(AsmToken::Slash)) 3209 return MatchOperand_Success; 3210 3211 // But when they do they shouldn't have an element type suffix. 3212 if (!Kind.empty()) { 3213 Error(S, "not expecting size suffix"); 3214 return MatchOperand_ParseFail; 3215 } 3216 3217 // Add a literal slash as operand 3218 Operands.push_back( 3219 AArch64Operand::CreateToken("/" , false, getLoc(), getContext())); 3220 3221 Parser.Lex(); // Eat the slash. 3222 3223 // Zeroing or merging? 3224 auto Pred = Parser.getTok().getString().lower(); 3225 if (Pred != "z" && Pred != "m") { 3226 Error(getLoc(), "expecting 'm' or 'z' predication"); 3227 return MatchOperand_ParseFail; 3228 } 3229 3230 // Add zero/merge token. 3231 const char *ZM = Pred == "z" ? "z" : "m"; 3232 Operands.push_back( 3233 AArch64Operand::CreateToken(ZM, false, getLoc(), getContext())); 3234 3235 Parser.Lex(); // Eat zero/merge token. 3236 return MatchOperand_Success; 3237 } 3238 3239 /// parseRegister - Parse a register operand. 3240 bool AArch64AsmParser::parseRegister(OperandVector &Operands) { 3241 // Try for a Neon vector register. 3242 if (!tryParseNeonVectorRegister(Operands)) 3243 return false; 3244 3245 // Otherwise try for a scalar register. 3246 if (tryParseGPROperand<false>(Operands) == MatchOperand_Success) 3247 return false; 3248 3249 return true; 3250 } 3251 3252 bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) { 3253 MCAsmParser &Parser = getParser(); 3254 bool HasELFModifier = false; 3255 AArch64MCExpr::VariantKind RefKind; 3256 3257 if (parseOptionalToken(AsmToken::Colon)) { 3258 HasELFModifier = true; 3259 3260 if (Parser.getTok().isNot(AsmToken::Identifier)) 3261 return TokError("expect relocation specifier in operand after ':'"); 3262 3263 std::string LowerCase = Parser.getTok().getIdentifier().lower(); 3264 RefKind = StringSwitch<AArch64MCExpr::VariantKind>(LowerCase) 3265 .Case("lo12", AArch64MCExpr::VK_LO12) 3266 .Case("abs_g3", AArch64MCExpr::VK_ABS_G3) 3267 .Case("abs_g2", AArch64MCExpr::VK_ABS_G2) 3268 .Case("abs_g2_s", AArch64MCExpr::VK_ABS_G2_S) 3269 .Case("abs_g2_nc", AArch64MCExpr::VK_ABS_G2_NC) 3270 .Case("abs_g1", AArch64MCExpr::VK_ABS_G1) 3271 .Case("abs_g1_s", AArch64MCExpr::VK_ABS_G1_S) 3272 .Case("abs_g1_nc", AArch64MCExpr::VK_ABS_G1_NC) 3273 .Case("abs_g0", AArch64MCExpr::VK_ABS_G0) 3274 .Case("abs_g0_s", AArch64MCExpr::VK_ABS_G0_S) 3275 .Case("abs_g0_nc", AArch64MCExpr::VK_ABS_G0_NC) 3276 .Case("prel_g3", AArch64MCExpr::VK_PREL_G3) 3277 .Case("prel_g2", AArch64MCExpr::VK_PREL_G2) 3278 .Case("prel_g2_nc", AArch64MCExpr::VK_PREL_G2_NC) 3279 .Case("prel_g1", AArch64MCExpr::VK_PREL_G1) 3280 .Case("prel_g1_nc", AArch64MCExpr::VK_PREL_G1_NC) 3281 .Case("prel_g0", AArch64MCExpr::VK_PREL_G0) 3282 .Case("prel_g0_nc", AArch64MCExpr::VK_PREL_G0_NC) 3283 .Case("dtprel_g2", AArch64MCExpr::VK_DTPREL_G2) 3284 .Case("dtprel_g1", AArch64MCExpr::VK_DTPREL_G1) 3285 .Case("dtprel_g1_nc", AArch64MCExpr::VK_DTPREL_G1_NC) 3286 .Case("dtprel_g0", AArch64MCExpr::VK_DTPREL_G0) 3287 .Case("dtprel_g0_nc", AArch64MCExpr::VK_DTPREL_G0_NC) 3288 .Case("dtprel_hi12", AArch64MCExpr::VK_DTPREL_HI12) 3289 .Case("dtprel_lo12", AArch64MCExpr::VK_DTPREL_LO12) 3290 .Case("dtprel_lo12_nc", AArch64MCExpr::VK_DTPREL_LO12_NC) 3291 .Case("pg_hi21_nc", AArch64MCExpr::VK_ABS_PAGE_NC) 3292 .Case("tprel_g2", AArch64MCExpr::VK_TPREL_G2) 3293 .Case("tprel_g1", AArch64MCExpr::VK_TPREL_G1) 3294 .Case("tprel_g1_nc", AArch64MCExpr::VK_TPREL_G1_NC) 3295 .Case("tprel_g0", AArch64MCExpr::VK_TPREL_G0) 3296 .Case("tprel_g0_nc", AArch64MCExpr::VK_TPREL_G0_NC) 3297 .Case("tprel_hi12", AArch64MCExpr::VK_TPREL_HI12) 3298 .Case("tprel_lo12", AArch64MCExpr::VK_TPREL_LO12) 3299 .Case("tprel_lo12_nc", AArch64MCExpr::VK_TPREL_LO12_NC) 3300 .Case("tlsdesc_lo12", AArch64MCExpr::VK_TLSDESC_LO12) 3301 .Case("got", AArch64MCExpr::VK_GOT_PAGE) 3302 .Case("got_lo12", AArch64MCExpr::VK_GOT_LO12) 3303 .Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE) 3304 .Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC) 3305 .Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1) 3306 .Case("gottprel_g0_nc", AArch64MCExpr::VK_GOTTPREL_G0_NC) 3307 .Case("tlsdesc", AArch64MCExpr::VK_TLSDESC_PAGE) 3308 .Case("secrel_lo12", AArch64MCExpr::VK_SECREL_LO12) 3309 .Case("secrel_hi12", AArch64MCExpr::VK_SECREL_HI12) 3310 .Default(AArch64MCExpr::VK_INVALID); 3311 3312 if (RefKind == AArch64MCExpr::VK_INVALID) 3313 return TokError("expect relocation specifier in operand after ':'"); 3314 3315 Parser.Lex(); // Eat identifier 3316 3317 if (parseToken(AsmToken::Colon, "expect ':' after relocation specifier")) 3318 return true; 3319 } 3320 3321 if (getParser().parseExpression(ImmVal)) 3322 return true; 3323 3324 if (HasELFModifier) 3325 ImmVal = AArch64MCExpr::create(ImmVal, RefKind, getContext()); 3326 3327 return false; 3328 } 3329 3330 template <RegKind VectorKind> 3331 OperandMatchResultTy 3332 AArch64AsmParser::tryParseVectorList(OperandVector &Operands, 3333 bool ExpectMatch) { 3334 MCAsmParser &Parser = getParser(); 3335 if (!Parser.getTok().is(AsmToken::LCurly)) 3336 return MatchOperand_NoMatch; 3337 3338 // Wrapper around parse function 3339 auto ParseVector = [this, &Parser](unsigned &Reg, StringRef &Kind, SMLoc Loc, 3340 bool NoMatchIsError) { 3341 auto RegTok = Parser.getTok(); 3342 auto ParseRes = tryParseVectorRegister(Reg, Kind, VectorKind); 3343 if (ParseRes == MatchOperand_Success) { 3344 if (parseVectorKind(Kind, VectorKind)) 3345 return ParseRes; 3346 llvm_unreachable("Expected a valid vector kind"); 3347 } 3348 3349 if (RegTok.isNot(AsmToken::Identifier) || 3350 ParseRes == MatchOperand_ParseFail || 3351 (ParseRes == MatchOperand_NoMatch && NoMatchIsError)) { 3352 Error(Loc, "vector register expected"); 3353 return MatchOperand_ParseFail; 3354 } 3355 3356 return MatchOperand_NoMatch; 3357 }; 3358 3359 SMLoc S = getLoc(); 3360 auto LCurly = Parser.getTok(); 3361 Parser.Lex(); // Eat left bracket token. 3362 3363 StringRef Kind; 3364 unsigned FirstReg; 3365 auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch); 3366 3367 // Put back the original left bracket if there was no match, so that 3368 // different types of list-operands can be matched (e.g. SVE, Neon). 3369 if (ParseRes == MatchOperand_NoMatch) 3370 Parser.getLexer().UnLex(LCurly); 3371 3372 if (ParseRes != MatchOperand_Success) 3373 return ParseRes; 3374 3375 int64_t PrevReg = FirstReg; 3376 unsigned Count = 1; 3377 3378 if (parseOptionalToken(AsmToken::Minus)) { 3379 SMLoc Loc = getLoc(); 3380 StringRef NextKind; 3381 3382 unsigned Reg; 3383 ParseRes = ParseVector(Reg, NextKind, getLoc(), true); 3384 if (ParseRes != MatchOperand_Success) 3385 return ParseRes; 3386 3387 // Any Kind suffices must match on all regs in the list. 3388 if (Kind != NextKind) { 3389 Error(Loc, "mismatched register size suffix"); 3390 return MatchOperand_ParseFail; 3391 } 3392 3393 unsigned Space = (PrevReg < Reg) ? (Reg - PrevReg) : (Reg + 32 - PrevReg); 3394 3395 if (Space == 0 || Space > 3) { 3396 Error(Loc, "invalid number of vectors"); 3397 return MatchOperand_ParseFail; 3398 } 3399 3400 Count += Space; 3401 } 3402 else { 3403 while (parseOptionalToken(AsmToken::Comma)) { 3404 SMLoc Loc = getLoc(); 3405 StringRef NextKind; 3406 unsigned Reg; 3407 ParseRes = ParseVector(Reg, NextKind, getLoc(), true); 3408 if (ParseRes != MatchOperand_Success) 3409 return ParseRes; 3410 3411 // Any Kind suffices must match on all regs in the list. 3412 if (Kind != NextKind) { 3413 Error(Loc, "mismatched register size suffix"); 3414 return MatchOperand_ParseFail; 3415 } 3416 3417 // Registers must be incremental (with wraparound at 31) 3418 if (getContext().getRegisterInfo()->getEncodingValue(Reg) != 3419 (getContext().getRegisterInfo()->getEncodingValue(PrevReg) + 1) % 32) { 3420 Error(Loc, "registers must be sequential"); 3421 return MatchOperand_ParseFail; 3422 } 3423 3424 PrevReg = Reg; 3425 ++Count; 3426 } 3427 } 3428 3429 if (parseToken(AsmToken::RCurly, "'}' expected")) 3430 return MatchOperand_ParseFail; 3431 3432 if (Count > 4) { 3433 Error(S, "invalid number of vectors"); 3434 return MatchOperand_ParseFail; 3435 } 3436 3437 unsigned NumElements = 0; 3438 unsigned ElementWidth = 0; 3439 if (!Kind.empty()) { 3440 if (const auto &VK = parseVectorKind(Kind, VectorKind)) 3441 std::tie(NumElements, ElementWidth) = *VK; 3442 } 3443 3444 Operands.push_back(AArch64Operand::CreateVectorList( 3445 FirstReg, Count, NumElements, ElementWidth, VectorKind, S, getLoc(), 3446 getContext())); 3447 3448 return MatchOperand_Success; 3449 } 3450 3451 /// parseNeonVectorList - Parse a vector list operand for AdvSIMD instructions. 3452 bool AArch64AsmParser::parseNeonVectorList(OperandVector &Operands) { 3453 auto ParseRes = tryParseVectorList<RegKind::NeonVector>(Operands, true); 3454 if (ParseRes != MatchOperand_Success) 3455 return true; 3456 3457 return tryParseVectorIndex(Operands) == MatchOperand_ParseFail; 3458 } 3459 3460 OperandMatchResultTy 3461 AArch64AsmParser::tryParseGPR64sp0Operand(OperandVector &Operands) { 3462 SMLoc StartLoc = getLoc(); 3463 3464 unsigned RegNum; 3465 OperandMatchResultTy Res = tryParseScalarRegister(RegNum); 3466 if (Res != MatchOperand_Success) 3467 return Res; 3468 3469 if (!parseOptionalToken(AsmToken::Comma)) { 3470 Operands.push_back(AArch64Operand::CreateReg( 3471 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext())); 3472 return MatchOperand_Success; 3473 } 3474 3475 parseOptionalToken(AsmToken::Hash); 3476 3477 if (getParser().getTok().isNot(AsmToken::Integer)) { 3478 Error(getLoc(), "index must be absent or #0"); 3479 return MatchOperand_ParseFail; 3480 } 3481 3482 const MCExpr *ImmVal; 3483 if (getParser().parseExpression(ImmVal) || !isa<MCConstantExpr>(ImmVal) || 3484 cast<MCConstantExpr>(ImmVal)->getValue() != 0) { 3485 Error(getLoc(), "index must be absent or #0"); 3486 return MatchOperand_ParseFail; 3487 } 3488 3489 Operands.push_back(AArch64Operand::CreateReg( 3490 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext())); 3491 return MatchOperand_Success; 3492 } 3493 3494 template <bool ParseShiftExtend, RegConstraintEqualityTy EqTy> 3495 OperandMatchResultTy 3496 AArch64AsmParser::tryParseGPROperand(OperandVector &Operands) { 3497 SMLoc StartLoc = getLoc(); 3498 3499 unsigned RegNum; 3500 OperandMatchResultTy Res = tryParseScalarRegister(RegNum); 3501 if (Res != MatchOperand_Success) 3502 return Res; 3503 3504 // No shift/extend is the default. 3505 if (!ParseShiftExtend || getParser().getTok().isNot(AsmToken::Comma)) { 3506 Operands.push_back(AArch64Operand::CreateReg( 3507 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext(), EqTy)); 3508 return MatchOperand_Success; 3509 } 3510 3511 // Eat the comma 3512 getParser().Lex(); 3513 3514 // Match the shift 3515 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> ExtOpnd; 3516 Res = tryParseOptionalShiftExtend(ExtOpnd); 3517 if (Res != MatchOperand_Success) 3518 return Res; 3519 3520 auto Ext = static_cast<AArch64Operand*>(ExtOpnd.back().get()); 3521 Operands.push_back(AArch64Operand::CreateReg( 3522 RegNum, RegKind::Scalar, StartLoc, Ext->getEndLoc(), getContext(), EqTy, 3523 Ext->getShiftExtendType(), Ext->getShiftExtendAmount(), 3524 Ext->hasShiftExtendAmount())); 3525 3526 return MatchOperand_Success; 3527 } 3528 3529 bool AArch64AsmParser::parseOptionalMulOperand(OperandVector &Operands) { 3530 MCAsmParser &Parser = getParser(); 3531 3532 // Some SVE instructions have a decoration after the immediate, i.e. 3533 // "mul vl". We parse them here and add tokens, which must be present in the 3534 // asm string in the tablegen instruction. 3535 bool NextIsVL = Parser.getLexer().peekTok().getString().equals_lower("vl"); 3536 bool NextIsHash = Parser.getLexer().peekTok().is(AsmToken::Hash); 3537 if (!Parser.getTok().getString().equals_lower("mul") || 3538 !(NextIsVL || NextIsHash)) 3539 return true; 3540 3541 Operands.push_back( 3542 AArch64Operand::CreateToken("mul", false, getLoc(), getContext())); 3543 Parser.Lex(); // Eat the "mul" 3544 3545 if (NextIsVL) { 3546 Operands.push_back( 3547 AArch64Operand::CreateToken("vl", false, getLoc(), getContext())); 3548 Parser.Lex(); // Eat the "vl" 3549 return false; 3550 } 3551 3552 if (NextIsHash) { 3553 Parser.Lex(); // Eat the # 3554 SMLoc S = getLoc(); 3555 3556 // Parse immediate operand. 3557 const MCExpr *ImmVal; 3558 if (!Parser.parseExpression(ImmVal)) 3559 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal)) { 3560 Operands.push_back(AArch64Operand::CreateImm( 3561 MCConstantExpr::create(MCE->getValue(), getContext()), S, getLoc(), 3562 getContext())); 3563 return MatchOperand_Success; 3564 } 3565 } 3566 3567 return Error(getLoc(), "expected 'vl' or '#<imm>'"); 3568 } 3569 3570 /// parseOperand - Parse a arm instruction operand. For now this parses the 3571 /// operand regardless of the mnemonic. 3572 bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode, 3573 bool invertCondCode) { 3574 MCAsmParser &Parser = getParser(); 3575 3576 OperandMatchResultTy ResTy = 3577 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/ true); 3578 3579 // Check if the current operand has a custom associated parser, if so, try to 3580 // custom parse the operand, or fallback to the general approach. 3581 if (ResTy == MatchOperand_Success) 3582 return false; 3583 // If there wasn't a custom match, try the generic matcher below. Otherwise, 3584 // there was a match, but an error occurred, in which case, just return that 3585 // the operand parsing failed. 3586 if (ResTy == MatchOperand_ParseFail) 3587 return true; 3588 3589 // Nothing custom, so do general case parsing. 3590 SMLoc S, E; 3591 switch (getLexer().getKind()) { 3592 default: { 3593 SMLoc S = getLoc(); 3594 const MCExpr *Expr; 3595 if (parseSymbolicImmVal(Expr)) 3596 return Error(S, "invalid operand"); 3597 3598 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1); 3599 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext())); 3600 return false; 3601 } 3602 case AsmToken::LBrac: { 3603 SMLoc Loc = Parser.getTok().getLoc(); 3604 Operands.push_back(AArch64Operand::CreateToken("[", false, Loc, 3605 getContext())); 3606 Parser.Lex(); // Eat '[' 3607 3608 // There's no comma after a '[', so we can parse the next operand 3609 // immediately. 3610 return parseOperand(Operands, false, false); 3611 } 3612 case AsmToken::LCurly: 3613 return parseNeonVectorList(Operands); 3614 case AsmToken::Identifier: { 3615 // If we're expecting a Condition Code operand, then just parse that. 3616 if (isCondCode) 3617 return parseCondCode(Operands, invertCondCode); 3618 3619 // If it's a register name, parse it. 3620 if (!parseRegister(Operands)) 3621 return false; 3622 3623 // See if this is a "mul vl" decoration or "mul #<int>" operand used 3624 // by SVE instructions. 3625 if (!parseOptionalMulOperand(Operands)) 3626 return false; 3627 3628 // This could be an optional "shift" or "extend" operand. 3629 OperandMatchResultTy GotShift = tryParseOptionalShiftExtend(Operands); 3630 // We can only continue if no tokens were eaten. 3631 if (GotShift != MatchOperand_NoMatch) 3632 return GotShift; 3633 3634 // This was not a register so parse other operands that start with an 3635 // identifier (like labels) as expressions and create them as immediates. 3636 const MCExpr *IdVal; 3637 S = getLoc(); 3638 if (getParser().parseExpression(IdVal)) 3639 return true; 3640 E = SMLoc::getFromPointer(getLoc().getPointer() - 1); 3641 Operands.push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext())); 3642 return false; 3643 } 3644 case AsmToken::Integer: 3645 case AsmToken::Real: 3646 case AsmToken::Hash: { 3647 // #42 -> immediate. 3648 S = getLoc(); 3649 3650 parseOptionalToken(AsmToken::Hash); 3651 3652 // Parse a negative sign 3653 bool isNegative = false; 3654 if (Parser.getTok().is(AsmToken::Minus)) { 3655 isNegative = true; 3656 // We need to consume this token only when we have a Real, otherwise 3657 // we let parseSymbolicImmVal take care of it 3658 if (Parser.getLexer().peekTok().is(AsmToken::Real)) 3659 Parser.Lex(); 3660 } 3661 3662 // The only Real that should come through here is a literal #0.0 for 3663 // the fcmp[e] r, #0.0 instructions. They expect raw token operands, 3664 // so convert the value. 3665 const AsmToken &Tok = Parser.getTok(); 3666 if (Tok.is(AsmToken::Real)) { 3667 APFloat RealVal(APFloat::IEEEdouble(), Tok.getString()); 3668 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 3669 if (Mnemonic != "fcmp" && Mnemonic != "fcmpe" && Mnemonic != "fcmeq" && 3670 Mnemonic != "fcmge" && Mnemonic != "fcmgt" && Mnemonic != "fcmle" && 3671 Mnemonic != "fcmlt" && Mnemonic != "fcmne") 3672 return TokError("unexpected floating point literal"); 3673 else if (IntVal != 0 || isNegative) 3674 return TokError("expected floating-point constant #0.0"); 3675 Parser.Lex(); // Eat the token. 3676 3677 Operands.push_back( 3678 AArch64Operand::CreateToken("#0", false, S, getContext())); 3679 Operands.push_back( 3680 AArch64Operand::CreateToken(".0", false, S, getContext())); 3681 return false; 3682 } 3683 3684 const MCExpr *ImmVal; 3685 if (parseSymbolicImmVal(ImmVal)) 3686 return true; 3687 3688 E = SMLoc::getFromPointer(getLoc().getPointer() - 1); 3689 Operands.push_back(AArch64Operand::CreateImm(ImmVal, S, E, getContext())); 3690 return false; 3691 } 3692 case AsmToken::Equal: { 3693 SMLoc Loc = getLoc(); 3694 if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val) 3695 return TokError("unexpected token in operand"); 3696 Parser.Lex(); // Eat '=' 3697 const MCExpr *SubExprVal; 3698 if (getParser().parseExpression(SubExprVal)) 3699 return true; 3700 3701 if (Operands.size() < 2 || 3702 !static_cast<AArch64Operand &>(*Operands[1]).isScalarReg()) 3703 return Error(Loc, "Only valid when first operand is register"); 3704 3705 bool IsXReg = 3706 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( 3707 Operands[1]->getReg()); 3708 3709 MCContext& Ctx = getContext(); 3710 E = SMLoc::getFromPointer(Loc.getPointer() - 1); 3711 // If the op is an imm and can be fit into a mov, then replace ldr with mov. 3712 if (isa<MCConstantExpr>(SubExprVal)) { 3713 uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue(); 3714 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16; 3715 while(Imm > 0xFFFF && countTrailingZeros(Imm) >= 16) { 3716 ShiftAmt += 16; 3717 Imm >>= 16; 3718 } 3719 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) { 3720 Operands[0] = AArch64Operand::CreateToken("movz", false, Loc, Ctx); 3721 Operands.push_back(AArch64Operand::CreateImm( 3722 MCConstantExpr::create(Imm, Ctx), S, E, Ctx)); 3723 if (ShiftAmt) 3724 Operands.push_back(AArch64Operand::CreateShiftExtend(AArch64_AM::LSL, 3725 ShiftAmt, true, S, E, Ctx)); 3726 return false; 3727 } 3728 APInt Simm = APInt(64, Imm << ShiftAmt); 3729 // check if the immediate is an unsigned or signed 32-bit int for W regs 3730 if (!IsXReg && !(Simm.isIntN(32) || Simm.isSignedIntN(32))) 3731 return Error(Loc, "Immediate too large for register"); 3732 } 3733 // If it is a label or an imm that cannot fit in a movz, put it into CP. 3734 const MCExpr *CPLoc = 3735 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc); 3736 Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx)); 3737 return false; 3738 } 3739 } 3740 } 3741 3742 bool AArch64AsmParser::regsEqual(const MCParsedAsmOperand &Op1, 3743 const MCParsedAsmOperand &Op2) const { 3744 auto &AOp1 = static_cast<const AArch64Operand&>(Op1); 3745 auto &AOp2 = static_cast<const AArch64Operand&>(Op2); 3746 if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg && 3747 AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg) 3748 return MCTargetAsmParser::regsEqual(Op1, Op2); 3749 3750 assert(AOp1.isScalarReg() && AOp2.isScalarReg() && 3751 "Testing equality of non-scalar registers not supported"); 3752 3753 // Check if a registers match their sub/super register classes. 3754 if (AOp1.getRegEqualityTy() == EqualsSuperReg) 3755 return getXRegFromWReg(Op1.getReg()) == Op2.getReg(); 3756 if (AOp1.getRegEqualityTy() == EqualsSubReg) 3757 return getWRegFromXReg(Op1.getReg()) == Op2.getReg(); 3758 if (AOp2.getRegEqualityTy() == EqualsSuperReg) 3759 return getXRegFromWReg(Op2.getReg()) == Op1.getReg(); 3760 if (AOp2.getRegEqualityTy() == EqualsSubReg) 3761 return getWRegFromXReg(Op2.getReg()) == Op1.getReg(); 3762 3763 return false; 3764 } 3765 3766 /// ParseInstruction - Parse an AArch64 instruction mnemonic followed by its 3767 /// operands. 3768 bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info, 3769 StringRef Name, SMLoc NameLoc, 3770 OperandVector &Operands) { 3771 MCAsmParser &Parser = getParser(); 3772 Name = StringSwitch<StringRef>(Name.lower()) 3773 .Case("beq", "b.eq") 3774 .Case("bne", "b.ne") 3775 .Case("bhs", "b.hs") 3776 .Case("bcs", "b.cs") 3777 .Case("blo", "b.lo") 3778 .Case("bcc", "b.cc") 3779 .Case("bmi", "b.mi") 3780 .Case("bpl", "b.pl") 3781 .Case("bvs", "b.vs") 3782 .Case("bvc", "b.vc") 3783 .Case("bhi", "b.hi") 3784 .Case("bls", "b.ls") 3785 .Case("bge", "b.ge") 3786 .Case("blt", "b.lt") 3787 .Case("bgt", "b.gt") 3788 .Case("ble", "b.le") 3789 .Case("bal", "b.al") 3790 .Case("bnv", "b.nv") 3791 .Default(Name); 3792 3793 // First check for the AArch64-specific .req directive. 3794 if (Parser.getTok().is(AsmToken::Identifier) && 3795 Parser.getTok().getIdentifier().lower() == ".req") { 3796 parseDirectiveReq(Name, NameLoc); 3797 // We always return 'error' for this, as we're done with this 3798 // statement and don't need to match the 'instruction." 3799 return true; 3800 } 3801 3802 // Create the leading tokens for the mnemonic, split by '.' characters. 3803 size_t Start = 0, Next = Name.find('.'); 3804 StringRef Head = Name.slice(Start, Next); 3805 3806 // IC, DC, AT, TLBI and Prediction invalidation instructions are aliases for 3807 // the SYS instruction. 3808 if (Head == "ic" || Head == "dc" || Head == "at" || Head == "tlbi" || 3809 Head == "cfp" || Head == "dvp" || Head == "cpp") 3810 return parseSysAlias(Head, NameLoc, Operands); 3811 3812 Operands.push_back( 3813 AArch64Operand::CreateToken(Head, false, NameLoc, getContext())); 3814 Mnemonic = Head; 3815 3816 // Handle condition codes for a branch mnemonic 3817 if (Head == "b" && Next != StringRef::npos) { 3818 Start = Next; 3819 Next = Name.find('.', Start + 1); 3820 Head = Name.slice(Start + 1, Next); 3821 3822 SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() + 3823 (Head.data() - Name.data())); 3824 AArch64CC::CondCode CC = parseCondCodeString(Head); 3825 if (CC == AArch64CC::Invalid) 3826 return Error(SuffixLoc, "invalid condition code"); 3827 Operands.push_back( 3828 AArch64Operand::CreateToken(".", true, SuffixLoc, getContext())); 3829 Operands.push_back( 3830 AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc, getContext())); 3831 } 3832 3833 // Add the remaining tokens in the mnemonic. 3834 while (Next != StringRef::npos) { 3835 Start = Next; 3836 Next = Name.find('.', Start + 1); 3837 Head = Name.slice(Start, Next); 3838 SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() + 3839 (Head.data() - Name.data()) + 1); 3840 Operands.push_back( 3841 AArch64Operand::CreateToken(Head, true, SuffixLoc, getContext())); 3842 } 3843 3844 // Conditional compare instructions have a Condition Code operand, which needs 3845 // to be parsed and an immediate operand created. 3846 bool condCodeFourthOperand = 3847 (Head == "ccmp" || Head == "ccmn" || Head == "fccmp" || 3848 Head == "fccmpe" || Head == "fcsel" || Head == "csel" || 3849 Head == "csinc" || Head == "csinv" || Head == "csneg"); 3850 3851 // These instructions are aliases to some of the conditional select 3852 // instructions. However, the condition code is inverted in the aliased 3853 // instruction. 3854 // 3855 // FIXME: Is this the correct way to handle these? Or should the parser 3856 // generate the aliased instructions directly? 3857 bool condCodeSecondOperand = (Head == "cset" || Head == "csetm"); 3858 bool condCodeThirdOperand = 3859 (Head == "cinc" || Head == "cinv" || Head == "cneg"); 3860 3861 // Read the remaining operands. 3862 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3863 3864 unsigned N = 1; 3865 do { 3866 // Parse and remember the operand. 3867 if (parseOperand(Operands, (N == 4 && condCodeFourthOperand) || 3868 (N == 3 && condCodeThirdOperand) || 3869 (N == 2 && condCodeSecondOperand), 3870 condCodeSecondOperand || condCodeThirdOperand)) { 3871 return true; 3872 } 3873 3874 // After successfully parsing some operands there are two special cases to 3875 // consider (i.e. notional operands not separated by commas). Both are due 3876 // to memory specifiers: 3877 // + An RBrac will end an address for load/store/prefetch 3878 // + An '!' will indicate a pre-indexed operation. 3879 // 3880 // It's someone else's responsibility to make sure these tokens are sane 3881 // in the given context! 3882 3883 SMLoc RLoc = Parser.getTok().getLoc(); 3884 if (parseOptionalToken(AsmToken::RBrac)) 3885 Operands.push_back( 3886 AArch64Operand::CreateToken("]", false, RLoc, getContext())); 3887 SMLoc ELoc = Parser.getTok().getLoc(); 3888 if (parseOptionalToken(AsmToken::Exclaim)) 3889 Operands.push_back( 3890 AArch64Operand::CreateToken("!", false, ELoc, getContext())); 3891 3892 ++N; 3893 } while (parseOptionalToken(AsmToken::Comma)); 3894 } 3895 3896 if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list")) 3897 return true; 3898 3899 return false; 3900 } 3901 3902 static inline bool isMatchingOrAlias(unsigned ZReg, unsigned Reg) { 3903 assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31)); 3904 return (ZReg == ((Reg - AArch64::B0) + AArch64::Z0)) || 3905 (ZReg == ((Reg - AArch64::H0) + AArch64::Z0)) || 3906 (ZReg == ((Reg - AArch64::S0) + AArch64::Z0)) || 3907 (ZReg == ((Reg - AArch64::D0) + AArch64::Z0)) || 3908 (ZReg == ((Reg - AArch64::Q0) + AArch64::Z0)) || 3909 (ZReg == ((Reg - AArch64::Z0) + AArch64::Z0)); 3910 } 3911 3912 // FIXME: This entire function is a giant hack to provide us with decent 3913 // operand range validation/diagnostics until TableGen/MC can be extended 3914 // to support autogeneration of this kind of validation. 3915 bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc, 3916 SmallVectorImpl<SMLoc> &Loc) { 3917 const MCRegisterInfo *RI = getContext().getRegisterInfo(); 3918 const MCInstrDesc &MCID = MII.get(Inst.getOpcode()); 3919 3920 // A prefix only applies to the instruction following it. Here we extract 3921 // prefix information for the next instruction before validating the current 3922 // one so that in the case of failure we don't erronously continue using the 3923 // current prefix. 3924 PrefixInfo Prefix = NextPrefix; 3925 NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.TSFlags); 3926 3927 // Before validating the instruction in isolation we run through the rules 3928 // applicable when it follows a prefix instruction. 3929 // NOTE: brk & hlt can be prefixed but require no additional validation. 3930 if (Prefix.isActive() && 3931 (Inst.getOpcode() != AArch64::BRK) && 3932 (Inst.getOpcode() != AArch64::HLT)) { 3933 3934 // Prefixed intructions must have a destructive operand. 3935 if ((MCID.TSFlags & AArch64::DestructiveInstTypeMask) == 3936 AArch64::NotDestructive) 3937 return Error(IDLoc, "instruction is unpredictable when following a" 3938 " movprfx, suggest replacing movprfx with mov"); 3939 3940 // Destination operands must match. 3941 if (Inst.getOperand(0).getReg() != Prefix.getDstReg()) 3942 return Error(Loc[0], "instruction is unpredictable when following a" 3943 " movprfx writing to a different destination"); 3944 3945 // Destination operand must not be used in any other location. 3946 for (unsigned i = 1; i < Inst.getNumOperands(); ++i) { 3947 if (Inst.getOperand(i).isReg() && 3948 (MCID.getOperandConstraint(i, MCOI::TIED_TO) == -1) && 3949 isMatchingOrAlias(Prefix.getDstReg(), Inst.getOperand(i).getReg())) 3950 return Error(Loc[0], "instruction is unpredictable when following a" 3951 " movprfx and destination also used as non-destructive" 3952 " source"); 3953 } 3954 3955 auto PPRRegClass = AArch64MCRegisterClasses[AArch64::PPRRegClassID]; 3956 if (Prefix.isPredicated()) { 3957 int PgIdx = -1; 3958 3959 // Find the instructions general predicate. 3960 for (unsigned i = 1; i < Inst.getNumOperands(); ++i) 3961 if (Inst.getOperand(i).isReg() && 3962 PPRRegClass.contains(Inst.getOperand(i).getReg())) { 3963 PgIdx = i; 3964 break; 3965 } 3966 3967 // Instruction must be predicated if the movprfx is predicated. 3968 if (PgIdx == -1 || 3969 (MCID.TSFlags & AArch64::ElementSizeMask) == AArch64::ElementSizeNone) 3970 return Error(IDLoc, "instruction is unpredictable when following a" 3971 " predicated movprfx, suggest using unpredicated movprfx"); 3972 3973 // Instruction must use same general predicate as the movprfx. 3974 if (Inst.getOperand(PgIdx).getReg() != Prefix.getPgReg()) 3975 return Error(IDLoc, "instruction is unpredictable when following a" 3976 " predicated movprfx using a different general predicate"); 3977 3978 // Instruction element type must match the movprfx. 3979 if ((MCID.TSFlags & AArch64::ElementSizeMask) != Prefix.getElementSize()) 3980 return Error(IDLoc, "instruction is unpredictable when following a" 3981 " predicated movprfx with a different element size"); 3982 } 3983 } 3984 3985 // Check for indexed addressing modes w/ the base register being the 3986 // same as a destination/source register or pair load where 3987 // the Rt == Rt2. All of those are undefined behaviour. 3988 switch (Inst.getOpcode()) { 3989 case AArch64::LDPSWpre: 3990 case AArch64::LDPWpost: 3991 case AArch64::LDPWpre: 3992 case AArch64::LDPXpost: 3993 case AArch64::LDPXpre: { 3994 unsigned Rt = Inst.getOperand(1).getReg(); 3995 unsigned Rt2 = Inst.getOperand(2).getReg(); 3996 unsigned Rn = Inst.getOperand(3).getReg(); 3997 if (RI->isSubRegisterEq(Rn, Rt)) 3998 return Error(Loc[0], "unpredictable LDP instruction, writeback base " 3999 "is also a destination"); 4000 if (RI->isSubRegisterEq(Rn, Rt2)) 4001 return Error(Loc[1], "unpredictable LDP instruction, writeback base " 4002 "is also a destination"); 4003 LLVM_FALLTHROUGH; 4004 } 4005 case AArch64::LDPDi: 4006 case AArch64::LDPQi: 4007 case AArch64::LDPSi: 4008 case AArch64::LDPSWi: 4009 case AArch64::LDPWi: 4010 case AArch64::LDPXi: { 4011 unsigned Rt = Inst.getOperand(0).getReg(); 4012 unsigned Rt2 = Inst.getOperand(1).getReg(); 4013 if (Rt == Rt2) 4014 return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt"); 4015 break; 4016 } 4017 case AArch64::LDPDpost: 4018 case AArch64::LDPDpre: 4019 case AArch64::LDPQpost: 4020 case AArch64::LDPQpre: 4021 case AArch64::LDPSpost: 4022 case AArch64::LDPSpre: 4023 case AArch64::LDPSWpost: { 4024 unsigned Rt = Inst.getOperand(1).getReg(); 4025 unsigned Rt2 = Inst.getOperand(2).getReg(); 4026 if (Rt == Rt2) 4027 return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt"); 4028 break; 4029 } 4030 case AArch64::STPDpost: 4031 case AArch64::STPDpre: 4032 case AArch64::STPQpost: 4033 case AArch64::STPQpre: 4034 case AArch64::STPSpost: 4035 case AArch64::STPSpre: 4036 case AArch64::STPWpost: 4037 case AArch64::STPWpre: 4038 case AArch64::STPXpost: 4039 case AArch64::STPXpre: { 4040 unsigned Rt = Inst.getOperand(1).getReg(); 4041 unsigned Rt2 = Inst.getOperand(2).getReg(); 4042 unsigned Rn = Inst.getOperand(3).getReg(); 4043 if (RI->isSubRegisterEq(Rn, Rt)) 4044 return Error(Loc[0], "unpredictable STP instruction, writeback base " 4045 "is also a source"); 4046 if (RI->isSubRegisterEq(Rn, Rt2)) 4047 return Error(Loc[1], "unpredictable STP instruction, writeback base " 4048 "is also a source"); 4049 break; 4050 } 4051 case AArch64::LDRBBpre: 4052 case AArch64::LDRBpre: 4053 case AArch64::LDRHHpre: 4054 case AArch64::LDRHpre: 4055 case AArch64::LDRSBWpre: 4056 case AArch64::LDRSBXpre: 4057 case AArch64::LDRSHWpre: 4058 case AArch64::LDRSHXpre: 4059 case AArch64::LDRSWpre: 4060 case AArch64::LDRWpre: 4061 case AArch64::LDRXpre: 4062 case AArch64::LDRBBpost: 4063 case AArch64::LDRBpost: 4064 case AArch64::LDRHHpost: 4065 case AArch64::LDRHpost: 4066 case AArch64::LDRSBWpost: 4067 case AArch64::LDRSBXpost: 4068 case AArch64::LDRSHWpost: 4069 case AArch64::LDRSHXpost: 4070 case AArch64::LDRSWpost: 4071 case AArch64::LDRWpost: 4072 case AArch64::LDRXpost: { 4073 unsigned Rt = Inst.getOperand(1).getReg(); 4074 unsigned Rn = Inst.getOperand(2).getReg(); 4075 if (RI->isSubRegisterEq(Rn, Rt)) 4076 return Error(Loc[0], "unpredictable LDR instruction, writeback base " 4077 "is also a source"); 4078 break; 4079 } 4080 case AArch64::STRBBpost: 4081 case AArch64::STRBpost: 4082 case AArch64::STRHHpost: 4083 case AArch64::STRHpost: 4084 case AArch64::STRWpost: 4085 case AArch64::STRXpost: 4086 case AArch64::STRBBpre: 4087 case AArch64::STRBpre: 4088 case AArch64::STRHHpre: 4089 case AArch64::STRHpre: 4090 case AArch64::STRWpre: 4091 case AArch64::STRXpre: { 4092 unsigned Rt = Inst.getOperand(1).getReg(); 4093 unsigned Rn = Inst.getOperand(2).getReg(); 4094 if (RI->isSubRegisterEq(Rn, Rt)) 4095 return Error(Loc[0], "unpredictable STR instruction, writeback base " 4096 "is also a source"); 4097 break; 4098 } 4099 case AArch64::STXRB: 4100 case AArch64::STXRH: 4101 case AArch64::STXRW: 4102 case AArch64::STXRX: 4103 case AArch64::STLXRB: 4104 case AArch64::STLXRH: 4105 case AArch64::STLXRW: 4106 case AArch64::STLXRX: { 4107 unsigned Rs = Inst.getOperand(0).getReg(); 4108 unsigned Rt = Inst.getOperand(1).getReg(); 4109 unsigned Rn = Inst.getOperand(2).getReg(); 4110 if (RI->isSubRegisterEq(Rt, Rs) || 4111 (RI->isSubRegisterEq(Rn, Rs) && Rn != AArch64::SP)) 4112 return Error(Loc[0], 4113 "unpredictable STXR instruction, status is also a source"); 4114 break; 4115 } 4116 case AArch64::STXPW: 4117 case AArch64::STXPX: 4118 case AArch64::STLXPW: 4119 case AArch64::STLXPX: { 4120 unsigned Rs = Inst.getOperand(0).getReg(); 4121 unsigned Rt1 = Inst.getOperand(1).getReg(); 4122 unsigned Rt2 = Inst.getOperand(2).getReg(); 4123 unsigned Rn = Inst.getOperand(3).getReg(); 4124 if (RI->isSubRegisterEq(Rt1, Rs) || RI->isSubRegisterEq(Rt2, Rs) || 4125 (RI->isSubRegisterEq(Rn, Rs) && Rn != AArch64::SP)) 4126 return Error(Loc[0], 4127 "unpredictable STXP instruction, status is also a source"); 4128 break; 4129 } 4130 case AArch64::LDRABwriteback: 4131 case AArch64::LDRAAwriteback: { 4132 unsigned Xt = Inst.getOperand(0).getReg(); 4133 unsigned Xn = Inst.getOperand(1).getReg(); 4134 if (Xt == Xn) 4135 return Error(Loc[0], 4136 "unpredictable LDRA instruction, writeback base" 4137 " is also a destination"); 4138 break; 4139 } 4140 } 4141 4142 4143 // Now check immediate ranges. Separate from the above as there is overlap 4144 // in the instructions being checked and this keeps the nested conditionals 4145 // to a minimum. 4146 switch (Inst.getOpcode()) { 4147 case AArch64::ADDSWri: 4148 case AArch64::ADDSXri: 4149 case AArch64::ADDWri: 4150 case AArch64::ADDXri: 4151 case AArch64::SUBSWri: 4152 case AArch64::SUBSXri: 4153 case AArch64::SUBWri: 4154 case AArch64::SUBXri: { 4155 // Annoyingly we can't do this in the isAddSubImm predicate, so there is 4156 // some slight duplication here. 4157 if (Inst.getOperand(2).isExpr()) { 4158 const MCExpr *Expr = Inst.getOperand(2).getExpr(); 4159 AArch64MCExpr::VariantKind ELFRefKind; 4160 MCSymbolRefExpr::VariantKind DarwinRefKind; 4161 int64_t Addend; 4162 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) { 4163 4164 // Only allow these with ADDXri. 4165 if ((DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF || 4166 DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) && 4167 Inst.getOpcode() == AArch64::ADDXri) 4168 return false; 4169 4170 // Only allow these with ADDXri/ADDWri 4171 if ((ELFRefKind == AArch64MCExpr::VK_LO12 || 4172 ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 || 4173 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 || 4174 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC || 4175 ELFRefKind == AArch64MCExpr::VK_TPREL_HI12 || 4176 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 || 4177 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC || 4178 ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12 || 4179 ELFRefKind == AArch64MCExpr::VK_SECREL_LO12 || 4180 ELFRefKind == AArch64MCExpr::VK_SECREL_HI12) && 4181 (Inst.getOpcode() == AArch64::ADDXri || 4182 Inst.getOpcode() == AArch64::ADDWri)) 4183 return false; 4184 4185 // Don't allow symbol refs in the immediate field otherwise 4186 // Note: Loc.back() may be Loc[1] or Loc[2] depending on the number of 4187 // operands of the original instruction (i.e. 'add w0, w1, borked' vs 4188 // 'cmp w0, 'borked') 4189 return Error(Loc.back(), "invalid immediate expression"); 4190 } 4191 // We don't validate more complex expressions here 4192 } 4193 return false; 4194 } 4195 default: 4196 return false; 4197 } 4198 } 4199 4200 static std::string AArch64MnemonicSpellCheck(StringRef S, 4201 const FeatureBitset &FBS, 4202 unsigned VariantID = 0); 4203 4204 bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode, 4205 uint64_t ErrorInfo, 4206 OperandVector &Operands) { 4207 switch (ErrCode) { 4208 case Match_InvalidTiedOperand: { 4209 RegConstraintEqualityTy EqTy = 4210 static_cast<const AArch64Operand &>(*Operands[ErrorInfo]) 4211 .getRegEqualityTy(); 4212 switch (EqTy) { 4213 case RegConstraintEqualityTy::EqualsSubReg: 4214 return Error(Loc, "operand must be 64-bit form of destination register"); 4215 case RegConstraintEqualityTy::EqualsSuperReg: 4216 return Error(Loc, "operand must be 32-bit form of destination register"); 4217 case RegConstraintEqualityTy::EqualsReg: 4218 return Error(Loc, "operand must match destination register"); 4219 } 4220 llvm_unreachable("Unknown RegConstraintEqualityTy"); 4221 } 4222 case Match_MissingFeature: 4223 return Error(Loc, 4224 "instruction requires a CPU feature not currently enabled"); 4225 case Match_InvalidOperand: 4226 return Error(Loc, "invalid operand for instruction"); 4227 case Match_InvalidSuffix: 4228 return Error(Loc, "invalid type suffix for instruction"); 4229 case Match_InvalidCondCode: 4230 return Error(Loc, "expected AArch64 condition code"); 4231 case Match_AddSubRegExtendSmall: 4232 return Error(Loc, 4233 "expected '[su]xt[bhw]' with optional integer in range [0, 4]"); 4234 case Match_AddSubRegExtendLarge: 4235 return Error(Loc, 4236 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]"); 4237 case Match_AddSubSecondSource: 4238 return Error(Loc, 4239 "expected compatible register, symbol or integer in range [0, 4095]"); 4240 case Match_LogicalSecondSource: 4241 return Error(Loc, "expected compatible register or logical immediate"); 4242 case Match_InvalidMovImm32Shift: 4243 return Error(Loc, "expected 'lsl' with optional integer 0 or 16"); 4244 case Match_InvalidMovImm64Shift: 4245 return Error(Loc, "expected 'lsl' with optional integer 0, 16, 32 or 48"); 4246 case Match_AddSubRegShift32: 4247 return Error(Loc, 4248 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]"); 4249 case Match_AddSubRegShift64: 4250 return Error(Loc, 4251 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]"); 4252 case Match_InvalidFPImm: 4253 return Error(Loc, 4254 "expected compatible register or floating-point constant"); 4255 case Match_InvalidMemoryIndexedSImm6: 4256 return Error(Loc, "index must be an integer in range [-32, 31]."); 4257 case Match_InvalidMemoryIndexedSImm5: 4258 return Error(Loc, "index must be an integer in range [-16, 15]."); 4259 case Match_InvalidMemoryIndexed1SImm4: 4260 return Error(Loc, "index must be an integer in range [-8, 7]."); 4261 case Match_InvalidMemoryIndexed2SImm4: 4262 return Error(Loc, "index must be a multiple of 2 in range [-16, 14]."); 4263 case Match_InvalidMemoryIndexed3SImm4: 4264 return Error(Loc, "index must be a multiple of 3 in range [-24, 21]."); 4265 case Match_InvalidMemoryIndexed4SImm4: 4266 return Error(Loc, "index must be a multiple of 4 in range [-32, 28]."); 4267 case Match_InvalidMemoryIndexed16SImm4: 4268 return Error(Loc, "index must be a multiple of 16 in range [-128, 112]."); 4269 case Match_InvalidMemoryIndexed32SImm4: 4270 return Error(Loc, "index must be a multiple of 32 in range [-256, 224]."); 4271 case Match_InvalidMemoryIndexed1SImm6: 4272 return Error(Loc, "index must be an integer in range [-32, 31]."); 4273 case Match_InvalidMemoryIndexedSImm8: 4274 return Error(Loc, "index must be an integer in range [-128, 127]."); 4275 case Match_InvalidMemoryIndexedSImm9: 4276 return Error(Loc, "index must be an integer in range [-256, 255]."); 4277 case Match_InvalidMemoryIndexed16SImm9: 4278 return Error(Loc, "index must be a multiple of 16 in range [-4096, 4080]."); 4279 case Match_InvalidMemoryIndexed8SImm10: 4280 return Error(Loc, "index must be a multiple of 8 in range [-4096, 4088]."); 4281 case Match_InvalidMemoryIndexed4SImm7: 4282 return Error(Loc, "index must be a multiple of 4 in range [-256, 252]."); 4283 case Match_InvalidMemoryIndexed8SImm7: 4284 return Error(Loc, "index must be a multiple of 8 in range [-512, 504]."); 4285 case Match_InvalidMemoryIndexed16SImm7: 4286 return Error(Loc, "index must be a multiple of 16 in range [-1024, 1008]."); 4287 case Match_InvalidMemoryIndexed8UImm5: 4288 return Error(Loc, "index must be a multiple of 8 in range [0, 248]."); 4289 case Match_InvalidMemoryIndexed4UImm5: 4290 return Error(Loc, "index must be a multiple of 4 in range [0, 124]."); 4291 case Match_InvalidMemoryIndexed2UImm5: 4292 return Error(Loc, "index must be a multiple of 2 in range [0, 62]."); 4293 case Match_InvalidMemoryIndexed8UImm6: 4294 return Error(Loc, "index must be a multiple of 8 in range [0, 504]."); 4295 case Match_InvalidMemoryIndexed16UImm6: 4296 return Error(Loc, "index must be a multiple of 16 in range [0, 1008]."); 4297 case Match_InvalidMemoryIndexed4UImm6: 4298 return Error(Loc, "index must be a multiple of 4 in range [0, 252]."); 4299 case Match_InvalidMemoryIndexed2UImm6: 4300 return Error(Loc, "index must be a multiple of 2 in range [0, 126]."); 4301 case Match_InvalidMemoryIndexed1UImm6: 4302 return Error(Loc, "index must be in range [0, 63]."); 4303 case Match_InvalidMemoryWExtend8: 4304 return Error(Loc, 4305 "expected 'uxtw' or 'sxtw' with optional shift of #0"); 4306 case Match_InvalidMemoryWExtend16: 4307 return Error(Loc, 4308 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1"); 4309 case Match_InvalidMemoryWExtend32: 4310 return Error(Loc, 4311 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2"); 4312 case Match_InvalidMemoryWExtend64: 4313 return Error(Loc, 4314 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3"); 4315 case Match_InvalidMemoryWExtend128: 4316 return Error(Loc, 4317 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4"); 4318 case Match_InvalidMemoryXExtend8: 4319 return Error(Loc, 4320 "expected 'lsl' or 'sxtx' with optional shift of #0"); 4321 case Match_InvalidMemoryXExtend16: 4322 return Error(Loc, 4323 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1"); 4324 case Match_InvalidMemoryXExtend32: 4325 return Error(Loc, 4326 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2"); 4327 case Match_InvalidMemoryXExtend64: 4328 return Error(Loc, 4329 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3"); 4330 case Match_InvalidMemoryXExtend128: 4331 return Error(Loc, 4332 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4"); 4333 case Match_InvalidMemoryIndexed1: 4334 return Error(Loc, "index must be an integer in range [0, 4095]."); 4335 case Match_InvalidMemoryIndexed2: 4336 return Error(Loc, "index must be a multiple of 2 in range [0, 8190]."); 4337 case Match_InvalidMemoryIndexed4: 4338 return Error(Loc, "index must be a multiple of 4 in range [0, 16380]."); 4339 case Match_InvalidMemoryIndexed8: 4340 return Error(Loc, "index must be a multiple of 8 in range [0, 32760]."); 4341 case Match_InvalidMemoryIndexed16: 4342 return Error(Loc, "index must be a multiple of 16 in range [0, 65520]."); 4343 case Match_InvalidImm0_1: 4344 return Error(Loc, "immediate must be an integer in range [0, 1]."); 4345 case Match_InvalidImm0_7: 4346 return Error(Loc, "immediate must be an integer in range [0, 7]."); 4347 case Match_InvalidImm0_15: 4348 return Error(Loc, "immediate must be an integer in range [0, 15]."); 4349 case Match_InvalidImm0_31: 4350 return Error(Loc, "immediate must be an integer in range [0, 31]."); 4351 case Match_InvalidImm0_63: 4352 return Error(Loc, "immediate must be an integer in range [0, 63]."); 4353 case Match_InvalidImm0_127: 4354 return Error(Loc, "immediate must be an integer in range [0, 127]."); 4355 case Match_InvalidImm0_255: 4356 return Error(Loc, "immediate must be an integer in range [0, 255]."); 4357 case Match_InvalidImm0_65535: 4358 return Error(Loc, "immediate must be an integer in range [0, 65535]."); 4359 case Match_InvalidImm1_8: 4360 return Error(Loc, "immediate must be an integer in range [1, 8]."); 4361 case Match_InvalidImm1_16: 4362 return Error(Loc, "immediate must be an integer in range [1, 16]."); 4363 case Match_InvalidImm1_32: 4364 return Error(Loc, "immediate must be an integer in range [1, 32]."); 4365 case Match_InvalidImm1_64: 4366 return Error(Loc, "immediate must be an integer in range [1, 64]."); 4367 case Match_InvalidSVEAddSubImm8: 4368 return Error(Loc, "immediate must be an integer in range [0, 255]" 4369 " with a shift amount of 0"); 4370 case Match_InvalidSVEAddSubImm16: 4371 case Match_InvalidSVEAddSubImm32: 4372 case Match_InvalidSVEAddSubImm64: 4373 return Error(Loc, "immediate must be an integer in range [0, 255] or a " 4374 "multiple of 256 in range [256, 65280]"); 4375 case Match_InvalidSVECpyImm8: 4376 return Error(Loc, "immediate must be an integer in range [-128, 255]" 4377 " with a shift amount of 0"); 4378 case Match_InvalidSVECpyImm16: 4379 return Error(Loc, "immediate must be an integer in range [-128, 127] or a " 4380 "multiple of 256 in range [-32768, 65280]"); 4381 case Match_InvalidSVECpyImm32: 4382 case Match_InvalidSVECpyImm64: 4383 return Error(Loc, "immediate must be an integer in range [-128, 127] or a " 4384 "multiple of 256 in range [-32768, 32512]"); 4385 case Match_InvalidIndexRange1_1: 4386 return Error(Loc, "expected lane specifier '[1]'"); 4387 case Match_InvalidIndexRange0_15: 4388 return Error(Loc, "vector lane must be an integer in range [0, 15]."); 4389 case Match_InvalidIndexRange0_7: 4390 return Error(Loc, "vector lane must be an integer in range [0, 7]."); 4391 case Match_InvalidIndexRange0_3: 4392 return Error(Loc, "vector lane must be an integer in range [0, 3]."); 4393 case Match_InvalidIndexRange0_1: 4394 return Error(Loc, "vector lane must be an integer in range [0, 1]."); 4395 case Match_InvalidSVEIndexRange0_63: 4396 return Error(Loc, "vector lane must be an integer in range [0, 63]."); 4397 case Match_InvalidSVEIndexRange0_31: 4398 return Error(Loc, "vector lane must be an integer in range [0, 31]."); 4399 case Match_InvalidSVEIndexRange0_15: 4400 return Error(Loc, "vector lane must be an integer in range [0, 15]."); 4401 case Match_InvalidSVEIndexRange0_7: 4402 return Error(Loc, "vector lane must be an integer in range [0, 7]."); 4403 case Match_InvalidSVEIndexRange0_3: 4404 return Error(Loc, "vector lane must be an integer in range [0, 3]."); 4405 case Match_InvalidLabel: 4406 return Error(Loc, "expected label or encodable integer pc offset"); 4407 case Match_MRS: 4408 return Error(Loc, "expected readable system register"); 4409 case Match_MSR: 4410 return Error(Loc, "expected writable system register or pstate"); 4411 case Match_InvalidComplexRotationEven: 4412 return Error(Loc, "complex rotation must be 0, 90, 180 or 270."); 4413 case Match_InvalidComplexRotationOdd: 4414 return Error(Loc, "complex rotation must be 90 or 270."); 4415 case Match_MnemonicFail: { 4416 std::string Suggestion = AArch64MnemonicSpellCheck( 4417 ((AArch64Operand &)*Operands[0]).getToken(), 4418 ComputeAvailableFeatures(STI->getFeatureBits())); 4419 return Error(Loc, "unrecognized instruction mnemonic" + Suggestion); 4420 } 4421 case Match_InvalidGPR64shifted8: 4422 return Error(Loc, "register must be x0..x30 or xzr, without shift"); 4423 case Match_InvalidGPR64shifted16: 4424 return Error(Loc, "register must be x0..x30 or xzr, with required shift 'lsl #1'"); 4425 case Match_InvalidGPR64shifted32: 4426 return Error(Loc, "register must be x0..x30 or xzr, with required shift 'lsl #2'"); 4427 case Match_InvalidGPR64shifted64: 4428 return Error(Loc, "register must be x0..x30 or xzr, with required shift 'lsl #3'"); 4429 case Match_InvalidGPR64NoXZRshifted8: 4430 return Error(Loc, "register must be x0..x30 without shift"); 4431 case Match_InvalidGPR64NoXZRshifted16: 4432 return Error(Loc, "register must be x0..x30 with required shift 'lsl #1'"); 4433 case Match_InvalidGPR64NoXZRshifted32: 4434 return Error(Loc, "register must be x0..x30 with required shift 'lsl #2'"); 4435 case Match_InvalidGPR64NoXZRshifted64: 4436 return Error(Loc, "register must be x0..x30 with required shift 'lsl #3'"); 4437 case Match_InvalidZPR32UXTW8: 4438 case Match_InvalidZPR32SXTW8: 4439 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'"); 4440 case Match_InvalidZPR32UXTW16: 4441 case Match_InvalidZPR32SXTW16: 4442 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'"); 4443 case Match_InvalidZPR32UXTW32: 4444 case Match_InvalidZPR32SXTW32: 4445 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'"); 4446 case Match_InvalidZPR32UXTW64: 4447 case Match_InvalidZPR32SXTW64: 4448 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'"); 4449 case Match_InvalidZPR64UXTW8: 4450 case Match_InvalidZPR64SXTW8: 4451 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'"); 4452 case Match_InvalidZPR64UXTW16: 4453 case Match_InvalidZPR64SXTW16: 4454 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'"); 4455 case Match_InvalidZPR64UXTW32: 4456 case Match_InvalidZPR64SXTW32: 4457 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'"); 4458 case Match_InvalidZPR64UXTW64: 4459 case Match_InvalidZPR64SXTW64: 4460 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'"); 4461 case Match_InvalidZPR32LSL8: 4462 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s'"); 4463 case Match_InvalidZPR32LSL16: 4464 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, lsl #1'"); 4465 case Match_InvalidZPR32LSL32: 4466 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, lsl #2'"); 4467 case Match_InvalidZPR32LSL64: 4468 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, lsl #3'"); 4469 case Match_InvalidZPR64LSL8: 4470 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d'"); 4471 case Match_InvalidZPR64LSL16: 4472 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, lsl #1'"); 4473 case Match_InvalidZPR64LSL32: 4474 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, lsl #2'"); 4475 case Match_InvalidZPR64LSL64: 4476 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, lsl #3'"); 4477 case Match_InvalidZPR0: 4478 return Error(Loc, "expected register without element width suffix"); 4479 case Match_InvalidZPR8: 4480 case Match_InvalidZPR16: 4481 case Match_InvalidZPR32: 4482 case Match_InvalidZPR64: 4483 case Match_InvalidZPR128: 4484 return Error(Loc, "invalid element width"); 4485 case Match_InvalidZPR_3b8: 4486 return Error(Loc, "Invalid restricted vector register, expected z0.b..z7.b"); 4487 case Match_InvalidZPR_3b16: 4488 return Error(Loc, "Invalid restricted vector register, expected z0.h..z7.h"); 4489 case Match_InvalidZPR_3b32: 4490 return Error(Loc, "Invalid restricted vector register, expected z0.s..z7.s"); 4491 case Match_InvalidZPR_4b16: 4492 return Error(Loc, "Invalid restricted vector register, expected z0.h..z15.h"); 4493 case Match_InvalidZPR_4b32: 4494 return Error(Loc, "Invalid restricted vector register, expected z0.s..z15.s"); 4495 case Match_InvalidZPR_4b64: 4496 return Error(Loc, "Invalid restricted vector register, expected z0.d..z15.d"); 4497 case Match_InvalidSVEPattern: 4498 return Error(Loc, "invalid predicate pattern"); 4499 case Match_InvalidSVEPredicateAnyReg: 4500 case Match_InvalidSVEPredicateBReg: 4501 case Match_InvalidSVEPredicateHReg: 4502 case Match_InvalidSVEPredicateSReg: 4503 case Match_InvalidSVEPredicateDReg: 4504 return Error(Loc, "invalid predicate register."); 4505 case Match_InvalidSVEPredicate3bAnyReg: 4506 return Error(Loc, "invalid restricted predicate register, expected p0..p7 (without element suffix)"); 4507 case Match_InvalidSVEPredicate3bBReg: 4508 return Error(Loc, "invalid restricted predicate register, expected p0.b..p7.b"); 4509 case Match_InvalidSVEPredicate3bHReg: 4510 return Error(Loc, "invalid restricted predicate register, expected p0.h..p7.h"); 4511 case Match_InvalidSVEPredicate3bSReg: 4512 return Error(Loc, "invalid restricted predicate register, expected p0.s..p7.s"); 4513 case Match_InvalidSVEPredicate3bDReg: 4514 return Error(Loc, "invalid restricted predicate register, expected p0.d..p7.d"); 4515 case Match_InvalidSVEExactFPImmOperandHalfOne: 4516 return Error(Loc, "Invalid floating point constant, expected 0.5 or 1.0."); 4517 case Match_InvalidSVEExactFPImmOperandHalfTwo: 4518 return Error(Loc, "Invalid floating point constant, expected 0.5 or 2.0."); 4519 case Match_InvalidSVEExactFPImmOperandZeroOne: 4520 return Error(Loc, "Invalid floating point constant, expected 0.0 or 1.0."); 4521 default: 4522 llvm_unreachable("unexpected error code!"); 4523 } 4524 } 4525 4526 static const char *getSubtargetFeatureName(uint64_t Val); 4527 4528 bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 4529 OperandVector &Operands, 4530 MCStreamer &Out, 4531 uint64_t &ErrorInfo, 4532 bool MatchingInlineAsm) { 4533 assert(!Operands.empty() && "Unexpect empty operand list!"); 4534 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[0]); 4535 assert(Op.isToken() && "Leading operand should always be a mnemonic!"); 4536 4537 StringRef Tok = Op.getToken(); 4538 unsigned NumOperands = Operands.size(); 4539 4540 if (NumOperands == 4 && Tok == "lsl") { 4541 AArch64Operand &Op2 = static_cast<AArch64Operand &>(*Operands[2]); 4542 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]); 4543 if (Op2.isScalarReg() && Op3.isImm()) { 4544 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm()); 4545 if (Op3CE) { 4546 uint64_t Op3Val = Op3CE->getValue(); 4547 uint64_t NewOp3Val = 0; 4548 uint64_t NewOp4Val = 0; 4549 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].contains( 4550 Op2.getReg())) { 4551 NewOp3Val = (32 - Op3Val) & 0x1f; 4552 NewOp4Val = 31 - Op3Val; 4553 } else { 4554 NewOp3Val = (64 - Op3Val) & 0x3f; 4555 NewOp4Val = 63 - Op3Val; 4556 } 4557 4558 const MCExpr *NewOp3 = MCConstantExpr::create(NewOp3Val, getContext()); 4559 const MCExpr *NewOp4 = MCConstantExpr::create(NewOp4Val, getContext()); 4560 4561 Operands[0] = AArch64Operand::CreateToken( 4562 "ubfm", false, Op.getStartLoc(), getContext()); 4563 Operands.push_back(AArch64Operand::CreateImm( 4564 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext())); 4565 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(), 4566 Op3.getEndLoc(), getContext()); 4567 } 4568 } 4569 } else if (NumOperands == 4 && Tok == "bfc") { 4570 // FIXME: Horrible hack to handle BFC->BFM alias. 4571 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]); 4572 AArch64Operand LSBOp = static_cast<AArch64Operand &>(*Operands[2]); 4573 AArch64Operand WidthOp = static_cast<AArch64Operand &>(*Operands[3]); 4574 4575 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) { 4576 const MCConstantExpr *LSBCE = dyn_cast<MCConstantExpr>(LSBOp.getImm()); 4577 const MCConstantExpr *WidthCE = dyn_cast<MCConstantExpr>(WidthOp.getImm()); 4578 4579 if (LSBCE && WidthCE) { 4580 uint64_t LSB = LSBCE->getValue(); 4581 uint64_t Width = WidthCE->getValue(); 4582 4583 uint64_t RegWidth = 0; 4584 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( 4585 Op1.getReg())) 4586 RegWidth = 64; 4587 else 4588 RegWidth = 32; 4589 4590 if (LSB >= RegWidth) 4591 return Error(LSBOp.getStartLoc(), 4592 "expected integer in range [0, 31]"); 4593 if (Width < 1 || Width > RegWidth) 4594 return Error(WidthOp.getStartLoc(), 4595 "expected integer in range [1, 32]"); 4596 4597 uint64_t ImmR = 0; 4598 if (RegWidth == 32) 4599 ImmR = (32 - LSB) & 0x1f; 4600 else 4601 ImmR = (64 - LSB) & 0x3f; 4602 4603 uint64_t ImmS = Width - 1; 4604 4605 if (ImmR != 0 && ImmS >= ImmR) 4606 return Error(WidthOp.getStartLoc(), 4607 "requested insert overflows register"); 4608 4609 const MCExpr *ImmRExpr = MCConstantExpr::create(ImmR, getContext()); 4610 const MCExpr *ImmSExpr = MCConstantExpr::create(ImmS, getContext()); 4611 Operands[0] = AArch64Operand::CreateToken( 4612 "bfm", false, Op.getStartLoc(), getContext()); 4613 Operands[2] = AArch64Operand::CreateReg( 4614 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar, 4615 SMLoc(), SMLoc(), getContext()); 4616 Operands[3] = AArch64Operand::CreateImm( 4617 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(), getContext()); 4618 Operands.emplace_back( 4619 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(), 4620 WidthOp.getEndLoc(), getContext())); 4621 } 4622 } 4623 } else if (NumOperands == 5) { 4624 // FIXME: Horrible hack to handle the BFI -> BFM, SBFIZ->SBFM, and 4625 // UBFIZ -> UBFM aliases. 4626 if (Tok == "bfi" || Tok == "sbfiz" || Tok == "ubfiz") { 4627 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]); 4628 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]); 4629 AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]); 4630 4631 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) { 4632 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm()); 4633 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm()); 4634 4635 if (Op3CE && Op4CE) { 4636 uint64_t Op3Val = Op3CE->getValue(); 4637 uint64_t Op4Val = Op4CE->getValue(); 4638 4639 uint64_t RegWidth = 0; 4640 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( 4641 Op1.getReg())) 4642 RegWidth = 64; 4643 else 4644 RegWidth = 32; 4645 4646 if (Op3Val >= RegWidth) 4647 return Error(Op3.getStartLoc(), 4648 "expected integer in range [0, 31]"); 4649 if (Op4Val < 1 || Op4Val > RegWidth) 4650 return Error(Op4.getStartLoc(), 4651 "expected integer in range [1, 32]"); 4652 4653 uint64_t NewOp3Val = 0; 4654 if (RegWidth == 32) 4655 NewOp3Val = (32 - Op3Val) & 0x1f; 4656 else 4657 NewOp3Val = (64 - Op3Val) & 0x3f; 4658 4659 uint64_t NewOp4Val = Op4Val - 1; 4660 4661 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val) 4662 return Error(Op4.getStartLoc(), 4663 "requested insert overflows register"); 4664 4665 const MCExpr *NewOp3 = 4666 MCConstantExpr::create(NewOp3Val, getContext()); 4667 const MCExpr *NewOp4 = 4668 MCConstantExpr::create(NewOp4Val, getContext()); 4669 Operands[3] = AArch64Operand::CreateImm( 4670 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext()); 4671 Operands[4] = AArch64Operand::CreateImm( 4672 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext()); 4673 if (Tok == "bfi") 4674 Operands[0] = AArch64Operand::CreateToken( 4675 "bfm", false, Op.getStartLoc(), getContext()); 4676 else if (Tok == "sbfiz") 4677 Operands[0] = AArch64Operand::CreateToken( 4678 "sbfm", false, Op.getStartLoc(), getContext()); 4679 else if (Tok == "ubfiz") 4680 Operands[0] = AArch64Operand::CreateToken( 4681 "ubfm", false, Op.getStartLoc(), getContext()); 4682 else 4683 llvm_unreachable("No valid mnemonic for alias?"); 4684 } 4685 } 4686 4687 // FIXME: Horrible hack to handle the BFXIL->BFM, SBFX->SBFM, and 4688 // UBFX -> UBFM aliases. 4689 } else if (NumOperands == 5 && 4690 (Tok == "bfxil" || Tok == "sbfx" || Tok == "ubfx")) { 4691 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]); 4692 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]); 4693 AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]); 4694 4695 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) { 4696 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm()); 4697 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm()); 4698 4699 if (Op3CE && Op4CE) { 4700 uint64_t Op3Val = Op3CE->getValue(); 4701 uint64_t Op4Val = Op4CE->getValue(); 4702 4703 uint64_t RegWidth = 0; 4704 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( 4705 Op1.getReg())) 4706 RegWidth = 64; 4707 else 4708 RegWidth = 32; 4709 4710 if (Op3Val >= RegWidth) 4711 return Error(Op3.getStartLoc(), 4712 "expected integer in range [0, 31]"); 4713 if (Op4Val < 1 || Op4Val > RegWidth) 4714 return Error(Op4.getStartLoc(), 4715 "expected integer in range [1, 32]"); 4716 4717 uint64_t NewOp4Val = Op3Val + Op4Val - 1; 4718 4719 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val) 4720 return Error(Op4.getStartLoc(), 4721 "requested extract overflows register"); 4722 4723 const MCExpr *NewOp4 = 4724 MCConstantExpr::create(NewOp4Val, getContext()); 4725 Operands[4] = AArch64Operand::CreateImm( 4726 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext()); 4727 if (Tok == "bfxil") 4728 Operands[0] = AArch64Operand::CreateToken( 4729 "bfm", false, Op.getStartLoc(), getContext()); 4730 else if (Tok == "sbfx") 4731 Operands[0] = AArch64Operand::CreateToken( 4732 "sbfm", false, Op.getStartLoc(), getContext()); 4733 else if (Tok == "ubfx") 4734 Operands[0] = AArch64Operand::CreateToken( 4735 "ubfm", false, Op.getStartLoc(), getContext()); 4736 else 4737 llvm_unreachable("No valid mnemonic for alias?"); 4738 } 4739 } 4740 } 4741 } 4742 4743 // The Cyclone CPU and early successors didn't execute the zero-cycle zeroing 4744 // instruction for FP registers correctly in some rare circumstances. Convert 4745 // it to a safe instruction and warn (because silently changing someone's 4746 // assembly is rude). 4747 if (getSTI().getFeatureBits()[AArch64::FeatureZCZeroingFPWorkaround] && 4748 NumOperands == 4 && Tok == "movi") { 4749 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]); 4750 AArch64Operand &Op2 = static_cast<AArch64Operand &>(*Operands[2]); 4751 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]); 4752 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) || 4753 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) { 4754 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken(); 4755 if (Suffix.lower() == ".2d" && 4756 cast<MCConstantExpr>(Op3.getImm())->getValue() == 0) { 4757 Warning(IDLoc, "instruction movi.2d with immediate #0 may not function" 4758 " correctly on this CPU, converting to equivalent movi.16b"); 4759 // Switch the suffix to .16b. 4760 unsigned Idx = Op1.isToken() ? 1 : 2; 4761 Operands[Idx] = AArch64Operand::CreateToken(".16b", false, IDLoc, 4762 getContext()); 4763 } 4764 } 4765 } 4766 4767 // FIXME: Horrible hack for sxtw and uxtw with Wn src and Xd dst operands. 4768 // InstAlias can't quite handle this since the reg classes aren't 4769 // subclasses. 4770 if (NumOperands == 3 && (Tok == "sxtw" || Tok == "uxtw")) { 4771 // The source register can be Wn here, but the matcher expects a 4772 // GPR64. Twiddle it here if necessary. 4773 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]); 4774 if (Op.isScalarReg()) { 4775 unsigned Reg = getXRegFromWReg(Op.getReg()); 4776 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar, 4777 Op.getStartLoc(), Op.getEndLoc(), 4778 getContext()); 4779 } 4780 } 4781 // FIXME: Likewise for sxt[bh] with a Xd dst operand 4782 else if (NumOperands == 3 && (Tok == "sxtb" || Tok == "sxth")) { 4783 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]); 4784 if (Op.isScalarReg() && 4785 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( 4786 Op.getReg())) { 4787 // The source register can be Wn here, but the matcher expects a 4788 // GPR64. Twiddle it here if necessary. 4789 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]); 4790 if (Op.isScalarReg()) { 4791 unsigned Reg = getXRegFromWReg(Op.getReg()); 4792 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar, 4793 Op.getStartLoc(), 4794 Op.getEndLoc(), getContext()); 4795 } 4796 } 4797 } 4798 // FIXME: Likewise for uxt[bh] with a Xd dst operand 4799 else if (NumOperands == 3 && (Tok == "uxtb" || Tok == "uxth")) { 4800 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]); 4801 if (Op.isScalarReg() && 4802 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( 4803 Op.getReg())) { 4804 // The source register can be Wn here, but the matcher expects a 4805 // GPR32. Twiddle it here if necessary. 4806 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]); 4807 if (Op.isScalarReg()) { 4808 unsigned Reg = getWRegFromXReg(Op.getReg()); 4809 Operands[1] = AArch64Operand::CreateReg(Reg, RegKind::Scalar, 4810 Op.getStartLoc(), 4811 Op.getEndLoc(), getContext()); 4812 } 4813 } 4814 } 4815 4816 MCInst Inst; 4817 FeatureBitset MissingFeatures; 4818 // First try to match against the secondary set of tables containing the 4819 // short-form NEON instructions (e.g. "fadd.2s v0, v1, v2"). 4820 unsigned MatchResult = 4821 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures, 4822 MatchingInlineAsm, 1); 4823 4824 // If that fails, try against the alternate table containing long-form NEON: 4825 // "fadd v0.2s, v1.2s, v2.2s" 4826 if (MatchResult != Match_Success) { 4827 // But first, save the short-form match result: we can use it in case the 4828 // long-form match also fails. 4829 auto ShortFormNEONErrorInfo = ErrorInfo; 4830 auto ShortFormNEONMatchResult = MatchResult; 4831 auto ShortFormNEONMissingFeatures = MissingFeatures; 4832 4833 MatchResult = 4834 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures, 4835 MatchingInlineAsm, 0); 4836 4837 // Now, both matches failed, and the long-form match failed on the mnemonic 4838 // suffix token operand. The short-form match failure is probably more 4839 // relevant: use it instead. 4840 if (MatchResult == Match_InvalidOperand && ErrorInfo == 1 && 4841 Operands.size() > 1 && ((AArch64Operand &)*Operands[1]).isToken() && 4842 ((AArch64Operand &)*Operands[1]).isTokenSuffix()) { 4843 MatchResult = ShortFormNEONMatchResult; 4844 ErrorInfo = ShortFormNEONErrorInfo; 4845 MissingFeatures = ShortFormNEONMissingFeatures; 4846 } 4847 } 4848 4849 switch (MatchResult) { 4850 case Match_Success: { 4851 // Perform range checking and other semantic validations 4852 SmallVector<SMLoc, 8> OperandLocs; 4853 NumOperands = Operands.size(); 4854 for (unsigned i = 1; i < NumOperands; ++i) 4855 OperandLocs.push_back(Operands[i]->getStartLoc()); 4856 if (validateInstruction(Inst, IDLoc, OperandLocs)) 4857 return true; 4858 4859 Inst.setLoc(IDLoc); 4860 Out.emitInstruction(Inst, getSTI()); 4861 return false; 4862 } 4863 case Match_MissingFeature: { 4864 assert(MissingFeatures.any() && "Unknown missing feature!"); 4865 // Special case the error message for the very common case where only 4866 // a single subtarget feature is missing (neon, e.g.). 4867 std::string Msg = "instruction requires:"; 4868 for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) { 4869 if (MissingFeatures[i]) { 4870 Msg += " "; 4871 Msg += getSubtargetFeatureName(i); 4872 } 4873 } 4874 return Error(IDLoc, Msg); 4875 } 4876 case Match_MnemonicFail: 4877 return showMatchError(IDLoc, MatchResult, ErrorInfo, Operands); 4878 case Match_InvalidOperand: { 4879 SMLoc ErrorLoc = IDLoc; 4880 4881 if (ErrorInfo != ~0ULL) { 4882 if (ErrorInfo >= Operands.size()) 4883 return Error(IDLoc, "too few operands for instruction", 4884 SMRange(IDLoc, getTok().getLoc())); 4885 4886 ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc(); 4887 if (ErrorLoc == SMLoc()) 4888 ErrorLoc = IDLoc; 4889 } 4890 // If the match failed on a suffix token operand, tweak the diagnostic 4891 // accordingly. 4892 if (((AArch64Operand &)*Operands[ErrorInfo]).isToken() && 4893 ((AArch64Operand &)*Operands[ErrorInfo]).isTokenSuffix()) 4894 MatchResult = Match_InvalidSuffix; 4895 4896 return showMatchError(ErrorLoc, MatchResult, ErrorInfo, Operands); 4897 } 4898 case Match_InvalidTiedOperand: 4899 case Match_InvalidMemoryIndexed1: 4900 case Match_InvalidMemoryIndexed2: 4901 case Match_InvalidMemoryIndexed4: 4902 case Match_InvalidMemoryIndexed8: 4903 case Match_InvalidMemoryIndexed16: 4904 case Match_InvalidCondCode: 4905 case Match_AddSubRegExtendSmall: 4906 case Match_AddSubRegExtendLarge: 4907 case Match_AddSubSecondSource: 4908 case Match_LogicalSecondSource: 4909 case Match_AddSubRegShift32: 4910 case Match_AddSubRegShift64: 4911 case Match_InvalidMovImm32Shift: 4912 case Match_InvalidMovImm64Shift: 4913 case Match_InvalidFPImm: 4914 case Match_InvalidMemoryWExtend8: 4915 case Match_InvalidMemoryWExtend16: 4916 case Match_InvalidMemoryWExtend32: 4917 case Match_InvalidMemoryWExtend64: 4918 case Match_InvalidMemoryWExtend128: 4919 case Match_InvalidMemoryXExtend8: 4920 case Match_InvalidMemoryXExtend16: 4921 case Match_InvalidMemoryXExtend32: 4922 case Match_InvalidMemoryXExtend64: 4923 case Match_InvalidMemoryXExtend128: 4924 case Match_InvalidMemoryIndexed1SImm4: 4925 case Match_InvalidMemoryIndexed2SImm4: 4926 case Match_InvalidMemoryIndexed3SImm4: 4927 case Match_InvalidMemoryIndexed4SImm4: 4928 case Match_InvalidMemoryIndexed1SImm6: 4929 case Match_InvalidMemoryIndexed16SImm4: 4930 case Match_InvalidMemoryIndexed32SImm4: 4931 case Match_InvalidMemoryIndexed4SImm7: 4932 case Match_InvalidMemoryIndexed8SImm7: 4933 case Match_InvalidMemoryIndexed16SImm7: 4934 case Match_InvalidMemoryIndexed8UImm5: 4935 case Match_InvalidMemoryIndexed4UImm5: 4936 case Match_InvalidMemoryIndexed2UImm5: 4937 case Match_InvalidMemoryIndexed1UImm6: 4938 case Match_InvalidMemoryIndexed2UImm6: 4939 case Match_InvalidMemoryIndexed4UImm6: 4940 case Match_InvalidMemoryIndexed8UImm6: 4941 case Match_InvalidMemoryIndexed16UImm6: 4942 case Match_InvalidMemoryIndexedSImm6: 4943 case Match_InvalidMemoryIndexedSImm5: 4944 case Match_InvalidMemoryIndexedSImm8: 4945 case Match_InvalidMemoryIndexedSImm9: 4946 case Match_InvalidMemoryIndexed16SImm9: 4947 case Match_InvalidMemoryIndexed8SImm10: 4948 case Match_InvalidImm0_1: 4949 case Match_InvalidImm0_7: 4950 case Match_InvalidImm0_15: 4951 case Match_InvalidImm0_31: 4952 case Match_InvalidImm0_63: 4953 case Match_InvalidImm0_127: 4954 case Match_InvalidImm0_255: 4955 case Match_InvalidImm0_65535: 4956 case Match_InvalidImm1_8: 4957 case Match_InvalidImm1_16: 4958 case Match_InvalidImm1_32: 4959 case Match_InvalidImm1_64: 4960 case Match_InvalidSVEAddSubImm8: 4961 case Match_InvalidSVEAddSubImm16: 4962 case Match_InvalidSVEAddSubImm32: 4963 case Match_InvalidSVEAddSubImm64: 4964 case Match_InvalidSVECpyImm8: 4965 case Match_InvalidSVECpyImm16: 4966 case Match_InvalidSVECpyImm32: 4967 case Match_InvalidSVECpyImm64: 4968 case Match_InvalidIndexRange1_1: 4969 case Match_InvalidIndexRange0_15: 4970 case Match_InvalidIndexRange0_7: 4971 case Match_InvalidIndexRange0_3: 4972 case Match_InvalidIndexRange0_1: 4973 case Match_InvalidSVEIndexRange0_63: 4974 case Match_InvalidSVEIndexRange0_31: 4975 case Match_InvalidSVEIndexRange0_15: 4976 case Match_InvalidSVEIndexRange0_7: 4977 case Match_InvalidSVEIndexRange0_3: 4978 case Match_InvalidLabel: 4979 case Match_InvalidComplexRotationEven: 4980 case Match_InvalidComplexRotationOdd: 4981 case Match_InvalidGPR64shifted8: 4982 case Match_InvalidGPR64shifted16: 4983 case Match_InvalidGPR64shifted32: 4984 case Match_InvalidGPR64shifted64: 4985 case Match_InvalidGPR64NoXZRshifted8: 4986 case Match_InvalidGPR64NoXZRshifted16: 4987 case Match_InvalidGPR64NoXZRshifted32: 4988 case Match_InvalidGPR64NoXZRshifted64: 4989 case Match_InvalidZPR32UXTW8: 4990 case Match_InvalidZPR32UXTW16: 4991 case Match_InvalidZPR32UXTW32: 4992 case Match_InvalidZPR32UXTW64: 4993 case Match_InvalidZPR32SXTW8: 4994 case Match_InvalidZPR32SXTW16: 4995 case Match_InvalidZPR32SXTW32: 4996 case Match_InvalidZPR32SXTW64: 4997 case Match_InvalidZPR64UXTW8: 4998 case Match_InvalidZPR64SXTW8: 4999 case Match_InvalidZPR64UXTW16: 5000 case Match_InvalidZPR64SXTW16: 5001 case Match_InvalidZPR64UXTW32: 5002 case Match_InvalidZPR64SXTW32: 5003 case Match_InvalidZPR64UXTW64: 5004 case Match_InvalidZPR64SXTW64: 5005 case Match_InvalidZPR32LSL8: 5006 case Match_InvalidZPR32LSL16: 5007 case Match_InvalidZPR32LSL32: 5008 case Match_InvalidZPR32LSL64: 5009 case Match_InvalidZPR64LSL8: 5010 case Match_InvalidZPR64LSL16: 5011 case Match_InvalidZPR64LSL32: 5012 case Match_InvalidZPR64LSL64: 5013 case Match_InvalidZPR0: 5014 case Match_InvalidZPR8: 5015 case Match_InvalidZPR16: 5016 case Match_InvalidZPR32: 5017 case Match_InvalidZPR64: 5018 case Match_InvalidZPR128: 5019 case Match_InvalidZPR_3b8: 5020 case Match_InvalidZPR_3b16: 5021 case Match_InvalidZPR_3b32: 5022 case Match_InvalidZPR_4b16: 5023 case Match_InvalidZPR_4b32: 5024 case Match_InvalidZPR_4b64: 5025 case Match_InvalidSVEPredicateAnyReg: 5026 case Match_InvalidSVEPattern: 5027 case Match_InvalidSVEPredicateBReg: 5028 case Match_InvalidSVEPredicateHReg: 5029 case Match_InvalidSVEPredicateSReg: 5030 case Match_InvalidSVEPredicateDReg: 5031 case Match_InvalidSVEPredicate3bAnyReg: 5032 case Match_InvalidSVEPredicate3bBReg: 5033 case Match_InvalidSVEPredicate3bHReg: 5034 case Match_InvalidSVEPredicate3bSReg: 5035 case Match_InvalidSVEPredicate3bDReg: 5036 case Match_InvalidSVEExactFPImmOperandHalfOne: 5037 case Match_InvalidSVEExactFPImmOperandHalfTwo: 5038 case Match_InvalidSVEExactFPImmOperandZeroOne: 5039 case Match_MSR: 5040 case Match_MRS: { 5041 if (ErrorInfo >= Operands.size()) 5042 return Error(IDLoc, "too few operands for instruction", SMRange(IDLoc, (*Operands.back()).getEndLoc())); 5043 // Any time we get here, there's nothing fancy to do. Just get the 5044 // operand SMLoc and display the diagnostic. 5045 SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc(); 5046 if (ErrorLoc == SMLoc()) 5047 ErrorLoc = IDLoc; 5048 return showMatchError(ErrorLoc, MatchResult, ErrorInfo, Operands); 5049 } 5050 } 5051 5052 llvm_unreachable("Implement any new match types added!"); 5053 } 5054 5055 /// ParseDirective parses the arm specific directives 5056 bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) { 5057 const MCObjectFileInfo::Environment Format = 5058 getContext().getObjectFileInfo()->getObjectFileType(); 5059 bool IsMachO = Format == MCObjectFileInfo::IsMachO; 5060 5061 auto IDVal = DirectiveID.getIdentifier().lower(); 5062 SMLoc Loc = DirectiveID.getLoc(); 5063 if (IDVal == ".arch") 5064 parseDirectiveArch(Loc); 5065 else if (IDVal == ".cpu") 5066 parseDirectiveCPU(Loc); 5067 else if (IDVal == ".tlsdesccall") 5068 parseDirectiveTLSDescCall(Loc); 5069 else if (IDVal == ".ltorg" || IDVal == ".pool") 5070 parseDirectiveLtorg(Loc); 5071 else if (IDVal == ".unreq") 5072 parseDirectiveUnreq(Loc); 5073 else if (IDVal == ".inst") 5074 parseDirectiveInst(Loc); 5075 else if (IDVal == ".cfi_negate_ra_state") 5076 parseDirectiveCFINegateRAState(); 5077 else if (IDVal == ".cfi_b_key_frame") 5078 parseDirectiveCFIBKeyFrame(); 5079 else if (IDVal == ".arch_extension") 5080 parseDirectiveArchExtension(Loc); 5081 else if (IsMachO) { 5082 if (IDVal == MCLOHDirectiveName()) 5083 parseDirectiveLOH(IDVal, Loc); 5084 else 5085 return true; 5086 } else 5087 return true; 5088 return false; 5089 } 5090 5091 static void ExpandCryptoAEK(AArch64::ArchKind ArchKind, 5092 SmallVector<StringRef, 4> &RequestedExtensions) { 5093 const bool NoCrypto = llvm::is_contained(RequestedExtensions, "nocrypto"); 5094 const bool Crypto = llvm::is_contained(RequestedExtensions, "crypto"); 5095 5096 if (!NoCrypto && Crypto) { 5097 switch (ArchKind) { 5098 default: 5099 // Map 'generic' (and others) to sha2 and aes, because 5100 // that was the traditional meaning of crypto. 5101 case AArch64::ArchKind::ARMV8_1A: 5102 case AArch64::ArchKind::ARMV8_2A: 5103 case AArch64::ArchKind::ARMV8_3A: 5104 RequestedExtensions.push_back("sha2"); 5105 RequestedExtensions.push_back("aes"); 5106 break; 5107 case AArch64::ArchKind::ARMV8_4A: 5108 case AArch64::ArchKind::ARMV8_5A: 5109 case AArch64::ArchKind::ARMV8_6A: 5110 RequestedExtensions.push_back("sm4"); 5111 RequestedExtensions.push_back("sha3"); 5112 RequestedExtensions.push_back("sha2"); 5113 RequestedExtensions.push_back("aes"); 5114 break; 5115 } 5116 } else if (NoCrypto) { 5117 switch (ArchKind) { 5118 default: 5119 // Map 'generic' (and others) to sha2 and aes, because 5120 // that was the traditional meaning of crypto. 5121 case AArch64::ArchKind::ARMV8_1A: 5122 case AArch64::ArchKind::ARMV8_2A: 5123 case AArch64::ArchKind::ARMV8_3A: 5124 RequestedExtensions.push_back("nosha2"); 5125 RequestedExtensions.push_back("noaes"); 5126 break; 5127 case AArch64::ArchKind::ARMV8_4A: 5128 case AArch64::ArchKind::ARMV8_5A: 5129 case AArch64::ArchKind::ARMV8_6A: 5130 RequestedExtensions.push_back("nosm4"); 5131 RequestedExtensions.push_back("nosha3"); 5132 RequestedExtensions.push_back("nosha2"); 5133 RequestedExtensions.push_back("noaes"); 5134 break; 5135 } 5136 } 5137 } 5138 5139 /// parseDirectiveArch 5140 /// ::= .arch token 5141 bool AArch64AsmParser::parseDirectiveArch(SMLoc L) { 5142 SMLoc ArchLoc = getLoc(); 5143 5144 StringRef Arch, ExtensionString; 5145 std::tie(Arch, ExtensionString) = 5146 getParser().parseStringToEndOfStatement().trim().split('+'); 5147 5148 AArch64::ArchKind ID = AArch64::parseArch(Arch); 5149 if (ID == AArch64::ArchKind::INVALID) 5150 return Error(ArchLoc, "unknown arch name"); 5151 5152 if (parseToken(AsmToken::EndOfStatement)) 5153 return true; 5154 5155 // Get the architecture and extension features. 5156 std::vector<StringRef> AArch64Features; 5157 AArch64::getArchFeatures(ID, AArch64Features); 5158 AArch64::getExtensionFeatures(AArch64::getDefaultExtensions("generic", ID), 5159 AArch64Features); 5160 5161 MCSubtargetInfo &STI = copySTI(); 5162 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end()); 5163 STI.setDefaultFeatures("generic", /*TuneCPU*/ "generic", 5164 join(ArchFeatures.begin(), ArchFeatures.end(), ",")); 5165 5166 SmallVector<StringRef, 4> RequestedExtensions; 5167 if (!ExtensionString.empty()) 5168 ExtensionString.split(RequestedExtensions, '+'); 5169 5170 ExpandCryptoAEK(ID, RequestedExtensions); 5171 5172 FeatureBitset Features = STI.getFeatureBits(); 5173 for (auto Name : RequestedExtensions) { 5174 bool EnableFeature = true; 5175 5176 if (Name.startswith_lower("no")) { 5177 EnableFeature = false; 5178 Name = Name.substr(2); 5179 } 5180 5181 for (const auto &Extension : ExtensionMap) { 5182 if (Extension.Name != Name) 5183 continue; 5184 5185 if (Extension.Features.none()) 5186 report_fatal_error("unsupported architectural extension: " + Name); 5187 5188 FeatureBitset ToggleFeatures = EnableFeature 5189 ? (~Features & Extension.Features) 5190 : ( Features & Extension.Features); 5191 FeatureBitset Features = 5192 ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures)); 5193 setAvailableFeatures(Features); 5194 break; 5195 } 5196 } 5197 return false; 5198 } 5199 5200 /// parseDirectiveArchExtension 5201 /// ::= .arch_extension [no]feature 5202 bool AArch64AsmParser::parseDirectiveArchExtension(SMLoc L) { 5203 SMLoc ExtLoc = getLoc(); 5204 5205 StringRef Name = getParser().parseStringToEndOfStatement().trim(); 5206 5207 if (parseToken(AsmToken::EndOfStatement, 5208 "unexpected token in '.arch_extension' directive")) 5209 return true; 5210 5211 bool EnableFeature = true; 5212 if (Name.startswith_lower("no")) { 5213 EnableFeature = false; 5214 Name = Name.substr(2); 5215 } 5216 5217 MCSubtargetInfo &STI = copySTI(); 5218 FeatureBitset Features = STI.getFeatureBits(); 5219 for (const auto &Extension : ExtensionMap) { 5220 if (Extension.Name != Name) 5221 continue; 5222 5223 if (Extension.Features.none()) 5224 return Error(ExtLoc, "unsupported architectural extension: " + Name); 5225 5226 FeatureBitset ToggleFeatures = EnableFeature 5227 ? (~Features & Extension.Features) 5228 : (Features & Extension.Features); 5229 FeatureBitset Features = 5230 ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures)); 5231 setAvailableFeatures(Features); 5232 return false; 5233 } 5234 5235 return Error(ExtLoc, "unknown architectural extension: " + Name); 5236 } 5237 5238 static SMLoc incrementLoc(SMLoc L, int Offset) { 5239 return SMLoc::getFromPointer(L.getPointer() + Offset); 5240 } 5241 5242 /// parseDirectiveCPU 5243 /// ::= .cpu id 5244 bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) { 5245 SMLoc CurLoc = getLoc(); 5246 5247 StringRef CPU, ExtensionString; 5248 std::tie(CPU, ExtensionString) = 5249 getParser().parseStringToEndOfStatement().trim().split('+'); 5250 5251 if (parseToken(AsmToken::EndOfStatement)) 5252 return true; 5253 5254 SmallVector<StringRef, 4> RequestedExtensions; 5255 if (!ExtensionString.empty()) 5256 ExtensionString.split(RequestedExtensions, '+'); 5257 5258 // FIXME This is using tablegen data, but should be moved to ARMTargetParser 5259 // once that is tablegen'ed 5260 if (!getSTI().isCPUStringValid(CPU)) { 5261 Error(CurLoc, "unknown CPU name"); 5262 return false; 5263 } 5264 5265 MCSubtargetInfo &STI = copySTI(); 5266 STI.setDefaultFeatures(CPU, /*TuneCPU*/ CPU, ""); 5267 CurLoc = incrementLoc(CurLoc, CPU.size()); 5268 5269 ExpandCryptoAEK(llvm::AArch64::getCPUArchKind(CPU), RequestedExtensions); 5270 5271 FeatureBitset Features = STI.getFeatureBits(); 5272 for (auto Name : RequestedExtensions) { 5273 // Advance source location past '+'. 5274 CurLoc = incrementLoc(CurLoc, 1); 5275 5276 bool EnableFeature = true; 5277 5278 if (Name.startswith_lower("no")) { 5279 EnableFeature = false; 5280 Name = Name.substr(2); 5281 } 5282 5283 bool FoundExtension = false; 5284 for (const auto &Extension : ExtensionMap) { 5285 if (Extension.Name != Name) 5286 continue; 5287 5288 if (Extension.Features.none()) 5289 report_fatal_error("unsupported architectural extension: " + Name); 5290 5291 FeatureBitset ToggleFeatures = EnableFeature 5292 ? (~Features & Extension.Features) 5293 : ( Features & Extension.Features); 5294 FeatureBitset Features = 5295 ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures)); 5296 setAvailableFeatures(Features); 5297 FoundExtension = true; 5298 5299 break; 5300 } 5301 5302 if (!FoundExtension) 5303 Error(CurLoc, "unsupported architectural extension"); 5304 5305 CurLoc = incrementLoc(CurLoc, Name.size()); 5306 } 5307 return false; 5308 } 5309 5310 /// parseDirectiveInst 5311 /// ::= .inst opcode [, ...] 5312 bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) { 5313 if (getLexer().is(AsmToken::EndOfStatement)) 5314 return Error(Loc, "expected expression following '.inst' directive"); 5315 5316 auto parseOp = [&]() -> bool { 5317 SMLoc L = getLoc(); 5318 const MCExpr *Expr = nullptr; 5319 if (check(getParser().parseExpression(Expr), L, "expected expression")) 5320 return true; 5321 const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr); 5322 if (check(!Value, L, "expected constant expression")) 5323 return true; 5324 getTargetStreamer().emitInst(Value->getValue()); 5325 return false; 5326 }; 5327 5328 if (parseMany(parseOp)) 5329 return addErrorSuffix(" in '.inst' directive"); 5330 return false; 5331 } 5332 5333 // parseDirectiveTLSDescCall: 5334 // ::= .tlsdesccall symbol 5335 bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) { 5336 StringRef Name; 5337 if (check(getParser().parseIdentifier(Name), L, 5338 "expected symbol after directive") || 5339 parseToken(AsmToken::EndOfStatement)) 5340 return true; 5341 5342 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 5343 const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext()); 5344 Expr = AArch64MCExpr::create(Expr, AArch64MCExpr::VK_TLSDESC, getContext()); 5345 5346 MCInst Inst; 5347 Inst.setOpcode(AArch64::TLSDESCCALL); 5348 Inst.addOperand(MCOperand::createExpr(Expr)); 5349 5350 getParser().getStreamer().emitInstruction(Inst, getSTI()); 5351 return false; 5352 } 5353 5354 /// ::= .loh <lohName | lohId> label1, ..., labelN 5355 /// The number of arguments depends on the loh identifier. 5356 bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) { 5357 MCLOHType Kind; 5358 if (getParser().getTok().isNot(AsmToken::Identifier)) { 5359 if (getParser().getTok().isNot(AsmToken::Integer)) 5360 return TokError("expected an identifier or a number in directive"); 5361 // We successfully get a numeric value for the identifier. 5362 // Check if it is valid. 5363 int64_t Id = getParser().getTok().getIntVal(); 5364 if (Id <= -1U && !isValidMCLOHType(Id)) 5365 return TokError("invalid numeric identifier in directive"); 5366 Kind = (MCLOHType)Id; 5367 } else { 5368 StringRef Name = getTok().getIdentifier(); 5369 // We successfully parse an identifier. 5370 // Check if it is a recognized one. 5371 int Id = MCLOHNameToId(Name); 5372 5373 if (Id == -1) 5374 return TokError("invalid identifier in directive"); 5375 Kind = (MCLOHType)Id; 5376 } 5377 // Consume the identifier. 5378 Lex(); 5379 // Get the number of arguments of this LOH. 5380 int NbArgs = MCLOHIdToNbArgs(Kind); 5381 5382 assert(NbArgs != -1 && "Invalid number of arguments"); 5383 5384 SmallVector<MCSymbol *, 3> Args; 5385 for (int Idx = 0; Idx < NbArgs; ++Idx) { 5386 StringRef Name; 5387 if (getParser().parseIdentifier(Name)) 5388 return TokError("expected identifier in directive"); 5389 Args.push_back(getContext().getOrCreateSymbol(Name)); 5390 5391 if (Idx + 1 == NbArgs) 5392 break; 5393 if (parseToken(AsmToken::Comma, 5394 "unexpected token in '" + Twine(IDVal) + "' directive")) 5395 return true; 5396 } 5397 if (parseToken(AsmToken::EndOfStatement, 5398 "unexpected token in '" + Twine(IDVal) + "' directive")) 5399 return true; 5400 5401 getStreamer().emitLOHDirective((MCLOHType)Kind, Args); 5402 return false; 5403 } 5404 5405 /// parseDirectiveLtorg 5406 /// ::= .ltorg | .pool 5407 bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) { 5408 if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive")) 5409 return true; 5410 getTargetStreamer().emitCurrentConstantPool(); 5411 return false; 5412 } 5413 5414 /// parseDirectiveReq 5415 /// ::= name .req registername 5416 bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) { 5417 MCAsmParser &Parser = getParser(); 5418 Parser.Lex(); // Eat the '.req' token. 5419 SMLoc SRegLoc = getLoc(); 5420 RegKind RegisterKind = RegKind::Scalar; 5421 unsigned RegNum; 5422 OperandMatchResultTy ParseRes = tryParseScalarRegister(RegNum); 5423 5424 if (ParseRes != MatchOperand_Success) { 5425 StringRef Kind; 5426 RegisterKind = RegKind::NeonVector; 5427 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector); 5428 5429 if (ParseRes == MatchOperand_ParseFail) 5430 return true; 5431 5432 if (ParseRes == MatchOperand_Success && !Kind.empty()) 5433 return Error(SRegLoc, "vector register without type specifier expected"); 5434 } 5435 5436 if (ParseRes != MatchOperand_Success) { 5437 StringRef Kind; 5438 RegisterKind = RegKind::SVEDataVector; 5439 ParseRes = 5440 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector); 5441 5442 if (ParseRes == MatchOperand_ParseFail) 5443 return true; 5444 5445 if (ParseRes == MatchOperand_Success && !Kind.empty()) 5446 return Error(SRegLoc, 5447 "sve vector register without type specifier expected"); 5448 } 5449 5450 if (ParseRes != MatchOperand_Success) { 5451 StringRef Kind; 5452 RegisterKind = RegKind::SVEPredicateVector; 5453 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector); 5454 5455 if (ParseRes == MatchOperand_ParseFail) 5456 return true; 5457 5458 if (ParseRes == MatchOperand_Success && !Kind.empty()) 5459 return Error(SRegLoc, 5460 "sve predicate register without type specifier expected"); 5461 } 5462 5463 if (ParseRes != MatchOperand_Success) 5464 return Error(SRegLoc, "register name or alias expected"); 5465 5466 // Shouldn't be anything else. 5467 if (parseToken(AsmToken::EndOfStatement, 5468 "unexpected input in .req directive")) 5469 return true; 5470 5471 auto pair = std::make_pair(RegisterKind, (unsigned) RegNum); 5472 if (RegisterReqs.insert(std::make_pair(Name, pair)).first->second != pair) 5473 Warning(L, "ignoring redefinition of register alias '" + Name + "'"); 5474 5475 return false; 5476 } 5477 5478 /// parseDirectiveUneq 5479 /// ::= .unreq registername 5480 bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) { 5481 MCAsmParser &Parser = getParser(); 5482 if (getTok().isNot(AsmToken::Identifier)) 5483 return TokError("unexpected input in .unreq directive."); 5484 RegisterReqs.erase(Parser.getTok().getIdentifier().lower()); 5485 Parser.Lex(); // Eat the identifier. 5486 if (parseToken(AsmToken::EndOfStatement)) 5487 return addErrorSuffix("in '.unreq' directive"); 5488 return false; 5489 } 5490 5491 bool AArch64AsmParser::parseDirectiveCFINegateRAState() { 5492 if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive")) 5493 return true; 5494 getStreamer().emitCFINegateRAState(); 5495 return false; 5496 } 5497 5498 /// parseDirectiveCFIBKeyFrame 5499 /// ::= .cfi_b_key 5500 bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() { 5501 if (parseToken(AsmToken::EndOfStatement, 5502 "unexpected token in '.cfi_b_key_frame'")) 5503 return true; 5504 getStreamer().emitCFIBKeyFrame(); 5505 return false; 5506 } 5507 5508 bool 5509 AArch64AsmParser::classifySymbolRef(const MCExpr *Expr, 5510 AArch64MCExpr::VariantKind &ELFRefKind, 5511 MCSymbolRefExpr::VariantKind &DarwinRefKind, 5512 int64_t &Addend) { 5513 ELFRefKind = AArch64MCExpr::VK_INVALID; 5514 DarwinRefKind = MCSymbolRefExpr::VK_None; 5515 Addend = 0; 5516 5517 if (const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) { 5518 ELFRefKind = AE->getKind(); 5519 Expr = AE->getSubExpr(); 5520 } 5521 5522 const MCSymbolRefExpr *SE = dyn_cast<MCSymbolRefExpr>(Expr); 5523 if (SE) { 5524 // It's a simple symbol reference with no addend. 5525 DarwinRefKind = SE->getKind(); 5526 return true; 5527 } 5528 5529 // Check that it looks like a symbol + an addend 5530 MCValue Res; 5531 bool Relocatable = Expr->evaluateAsRelocatable(Res, nullptr, nullptr); 5532 if (!Relocatable || Res.getSymB()) 5533 return false; 5534 5535 // Treat expressions with an ELFRefKind (like ":abs_g1:3", or 5536 // ":abs_g1:x" where x is constant) as symbolic even if there is no symbol. 5537 if (!Res.getSymA() && ELFRefKind == AArch64MCExpr::VK_INVALID) 5538 return false; 5539 5540 if (Res.getSymA()) 5541 DarwinRefKind = Res.getSymA()->getKind(); 5542 Addend = Res.getConstant(); 5543 5544 // It's some symbol reference + a constant addend, but really 5545 // shouldn't use both Darwin and ELF syntax. 5546 return ELFRefKind == AArch64MCExpr::VK_INVALID || 5547 DarwinRefKind == MCSymbolRefExpr::VK_None; 5548 } 5549 5550 /// Force static initialization. 5551 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64AsmParser() { 5552 RegisterMCAsmParser<AArch64AsmParser> X(getTheAArch64leTarget()); 5553 RegisterMCAsmParser<AArch64AsmParser> Y(getTheAArch64beTarget()); 5554 RegisterMCAsmParser<AArch64AsmParser> Z(getTheARM64Target()); 5555 RegisterMCAsmParser<AArch64AsmParser> W(getTheARM64_32Target()); 5556 RegisterMCAsmParser<AArch64AsmParser> V(getTheAArch64_32Target()); 5557 } 5558 5559 #define GET_REGISTER_MATCHER 5560 #define GET_SUBTARGET_FEATURE_NAME 5561 #define GET_MATCHER_IMPLEMENTATION 5562 #define GET_MNEMONIC_SPELL_CHECKER 5563 #include "AArch64GenAsmMatcher.inc" 5564 5565 // Define this matcher function after the auto-generated include so we 5566 // have the match class enum definitions. 5567 unsigned AArch64AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, 5568 unsigned Kind) { 5569 AArch64Operand &Op = static_cast<AArch64Operand &>(AsmOp); 5570 // If the kind is a token for a literal immediate, check if our asm 5571 // operand matches. This is for InstAliases which have a fixed-value 5572 // immediate in the syntax. 5573 int64_t ExpectedVal; 5574 switch (Kind) { 5575 default: 5576 return Match_InvalidOperand; 5577 case MCK__HASH_0: 5578 ExpectedVal = 0; 5579 break; 5580 case MCK__HASH_1: 5581 ExpectedVal = 1; 5582 break; 5583 case MCK__HASH_12: 5584 ExpectedVal = 12; 5585 break; 5586 case MCK__HASH_16: 5587 ExpectedVal = 16; 5588 break; 5589 case MCK__HASH_2: 5590 ExpectedVal = 2; 5591 break; 5592 case MCK__HASH_24: 5593 ExpectedVal = 24; 5594 break; 5595 case MCK__HASH_3: 5596 ExpectedVal = 3; 5597 break; 5598 case MCK__HASH_32: 5599 ExpectedVal = 32; 5600 break; 5601 case MCK__HASH_4: 5602 ExpectedVal = 4; 5603 break; 5604 case MCK__HASH_48: 5605 ExpectedVal = 48; 5606 break; 5607 case MCK__HASH_6: 5608 ExpectedVal = 6; 5609 break; 5610 case MCK__HASH_64: 5611 ExpectedVal = 64; 5612 break; 5613 case MCK__HASH_8: 5614 ExpectedVal = 8; 5615 break; 5616 } 5617 if (!Op.isImm()) 5618 return Match_InvalidOperand; 5619 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm()); 5620 if (!CE) 5621 return Match_InvalidOperand; 5622 if (CE->getValue() == ExpectedVal) 5623 return Match_Success; 5624 return Match_InvalidOperand; 5625 } 5626 5627 OperandMatchResultTy 5628 AArch64AsmParser::tryParseGPRSeqPair(OperandVector &Operands) { 5629 5630 SMLoc S = getLoc(); 5631 5632 if (getParser().getTok().isNot(AsmToken::Identifier)) { 5633 Error(S, "expected register"); 5634 return MatchOperand_ParseFail; 5635 } 5636 5637 unsigned FirstReg; 5638 OperandMatchResultTy Res = tryParseScalarRegister(FirstReg); 5639 if (Res != MatchOperand_Success) 5640 return MatchOperand_ParseFail; 5641 5642 const MCRegisterClass &WRegClass = 5643 AArch64MCRegisterClasses[AArch64::GPR32RegClassID]; 5644 const MCRegisterClass &XRegClass = 5645 AArch64MCRegisterClasses[AArch64::GPR64RegClassID]; 5646 5647 bool isXReg = XRegClass.contains(FirstReg), 5648 isWReg = WRegClass.contains(FirstReg); 5649 if (!isXReg && !isWReg) { 5650 Error(S, "expected first even register of a " 5651 "consecutive same-size even/odd register pair"); 5652 return MatchOperand_ParseFail; 5653 } 5654 5655 const MCRegisterInfo *RI = getContext().getRegisterInfo(); 5656 unsigned FirstEncoding = RI->getEncodingValue(FirstReg); 5657 5658 if (FirstEncoding & 0x1) { 5659 Error(S, "expected first even register of a " 5660 "consecutive same-size even/odd register pair"); 5661 return MatchOperand_ParseFail; 5662 } 5663 5664 if (getParser().getTok().isNot(AsmToken::Comma)) { 5665 Error(getLoc(), "expected comma"); 5666 return MatchOperand_ParseFail; 5667 } 5668 // Eat the comma 5669 getParser().Lex(); 5670 5671 SMLoc E = getLoc(); 5672 unsigned SecondReg; 5673 Res = tryParseScalarRegister(SecondReg); 5674 if (Res != MatchOperand_Success) 5675 return MatchOperand_ParseFail; 5676 5677 if (RI->getEncodingValue(SecondReg) != FirstEncoding + 1 || 5678 (isXReg && !XRegClass.contains(SecondReg)) || 5679 (isWReg && !WRegClass.contains(SecondReg))) { 5680 Error(E,"expected second odd register of a " 5681 "consecutive same-size even/odd register pair"); 5682 return MatchOperand_ParseFail; 5683 } 5684 5685 unsigned Pair = 0; 5686 if (isXReg) { 5687 Pair = RI->getMatchingSuperReg(FirstReg, AArch64::sube64, 5688 &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]); 5689 } else { 5690 Pair = RI->getMatchingSuperReg(FirstReg, AArch64::sube32, 5691 &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]); 5692 } 5693 5694 Operands.push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S, 5695 getLoc(), getContext())); 5696 5697 return MatchOperand_Success; 5698 } 5699 5700 template <bool ParseShiftExtend, bool ParseSuffix> 5701 OperandMatchResultTy 5702 AArch64AsmParser::tryParseSVEDataVector(OperandVector &Operands) { 5703 const SMLoc S = getLoc(); 5704 // Check for a SVE vector register specifier first. 5705 unsigned RegNum; 5706 StringRef Kind; 5707 5708 OperandMatchResultTy Res = 5709 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector); 5710 5711 if (Res != MatchOperand_Success) 5712 return Res; 5713 5714 if (ParseSuffix && Kind.empty()) 5715 return MatchOperand_NoMatch; 5716 5717 const auto &KindRes = parseVectorKind(Kind, RegKind::SVEDataVector); 5718 if (!KindRes) 5719 return MatchOperand_NoMatch; 5720 5721 unsigned ElementWidth = KindRes->second; 5722 5723 // No shift/extend is the default. 5724 if (!ParseShiftExtend || getParser().getTok().isNot(AsmToken::Comma)) { 5725 Operands.push_back(AArch64Operand::CreateVectorReg( 5726 RegNum, RegKind::SVEDataVector, ElementWidth, S, S, getContext())); 5727 5728 OperandMatchResultTy Res = tryParseVectorIndex(Operands); 5729 if (Res == MatchOperand_ParseFail) 5730 return MatchOperand_ParseFail; 5731 return MatchOperand_Success; 5732 } 5733 5734 // Eat the comma 5735 getParser().Lex(); 5736 5737 // Match the shift 5738 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> ExtOpnd; 5739 Res = tryParseOptionalShiftExtend(ExtOpnd); 5740 if (Res != MatchOperand_Success) 5741 return Res; 5742 5743 auto Ext = static_cast<AArch64Operand *>(ExtOpnd.back().get()); 5744 Operands.push_back(AArch64Operand::CreateVectorReg( 5745 RegNum, RegKind::SVEDataVector, ElementWidth, S, Ext->getEndLoc(), 5746 getContext(), Ext->getShiftExtendType(), Ext->getShiftExtendAmount(), 5747 Ext->hasShiftExtendAmount())); 5748 5749 return MatchOperand_Success; 5750 } 5751 5752 OperandMatchResultTy 5753 AArch64AsmParser::tryParseSVEPattern(OperandVector &Operands) { 5754 MCAsmParser &Parser = getParser(); 5755 5756 SMLoc SS = getLoc(); 5757 const AsmToken &TokE = Parser.getTok(); 5758 bool IsHash = TokE.is(AsmToken::Hash); 5759 5760 if (!IsHash && TokE.isNot(AsmToken::Identifier)) 5761 return MatchOperand_NoMatch; 5762 5763 int64_t Pattern; 5764 if (IsHash) { 5765 Parser.Lex(); // Eat hash 5766 5767 // Parse the immediate operand. 5768 const MCExpr *ImmVal; 5769 SS = getLoc(); 5770 if (Parser.parseExpression(ImmVal)) 5771 return MatchOperand_ParseFail; 5772 5773 auto *MCE = dyn_cast<MCConstantExpr>(ImmVal); 5774 if (!MCE) 5775 return MatchOperand_ParseFail; 5776 5777 Pattern = MCE->getValue(); 5778 } else { 5779 // Parse the pattern 5780 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.getString()); 5781 if (!Pat) 5782 return MatchOperand_NoMatch; 5783 5784 Parser.Lex(); 5785 Pattern = Pat->Encoding; 5786 assert(Pattern >= 0 && Pattern < 32); 5787 } 5788 5789 Operands.push_back( 5790 AArch64Operand::CreateImm(MCConstantExpr::create(Pattern, getContext()), 5791 SS, getLoc(), getContext())); 5792 5793 return MatchOperand_Success; 5794 } 5795