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 {"tlb-rmi", {AArch64::FeatureTLB_RMI}}, 2845 {"pan-rwv", {AArch64::FeaturePAN_RWV}}, 2846 {"ccpp", {AArch64::FeatureCCPP}}, 2847 {"sve", {AArch64::FeatureSVE}}, 2848 {"sve2", {AArch64::FeatureSVE2}}, 2849 {"sve2-aes", {AArch64::FeatureSVE2AES}}, 2850 {"sve2-sm4", {AArch64::FeatureSVE2SM4}}, 2851 {"sve2-sha3", {AArch64::FeatureSVE2SHA3}}, 2852 {"sve2-bitperm", {AArch64::FeatureSVE2BitPerm}}, 2853 // FIXME: Unsupported extensions 2854 {"pan", {}}, 2855 {"lor", {}}, 2856 {"rdma", {}}, 2857 {"profile", {}}, 2858 }; 2859 2860 static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str) { 2861 if (FBS[AArch64::HasV8_1aOps]) 2862 Str += "ARMv8.1a"; 2863 else if (FBS[AArch64::HasV8_2aOps]) 2864 Str += "ARMv8.2a"; 2865 else if (FBS[AArch64::HasV8_3aOps]) 2866 Str += "ARMv8.3a"; 2867 else if (FBS[AArch64::HasV8_4aOps]) 2868 Str += "ARMv8.4a"; 2869 else if (FBS[AArch64::HasV8_5aOps]) 2870 Str += "ARMv8.5a"; 2871 else if (FBS[AArch64::HasV8_6aOps]) 2872 Str += "ARMv8.6a"; 2873 else { 2874 auto ext = std::find_if(std::begin(ExtensionMap), 2875 std::end(ExtensionMap), 2876 [&](const Extension& e) 2877 // Use & in case multiple features are enabled 2878 { return (FBS & e.Features) != FeatureBitset(); } 2879 ); 2880 2881 Str += ext != std::end(ExtensionMap) ? ext->Name : "(unknown)"; 2882 } 2883 } 2884 2885 void AArch64AsmParser::createSysAlias(uint16_t Encoding, OperandVector &Operands, 2886 SMLoc S) { 2887 const uint16_t Op2 = Encoding & 7; 2888 const uint16_t Cm = (Encoding & 0x78) >> 3; 2889 const uint16_t Cn = (Encoding & 0x780) >> 7; 2890 const uint16_t Op1 = (Encoding & 0x3800) >> 11; 2891 2892 const MCExpr *Expr = MCConstantExpr::create(Op1, getContext()); 2893 2894 Operands.push_back( 2895 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext())); 2896 Operands.push_back( 2897 AArch64Operand::CreateSysCR(Cn, S, getLoc(), getContext())); 2898 Operands.push_back( 2899 AArch64Operand::CreateSysCR(Cm, S, getLoc(), getContext())); 2900 Expr = MCConstantExpr::create(Op2, getContext()); 2901 Operands.push_back( 2902 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext())); 2903 } 2904 2905 /// parseSysAlias - The IC, DC, AT, and TLBI instructions are simple aliases for 2906 /// the SYS instruction. Parse them specially so that we create a SYS MCInst. 2907 bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc, 2908 OperandVector &Operands) { 2909 if (Name.find('.') != StringRef::npos) 2910 return TokError("invalid operand"); 2911 2912 Mnemonic = Name; 2913 Operands.push_back( 2914 AArch64Operand::CreateToken("sys", false, NameLoc, getContext())); 2915 2916 MCAsmParser &Parser = getParser(); 2917 const AsmToken &Tok = Parser.getTok(); 2918 StringRef Op = Tok.getString(); 2919 SMLoc S = Tok.getLoc(); 2920 2921 if (Mnemonic == "ic") { 2922 const AArch64IC::IC *IC = AArch64IC::lookupICByName(Op); 2923 if (!IC) 2924 return TokError("invalid operand for IC instruction"); 2925 else if (!IC->haveFeatures(getSTI().getFeatureBits())) { 2926 std::string Str("IC " + std::string(IC->Name) + " requires "); 2927 setRequiredFeatureString(IC->getRequiredFeatures(), Str); 2928 return TokError(Str.c_str()); 2929 } 2930 createSysAlias(IC->Encoding, Operands, S); 2931 } else if (Mnemonic == "dc") { 2932 const AArch64DC::DC *DC = AArch64DC::lookupDCByName(Op); 2933 if (!DC) 2934 return TokError("invalid operand for DC instruction"); 2935 else if (!DC->haveFeatures(getSTI().getFeatureBits())) { 2936 std::string Str("DC " + std::string(DC->Name) + " requires "); 2937 setRequiredFeatureString(DC->getRequiredFeatures(), Str); 2938 return TokError(Str.c_str()); 2939 } 2940 createSysAlias(DC->Encoding, Operands, S); 2941 } else if (Mnemonic == "at") { 2942 const AArch64AT::AT *AT = AArch64AT::lookupATByName(Op); 2943 if (!AT) 2944 return TokError("invalid operand for AT instruction"); 2945 else if (!AT->haveFeatures(getSTI().getFeatureBits())) { 2946 std::string Str("AT " + std::string(AT->Name) + " requires "); 2947 setRequiredFeatureString(AT->getRequiredFeatures(), Str); 2948 return TokError(Str.c_str()); 2949 } 2950 createSysAlias(AT->Encoding, Operands, S); 2951 } else if (Mnemonic == "tlbi") { 2952 const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByName(Op); 2953 if (!TLBI) 2954 return TokError("invalid operand for TLBI instruction"); 2955 else if (!TLBI->haveFeatures(getSTI().getFeatureBits())) { 2956 std::string Str("TLBI " + std::string(TLBI->Name) + " requires "); 2957 setRequiredFeatureString(TLBI->getRequiredFeatures(), Str); 2958 return TokError(Str.c_str()); 2959 } 2960 createSysAlias(TLBI->Encoding, Operands, S); 2961 } else if (Mnemonic == "cfp" || Mnemonic == "dvp" || Mnemonic == "cpp") { 2962 const AArch64PRCTX::PRCTX *PRCTX = AArch64PRCTX::lookupPRCTXByName(Op); 2963 if (!PRCTX) 2964 return TokError("invalid operand for prediction restriction instruction"); 2965 else if (!PRCTX->haveFeatures(getSTI().getFeatureBits())) { 2966 std::string Str( 2967 Mnemonic.upper() + std::string(PRCTX->Name) + " requires "); 2968 setRequiredFeatureString(PRCTX->getRequiredFeatures(), Str); 2969 return TokError(Str.c_str()); 2970 } 2971 uint16_t PRCTX_Op2 = 2972 Mnemonic == "cfp" ? 4 : 2973 Mnemonic == "dvp" ? 5 : 2974 Mnemonic == "cpp" ? 7 : 2975 0; 2976 assert(PRCTX_Op2 && "Invalid mnemonic for prediction restriction instruction"); 2977 createSysAlias(PRCTX->Encoding << 3 | PRCTX_Op2 , Operands, S); 2978 } 2979 2980 Parser.Lex(); // Eat operand. 2981 2982 bool ExpectRegister = (Op.lower().find("all") == StringRef::npos); 2983 bool HasRegister = false; 2984 2985 // Check for the optional register operand. 2986 if (parseOptionalToken(AsmToken::Comma)) { 2987 if (Tok.isNot(AsmToken::Identifier) || parseRegister(Operands)) 2988 return TokError("expected register operand"); 2989 HasRegister = true; 2990 } 2991 2992 if (ExpectRegister && !HasRegister) 2993 return TokError("specified " + Mnemonic + " op requires a register"); 2994 else if (!ExpectRegister && HasRegister) 2995 return TokError("specified " + Mnemonic + " op does not use a register"); 2996 2997 if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list")) 2998 return true; 2999 3000 return false; 3001 } 3002 3003 OperandMatchResultTy 3004 AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) { 3005 MCAsmParser &Parser = getParser(); 3006 const AsmToken &Tok = Parser.getTok(); 3007 3008 if (Mnemonic == "tsb" && Tok.isNot(AsmToken::Identifier)) { 3009 TokError("'csync' operand expected"); 3010 return MatchOperand_ParseFail; 3011 // Can be either a #imm style literal or an option name 3012 } else if (parseOptionalToken(AsmToken::Hash) || Tok.is(AsmToken::Integer)) { 3013 // Immediate operand. 3014 const MCExpr *ImmVal; 3015 SMLoc ExprLoc = getLoc(); 3016 if (getParser().parseExpression(ImmVal)) 3017 return MatchOperand_ParseFail; 3018 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 3019 if (!MCE) { 3020 Error(ExprLoc, "immediate value expected for barrier operand"); 3021 return MatchOperand_ParseFail; 3022 } 3023 if (MCE->getValue() < 0 || MCE->getValue() > 15) { 3024 Error(ExprLoc, "barrier operand out of range"); 3025 return MatchOperand_ParseFail; 3026 } 3027 auto DB = AArch64DB::lookupDBByEncoding(MCE->getValue()); 3028 Operands.push_back(AArch64Operand::CreateBarrier( 3029 MCE->getValue(), DB ? DB->Name : "", ExprLoc, getContext())); 3030 return MatchOperand_Success; 3031 } 3032 3033 if (Tok.isNot(AsmToken::Identifier)) { 3034 TokError("invalid operand for instruction"); 3035 return MatchOperand_ParseFail; 3036 } 3037 3038 auto TSB = AArch64TSB::lookupTSBByName(Tok.getString()); 3039 // The only valid named option for ISB is 'sy' 3040 auto DB = AArch64DB::lookupDBByName(Tok.getString()); 3041 if (Mnemonic == "isb" && (!DB || DB->Encoding != AArch64DB::sy)) { 3042 TokError("'sy' or #imm operand expected"); 3043 return MatchOperand_ParseFail; 3044 // The only valid named option for TSB is 'csync' 3045 } else if (Mnemonic == "tsb" && (!TSB || TSB->Encoding != AArch64TSB::csync)) { 3046 TokError("'csync' operand expected"); 3047 return MatchOperand_ParseFail; 3048 } else if (!DB && !TSB) { 3049 TokError("invalid barrier option name"); 3050 return MatchOperand_ParseFail; 3051 } 3052 3053 Operands.push_back(AArch64Operand::CreateBarrier( 3054 DB ? DB->Encoding : TSB->Encoding, Tok.getString(), getLoc(), getContext())); 3055 Parser.Lex(); // Consume the option 3056 3057 return MatchOperand_Success; 3058 } 3059 3060 OperandMatchResultTy 3061 AArch64AsmParser::tryParseSysReg(OperandVector &Operands) { 3062 MCAsmParser &Parser = getParser(); 3063 const AsmToken &Tok = Parser.getTok(); 3064 3065 if (Tok.isNot(AsmToken::Identifier)) 3066 return MatchOperand_NoMatch; 3067 3068 int MRSReg, MSRReg; 3069 auto SysReg = AArch64SysReg::lookupSysRegByName(Tok.getString()); 3070 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) { 3071 MRSReg = SysReg->Readable ? SysReg->Encoding : -1; 3072 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1; 3073 } else 3074 MRSReg = MSRReg = AArch64SysReg::parseGenericRegister(Tok.getString()); 3075 3076 auto PState = AArch64PState::lookupPStateByName(Tok.getString()); 3077 unsigned PStateImm = -1; 3078 if (PState && PState->haveFeatures(getSTI().getFeatureBits())) 3079 PStateImm = PState->Encoding; 3080 3081 Operands.push_back( 3082 AArch64Operand::CreateSysReg(Tok.getString(), getLoc(), MRSReg, MSRReg, 3083 PStateImm, getContext())); 3084 Parser.Lex(); // Eat identifier 3085 3086 return MatchOperand_Success; 3087 } 3088 3089 /// tryParseNeonVectorRegister - Parse a vector register operand. 3090 bool AArch64AsmParser::tryParseNeonVectorRegister(OperandVector &Operands) { 3091 MCAsmParser &Parser = getParser(); 3092 if (Parser.getTok().isNot(AsmToken::Identifier)) 3093 return true; 3094 3095 SMLoc S = getLoc(); 3096 // Check for a vector register specifier first. 3097 StringRef Kind; 3098 unsigned Reg; 3099 OperandMatchResultTy Res = 3100 tryParseVectorRegister(Reg, Kind, RegKind::NeonVector); 3101 if (Res != MatchOperand_Success) 3102 return true; 3103 3104 const auto &KindRes = parseVectorKind(Kind, RegKind::NeonVector); 3105 if (!KindRes) 3106 return true; 3107 3108 unsigned ElementWidth = KindRes->second; 3109 Operands.push_back( 3110 AArch64Operand::CreateVectorReg(Reg, RegKind::NeonVector, ElementWidth, 3111 S, getLoc(), getContext())); 3112 3113 // If there was an explicit qualifier, that goes on as a literal text 3114 // operand. 3115 if (!Kind.empty()) 3116 Operands.push_back( 3117 AArch64Operand::CreateToken(Kind, false, S, getContext())); 3118 3119 return tryParseVectorIndex(Operands) == MatchOperand_ParseFail; 3120 } 3121 3122 OperandMatchResultTy 3123 AArch64AsmParser::tryParseVectorIndex(OperandVector &Operands) { 3124 SMLoc SIdx = getLoc(); 3125 if (parseOptionalToken(AsmToken::LBrac)) { 3126 const MCExpr *ImmVal; 3127 if (getParser().parseExpression(ImmVal)) 3128 return MatchOperand_NoMatch; 3129 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 3130 if (!MCE) { 3131 TokError("immediate value expected for vector index"); 3132 return MatchOperand_ParseFail;; 3133 } 3134 3135 SMLoc E = getLoc(); 3136 3137 if (parseToken(AsmToken::RBrac, "']' expected")) 3138 return MatchOperand_ParseFail;; 3139 3140 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx, 3141 E, getContext())); 3142 return MatchOperand_Success; 3143 } 3144 3145 return MatchOperand_NoMatch; 3146 } 3147 3148 // tryParseVectorRegister - Try to parse a vector register name with 3149 // optional kind specifier. If it is a register specifier, eat the token 3150 // and return it. 3151 OperandMatchResultTy 3152 AArch64AsmParser::tryParseVectorRegister(unsigned &Reg, StringRef &Kind, 3153 RegKind MatchKind) { 3154 MCAsmParser &Parser = getParser(); 3155 const AsmToken &Tok = Parser.getTok(); 3156 3157 if (Tok.isNot(AsmToken::Identifier)) 3158 return MatchOperand_NoMatch; 3159 3160 StringRef Name = Tok.getString(); 3161 // If there is a kind specifier, it's separated from the register name by 3162 // a '.'. 3163 size_t Start = 0, Next = Name.find('.'); 3164 StringRef Head = Name.slice(Start, Next); 3165 unsigned RegNum = matchRegisterNameAlias(Head, MatchKind); 3166 3167 if (RegNum) { 3168 if (Next != StringRef::npos) { 3169 Kind = Name.slice(Next, StringRef::npos); 3170 if (!isValidVectorKind(Kind, MatchKind)) { 3171 TokError("invalid vector kind qualifier"); 3172 return MatchOperand_ParseFail; 3173 } 3174 } 3175 Parser.Lex(); // Eat the register token. 3176 3177 Reg = RegNum; 3178 return MatchOperand_Success; 3179 } 3180 3181 return MatchOperand_NoMatch; 3182 } 3183 3184 /// tryParseSVEPredicateVector - Parse a SVE predicate register operand. 3185 OperandMatchResultTy 3186 AArch64AsmParser::tryParseSVEPredicateVector(OperandVector &Operands) { 3187 // Check for a SVE predicate register specifier first. 3188 const SMLoc S = getLoc(); 3189 StringRef Kind; 3190 unsigned RegNum; 3191 auto Res = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector); 3192 if (Res != MatchOperand_Success) 3193 return Res; 3194 3195 const auto &KindRes = parseVectorKind(Kind, RegKind::SVEPredicateVector); 3196 if (!KindRes) 3197 return MatchOperand_NoMatch; 3198 3199 unsigned ElementWidth = KindRes->second; 3200 Operands.push_back(AArch64Operand::CreateVectorReg( 3201 RegNum, RegKind::SVEPredicateVector, ElementWidth, S, 3202 getLoc(), getContext())); 3203 3204 // Not all predicates are followed by a '/m' or '/z'. 3205 MCAsmParser &Parser = getParser(); 3206 if (Parser.getTok().isNot(AsmToken::Slash)) 3207 return MatchOperand_Success; 3208 3209 // But when they do they shouldn't have an element type suffix. 3210 if (!Kind.empty()) { 3211 Error(S, "not expecting size suffix"); 3212 return MatchOperand_ParseFail; 3213 } 3214 3215 // Add a literal slash as operand 3216 Operands.push_back( 3217 AArch64Operand::CreateToken("/" , false, getLoc(), getContext())); 3218 3219 Parser.Lex(); // Eat the slash. 3220 3221 // Zeroing or merging? 3222 auto Pred = Parser.getTok().getString().lower(); 3223 if (Pred != "z" && Pred != "m") { 3224 Error(getLoc(), "expecting 'm' or 'z' predication"); 3225 return MatchOperand_ParseFail; 3226 } 3227 3228 // Add zero/merge token. 3229 const char *ZM = Pred == "z" ? "z" : "m"; 3230 Operands.push_back( 3231 AArch64Operand::CreateToken(ZM, false, getLoc(), getContext())); 3232 3233 Parser.Lex(); // Eat zero/merge token. 3234 return MatchOperand_Success; 3235 } 3236 3237 /// parseRegister - Parse a register operand. 3238 bool AArch64AsmParser::parseRegister(OperandVector &Operands) { 3239 // Try for a Neon vector register. 3240 if (!tryParseNeonVectorRegister(Operands)) 3241 return false; 3242 3243 // Otherwise try for a scalar register. 3244 if (tryParseGPROperand<false>(Operands) == MatchOperand_Success) 3245 return false; 3246 3247 return true; 3248 } 3249 3250 bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) { 3251 MCAsmParser &Parser = getParser(); 3252 bool HasELFModifier = false; 3253 AArch64MCExpr::VariantKind RefKind; 3254 3255 if (parseOptionalToken(AsmToken::Colon)) { 3256 HasELFModifier = true; 3257 3258 if (Parser.getTok().isNot(AsmToken::Identifier)) 3259 return TokError("expect relocation specifier in operand after ':'"); 3260 3261 std::string LowerCase = Parser.getTok().getIdentifier().lower(); 3262 RefKind = StringSwitch<AArch64MCExpr::VariantKind>(LowerCase) 3263 .Case("lo12", AArch64MCExpr::VK_LO12) 3264 .Case("abs_g3", AArch64MCExpr::VK_ABS_G3) 3265 .Case("abs_g2", AArch64MCExpr::VK_ABS_G2) 3266 .Case("abs_g2_s", AArch64MCExpr::VK_ABS_G2_S) 3267 .Case("abs_g2_nc", AArch64MCExpr::VK_ABS_G2_NC) 3268 .Case("abs_g1", AArch64MCExpr::VK_ABS_G1) 3269 .Case("abs_g1_s", AArch64MCExpr::VK_ABS_G1_S) 3270 .Case("abs_g1_nc", AArch64MCExpr::VK_ABS_G1_NC) 3271 .Case("abs_g0", AArch64MCExpr::VK_ABS_G0) 3272 .Case("abs_g0_s", AArch64MCExpr::VK_ABS_G0_S) 3273 .Case("abs_g0_nc", AArch64MCExpr::VK_ABS_G0_NC) 3274 .Case("prel_g3", AArch64MCExpr::VK_PREL_G3) 3275 .Case("prel_g2", AArch64MCExpr::VK_PREL_G2) 3276 .Case("prel_g2_nc", AArch64MCExpr::VK_PREL_G2_NC) 3277 .Case("prel_g1", AArch64MCExpr::VK_PREL_G1) 3278 .Case("prel_g1_nc", AArch64MCExpr::VK_PREL_G1_NC) 3279 .Case("prel_g0", AArch64MCExpr::VK_PREL_G0) 3280 .Case("prel_g0_nc", AArch64MCExpr::VK_PREL_G0_NC) 3281 .Case("dtprel_g2", AArch64MCExpr::VK_DTPREL_G2) 3282 .Case("dtprel_g1", AArch64MCExpr::VK_DTPREL_G1) 3283 .Case("dtprel_g1_nc", AArch64MCExpr::VK_DTPREL_G1_NC) 3284 .Case("dtprel_g0", AArch64MCExpr::VK_DTPREL_G0) 3285 .Case("dtprel_g0_nc", AArch64MCExpr::VK_DTPREL_G0_NC) 3286 .Case("dtprel_hi12", AArch64MCExpr::VK_DTPREL_HI12) 3287 .Case("dtprel_lo12", AArch64MCExpr::VK_DTPREL_LO12) 3288 .Case("dtprel_lo12_nc", AArch64MCExpr::VK_DTPREL_LO12_NC) 3289 .Case("pg_hi21_nc", AArch64MCExpr::VK_ABS_PAGE_NC) 3290 .Case("tprel_g2", AArch64MCExpr::VK_TPREL_G2) 3291 .Case("tprel_g1", AArch64MCExpr::VK_TPREL_G1) 3292 .Case("tprel_g1_nc", AArch64MCExpr::VK_TPREL_G1_NC) 3293 .Case("tprel_g0", AArch64MCExpr::VK_TPREL_G0) 3294 .Case("tprel_g0_nc", AArch64MCExpr::VK_TPREL_G0_NC) 3295 .Case("tprel_hi12", AArch64MCExpr::VK_TPREL_HI12) 3296 .Case("tprel_lo12", AArch64MCExpr::VK_TPREL_LO12) 3297 .Case("tprel_lo12_nc", AArch64MCExpr::VK_TPREL_LO12_NC) 3298 .Case("tlsdesc_lo12", AArch64MCExpr::VK_TLSDESC_LO12) 3299 .Case("got", AArch64MCExpr::VK_GOT_PAGE) 3300 .Case("got_lo12", AArch64MCExpr::VK_GOT_LO12) 3301 .Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE) 3302 .Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC) 3303 .Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1) 3304 .Case("gottprel_g0_nc", AArch64MCExpr::VK_GOTTPREL_G0_NC) 3305 .Case("tlsdesc", AArch64MCExpr::VK_TLSDESC_PAGE) 3306 .Case("secrel_lo12", AArch64MCExpr::VK_SECREL_LO12) 3307 .Case("secrel_hi12", AArch64MCExpr::VK_SECREL_HI12) 3308 .Default(AArch64MCExpr::VK_INVALID); 3309 3310 if (RefKind == AArch64MCExpr::VK_INVALID) 3311 return TokError("expect relocation specifier in operand after ':'"); 3312 3313 Parser.Lex(); // Eat identifier 3314 3315 if (parseToken(AsmToken::Colon, "expect ':' after relocation specifier")) 3316 return true; 3317 } 3318 3319 if (getParser().parseExpression(ImmVal)) 3320 return true; 3321 3322 if (HasELFModifier) 3323 ImmVal = AArch64MCExpr::create(ImmVal, RefKind, getContext()); 3324 3325 return false; 3326 } 3327 3328 template <RegKind VectorKind> 3329 OperandMatchResultTy 3330 AArch64AsmParser::tryParseVectorList(OperandVector &Operands, 3331 bool ExpectMatch) { 3332 MCAsmParser &Parser = getParser(); 3333 if (!Parser.getTok().is(AsmToken::LCurly)) 3334 return MatchOperand_NoMatch; 3335 3336 // Wrapper around parse function 3337 auto ParseVector = [this, &Parser](unsigned &Reg, StringRef &Kind, SMLoc Loc, 3338 bool NoMatchIsError) { 3339 auto RegTok = Parser.getTok(); 3340 auto ParseRes = tryParseVectorRegister(Reg, Kind, VectorKind); 3341 if (ParseRes == MatchOperand_Success) { 3342 if (parseVectorKind(Kind, VectorKind)) 3343 return ParseRes; 3344 llvm_unreachable("Expected a valid vector kind"); 3345 } 3346 3347 if (RegTok.isNot(AsmToken::Identifier) || 3348 ParseRes == MatchOperand_ParseFail || 3349 (ParseRes == MatchOperand_NoMatch && NoMatchIsError)) { 3350 Error(Loc, "vector register expected"); 3351 return MatchOperand_ParseFail; 3352 } 3353 3354 return MatchOperand_NoMatch; 3355 }; 3356 3357 SMLoc S = getLoc(); 3358 auto LCurly = Parser.getTok(); 3359 Parser.Lex(); // Eat left bracket token. 3360 3361 StringRef Kind; 3362 unsigned FirstReg; 3363 auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch); 3364 3365 // Put back the original left bracket if there was no match, so that 3366 // different types of list-operands can be matched (e.g. SVE, Neon). 3367 if (ParseRes == MatchOperand_NoMatch) 3368 Parser.getLexer().UnLex(LCurly); 3369 3370 if (ParseRes != MatchOperand_Success) 3371 return ParseRes; 3372 3373 int64_t PrevReg = FirstReg; 3374 unsigned Count = 1; 3375 3376 if (parseOptionalToken(AsmToken::Minus)) { 3377 SMLoc Loc = getLoc(); 3378 StringRef NextKind; 3379 3380 unsigned Reg; 3381 ParseRes = ParseVector(Reg, NextKind, getLoc(), true); 3382 if (ParseRes != MatchOperand_Success) 3383 return ParseRes; 3384 3385 // Any Kind suffices must match on all regs in the list. 3386 if (Kind != NextKind) { 3387 Error(Loc, "mismatched register size suffix"); 3388 return MatchOperand_ParseFail; 3389 } 3390 3391 unsigned Space = (PrevReg < Reg) ? (Reg - PrevReg) : (Reg + 32 - PrevReg); 3392 3393 if (Space == 0 || Space > 3) { 3394 Error(Loc, "invalid number of vectors"); 3395 return MatchOperand_ParseFail; 3396 } 3397 3398 Count += Space; 3399 } 3400 else { 3401 while (parseOptionalToken(AsmToken::Comma)) { 3402 SMLoc Loc = getLoc(); 3403 StringRef NextKind; 3404 unsigned Reg; 3405 ParseRes = ParseVector(Reg, NextKind, getLoc(), true); 3406 if (ParseRes != MatchOperand_Success) 3407 return ParseRes; 3408 3409 // Any Kind suffices must match on all regs in the list. 3410 if (Kind != NextKind) { 3411 Error(Loc, "mismatched register size suffix"); 3412 return MatchOperand_ParseFail; 3413 } 3414 3415 // Registers must be incremental (with wraparound at 31) 3416 if (getContext().getRegisterInfo()->getEncodingValue(Reg) != 3417 (getContext().getRegisterInfo()->getEncodingValue(PrevReg) + 1) % 32) { 3418 Error(Loc, "registers must be sequential"); 3419 return MatchOperand_ParseFail; 3420 } 3421 3422 PrevReg = Reg; 3423 ++Count; 3424 } 3425 } 3426 3427 if (parseToken(AsmToken::RCurly, "'}' expected")) 3428 return MatchOperand_ParseFail; 3429 3430 if (Count > 4) { 3431 Error(S, "invalid number of vectors"); 3432 return MatchOperand_ParseFail; 3433 } 3434 3435 unsigned NumElements = 0; 3436 unsigned ElementWidth = 0; 3437 if (!Kind.empty()) { 3438 if (const auto &VK = parseVectorKind(Kind, VectorKind)) 3439 std::tie(NumElements, ElementWidth) = *VK; 3440 } 3441 3442 Operands.push_back(AArch64Operand::CreateVectorList( 3443 FirstReg, Count, NumElements, ElementWidth, VectorKind, S, getLoc(), 3444 getContext())); 3445 3446 return MatchOperand_Success; 3447 } 3448 3449 /// parseNeonVectorList - Parse a vector list operand for AdvSIMD instructions. 3450 bool AArch64AsmParser::parseNeonVectorList(OperandVector &Operands) { 3451 auto ParseRes = tryParseVectorList<RegKind::NeonVector>(Operands, true); 3452 if (ParseRes != MatchOperand_Success) 3453 return true; 3454 3455 return tryParseVectorIndex(Operands) == MatchOperand_ParseFail; 3456 } 3457 3458 OperandMatchResultTy 3459 AArch64AsmParser::tryParseGPR64sp0Operand(OperandVector &Operands) { 3460 SMLoc StartLoc = getLoc(); 3461 3462 unsigned RegNum; 3463 OperandMatchResultTy Res = tryParseScalarRegister(RegNum); 3464 if (Res != MatchOperand_Success) 3465 return Res; 3466 3467 if (!parseOptionalToken(AsmToken::Comma)) { 3468 Operands.push_back(AArch64Operand::CreateReg( 3469 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext())); 3470 return MatchOperand_Success; 3471 } 3472 3473 parseOptionalToken(AsmToken::Hash); 3474 3475 if (getParser().getTok().isNot(AsmToken::Integer)) { 3476 Error(getLoc(), "index must be absent or #0"); 3477 return MatchOperand_ParseFail; 3478 } 3479 3480 const MCExpr *ImmVal; 3481 if (getParser().parseExpression(ImmVal) || !isa<MCConstantExpr>(ImmVal) || 3482 cast<MCConstantExpr>(ImmVal)->getValue() != 0) { 3483 Error(getLoc(), "index must be absent or #0"); 3484 return MatchOperand_ParseFail; 3485 } 3486 3487 Operands.push_back(AArch64Operand::CreateReg( 3488 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext())); 3489 return MatchOperand_Success; 3490 } 3491 3492 template <bool ParseShiftExtend, RegConstraintEqualityTy EqTy> 3493 OperandMatchResultTy 3494 AArch64AsmParser::tryParseGPROperand(OperandVector &Operands) { 3495 SMLoc StartLoc = getLoc(); 3496 3497 unsigned RegNum; 3498 OperandMatchResultTy Res = tryParseScalarRegister(RegNum); 3499 if (Res != MatchOperand_Success) 3500 return Res; 3501 3502 // No shift/extend is the default. 3503 if (!ParseShiftExtend || getParser().getTok().isNot(AsmToken::Comma)) { 3504 Operands.push_back(AArch64Operand::CreateReg( 3505 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext(), EqTy)); 3506 return MatchOperand_Success; 3507 } 3508 3509 // Eat the comma 3510 getParser().Lex(); 3511 3512 // Match the shift 3513 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> ExtOpnd; 3514 Res = tryParseOptionalShiftExtend(ExtOpnd); 3515 if (Res != MatchOperand_Success) 3516 return Res; 3517 3518 auto Ext = static_cast<AArch64Operand*>(ExtOpnd.back().get()); 3519 Operands.push_back(AArch64Operand::CreateReg( 3520 RegNum, RegKind::Scalar, StartLoc, Ext->getEndLoc(), getContext(), EqTy, 3521 Ext->getShiftExtendType(), Ext->getShiftExtendAmount(), 3522 Ext->hasShiftExtendAmount())); 3523 3524 return MatchOperand_Success; 3525 } 3526 3527 bool AArch64AsmParser::parseOptionalMulOperand(OperandVector &Operands) { 3528 MCAsmParser &Parser = getParser(); 3529 3530 // Some SVE instructions have a decoration after the immediate, i.e. 3531 // "mul vl". We parse them here and add tokens, which must be present in the 3532 // asm string in the tablegen instruction. 3533 bool NextIsVL = Parser.getLexer().peekTok().getString().equals_lower("vl"); 3534 bool NextIsHash = Parser.getLexer().peekTok().is(AsmToken::Hash); 3535 if (!Parser.getTok().getString().equals_lower("mul") || 3536 !(NextIsVL || NextIsHash)) 3537 return true; 3538 3539 Operands.push_back( 3540 AArch64Operand::CreateToken("mul", false, getLoc(), getContext())); 3541 Parser.Lex(); // Eat the "mul" 3542 3543 if (NextIsVL) { 3544 Operands.push_back( 3545 AArch64Operand::CreateToken("vl", false, getLoc(), getContext())); 3546 Parser.Lex(); // Eat the "vl" 3547 return false; 3548 } 3549 3550 if (NextIsHash) { 3551 Parser.Lex(); // Eat the # 3552 SMLoc S = getLoc(); 3553 3554 // Parse immediate operand. 3555 const MCExpr *ImmVal; 3556 if (!Parser.parseExpression(ImmVal)) 3557 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal)) { 3558 Operands.push_back(AArch64Operand::CreateImm( 3559 MCConstantExpr::create(MCE->getValue(), getContext()), S, getLoc(), 3560 getContext())); 3561 return MatchOperand_Success; 3562 } 3563 } 3564 3565 return Error(getLoc(), "expected 'vl' or '#<imm>'"); 3566 } 3567 3568 /// parseOperand - Parse a arm instruction operand. For now this parses the 3569 /// operand regardless of the mnemonic. 3570 bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode, 3571 bool invertCondCode) { 3572 MCAsmParser &Parser = getParser(); 3573 3574 OperandMatchResultTy ResTy = 3575 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/ true); 3576 3577 // Check if the current operand has a custom associated parser, if so, try to 3578 // custom parse the operand, or fallback to the general approach. 3579 if (ResTy == MatchOperand_Success) 3580 return false; 3581 // If there wasn't a custom match, try the generic matcher below. Otherwise, 3582 // there was a match, but an error occurred, in which case, just return that 3583 // the operand parsing failed. 3584 if (ResTy == MatchOperand_ParseFail) 3585 return true; 3586 3587 // Nothing custom, so do general case parsing. 3588 SMLoc S, E; 3589 switch (getLexer().getKind()) { 3590 default: { 3591 SMLoc S = getLoc(); 3592 const MCExpr *Expr; 3593 if (parseSymbolicImmVal(Expr)) 3594 return Error(S, "invalid operand"); 3595 3596 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1); 3597 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext())); 3598 return false; 3599 } 3600 case AsmToken::LBrac: { 3601 SMLoc Loc = Parser.getTok().getLoc(); 3602 Operands.push_back(AArch64Operand::CreateToken("[", false, Loc, 3603 getContext())); 3604 Parser.Lex(); // Eat '[' 3605 3606 // There's no comma after a '[', so we can parse the next operand 3607 // immediately. 3608 return parseOperand(Operands, false, false); 3609 } 3610 case AsmToken::LCurly: 3611 return parseNeonVectorList(Operands); 3612 case AsmToken::Identifier: { 3613 // If we're expecting a Condition Code operand, then just parse that. 3614 if (isCondCode) 3615 return parseCondCode(Operands, invertCondCode); 3616 3617 // If it's a register name, parse it. 3618 if (!parseRegister(Operands)) 3619 return false; 3620 3621 // See if this is a "mul vl" decoration or "mul #<int>" operand used 3622 // by SVE instructions. 3623 if (!parseOptionalMulOperand(Operands)) 3624 return false; 3625 3626 // This could be an optional "shift" or "extend" operand. 3627 OperandMatchResultTy GotShift = tryParseOptionalShiftExtend(Operands); 3628 // We can only continue if no tokens were eaten. 3629 if (GotShift != MatchOperand_NoMatch) 3630 return GotShift; 3631 3632 // This was not a register so parse other operands that start with an 3633 // identifier (like labels) as expressions and create them as immediates. 3634 const MCExpr *IdVal; 3635 S = getLoc(); 3636 if (getParser().parseExpression(IdVal)) 3637 return true; 3638 E = SMLoc::getFromPointer(getLoc().getPointer() - 1); 3639 Operands.push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext())); 3640 return false; 3641 } 3642 case AsmToken::Integer: 3643 case AsmToken::Real: 3644 case AsmToken::Hash: { 3645 // #42 -> immediate. 3646 S = getLoc(); 3647 3648 parseOptionalToken(AsmToken::Hash); 3649 3650 // Parse a negative sign 3651 bool isNegative = false; 3652 if (Parser.getTok().is(AsmToken::Minus)) { 3653 isNegative = true; 3654 // We need to consume this token only when we have a Real, otherwise 3655 // we let parseSymbolicImmVal take care of it 3656 if (Parser.getLexer().peekTok().is(AsmToken::Real)) 3657 Parser.Lex(); 3658 } 3659 3660 // The only Real that should come through here is a literal #0.0 for 3661 // the fcmp[e] r, #0.0 instructions. They expect raw token operands, 3662 // so convert the value. 3663 const AsmToken &Tok = Parser.getTok(); 3664 if (Tok.is(AsmToken::Real)) { 3665 APFloat RealVal(APFloat::IEEEdouble(), Tok.getString()); 3666 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 3667 if (Mnemonic != "fcmp" && Mnemonic != "fcmpe" && Mnemonic != "fcmeq" && 3668 Mnemonic != "fcmge" && Mnemonic != "fcmgt" && Mnemonic != "fcmle" && 3669 Mnemonic != "fcmlt" && Mnemonic != "fcmne") 3670 return TokError("unexpected floating point literal"); 3671 else if (IntVal != 0 || isNegative) 3672 return TokError("expected floating-point constant #0.0"); 3673 Parser.Lex(); // Eat the token. 3674 3675 Operands.push_back( 3676 AArch64Operand::CreateToken("#0", false, S, getContext())); 3677 Operands.push_back( 3678 AArch64Operand::CreateToken(".0", false, S, getContext())); 3679 return false; 3680 } 3681 3682 const MCExpr *ImmVal; 3683 if (parseSymbolicImmVal(ImmVal)) 3684 return true; 3685 3686 E = SMLoc::getFromPointer(getLoc().getPointer() - 1); 3687 Operands.push_back(AArch64Operand::CreateImm(ImmVal, S, E, getContext())); 3688 return false; 3689 } 3690 case AsmToken::Equal: { 3691 SMLoc Loc = getLoc(); 3692 if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val) 3693 return TokError("unexpected token in operand"); 3694 Parser.Lex(); // Eat '=' 3695 const MCExpr *SubExprVal; 3696 if (getParser().parseExpression(SubExprVal)) 3697 return true; 3698 3699 if (Operands.size() < 2 || 3700 !static_cast<AArch64Operand &>(*Operands[1]).isScalarReg()) 3701 return Error(Loc, "Only valid when first operand is register"); 3702 3703 bool IsXReg = 3704 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( 3705 Operands[1]->getReg()); 3706 3707 MCContext& Ctx = getContext(); 3708 E = SMLoc::getFromPointer(Loc.getPointer() - 1); 3709 // If the op is an imm and can be fit into a mov, then replace ldr with mov. 3710 if (isa<MCConstantExpr>(SubExprVal)) { 3711 uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue(); 3712 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16; 3713 while(Imm > 0xFFFF && countTrailingZeros(Imm) >= 16) { 3714 ShiftAmt += 16; 3715 Imm >>= 16; 3716 } 3717 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) { 3718 Operands[0] = AArch64Operand::CreateToken("movz", false, Loc, Ctx); 3719 Operands.push_back(AArch64Operand::CreateImm( 3720 MCConstantExpr::create(Imm, Ctx), S, E, Ctx)); 3721 if (ShiftAmt) 3722 Operands.push_back(AArch64Operand::CreateShiftExtend(AArch64_AM::LSL, 3723 ShiftAmt, true, S, E, Ctx)); 3724 return false; 3725 } 3726 APInt Simm = APInt(64, Imm << ShiftAmt); 3727 // check if the immediate is an unsigned or signed 32-bit int for W regs 3728 if (!IsXReg && !(Simm.isIntN(32) || Simm.isSignedIntN(32))) 3729 return Error(Loc, "Immediate too large for register"); 3730 } 3731 // If it is a label or an imm that cannot fit in a movz, put it into CP. 3732 const MCExpr *CPLoc = 3733 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc); 3734 Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx)); 3735 return false; 3736 } 3737 } 3738 } 3739 3740 bool AArch64AsmParser::regsEqual(const MCParsedAsmOperand &Op1, 3741 const MCParsedAsmOperand &Op2) const { 3742 auto &AOp1 = static_cast<const AArch64Operand&>(Op1); 3743 auto &AOp2 = static_cast<const AArch64Operand&>(Op2); 3744 if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg && 3745 AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg) 3746 return MCTargetAsmParser::regsEqual(Op1, Op2); 3747 3748 assert(AOp1.isScalarReg() && AOp2.isScalarReg() && 3749 "Testing equality of non-scalar registers not supported"); 3750 3751 // Check if a registers match their sub/super register classes. 3752 if (AOp1.getRegEqualityTy() == EqualsSuperReg) 3753 return getXRegFromWReg(Op1.getReg()) == Op2.getReg(); 3754 if (AOp1.getRegEqualityTy() == EqualsSubReg) 3755 return getWRegFromXReg(Op1.getReg()) == Op2.getReg(); 3756 if (AOp2.getRegEqualityTy() == EqualsSuperReg) 3757 return getXRegFromWReg(Op2.getReg()) == Op1.getReg(); 3758 if (AOp2.getRegEqualityTy() == EqualsSubReg) 3759 return getWRegFromXReg(Op2.getReg()) == Op1.getReg(); 3760 3761 return false; 3762 } 3763 3764 /// ParseInstruction - Parse an AArch64 instruction mnemonic followed by its 3765 /// operands. 3766 bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info, 3767 StringRef Name, SMLoc NameLoc, 3768 OperandVector &Operands) { 3769 MCAsmParser &Parser = getParser(); 3770 Name = StringSwitch<StringRef>(Name.lower()) 3771 .Case("beq", "b.eq") 3772 .Case("bne", "b.ne") 3773 .Case("bhs", "b.hs") 3774 .Case("bcs", "b.cs") 3775 .Case("blo", "b.lo") 3776 .Case("bcc", "b.cc") 3777 .Case("bmi", "b.mi") 3778 .Case("bpl", "b.pl") 3779 .Case("bvs", "b.vs") 3780 .Case("bvc", "b.vc") 3781 .Case("bhi", "b.hi") 3782 .Case("bls", "b.ls") 3783 .Case("bge", "b.ge") 3784 .Case("blt", "b.lt") 3785 .Case("bgt", "b.gt") 3786 .Case("ble", "b.le") 3787 .Case("bal", "b.al") 3788 .Case("bnv", "b.nv") 3789 .Default(Name); 3790 3791 // First check for the AArch64-specific .req directive. 3792 if (Parser.getTok().is(AsmToken::Identifier) && 3793 Parser.getTok().getIdentifier().lower() == ".req") { 3794 parseDirectiveReq(Name, NameLoc); 3795 // We always return 'error' for this, as we're done with this 3796 // statement and don't need to match the 'instruction." 3797 return true; 3798 } 3799 3800 // Create the leading tokens for the mnemonic, split by '.' characters. 3801 size_t Start = 0, Next = Name.find('.'); 3802 StringRef Head = Name.slice(Start, Next); 3803 3804 // IC, DC, AT, TLBI and Prediction invalidation instructions are aliases for 3805 // the SYS instruction. 3806 if (Head == "ic" || Head == "dc" || Head == "at" || Head == "tlbi" || 3807 Head == "cfp" || Head == "dvp" || Head == "cpp") 3808 return parseSysAlias(Head, NameLoc, Operands); 3809 3810 Operands.push_back( 3811 AArch64Operand::CreateToken(Head, false, NameLoc, getContext())); 3812 Mnemonic = Head; 3813 3814 // Handle condition codes for a branch mnemonic 3815 if (Head == "b" && Next != StringRef::npos) { 3816 Start = Next; 3817 Next = Name.find('.', Start + 1); 3818 Head = Name.slice(Start + 1, Next); 3819 3820 SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() + 3821 (Head.data() - Name.data())); 3822 AArch64CC::CondCode CC = parseCondCodeString(Head); 3823 if (CC == AArch64CC::Invalid) 3824 return Error(SuffixLoc, "invalid condition code"); 3825 Operands.push_back( 3826 AArch64Operand::CreateToken(".", true, SuffixLoc, getContext())); 3827 Operands.push_back( 3828 AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc, getContext())); 3829 } 3830 3831 // Add the remaining tokens in the mnemonic. 3832 while (Next != StringRef::npos) { 3833 Start = Next; 3834 Next = Name.find('.', Start + 1); 3835 Head = Name.slice(Start, Next); 3836 SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() + 3837 (Head.data() - Name.data()) + 1); 3838 Operands.push_back( 3839 AArch64Operand::CreateToken(Head, true, SuffixLoc, getContext())); 3840 } 3841 3842 // Conditional compare instructions have a Condition Code operand, which needs 3843 // to be parsed and an immediate operand created. 3844 bool condCodeFourthOperand = 3845 (Head == "ccmp" || Head == "ccmn" || Head == "fccmp" || 3846 Head == "fccmpe" || Head == "fcsel" || Head == "csel" || 3847 Head == "csinc" || Head == "csinv" || Head == "csneg"); 3848 3849 // These instructions are aliases to some of the conditional select 3850 // instructions. However, the condition code is inverted in the aliased 3851 // instruction. 3852 // 3853 // FIXME: Is this the correct way to handle these? Or should the parser 3854 // generate the aliased instructions directly? 3855 bool condCodeSecondOperand = (Head == "cset" || Head == "csetm"); 3856 bool condCodeThirdOperand = 3857 (Head == "cinc" || Head == "cinv" || Head == "cneg"); 3858 3859 // Read the remaining operands. 3860 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3861 3862 unsigned N = 1; 3863 do { 3864 // Parse and remember the operand. 3865 if (parseOperand(Operands, (N == 4 && condCodeFourthOperand) || 3866 (N == 3 && condCodeThirdOperand) || 3867 (N == 2 && condCodeSecondOperand), 3868 condCodeSecondOperand || condCodeThirdOperand)) { 3869 return true; 3870 } 3871 3872 // After successfully parsing some operands there are two special cases to 3873 // consider (i.e. notional operands not separated by commas). Both are due 3874 // to memory specifiers: 3875 // + An RBrac will end an address for load/store/prefetch 3876 // + An '!' will indicate a pre-indexed operation. 3877 // 3878 // It's someone else's responsibility to make sure these tokens are sane 3879 // in the given context! 3880 3881 SMLoc RLoc = Parser.getTok().getLoc(); 3882 if (parseOptionalToken(AsmToken::RBrac)) 3883 Operands.push_back( 3884 AArch64Operand::CreateToken("]", false, RLoc, getContext())); 3885 SMLoc ELoc = Parser.getTok().getLoc(); 3886 if (parseOptionalToken(AsmToken::Exclaim)) 3887 Operands.push_back( 3888 AArch64Operand::CreateToken("!", false, ELoc, getContext())); 3889 3890 ++N; 3891 } while (parseOptionalToken(AsmToken::Comma)); 3892 } 3893 3894 if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list")) 3895 return true; 3896 3897 return false; 3898 } 3899 3900 static inline bool isMatchingOrAlias(unsigned ZReg, unsigned Reg) { 3901 assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31)); 3902 return (ZReg == ((Reg - AArch64::B0) + AArch64::Z0)) || 3903 (ZReg == ((Reg - AArch64::H0) + AArch64::Z0)) || 3904 (ZReg == ((Reg - AArch64::S0) + AArch64::Z0)) || 3905 (ZReg == ((Reg - AArch64::D0) + AArch64::Z0)) || 3906 (ZReg == ((Reg - AArch64::Q0) + AArch64::Z0)) || 3907 (ZReg == ((Reg - AArch64::Z0) + AArch64::Z0)); 3908 } 3909 3910 // FIXME: This entire function is a giant hack to provide us with decent 3911 // operand range validation/diagnostics until TableGen/MC can be extended 3912 // to support autogeneration of this kind of validation. 3913 bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc, 3914 SmallVectorImpl<SMLoc> &Loc) { 3915 const MCRegisterInfo *RI = getContext().getRegisterInfo(); 3916 const MCInstrDesc &MCID = MII.get(Inst.getOpcode()); 3917 3918 // A prefix only applies to the instruction following it. Here we extract 3919 // prefix information for the next instruction before validating the current 3920 // one so that in the case of failure we don't erronously continue using the 3921 // current prefix. 3922 PrefixInfo Prefix = NextPrefix; 3923 NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.TSFlags); 3924 3925 // Before validating the instruction in isolation we run through the rules 3926 // applicable when it follows a prefix instruction. 3927 // NOTE: brk & hlt can be prefixed but require no additional validation. 3928 if (Prefix.isActive() && 3929 (Inst.getOpcode() != AArch64::BRK) && 3930 (Inst.getOpcode() != AArch64::HLT)) { 3931 3932 // Prefixed intructions must have a destructive operand. 3933 if ((MCID.TSFlags & AArch64::DestructiveInstTypeMask) == 3934 AArch64::NotDestructive) 3935 return Error(IDLoc, "instruction is unpredictable when following a" 3936 " movprfx, suggest replacing movprfx with mov"); 3937 3938 // Destination operands must match. 3939 if (Inst.getOperand(0).getReg() != Prefix.getDstReg()) 3940 return Error(Loc[0], "instruction is unpredictable when following a" 3941 " movprfx writing to a different destination"); 3942 3943 // Destination operand must not be used in any other location. 3944 for (unsigned i = 1; i < Inst.getNumOperands(); ++i) { 3945 if (Inst.getOperand(i).isReg() && 3946 (MCID.getOperandConstraint(i, MCOI::TIED_TO) == -1) && 3947 isMatchingOrAlias(Prefix.getDstReg(), Inst.getOperand(i).getReg())) 3948 return Error(Loc[0], "instruction is unpredictable when following a" 3949 " movprfx and destination also used as non-destructive" 3950 " source"); 3951 } 3952 3953 auto PPRRegClass = AArch64MCRegisterClasses[AArch64::PPRRegClassID]; 3954 if (Prefix.isPredicated()) { 3955 int PgIdx = -1; 3956 3957 // Find the instructions general predicate. 3958 for (unsigned i = 1; i < Inst.getNumOperands(); ++i) 3959 if (Inst.getOperand(i).isReg() && 3960 PPRRegClass.contains(Inst.getOperand(i).getReg())) { 3961 PgIdx = i; 3962 break; 3963 } 3964 3965 // Instruction must be predicated if the movprfx is predicated. 3966 if (PgIdx == -1 || 3967 (MCID.TSFlags & AArch64::ElementSizeMask) == AArch64::ElementSizeNone) 3968 return Error(IDLoc, "instruction is unpredictable when following a" 3969 " predicated movprfx, suggest using unpredicated movprfx"); 3970 3971 // Instruction must use same general predicate as the movprfx. 3972 if (Inst.getOperand(PgIdx).getReg() != Prefix.getPgReg()) 3973 return Error(IDLoc, "instruction is unpredictable when following a" 3974 " predicated movprfx using a different general predicate"); 3975 3976 // Instruction element type must match the movprfx. 3977 if ((MCID.TSFlags & AArch64::ElementSizeMask) != Prefix.getElementSize()) 3978 return Error(IDLoc, "instruction is unpredictable when following a" 3979 " predicated movprfx with a different element size"); 3980 } 3981 } 3982 3983 // Check for indexed addressing modes w/ the base register being the 3984 // same as a destination/source register or pair load where 3985 // the Rt == Rt2. All of those are undefined behaviour. 3986 switch (Inst.getOpcode()) { 3987 case AArch64::LDPSWpre: 3988 case AArch64::LDPWpost: 3989 case AArch64::LDPWpre: 3990 case AArch64::LDPXpost: 3991 case AArch64::LDPXpre: { 3992 unsigned Rt = Inst.getOperand(1).getReg(); 3993 unsigned Rt2 = Inst.getOperand(2).getReg(); 3994 unsigned Rn = Inst.getOperand(3).getReg(); 3995 if (RI->isSubRegisterEq(Rn, Rt)) 3996 return Error(Loc[0], "unpredictable LDP instruction, writeback base " 3997 "is also a destination"); 3998 if (RI->isSubRegisterEq(Rn, Rt2)) 3999 return Error(Loc[1], "unpredictable LDP instruction, writeback base " 4000 "is also a destination"); 4001 LLVM_FALLTHROUGH; 4002 } 4003 case AArch64::LDPDi: 4004 case AArch64::LDPQi: 4005 case AArch64::LDPSi: 4006 case AArch64::LDPSWi: 4007 case AArch64::LDPWi: 4008 case AArch64::LDPXi: { 4009 unsigned Rt = Inst.getOperand(0).getReg(); 4010 unsigned Rt2 = Inst.getOperand(1).getReg(); 4011 if (Rt == Rt2) 4012 return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt"); 4013 break; 4014 } 4015 case AArch64::LDPDpost: 4016 case AArch64::LDPDpre: 4017 case AArch64::LDPQpost: 4018 case AArch64::LDPQpre: 4019 case AArch64::LDPSpost: 4020 case AArch64::LDPSpre: 4021 case AArch64::LDPSWpost: { 4022 unsigned Rt = Inst.getOperand(1).getReg(); 4023 unsigned Rt2 = Inst.getOperand(2).getReg(); 4024 if (Rt == Rt2) 4025 return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt"); 4026 break; 4027 } 4028 case AArch64::STPDpost: 4029 case AArch64::STPDpre: 4030 case AArch64::STPQpost: 4031 case AArch64::STPQpre: 4032 case AArch64::STPSpost: 4033 case AArch64::STPSpre: 4034 case AArch64::STPWpost: 4035 case AArch64::STPWpre: 4036 case AArch64::STPXpost: 4037 case AArch64::STPXpre: { 4038 unsigned Rt = Inst.getOperand(1).getReg(); 4039 unsigned Rt2 = Inst.getOperand(2).getReg(); 4040 unsigned Rn = Inst.getOperand(3).getReg(); 4041 if (RI->isSubRegisterEq(Rn, Rt)) 4042 return Error(Loc[0], "unpredictable STP instruction, writeback base " 4043 "is also a source"); 4044 if (RI->isSubRegisterEq(Rn, Rt2)) 4045 return Error(Loc[1], "unpredictable STP instruction, writeback base " 4046 "is also a source"); 4047 break; 4048 } 4049 case AArch64::LDRBBpre: 4050 case AArch64::LDRBpre: 4051 case AArch64::LDRHHpre: 4052 case AArch64::LDRHpre: 4053 case AArch64::LDRSBWpre: 4054 case AArch64::LDRSBXpre: 4055 case AArch64::LDRSHWpre: 4056 case AArch64::LDRSHXpre: 4057 case AArch64::LDRSWpre: 4058 case AArch64::LDRWpre: 4059 case AArch64::LDRXpre: 4060 case AArch64::LDRBBpost: 4061 case AArch64::LDRBpost: 4062 case AArch64::LDRHHpost: 4063 case AArch64::LDRHpost: 4064 case AArch64::LDRSBWpost: 4065 case AArch64::LDRSBXpost: 4066 case AArch64::LDRSHWpost: 4067 case AArch64::LDRSHXpost: 4068 case AArch64::LDRSWpost: 4069 case AArch64::LDRWpost: 4070 case AArch64::LDRXpost: { 4071 unsigned Rt = Inst.getOperand(1).getReg(); 4072 unsigned Rn = Inst.getOperand(2).getReg(); 4073 if (RI->isSubRegisterEq(Rn, Rt)) 4074 return Error(Loc[0], "unpredictable LDR instruction, writeback base " 4075 "is also a source"); 4076 break; 4077 } 4078 case AArch64::STRBBpost: 4079 case AArch64::STRBpost: 4080 case AArch64::STRHHpost: 4081 case AArch64::STRHpost: 4082 case AArch64::STRWpost: 4083 case AArch64::STRXpost: 4084 case AArch64::STRBBpre: 4085 case AArch64::STRBpre: 4086 case AArch64::STRHHpre: 4087 case AArch64::STRHpre: 4088 case AArch64::STRWpre: 4089 case AArch64::STRXpre: { 4090 unsigned Rt = Inst.getOperand(1).getReg(); 4091 unsigned Rn = Inst.getOperand(2).getReg(); 4092 if (RI->isSubRegisterEq(Rn, Rt)) 4093 return Error(Loc[0], "unpredictable STR instruction, writeback base " 4094 "is also a source"); 4095 break; 4096 } 4097 case AArch64::STXRB: 4098 case AArch64::STXRH: 4099 case AArch64::STXRW: 4100 case AArch64::STXRX: 4101 case AArch64::STLXRB: 4102 case AArch64::STLXRH: 4103 case AArch64::STLXRW: 4104 case AArch64::STLXRX: { 4105 unsigned Rs = Inst.getOperand(0).getReg(); 4106 unsigned Rt = Inst.getOperand(1).getReg(); 4107 unsigned Rn = Inst.getOperand(2).getReg(); 4108 if (RI->isSubRegisterEq(Rt, Rs) || 4109 (RI->isSubRegisterEq(Rn, Rs) && Rn != AArch64::SP)) 4110 return Error(Loc[0], 4111 "unpredictable STXR instruction, status is also a source"); 4112 break; 4113 } 4114 case AArch64::STXPW: 4115 case AArch64::STXPX: 4116 case AArch64::STLXPW: 4117 case AArch64::STLXPX: { 4118 unsigned Rs = Inst.getOperand(0).getReg(); 4119 unsigned Rt1 = Inst.getOperand(1).getReg(); 4120 unsigned Rt2 = Inst.getOperand(2).getReg(); 4121 unsigned Rn = Inst.getOperand(3).getReg(); 4122 if (RI->isSubRegisterEq(Rt1, Rs) || RI->isSubRegisterEq(Rt2, Rs) || 4123 (RI->isSubRegisterEq(Rn, Rs) && Rn != AArch64::SP)) 4124 return Error(Loc[0], 4125 "unpredictable STXP instruction, status is also a source"); 4126 break; 4127 } 4128 case AArch64::LDRABwriteback: 4129 case AArch64::LDRAAwriteback: { 4130 unsigned Xt = Inst.getOperand(0).getReg(); 4131 unsigned Xn = Inst.getOperand(1).getReg(); 4132 if (Xt == Xn) 4133 return Error(Loc[0], 4134 "unpredictable LDRA instruction, writeback base" 4135 " is also a destination"); 4136 break; 4137 } 4138 } 4139 4140 4141 // Now check immediate ranges. Separate from the above as there is overlap 4142 // in the instructions being checked and this keeps the nested conditionals 4143 // to a minimum. 4144 switch (Inst.getOpcode()) { 4145 case AArch64::ADDSWri: 4146 case AArch64::ADDSXri: 4147 case AArch64::ADDWri: 4148 case AArch64::ADDXri: 4149 case AArch64::SUBSWri: 4150 case AArch64::SUBSXri: 4151 case AArch64::SUBWri: 4152 case AArch64::SUBXri: { 4153 // Annoyingly we can't do this in the isAddSubImm predicate, so there is 4154 // some slight duplication here. 4155 if (Inst.getOperand(2).isExpr()) { 4156 const MCExpr *Expr = Inst.getOperand(2).getExpr(); 4157 AArch64MCExpr::VariantKind ELFRefKind; 4158 MCSymbolRefExpr::VariantKind DarwinRefKind; 4159 int64_t Addend; 4160 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) { 4161 4162 // Only allow these with ADDXri. 4163 if ((DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF || 4164 DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) && 4165 Inst.getOpcode() == AArch64::ADDXri) 4166 return false; 4167 4168 // Only allow these with ADDXri/ADDWri 4169 if ((ELFRefKind == AArch64MCExpr::VK_LO12 || 4170 ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 || 4171 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 || 4172 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC || 4173 ELFRefKind == AArch64MCExpr::VK_TPREL_HI12 || 4174 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 || 4175 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC || 4176 ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12 || 4177 ELFRefKind == AArch64MCExpr::VK_SECREL_LO12 || 4178 ELFRefKind == AArch64MCExpr::VK_SECREL_HI12) && 4179 (Inst.getOpcode() == AArch64::ADDXri || 4180 Inst.getOpcode() == AArch64::ADDWri)) 4181 return false; 4182 4183 // Don't allow symbol refs in the immediate field otherwise 4184 // Note: Loc.back() may be Loc[1] or Loc[2] depending on the number of 4185 // operands of the original instruction (i.e. 'add w0, w1, borked' vs 4186 // 'cmp w0, 'borked') 4187 return Error(Loc.back(), "invalid immediate expression"); 4188 } 4189 // We don't validate more complex expressions here 4190 } 4191 return false; 4192 } 4193 default: 4194 return false; 4195 } 4196 } 4197 4198 static std::string AArch64MnemonicSpellCheck(StringRef S, 4199 const FeatureBitset &FBS, 4200 unsigned VariantID = 0); 4201 4202 bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode, 4203 uint64_t ErrorInfo, 4204 OperandVector &Operands) { 4205 switch (ErrCode) { 4206 case Match_InvalidTiedOperand: { 4207 RegConstraintEqualityTy EqTy = 4208 static_cast<const AArch64Operand &>(*Operands[ErrorInfo]) 4209 .getRegEqualityTy(); 4210 switch (EqTy) { 4211 case RegConstraintEqualityTy::EqualsSubReg: 4212 return Error(Loc, "operand must be 64-bit form of destination register"); 4213 case RegConstraintEqualityTy::EqualsSuperReg: 4214 return Error(Loc, "operand must be 32-bit form of destination register"); 4215 case RegConstraintEqualityTy::EqualsReg: 4216 return Error(Loc, "operand must match destination register"); 4217 } 4218 llvm_unreachable("Unknown RegConstraintEqualityTy"); 4219 } 4220 case Match_MissingFeature: 4221 return Error(Loc, 4222 "instruction requires a CPU feature not currently enabled"); 4223 case Match_InvalidOperand: 4224 return Error(Loc, "invalid operand for instruction"); 4225 case Match_InvalidSuffix: 4226 return Error(Loc, "invalid type suffix for instruction"); 4227 case Match_InvalidCondCode: 4228 return Error(Loc, "expected AArch64 condition code"); 4229 case Match_AddSubRegExtendSmall: 4230 return Error(Loc, 4231 "expected '[su]xt[bhw]' with optional integer in range [0, 4]"); 4232 case Match_AddSubRegExtendLarge: 4233 return Error(Loc, 4234 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]"); 4235 case Match_AddSubSecondSource: 4236 return Error(Loc, 4237 "expected compatible register, symbol or integer in range [0, 4095]"); 4238 case Match_LogicalSecondSource: 4239 return Error(Loc, "expected compatible register or logical immediate"); 4240 case Match_InvalidMovImm32Shift: 4241 return Error(Loc, "expected 'lsl' with optional integer 0 or 16"); 4242 case Match_InvalidMovImm64Shift: 4243 return Error(Loc, "expected 'lsl' with optional integer 0, 16, 32 or 48"); 4244 case Match_AddSubRegShift32: 4245 return Error(Loc, 4246 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]"); 4247 case Match_AddSubRegShift64: 4248 return Error(Loc, 4249 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]"); 4250 case Match_InvalidFPImm: 4251 return Error(Loc, 4252 "expected compatible register or floating-point constant"); 4253 case Match_InvalidMemoryIndexedSImm6: 4254 return Error(Loc, "index must be an integer in range [-32, 31]."); 4255 case Match_InvalidMemoryIndexedSImm5: 4256 return Error(Loc, "index must be an integer in range [-16, 15]."); 4257 case Match_InvalidMemoryIndexed1SImm4: 4258 return Error(Loc, "index must be an integer in range [-8, 7]."); 4259 case Match_InvalidMemoryIndexed2SImm4: 4260 return Error(Loc, "index must be a multiple of 2 in range [-16, 14]."); 4261 case Match_InvalidMemoryIndexed3SImm4: 4262 return Error(Loc, "index must be a multiple of 3 in range [-24, 21]."); 4263 case Match_InvalidMemoryIndexed4SImm4: 4264 return Error(Loc, "index must be a multiple of 4 in range [-32, 28]."); 4265 case Match_InvalidMemoryIndexed16SImm4: 4266 return Error(Loc, "index must be a multiple of 16 in range [-128, 112]."); 4267 case Match_InvalidMemoryIndexed32SImm4: 4268 return Error(Loc, "index must be a multiple of 32 in range [-256, 224]."); 4269 case Match_InvalidMemoryIndexed1SImm6: 4270 return Error(Loc, "index must be an integer in range [-32, 31]."); 4271 case Match_InvalidMemoryIndexedSImm8: 4272 return Error(Loc, "index must be an integer in range [-128, 127]."); 4273 case Match_InvalidMemoryIndexedSImm9: 4274 return Error(Loc, "index must be an integer in range [-256, 255]."); 4275 case Match_InvalidMemoryIndexed16SImm9: 4276 return Error(Loc, "index must be a multiple of 16 in range [-4096, 4080]."); 4277 case Match_InvalidMemoryIndexed8SImm10: 4278 return Error(Loc, "index must be a multiple of 8 in range [-4096, 4088]."); 4279 case Match_InvalidMemoryIndexed4SImm7: 4280 return Error(Loc, "index must be a multiple of 4 in range [-256, 252]."); 4281 case Match_InvalidMemoryIndexed8SImm7: 4282 return Error(Loc, "index must be a multiple of 8 in range [-512, 504]."); 4283 case Match_InvalidMemoryIndexed16SImm7: 4284 return Error(Loc, "index must be a multiple of 16 in range [-1024, 1008]."); 4285 case Match_InvalidMemoryIndexed8UImm5: 4286 return Error(Loc, "index must be a multiple of 8 in range [0, 248]."); 4287 case Match_InvalidMemoryIndexed4UImm5: 4288 return Error(Loc, "index must be a multiple of 4 in range [0, 124]."); 4289 case Match_InvalidMemoryIndexed2UImm5: 4290 return Error(Loc, "index must be a multiple of 2 in range [0, 62]."); 4291 case Match_InvalidMemoryIndexed8UImm6: 4292 return Error(Loc, "index must be a multiple of 8 in range [0, 504]."); 4293 case Match_InvalidMemoryIndexed16UImm6: 4294 return Error(Loc, "index must be a multiple of 16 in range [0, 1008]."); 4295 case Match_InvalidMemoryIndexed4UImm6: 4296 return Error(Loc, "index must be a multiple of 4 in range [0, 252]."); 4297 case Match_InvalidMemoryIndexed2UImm6: 4298 return Error(Loc, "index must be a multiple of 2 in range [0, 126]."); 4299 case Match_InvalidMemoryIndexed1UImm6: 4300 return Error(Loc, "index must be in range [0, 63]."); 4301 case Match_InvalidMemoryWExtend8: 4302 return Error(Loc, 4303 "expected 'uxtw' or 'sxtw' with optional shift of #0"); 4304 case Match_InvalidMemoryWExtend16: 4305 return Error(Loc, 4306 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1"); 4307 case Match_InvalidMemoryWExtend32: 4308 return Error(Loc, 4309 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2"); 4310 case Match_InvalidMemoryWExtend64: 4311 return Error(Loc, 4312 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3"); 4313 case Match_InvalidMemoryWExtend128: 4314 return Error(Loc, 4315 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4"); 4316 case Match_InvalidMemoryXExtend8: 4317 return Error(Loc, 4318 "expected 'lsl' or 'sxtx' with optional shift of #0"); 4319 case Match_InvalidMemoryXExtend16: 4320 return Error(Loc, 4321 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1"); 4322 case Match_InvalidMemoryXExtend32: 4323 return Error(Loc, 4324 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2"); 4325 case Match_InvalidMemoryXExtend64: 4326 return Error(Loc, 4327 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3"); 4328 case Match_InvalidMemoryXExtend128: 4329 return Error(Loc, 4330 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4"); 4331 case Match_InvalidMemoryIndexed1: 4332 return Error(Loc, "index must be an integer in range [0, 4095]."); 4333 case Match_InvalidMemoryIndexed2: 4334 return Error(Loc, "index must be a multiple of 2 in range [0, 8190]."); 4335 case Match_InvalidMemoryIndexed4: 4336 return Error(Loc, "index must be a multiple of 4 in range [0, 16380]."); 4337 case Match_InvalidMemoryIndexed8: 4338 return Error(Loc, "index must be a multiple of 8 in range [0, 32760]."); 4339 case Match_InvalidMemoryIndexed16: 4340 return Error(Loc, "index must be a multiple of 16 in range [0, 65520]."); 4341 case Match_InvalidImm0_1: 4342 return Error(Loc, "immediate must be an integer in range [0, 1]."); 4343 case Match_InvalidImm0_7: 4344 return Error(Loc, "immediate must be an integer in range [0, 7]."); 4345 case Match_InvalidImm0_15: 4346 return Error(Loc, "immediate must be an integer in range [0, 15]."); 4347 case Match_InvalidImm0_31: 4348 return Error(Loc, "immediate must be an integer in range [0, 31]."); 4349 case Match_InvalidImm0_63: 4350 return Error(Loc, "immediate must be an integer in range [0, 63]."); 4351 case Match_InvalidImm0_127: 4352 return Error(Loc, "immediate must be an integer in range [0, 127]."); 4353 case Match_InvalidImm0_255: 4354 return Error(Loc, "immediate must be an integer in range [0, 255]."); 4355 case Match_InvalidImm0_65535: 4356 return Error(Loc, "immediate must be an integer in range [0, 65535]."); 4357 case Match_InvalidImm1_8: 4358 return Error(Loc, "immediate must be an integer in range [1, 8]."); 4359 case Match_InvalidImm1_16: 4360 return Error(Loc, "immediate must be an integer in range [1, 16]."); 4361 case Match_InvalidImm1_32: 4362 return Error(Loc, "immediate must be an integer in range [1, 32]."); 4363 case Match_InvalidImm1_64: 4364 return Error(Loc, "immediate must be an integer in range [1, 64]."); 4365 case Match_InvalidSVEAddSubImm8: 4366 return Error(Loc, "immediate must be an integer in range [0, 255]" 4367 " with a shift amount of 0"); 4368 case Match_InvalidSVEAddSubImm16: 4369 case Match_InvalidSVEAddSubImm32: 4370 case Match_InvalidSVEAddSubImm64: 4371 return Error(Loc, "immediate must be an integer in range [0, 255] or a " 4372 "multiple of 256 in range [256, 65280]"); 4373 case Match_InvalidSVECpyImm8: 4374 return Error(Loc, "immediate must be an integer in range [-128, 255]" 4375 " with a shift amount of 0"); 4376 case Match_InvalidSVECpyImm16: 4377 return Error(Loc, "immediate must be an integer in range [-128, 127] or a " 4378 "multiple of 256 in range [-32768, 65280]"); 4379 case Match_InvalidSVECpyImm32: 4380 case Match_InvalidSVECpyImm64: 4381 return Error(Loc, "immediate must be an integer in range [-128, 127] or a " 4382 "multiple of 256 in range [-32768, 32512]"); 4383 case Match_InvalidIndexRange1_1: 4384 return Error(Loc, "expected lane specifier '[1]'"); 4385 case Match_InvalidIndexRange0_15: 4386 return Error(Loc, "vector lane must be an integer in range [0, 15]."); 4387 case Match_InvalidIndexRange0_7: 4388 return Error(Loc, "vector lane must be an integer in range [0, 7]."); 4389 case Match_InvalidIndexRange0_3: 4390 return Error(Loc, "vector lane must be an integer in range [0, 3]."); 4391 case Match_InvalidIndexRange0_1: 4392 return Error(Loc, "vector lane must be an integer in range [0, 1]."); 4393 case Match_InvalidSVEIndexRange0_63: 4394 return Error(Loc, "vector lane must be an integer in range [0, 63]."); 4395 case Match_InvalidSVEIndexRange0_31: 4396 return Error(Loc, "vector lane must be an integer in range [0, 31]."); 4397 case Match_InvalidSVEIndexRange0_15: 4398 return Error(Loc, "vector lane must be an integer in range [0, 15]."); 4399 case Match_InvalidSVEIndexRange0_7: 4400 return Error(Loc, "vector lane must be an integer in range [0, 7]."); 4401 case Match_InvalidSVEIndexRange0_3: 4402 return Error(Loc, "vector lane must be an integer in range [0, 3]."); 4403 case Match_InvalidLabel: 4404 return Error(Loc, "expected label or encodable integer pc offset"); 4405 case Match_MRS: 4406 return Error(Loc, "expected readable system register"); 4407 case Match_MSR: 4408 return Error(Loc, "expected writable system register or pstate"); 4409 case Match_InvalidComplexRotationEven: 4410 return Error(Loc, "complex rotation must be 0, 90, 180 or 270."); 4411 case Match_InvalidComplexRotationOdd: 4412 return Error(Loc, "complex rotation must be 90 or 270."); 4413 case Match_MnemonicFail: { 4414 std::string Suggestion = AArch64MnemonicSpellCheck( 4415 ((AArch64Operand &)*Operands[0]).getToken(), 4416 ComputeAvailableFeatures(STI->getFeatureBits())); 4417 return Error(Loc, "unrecognized instruction mnemonic" + Suggestion); 4418 } 4419 case Match_InvalidGPR64shifted8: 4420 return Error(Loc, "register must be x0..x30 or xzr, without shift"); 4421 case Match_InvalidGPR64shifted16: 4422 return Error(Loc, "register must be x0..x30 or xzr, with required shift 'lsl #1'"); 4423 case Match_InvalidGPR64shifted32: 4424 return Error(Loc, "register must be x0..x30 or xzr, with required shift 'lsl #2'"); 4425 case Match_InvalidGPR64shifted64: 4426 return Error(Loc, "register must be x0..x30 or xzr, with required shift 'lsl #3'"); 4427 case Match_InvalidGPR64NoXZRshifted8: 4428 return Error(Loc, "register must be x0..x30 without shift"); 4429 case Match_InvalidGPR64NoXZRshifted16: 4430 return Error(Loc, "register must be x0..x30 with required shift 'lsl #1'"); 4431 case Match_InvalidGPR64NoXZRshifted32: 4432 return Error(Loc, "register must be x0..x30 with required shift 'lsl #2'"); 4433 case Match_InvalidGPR64NoXZRshifted64: 4434 return Error(Loc, "register must be x0..x30 with required shift 'lsl #3'"); 4435 case Match_InvalidZPR32UXTW8: 4436 case Match_InvalidZPR32SXTW8: 4437 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'"); 4438 case Match_InvalidZPR32UXTW16: 4439 case Match_InvalidZPR32SXTW16: 4440 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'"); 4441 case Match_InvalidZPR32UXTW32: 4442 case Match_InvalidZPR32SXTW32: 4443 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'"); 4444 case Match_InvalidZPR32UXTW64: 4445 case Match_InvalidZPR32SXTW64: 4446 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'"); 4447 case Match_InvalidZPR64UXTW8: 4448 case Match_InvalidZPR64SXTW8: 4449 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'"); 4450 case Match_InvalidZPR64UXTW16: 4451 case Match_InvalidZPR64SXTW16: 4452 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'"); 4453 case Match_InvalidZPR64UXTW32: 4454 case Match_InvalidZPR64SXTW32: 4455 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'"); 4456 case Match_InvalidZPR64UXTW64: 4457 case Match_InvalidZPR64SXTW64: 4458 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'"); 4459 case Match_InvalidZPR32LSL8: 4460 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s'"); 4461 case Match_InvalidZPR32LSL16: 4462 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, lsl #1'"); 4463 case Match_InvalidZPR32LSL32: 4464 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, lsl #2'"); 4465 case Match_InvalidZPR32LSL64: 4466 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, lsl #3'"); 4467 case Match_InvalidZPR64LSL8: 4468 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d'"); 4469 case Match_InvalidZPR64LSL16: 4470 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, lsl #1'"); 4471 case Match_InvalidZPR64LSL32: 4472 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, lsl #2'"); 4473 case Match_InvalidZPR64LSL64: 4474 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, lsl #3'"); 4475 case Match_InvalidZPR0: 4476 return Error(Loc, "expected register without element width suffix"); 4477 case Match_InvalidZPR8: 4478 case Match_InvalidZPR16: 4479 case Match_InvalidZPR32: 4480 case Match_InvalidZPR64: 4481 case Match_InvalidZPR128: 4482 return Error(Loc, "invalid element width"); 4483 case Match_InvalidZPR_3b8: 4484 return Error(Loc, "Invalid restricted vector register, expected z0.b..z7.b"); 4485 case Match_InvalidZPR_3b16: 4486 return Error(Loc, "Invalid restricted vector register, expected z0.h..z7.h"); 4487 case Match_InvalidZPR_3b32: 4488 return Error(Loc, "Invalid restricted vector register, expected z0.s..z7.s"); 4489 case Match_InvalidZPR_4b16: 4490 return Error(Loc, "Invalid restricted vector register, expected z0.h..z15.h"); 4491 case Match_InvalidZPR_4b32: 4492 return Error(Loc, "Invalid restricted vector register, expected z0.s..z15.s"); 4493 case Match_InvalidZPR_4b64: 4494 return Error(Loc, "Invalid restricted vector register, expected z0.d..z15.d"); 4495 case Match_InvalidSVEPattern: 4496 return Error(Loc, "invalid predicate pattern"); 4497 case Match_InvalidSVEPredicateAnyReg: 4498 case Match_InvalidSVEPredicateBReg: 4499 case Match_InvalidSVEPredicateHReg: 4500 case Match_InvalidSVEPredicateSReg: 4501 case Match_InvalidSVEPredicateDReg: 4502 return Error(Loc, "invalid predicate register."); 4503 case Match_InvalidSVEPredicate3bAnyReg: 4504 return Error(Loc, "invalid restricted predicate register, expected p0..p7 (without element suffix)"); 4505 case Match_InvalidSVEPredicate3bBReg: 4506 return Error(Loc, "invalid restricted predicate register, expected p0.b..p7.b"); 4507 case Match_InvalidSVEPredicate3bHReg: 4508 return Error(Loc, "invalid restricted predicate register, expected p0.h..p7.h"); 4509 case Match_InvalidSVEPredicate3bSReg: 4510 return Error(Loc, "invalid restricted predicate register, expected p0.s..p7.s"); 4511 case Match_InvalidSVEPredicate3bDReg: 4512 return Error(Loc, "invalid restricted predicate register, expected p0.d..p7.d"); 4513 case Match_InvalidSVEExactFPImmOperandHalfOne: 4514 return Error(Loc, "Invalid floating point constant, expected 0.5 or 1.0."); 4515 case Match_InvalidSVEExactFPImmOperandHalfTwo: 4516 return Error(Loc, "Invalid floating point constant, expected 0.5 or 2.0."); 4517 case Match_InvalidSVEExactFPImmOperandZeroOne: 4518 return Error(Loc, "Invalid floating point constant, expected 0.0 or 1.0."); 4519 default: 4520 llvm_unreachable("unexpected error code!"); 4521 } 4522 } 4523 4524 static const char *getSubtargetFeatureName(uint64_t Val); 4525 4526 bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 4527 OperandVector &Operands, 4528 MCStreamer &Out, 4529 uint64_t &ErrorInfo, 4530 bool MatchingInlineAsm) { 4531 assert(!Operands.empty() && "Unexpect empty operand list!"); 4532 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[0]); 4533 assert(Op.isToken() && "Leading operand should always be a mnemonic!"); 4534 4535 StringRef Tok = Op.getToken(); 4536 unsigned NumOperands = Operands.size(); 4537 4538 if (NumOperands == 4 && Tok == "lsl") { 4539 AArch64Operand &Op2 = static_cast<AArch64Operand &>(*Operands[2]); 4540 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]); 4541 if (Op2.isScalarReg() && Op3.isImm()) { 4542 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm()); 4543 if (Op3CE) { 4544 uint64_t Op3Val = Op3CE->getValue(); 4545 uint64_t NewOp3Val = 0; 4546 uint64_t NewOp4Val = 0; 4547 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].contains( 4548 Op2.getReg())) { 4549 NewOp3Val = (32 - Op3Val) & 0x1f; 4550 NewOp4Val = 31 - Op3Val; 4551 } else { 4552 NewOp3Val = (64 - Op3Val) & 0x3f; 4553 NewOp4Val = 63 - Op3Val; 4554 } 4555 4556 const MCExpr *NewOp3 = MCConstantExpr::create(NewOp3Val, getContext()); 4557 const MCExpr *NewOp4 = MCConstantExpr::create(NewOp4Val, getContext()); 4558 4559 Operands[0] = AArch64Operand::CreateToken( 4560 "ubfm", false, Op.getStartLoc(), getContext()); 4561 Operands.push_back(AArch64Operand::CreateImm( 4562 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext())); 4563 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(), 4564 Op3.getEndLoc(), getContext()); 4565 } 4566 } 4567 } else if (NumOperands == 4 && Tok == "bfc") { 4568 // FIXME: Horrible hack to handle BFC->BFM alias. 4569 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]); 4570 AArch64Operand LSBOp = static_cast<AArch64Operand &>(*Operands[2]); 4571 AArch64Operand WidthOp = static_cast<AArch64Operand &>(*Operands[3]); 4572 4573 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) { 4574 const MCConstantExpr *LSBCE = dyn_cast<MCConstantExpr>(LSBOp.getImm()); 4575 const MCConstantExpr *WidthCE = dyn_cast<MCConstantExpr>(WidthOp.getImm()); 4576 4577 if (LSBCE && WidthCE) { 4578 uint64_t LSB = LSBCE->getValue(); 4579 uint64_t Width = WidthCE->getValue(); 4580 4581 uint64_t RegWidth = 0; 4582 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( 4583 Op1.getReg())) 4584 RegWidth = 64; 4585 else 4586 RegWidth = 32; 4587 4588 if (LSB >= RegWidth) 4589 return Error(LSBOp.getStartLoc(), 4590 "expected integer in range [0, 31]"); 4591 if (Width < 1 || Width > RegWidth) 4592 return Error(WidthOp.getStartLoc(), 4593 "expected integer in range [1, 32]"); 4594 4595 uint64_t ImmR = 0; 4596 if (RegWidth == 32) 4597 ImmR = (32 - LSB) & 0x1f; 4598 else 4599 ImmR = (64 - LSB) & 0x3f; 4600 4601 uint64_t ImmS = Width - 1; 4602 4603 if (ImmR != 0 && ImmS >= ImmR) 4604 return Error(WidthOp.getStartLoc(), 4605 "requested insert overflows register"); 4606 4607 const MCExpr *ImmRExpr = MCConstantExpr::create(ImmR, getContext()); 4608 const MCExpr *ImmSExpr = MCConstantExpr::create(ImmS, getContext()); 4609 Operands[0] = AArch64Operand::CreateToken( 4610 "bfm", false, Op.getStartLoc(), getContext()); 4611 Operands[2] = AArch64Operand::CreateReg( 4612 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar, 4613 SMLoc(), SMLoc(), getContext()); 4614 Operands[3] = AArch64Operand::CreateImm( 4615 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(), getContext()); 4616 Operands.emplace_back( 4617 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(), 4618 WidthOp.getEndLoc(), getContext())); 4619 } 4620 } 4621 } else if (NumOperands == 5) { 4622 // FIXME: Horrible hack to handle the BFI -> BFM, SBFIZ->SBFM, and 4623 // UBFIZ -> UBFM aliases. 4624 if (Tok == "bfi" || Tok == "sbfiz" || Tok == "ubfiz") { 4625 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]); 4626 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]); 4627 AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]); 4628 4629 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) { 4630 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm()); 4631 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm()); 4632 4633 if (Op3CE && Op4CE) { 4634 uint64_t Op3Val = Op3CE->getValue(); 4635 uint64_t Op4Val = Op4CE->getValue(); 4636 4637 uint64_t RegWidth = 0; 4638 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( 4639 Op1.getReg())) 4640 RegWidth = 64; 4641 else 4642 RegWidth = 32; 4643 4644 if (Op3Val >= RegWidth) 4645 return Error(Op3.getStartLoc(), 4646 "expected integer in range [0, 31]"); 4647 if (Op4Val < 1 || Op4Val > RegWidth) 4648 return Error(Op4.getStartLoc(), 4649 "expected integer in range [1, 32]"); 4650 4651 uint64_t NewOp3Val = 0; 4652 if (RegWidth == 32) 4653 NewOp3Val = (32 - Op3Val) & 0x1f; 4654 else 4655 NewOp3Val = (64 - Op3Val) & 0x3f; 4656 4657 uint64_t NewOp4Val = Op4Val - 1; 4658 4659 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val) 4660 return Error(Op4.getStartLoc(), 4661 "requested insert overflows register"); 4662 4663 const MCExpr *NewOp3 = 4664 MCConstantExpr::create(NewOp3Val, getContext()); 4665 const MCExpr *NewOp4 = 4666 MCConstantExpr::create(NewOp4Val, getContext()); 4667 Operands[3] = AArch64Operand::CreateImm( 4668 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext()); 4669 Operands[4] = AArch64Operand::CreateImm( 4670 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext()); 4671 if (Tok == "bfi") 4672 Operands[0] = AArch64Operand::CreateToken( 4673 "bfm", false, Op.getStartLoc(), getContext()); 4674 else if (Tok == "sbfiz") 4675 Operands[0] = AArch64Operand::CreateToken( 4676 "sbfm", false, Op.getStartLoc(), getContext()); 4677 else if (Tok == "ubfiz") 4678 Operands[0] = AArch64Operand::CreateToken( 4679 "ubfm", false, Op.getStartLoc(), getContext()); 4680 else 4681 llvm_unreachable("No valid mnemonic for alias?"); 4682 } 4683 } 4684 4685 // FIXME: Horrible hack to handle the BFXIL->BFM, SBFX->SBFM, and 4686 // UBFX -> UBFM aliases. 4687 } else if (NumOperands == 5 && 4688 (Tok == "bfxil" || Tok == "sbfx" || Tok == "ubfx")) { 4689 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]); 4690 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]); 4691 AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]); 4692 4693 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) { 4694 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm()); 4695 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm()); 4696 4697 if (Op3CE && Op4CE) { 4698 uint64_t Op3Val = Op3CE->getValue(); 4699 uint64_t Op4Val = Op4CE->getValue(); 4700 4701 uint64_t RegWidth = 0; 4702 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( 4703 Op1.getReg())) 4704 RegWidth = 64; 4705 else 4706 RegWidth = 32; 4707 4708 if (Op3Val >= RegWidth) 4709 return Error(Op3.getStartLoc(), 4710 "expected integer in range [0, 31]"); 4711 if (Op4Val < 1 || Op4Val > RegWidth) 4712 return Error(Op4.getStartLoc(), 4713 "expected integer in range [1, 32]"); 4714 4715 uint64_t NewOp4Val = Op3Val + Op4Val - 1; 4716 4717 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val) 4718 return Error(Op4.getStartLoc(), 4719 "requested extract overflows register"); 4720 4721 const MCExpr *NewOp4 = 4722 MCConstantExpr::create(NewOp4Val, getContext()); 4723 Operands[4] = AArch64Operand::CreateImm( 4724 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext()); 4725 if (Tok == "bfxil") 4726 Operands[0] = AArch64Operand::CreateToken( 4727 "bfm", false, Op.getStartLoc(), getContext()); 4728 else if (Tok == "sbfx") 4729 Operands[0] = AArch64Operand::CreateToken( 4730 "sbfm", false, Op.getStartLoc(), getContext()); 4731 else if (Tok == "ubfx") 4732 Operands[0] = AArch64Operand::CreateToken( 4733 "ubfm", false, Op.getStartLoc(), getContext()); 4734 else 4735 llvm_unreachable("No valid mnemonic for alias?"); 4736 } 4737 } 4738 } 4739 } 4740 4741 // The Cyclone CPU and early successors didn't execute the zero-cycle zeroing 4742 // instruction for FP registers correctly in some rare circumstances. Convert 4743 // it to a safe instruction and warn (because silently changing someone's 4744 // assembly is rude). 4745 if (getSTI().getFeatureBits()[AArch64::FeatureZCZeroingFPWorkaround] && 4746 NumOperands == 4 && Tok == "movi") { 4747 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]); 4748 AArch64Operand &Op2 = static_cast<AArch64Operand &>(*Operands[2]); 4749 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]); 4750 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) || 4751 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) { 4752 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken(); 4753 if (Suffix.lower() == ".2d" && 4754 cast<MCConstantExpr>(Op3.getImm())->getValue() == 0) { 4755 Warning(IDLoc, "instruction movi.2d with immediate #0 may not function" 4756 " correctly on this CPU, converting to equivalent movi.16b"); 4757 // Switch the suffix to .16b. 4758 unsigned Idx = Op1.isToken() ? 1 : 2; 4759 Operands[Idx] = AArch64Operand::CreateToken(".16b", false, IDLoc, 4760 getContext()); 4761 } 4762 } 4763 } 4764 4765 // FIXME: Horrible hack for sxtw and uxtw with Wn src and Xd dst operands. 4766 // InstAlias can't quite handle this since the reg classes aren't 4767 // subclasses. 4768 if (NumOperands == 3 && (Tok == "sxtw" || Tok == "uxtw")) { 4769 // The source register can be Wn here, but the matcher expects a 4770 // GPR64. Twiddle it here if necessary. 4771 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]); 4772 if (Op.isScalarReg()) { 4773 unsigned Reg = getXRegFromWReg(Op.getReg()); 4774 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar, 4775 Op.getStartLoc(), Op.getEndLoc(), 4776 getContext()); 4777 } 4778 } 4779 // FIXME: Likewise for sxt[bh] with a Xd dst operand 4780 else if (NumOperands == 3 && (Tok == "sxtb" || Tok == "sxth")) { 4781 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]); 4782 if (Op.isScalarReg() && 4783 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( 4784 Op.getReg())) { 4785 // The source register can be Wn here, but the matcher expects a 4786 // GPR64. Twiddle it here if necessary. 4787 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]); 4788 if (Op.isScalarReg()) { 4789 unsigned Reg = getXRegFromWReg(Op.getReg()); 4790 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar, 4791 Op.getStartLoc(), 4792 Op.getEndLoc(), getContext()); 4793 } 4794 } 4795 } 4796 // FIXME: Likewise for uxt[bh] with a Xd dst operand 4797 else if (NumOperands == 3 && (Tok == "uxtb" || Tok == "uxth")) { 4798 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]); 4799 if (Op.isScalarReg() && 4800 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( 4801 Op.getReg())) { 4802 // The source register can be Wn here, but the matcher expects a 4803 // GPR32. Twiddle it here if necessary. 4804 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]); 4805 if (Op.isScalarReg()) { 4806 unsigned Reg = getWRegFromXReg(Op.getReg()); 4807 Operands[1] = AArch64Operand::CreateReg(Reg, RegKind::Scalar, 4808 Op.getStartLoc(), 4809 Op.getEndLoc(), getContext()); 4810 } 4811 } 4812 } 4813 4814 MCInst Inst; 4815 FeatureBitset MissingFeatures; 4816 // First try to match against the secondary set of tables containing the 4817 // short-form NEON instructions (e.g. "fadd.2s v0, v1, v2"). 4818 unsigned MatchResult = 4819 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures, 4820 MatchingInlineAsm, 1); 4821 4822 // If that fails, try against the alternate table containing long-form NEON: 4823 // "fadd v0.2s, v1.2s, v2.2s" 4824 if (MatchResult != Match_Success) { 4825 // But first, save the short-form match result: we can use it in case the 4826 // long-form match also fails. 4827 auto ShortFormNEONErrorInfo = ErrorInfo; 4828 auto ShortFormNEONMatchResult = MatchResult; 4829 auto ShortFormNEONMissingFeatures = MissingFeatures; 4830 4831 MatchResult = 4832 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures, 4833 MatchingInlineAsm, 0); 4834 4835 // Now, both matches failed, and the long-form match failed on the mnemonic 4836 // suffix token operand. The short-form match failure is probably more 4837 // relevant: use it instead. 4838 if (MatchResult == Match_InvalidOperand && ErrorInfo == 1 && 4839 Operands.size() > 1 && ((AArch64Operand &)*Operands[1]).isToken() && 4840 ((AArch64Operand &)*Operands[1]).isTokenSuffix()) { 4841 MatchResult = ShortFormNEONMatchResult; 4842 ErrorInfo = ShortFormNEONErrorInfo; 4843 MissingFeatures = ShortFormNEONMissingFeatures; 4844 } 4845 } 4846 4847 switch (MatchResult) { 4848 case Match_Success: { 4849 // Perform range checking and other semantic validations 4850 SmallVector<SMLoc, 8> OperandLocs; 4851 NumOperands = Operands.size(); 4852 for (unsigned i = 1; i < NumOperands; ++i) 4853 OperandLocs.push_back(Operands[i]->getStartLoc()); 4854 if (validateInstruction(Inst, IDLoc, OperandLocs)) 4855 return true; 4856 4857 Inst.setLoc(IDLoc); 4858 Out.emitInstruction(Inst, getSTI()); 4859 return false; 4860 } 4861 case Match_MissingFeature: { 4862 assert(MissingFeatures.any() && "Unknown missing feature!"); 4863 // Special case the error message for the very common case where only 4864 // a single subtarget feature is missing (neon, e.g.). 4865 std::string Msg = "instruction requires:"; 4866 for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) { 4867 if (MissingFeatures[i]) { 4868 Msg += " "; 4869 Msg += getSubtargetFeatureName(i); 4870 } 4871 } 4872 return Error(IDLoc, Msg); 4873 } 4874 case Match_MnemonicFail: 4875 return showMatchError(IDLoc, MatchResult, ErrorInfo, Operands); 4876 case Match_InvalidOperand: { 4877 SMLoc ErrorLoc = IDLoc; 4878 4879 if (ErrorInfo != ~0ULL) { 4880 if (ErrorInfo >= Operands.size()) 4881 return Error(IDLoc, "too few operands for instruction", 4882 SMRange(IDLoc, getTok().getLoc())); 4883 4884 ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc(); 4885 if (ErrorLoc == SMLoc()) 4886 ErrorLoc = IDLoc; 4887 } 4888 // If the match failed on a suffix token operand, tweak the diagnostic 4889 // accordingly. 4890 if (((AArch64Operand &)*Operands[ErrorInfo]).isToken() && 4891 ((AArch64Operand &)*Operands[ErrorInfo]).isTokenSuffix()) 4892 MatchResult = Match_InvalidSuffix; 4893 4894 return showMatchError(ErrorLoc, MatchResult, ErrorInfo, Operands); 4895 } 4896 case Match_InvalidTiedOperand: 4897 case Match_InvalidMemoryIndexed1: 4898 case Match_InvalidMemoryIndexed2: 4899 case Match_InvalidMemoryIndexed4: 4900 case Match_InvalidMemoryIndexed8: 4901 case Match_InvalidMemoryIndexed16: 4902 case Match_InvalidCondCode: 4903 case Match_AddSubRegExtendSmall: 4904 case Match_AddSubRegExtendLarge: 4905 case Match_AddSubSecondSource: 4906 case Match_LogicalSecondSource: 4907 case Match_AddSubRegShift32: 4908 case Match_AddSubRegShift64: 4909 case Match_InvalidMovImm32Shift: 4910 case Match_InvalidMovImm64Shift: 4911 case Match_InvalidFPImm: 4912 case Match_InvalidMemoryWExtend8: 4913 case Match_InvalidMemoryWExtend16: 4914 case Match_InvalidMemoryWExtend32: 4915 case Match_InvalidMemoryWExtend64: 4916 case Match_InvalidMemoryWExtend128: 4917 case Match_InvalidMemoryXExtend8: 4918 case Match_InvalidMemoryXExtend16: 4919 case Match_InvalidMemoryXExtend32: 4920 case Match_InvalidMemoryXExtend64: 4921 case Match_InvalidMemoryXExtend128: 4922 case Match_InvalidMemoryIndexed1SImm4: 4923 case Match_InvalidMemoryIndexed2SImm4: 4924 case Match_InvalidMemoryIndexed3SImm4: 4925 case Match_InvalidMemoryIndexed4SImm4: 4926 case Match_InvalidMemoryIndexed1SImm6: 4927 case Match_InvalidMemoryIndexed16SImm4: 4928 case Match_InvalidMemoryIndexed32SImm4: 4929 case Match_InvalidMemoryIndexed4SImm7: 4930 case Match_InvalidMemoryIndexed8SImm7: 4931 case Match_InvalidMemoryIndexed16SImm7: 4932 case Match_InvalidMemoryIndexed8UImm5: 4933 case Match_InvalidMemoryIndexed4UImm5: 4934 case Match_InvalidMemoryIndexed2UImm5: 4935 case Match_InvalidMemoryIndexed1UImm6: 4936 case Match_InvalidMemoryIndexed2UImm6: 4937 case Match_InvalidMemoryIndexed4UImm6: 4938 case Match_InvalidMemoryIndexed8UImm6: 4939 case Match_InvalidMemoryIndexed16UImm6: 4940 case Match_InvalidMemoryIndexedSImm6: 4941 case Match_InvalidMemoryIndexedSImm5: 4942 case Match_InvalidMemoryIndexedSImm8: 4943 case Match_InvalidMemoryIndexedSImm9: 4944 case Match_InvalidMemoryIndexed16SImm9: 4945 case Match_InvalidMemoryIndexed8SImm10: 4946 case Match_InvalidImm0_1: 4947 case Match_InvalidImm0_7: 4948 case Match_InvalidImm0_15: 4949 case Match_InvalidImm0_31: 4950 case Match_InvalidImm0_63: 4951 case Match_InvalidImm0_127: 4952 case Match_InvalidImm0_255: 4953 case Match_InvalidImm0_65535: 4954 case Match_InvalidImm1_8: 4955 case Match_InvalidImm1_16: 4956 case Match_InvalidImm1_32: 4957 case Match_InvalidImm1_64: 4958 case Match_InvalidSVEAddSubImm8: 4959 case Match_InvalidSVEAddSubImm16: 4960 case Match_InvalidSVEAddSubImm32: 4961 case Match_InvalidSVEAddSubImm64: 4962 case Match_InvalidSVECpyImm8: 4963 case Match_InvalidSVECpyImm16: 4964 case Match_InvalidSVECpyImm32: 4965 case Match_InvalidSVECpyImm64: 4966 case Match_InvalidIndexRange1_1: 4967 case Match_InvalidIndexRange0_15: 4968 case Match_InvalidIndexRange0_7: 4969 case Match_InvalidIndexRange0_3: 4970 case Match_InvalidIndexRange0_1: 4971 case Match_InvalidSVEIndexRange0_63: 4972 case Match_InvalidSVEIndexRange0_31: 4973 case Match_InvalidSVEIndexRange0_15: 4974 case Match_InvalidSVEIndexRange0_7: 4975 case Match_InvalidSVEIndexRange0_3: 4976 case Match_InvalidLabel: 4977 case Match_InvalidComplexRotationEven: 4978 case Match_InvalidComplexRotationOdd: 4979 case Match_InvalidGPR64shifted8: 4980 case Match_InvalidGPR64shifted16: 4981 case Match_InvalidGPR64shifted32: 4982 case Match_InvalidGPR64shifted64: 4983 case Match_InvalidGPR64NoXZRshifted8: 4984 case Match_InvalidGPR64NoXZRshifted16: 4985 case Match_InvalidGPR64NoXZRshifted32: 4986 case Match_InvalidGPR64NoXZRshifted64: 4987 case Match_InvalidZPR32UXTW8: 4988 case Match_InvalidZPR32UXTW16: 4989 case Match_InvalidZPR32UXTW32: 4990 case Match_InvalidZPR32UXTW64: 4991 case Match_InvalidZPR32SXTW8: 4992 case Match_InvalidZPR32SXTW16: 4993 case Match_InvalidZPR32SXTW32: 4994 case Match_InvalidZPR32SXTW64: 4995 case Match_InvalidZPR64UXTW8: 4996 case Match_InvalidZPR64SXTW8: 4997 case Match_InvalidZPR64UXTW16: 4998 case Match_InvalidZPR64SXTW16: 4999 case Match_InvalidZPR64UXTW32: 5000 case Match_InvalidZPR64SXTW32: 5001 case Match_InvalidZPR64UXTW64: 5002 case Match_InvalidZPR64SXTW64: 5003 case Match_InvalidZPR32LSL8: 5004 case Match_InvalidZPR32LSL16: 5005 case Match_InvalidZPR32LSL32: 5006 case Match_InvalidZPR32LSL64: 5007 case Match_InvalidZPR64LSL8: 5008 case Match_InvalidZPR64LSL16: 5009 case Match_InvalidZPR64LSL32: 5010 case Match_InvalidZPR64LSL64: 5011 case Match_InvalidZPR0: 5012 case Match_InvalidZPR8: 5013 case Match_InvalidZPR16: 5014 case Match_InvalidZPR32: 5015 case Match_InvalidZPR64: 5016 case Match_InvalidZPR128: 5017 case Match_InvalidZPR_3b8: 5018 case Match_InvalidZPR_3b16: 5019 case Match_InvalidZPR_3b32: 5020 case Match_InvalidZPR_4b16: 5021 case Match_InvalidZPR_4b32: 5022 case Match_InvalidZPR_4b64: 5023 case Match_InvalidSVEPredicateAnyReg: 5024 case Match_InvalidSVEPattern: 5025 case Match_InvalidSVEPredicateBReg: 5026 case Match_InvalidSVEPredicateHReg: 5027 case Match_InvalidSVEPredicateSReg: 5028 case Match_InvalidSVEPredicateDReg: 5029 case Match_InvalidSVEPredicate3bAnyReg: 5030 case Match_InvalidSVEPredicate3bBReg: 5031 case Match_InvalidSVEPredicate3bHReg: 5032 case Match_InvalidSVEPredicate3bSReg: 5033 case Match_InvalidSVEPredicate3bDReg: 5034 case Match_InvalidSVEExactFPImmOperandHalfOne: 5035 case Match_InvalidSVEExactFPImmOperandHalfTwo: 5036 case Match_InvalidSVEExactFPImmOperandZeroOne: 5037 case Match_MSR: 5038 case Match_MRS: { 5039 if (ErrorInfo >= Operands.size()) 5040 return Error(IDLoc, "too few operands for instruction", SMRange(IDLoc, (*Operands.back()).getEndLoc())); 5041 // Any time we get here, there's nothing fancy to do. Just get the 5042 // operand SMLoc and display the diagnostic. 5043 SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc(); 5044 if (ErrorLoc == SMLoc()) 5045 ErrorLoc = IDLoc; 5046 return showMatchError(ErrorLoc, MatchResult, ErrorInfo, Operands); 5047 } 5048 } 5049 5050 llvm_unreachable("Implement any new match types added!"); 5051 } 5052 5053 /// ParseDirective parses the arm specific directives 5054 bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) { 5055 const MCObjectFileInfo::Environment Format = 5056 getContext().getObjectFileInfo()->getObjectFileType(); 5057 bool IsMachO = Format == MCObjectFileInfo::IsMachO; 5058 5059 auto IDVal = DirectiveID.getIdentifier().lower(); 5060 SMLoc Loc = DirectiveID.getLoc(); 5061 if (IDVal == ".arch") 5062 parseDirectiveArch(Loc); 5063 else if (IDVal == ".cpu") 5064 parseDirectiveCPU(Loc); 5065 else if (IDVal == ".tlsdesccall") 5066 parseDirectiveTLSDescCall(Loc); 5067 else if (IDVal == ".ltorg" || IDVal == ".pool") 5068 parseDirectiveLtorg(Loc); 5069 else if (IDVal == ".unreq") 5070 parseDirectiveUnreq(Loc); 5071 else if (IDVal == ".inst") 5072 parseDirectiveInst(Loc); 5073 else if (IDVal == ".cfi_negate_ra_state") 5074 parseDirectiveCFINegateRAState(); 5075 else if (IDVal == ".cfi_b_key_frame") 5076 parseDirectiveCFIBKeyFrame(); 5077 else if (IDVal == ".arch_extension") 5078 parseDirectiveArchExtension(Loc); 5079 else if (IsMachO) { 5080 if (IDVal == MCLOHDirectiveName()) 5081 parseDirectiveLOH(IDVal, Loc); 5082 else 5083 return true; 5084 } else 5085 return true; 5086 return false; 5087 } 5088 5089 static void ExpandCryptoAEK(AArch64::ArchKind ArchKind, 5090 SmallVector<StringRef, 4> &RequestedExtensions) { 5091 const bool NoCrypto = 5092 (std::find(RequestedExtensions.begin(), RequestedExtensions.end(), 5093 "nocrypto") != std::end(RequestedExtensions)); 5094 const bool Crypto = 5095 (std::find(RequestedExtensions.begin(), RequestedExtensions.end(), 5096 "crypto") != std::end(RequestedExtensions)); 5097 5098 if (!NoCrypto && Crypto) { 5099 switch (ArchKind) { 5100 default: 5101 // Map 'generic' (and others) to sha2 and aes, because 5102 // that was the traditional meaning of crypto. 5103 case AArch64::ArchKind::ARMV8_1A: 5104 case AArch64::ArchKind::ARMV8_2A: 5105 case AArch64::ArchKind::ARMV8_3A: 5106 RequestedExtensions.push_back("sha2"); 5107 RequestedExtensions.push_back("aes"); 5108 break; 5109 case AArch64::ArchKind::ARMV8_4A: 5110 case AArch64::ArchKind::ARMV8_5A: 5111 case AArch64::ArchKind::ARMV8_6A: 5112 RequestedExtensions.push_back("sm4"); 5113 RequestedExtensions.push_back("sha3"); 5114 RequestedExtensions.push_back("sha2"); 5115 RequestedExtensions.push_back("aes"); 5116 break; 5117 } 5118 } else if (NoCrypto) { 5119 switch (ArchKind) { 5120 default: 5121 // Map 'generic' (and others) to sha2 and aes, because 5122 // that was the traditional meaning of crypto. 5123 case AArch64::ArchKind::ARMV8_1A: 5124 case AArch64::ArchKind::ARMV8_2A: 5125 case AArch64::ArchKind::ARMV8_3A: 5126 RequestedExtensions.push_back("nosha2"); 5127 RequestedExtensions.push_back("noaes"); 5128 break; 5129 case AArch64::ArchKind::ARMV8_4A: 5130 case AArch64::ArchKind::ARMV8_5A: 5131 case AArch64::ArchKind::ARMV8_6A: 5132 RequestedExtensions.push_back("nosm4"); 5133 RequestedExtensions.push_back("nosha3"); 5134 RequestedExtensions.push_back("nosha2"); 5135 RequestedExtensions.push_back("noaes"); 5136 break; 5137 } 5138 } 5139 } 5140 5141 /// parseDirectiveArch 5142 /// ::= .arch token 5143 bool AArch64AsmParser::parseDirectiveArch(SMLoc L) { 5144 SMLoc ArchLoc = getLoc(); 5145 5146 StringRef Arch, ExtensionString; 5147 std::tie(Arch, ExtensionString) = 5148 getParser().parseStringToEndOfStatement().trim().split('+'); 5149 5150 AArch64::ArchKind ID = AArch64::parseArch(Arch); 5151 if (ID == AArch64::ArchKind::INVALID) 5152 return Error(ArchLoc, "unknown arch name"); 5153 5154 if (parseToken(AsmToken::EndOfStatement)) 5155 return true; 5156 5157 // Get the architecture and extension features. 5158 std::vector<StringRef> AArch64Features; 5159 AArch64::getArchFeatures(ID, AArch64Features); 5160 AArch64::getExtensionFeatures(AArch64::getDefaultExtensions("generic", ID), 5161 AArch64Features); 5162 5163 MCSubtargetInfo &STI = copySTI(); 5164 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end()); 5165 STI.setDefaultFeatures("generic", join(ArchFeatures.begin(), ArchFeatures.end(), ",")); 5166 5167 SmallVector<StringRef, 4> RequestedExtensions; 5168 if (!ExtensionString.empty()) 5169 ExtensionString.split(RequestedExtensions, '+'); 5170 5171 ExpandCryptoAEK(ID, RequestedExtensions); 5172 5173 FeatureBitset Features = STI.getFeatureBits(); 5174 for (auto Name : RequestedExtensions) { 5175 bool EnableFeature = true; 5176 5177 if (Name.startswith_lower("no")) { 5178 EnableFeature = false; 5179 Name = Name.substr(2); 5180 } 5181 5182 for (const auto &Extension : ExtensionMap) { 5183 if (Extension.Name != Name) 5184 continue; 5185 5186 if (Extension.Features.none()) 5187 report_fatal_error("unsupported architectural extension: " + Name); 5188 5189 FeatureBitset ToggleFeatures = EnableFeature 5190 ? (~Features & Extension.Features) 5191 : ( Features & Extension.Features); 5192 FeatureBitset Features = 5193 ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures)); 5194 setAvailableFeatures(Features); 5195 break; 5196 } 5197 } 5198 return false; 5199 } 5200 5201 /// parseDirectiveArchExtension 5202 /// ::= .arch_extension [no]feature 5203 bool AArch64AsmParser::parseDirectiveArchExtension(SMLoc L) { 5204 SMLoc ExtLoc = getLoc(); 5205 5206 StringRef Name = getParser().parseStringToEndOfStatement().trim(); 5207 5208 if (parseToken(AsmToken::EndOfStatement, 5209 "unexpected token in '.arch_extension' directive")) 5210 return true; 5211 5212 bool EnableFeature = true; 5213 if (Name.startswith_lower("no")) { 5214 EnableFeature = false; 5215 Name = Name.substr(2); 5216 } 5217 5218 MCSubtargetInfo &STI = copySTI(); 5219 FeatureBitset Features = STI.getFeatureBits(); 5220 for (const auto &Extension : ExtensionMap) { 5221 if (Extension.Name != Name) 5222 continue; 5223 5224 if (Extension.Features.none()) 5225 return Error(ExtLoc, "unsupported architectural extension: " + Name); 5226 5227 FeatureBitset ToggleFeatures = EnableFeature 5228 ? (~Features & Extension.Features) 5229 : (Features & Extension.Features); 5230 FeatureBitset Features = 5231 ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures)); 5232 setAvailableFeatures(Features); 5233 return false; 5234 } 5235 5236 return Error(ExtLoc, "unknown architectural extension: " + Name); 5237 } 5238 5239 static SMLoc incrementLoc(SMLoc L, int Offset) { 5240 return SMLoc::getFromPointer(L.getPointer() + Offset); 5241 } 5242 5243 /// parseDirectiveCPU 5244 /// ::= .cpu id 5245 bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) { 5246 SMLoc CurLoc = getLoc(); 5247 5248 StringRef CPU, ExtensionString; 5249 std::tie(CPU, ExtensionString) = 5250 getParser().parseStringToEndOfStatement().trim().split('+'); 5251 5252 if (parseToken(AsmToken::EndOfStatement)) 5253 return true; 5254 5255 SmallVector<StringRef, 4> RequestedExtensions; 5256 if (!ExtensionString.empty()) 5257 ExtensionString.split(RequestedExtensions, '+'); 5258 5259 // FIXME This is using tablegen data, but should be moved to ARMTargetParser 5260 // once that is tablegen'ed 5261 if (!getSTI().isCPUStringValid(CPU)) { 5262 Error(CurLoc, "unknown CPU name"); 5263 return false; 5264 } 5265 5266 MCSubtargetInfo &STI = copySTI(); 5267 STI.setDefaultFeatures(CPU, ""); 5268 CurLoc = incrementLoc(CurLoc, CPU.size()); 5269 5270 ExpandCryptoAEK(llvm::AArch64::getCPUArchKind(CPU), RequestedExtensions); 5271 5272 FeatureBitset Features = STI.getFeatureBits(); 5273 for (auto Name : RequestedExtensions) { 5274 // Advance source location past '+'. 5275 CurLoc = incrementLoc(CurLoc, 1); 5276 5277 bool EnableFeature = true; 5278 5279 if (Name.startswith_lower("no")) { 5280 EnableFeature = false; 5281 Name = Name.substr(2); 5282 } 5283 5284 bool FoundExtension = false; 5285 for (const auto &Extension : ExtensionMap) { 5286 if (Extension.Name != Name) 5287 continue; 5288 5289 if (Extension.Features.none()) 5290 report_fatal_error("unsupported architectural extension: " + Name); 5291 5292 FeatureBitset ToggleFeatures = EnableFeature 5293 ? (~Features & Extension.Features) 5294 : ( Features & Extension.Features); 5295 FeatureBitset Features = 5296 ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures)); 5297 setAvailableFeatures(Features); 5298 FoundExtension = true; 5299 5300 break; 5301 } 5302 5303 if (!FoundExtension) 5304 Error(CurLoc, "unsupported architectural extension"); 5305 5306 CurLoc = incrementLoc(CurLoc, Name.size()); 5307 } 5308 return false; 5309 } 5310 5311 /// parseDirectiveInst 5312 /// ::= .inst opcode [, ...] 5313 bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) { 5314 if (getLexer().is(AsmToken::EndOfStatement)) 5315 return Error(Loc, "expected expression following '.inst' directive"); 5316 5317 auto parseOp = [&]() -> bool { 5318 SMLoc L = getLoc(); 5319 const MCExpr *Expr = nullptr; 5320 if (check(getParser().parseExpression(Expr), L, "expected expression")) 5321 return true; 5322 const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr); 5323 if (check(!Value, L, "expected constant expression")) 5324 return true; 5325 getTargetStreamer().emitInst(Value->getValue()); 5326 return false; 5327 }; 5328 5329 if (parseMany(parseOp)) 5330 return addErrorSuffix(" in '.inst' directive"); 5331 return false; 5332 } 5333 5334 // parseDirectiveTLSDescCall: 5335 // ::= .tlsdesccall symbol 5336 bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) { 5337 StringRef Name; 5338 if (check(getParser().parseIdentifier(Name), L, 5339 "expected symbol after directive") || 5340 parseToken(AsmToken::EndOfStatement)) 5341 return true; 5342 5343 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 5344 const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext()); 5345 Expr = AArch64MCExpr::create(Expr, AArch64MCExpr::VK_TLSDESC, getContext()); 5346 5347 MCInst Inst; 5348 Inst.setOpcode(AArch64::TLSDESCCALL); 5349 Inst.addOperand(MCOperand::createExpr(Expr)); 5350 5351 getParser().getStreamer().emitInstruction(Inst, getSTI()); 5352 return false; 5353 } 5354 5355 /// ::= .loh <lohName | lohId> label1, ..., labelN 5356 /// The number of arguments depends on the loh identifier. 5357 bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) { 5358 MCLOHType Kind; 5359 if (getParser().getTok().isNot(AsmToken::Identifier)) { 5360 if (getParser().getTok().isNot(AsmToken::Integer)) 5361 return TokError("expected an identifier or a number in directive"); 5362 // We successfully get a numeric value for the identifier. 5363 // Check if it is valid. 5364 int64_t Id = getParser().getTok().getIntVal(); 5365 if (Id <= -1U && !isValidMCLOHType(Id)) 5366 return TokError("invalid numeric identifier in directive"); 5367 Kind = (MCLOHType)Id; 5368 } else { 5369 StringRef Name = getTok().getIdentifier(); 5370 // We successfully parse an identifier. 5371 // Check if it is a recognized one. 5372 int Id = MCLOHNameToId(Name); 5373 5374 if (Id == -1) 5375 return TokError("invalid identifier in directive"); 5376 Kind = (MCLOHType)Id; 5377 } 5378 // Consume the identifier. 5379 Lex(); 5380 // Get the number of arguments of this LOH. 5381 int NbArgs = MCLOHIdToNbArgs(Kind); 5382 5383 assert(NbArgs != -1 && "Invalid number of arguments"); 5384 5385 SmallVector<MCSymbol *, 3> Args; 5386 for (int Idx = 0; Idx < NbArgs; ++Idx) { 5387 StringRef Name; 5388 if (getParser().parseIdentifier(Name)) 5389 return TokError("expected identifier in directive"); 5390 Args.push_back(getContext().getOrCreateSymbol(Name)); 5391 5392 if (Idx + 1 == NbArgs) 5393 break; 5394 if (parseToken(AsmToken::Comma, 5395 "unexpected token in '" + Twine(IDVal) + "' directive")) 5396 return true; 5397 } 5398 if (parseToken(AsmToken::EndOfStatement, 5399 "unexpected token in '" + Twine(IDVal) + "' directive")) 5400 return true; 5401 5402 getStreamer().emitLOHDirective((MCLOHType)Kind, Args); 5403 return false; 5404 } 5405 5406 /// parseDirectiveLtorg 5407 /// ::= .ltorg | .pool 5408 bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) { 5409 if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive")) 5410 return true; 5411 getTargetStreamer().emitCurrentConstantPool(); 5412 return false; 5413 } 5414 5415 /// parseDirectiveReq 5416 /// ::= name .req registername 5417 bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) { 5418 MCAsmParser &Parser = getParser(); 5419 Parser.Lex(); // Eat the '.req' token. 5420 SMLoc SRegLoc = getLoc(); 5421 RegKind RegisterKind = RegKind::Scalar; 5422 unsigned RegNum; 5423 OperandMatchResultTy ParseRes = tryParseScalarRegister(RegNum); 5424 5425 if (ParseRes != MatchOperand_Success) { 5426 StringRef Kind; 5427 RegisterKind = RegKind::NeonVector; 5428 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector); 5429 5430 if (ParseRes == MatchOperand_ParseFail) 5431 return true; 5432 5433 if (ParseRes == MatchOperand_Success && !Kind.empty()) 5434 return Error(SRegLoc, "vector register without type specifier expected"); 5435 } 5436 5437 if (ParseRes != MatchOperand_Success) { 5438 StringRef Kind; 5439 RegisterKind = RegKind::SVEDataVector; 5440 ParseRes = 5441 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector); 5442 5443 if (ParseRes == MatchOperand_ParseFail) 5444 return true; 5445 5446 if (ParseRes == MatchOperand_Success && !Kind.empty()) 5447 return Error(SRegLoc, 5448 "sve vector register without type specifier expected"); 5449 } 5450 5451 if (ParseRes != MatchOperand_Success) { 5452 StringRef Kind; 5453 RegisterKind = RegKind::SVEPredicateVector; 5454 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector); 5455 5456 if (ParseRes == MatchOperand_ParseFail) 5457 return true; 5458 5459 if (ParseRes == MatchOperand_Success && !Kind.empty()) 5460 return Error(SRegLoc, 5461 "sve predicate register without type specifier expected"); 5462 } 5463 5464 if (ParseRes != MatchOperand_Success) 5465 return Error(SRegLoc, "register name or alias expected"); 5466 5467 // Shouldn't be anything else. 5468 if (parseToken(AsmToken::EndOfStatement, 5469 "unexpected input in .req directive")) 5470 return true; 5471 5472 auto pair = std::make_pair(RegisterKind, (unsigned) RegNum); 5473 if (RegisterReqs.insert(std::make_pair(Name, pair)).first->second != pair) 5474 Warning(L, "ignoring redefinition of register alias '" + Name + "'"); 5475 5476 return false; 5477 } 5478 5479 /// parseDirectiveUneq 5480 /// ::= .unreq registername 5481 bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) { 5482 MCAsmParser &Parser = getParser(); 5483 if (getTok().isNot(AsmToken::Identifier)) 5484 return TokError("unexpected input in .unreq directive."); 5485 RegisterReqs.erase(Parser.getTok().getIdentifier().lower()); 5486 Parser.Lex(); // Eat the identifier. 5487 if (parseToken(AsmToken::EndOfStatement)) 5488 return addErrorSuffix("in '.unreq' directive"); 5489 return false; 5490 } 5491 5492 bool AArch64AsmParser::parseDirectiveCFINegateRAState() { 5493 if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive")) 5494 return true; 5495 getStreamer().emitCFINegateRAState(); 5496 return false; 5497 } 5498 5499 /// parseDirectiveCFIBKeyFrame 5500 /// ::= .cfi_b_key 5501 bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() { 5502 if (parseToken(AsmToken::EndOfStatement, 5503 "unexpected token in '.cfi_b_key_frame'")) 5504 return true; 5505 getStreamer().emitCFIBKeyFrame(); 5506 return false; 5507 } 5508 5509 bool 5510 AArch64AsmParser::classifySymbolRef(const MCExpr *Expr, 5511 AArch64MCExpr::VariantKind &ELFRefKind, 5512 MCSymbolRefExpr::VariantKind &DarwinRefKind, 5513 int64_t &Addend) { 5514 ELFRefKind = AArch64MCExpr::VK_INVALID; 5515 DarwinRefKind = MCSymbolRefExpr::VK_None; 5516 Addend = 0; 5517 5518 if (const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) { 5519 ELFRefKind = AE->getKind(); 5520 Expr = AE->getSubExpr(); 5521 } 5522 5523 const MCSymbolRefExpr *SE = dyn_cast<MCSymbolRefExpr>(Expr); 5524 if (SE) { 5525 // It's a simple symbol reference with no addend. 5526 DarwinRefKind = SE->getKind(); 5527 return true; 5528 } 5529 5530 // Check that it looks like a symbol + an addend 5531 MCValue Res; 5532 bool Relocatable = Expr->evaluateAsRelocatable(Res, nullptr, nullptr); 5533 if (!Relocatable || Res.getSymB()) 5534 return false; 5535 5536 // Treat expressions with an ELFRefKind (like ":abs_g1:3", or 5537 // ":abs_g1:x" where x is constant) as symbolic even if there is no symbol. 5538 if (!Res.getSymA() && ELFRefKind == AArch64MCExpr::VK_INVALID) 5539 return false; 5540 5541 if (Res.getSymA()) 5542 DarwinRefKind = Res.getSymA()->getKind(); 5543 Addend = Res.getConstant(); 5544 5545 // It's some symbol reference + a constant addend, but really 5546 // shouldn't use both Darwin and ELF syntax. 5547 return ELFRefKind == AArch64MCExpr::VK_INVALID || 5548 DarwinRefKind == MCSymbolRefExpr::VK_None; 5549 } 5550 5551 /// Force static initialization. 5552 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64AsmParser() { 5553 RegisterMCAsmParser<AArch64AsmParser> X(getTheAArch64leTarget()); 5554 RegisterMCAsmParser<AArch64AsmParser> Y(getTheAArch64beTarget()); 5555 RegisterMCAsmParser<AArch64AsmParser> Z(getTheARM64Target()); 5556 RegisterMCAsmParser<AArch64AsmParser> W(getTheARM64_32Target()); 5557 RegisterMCAsmParser<AArch64AsmParser> V(getTheAArch64_32Target()); 5558 } 5559 5560 #define GET_REGISTER_MATCHER 5561 #define GET_SUBTARGET_FEATURE_NAME 5562 #define GET_MATCHER_IMPLEMENTATION 5563 #define GET_MNEMONIC_SPELL_CHECKER 5564 #include "AArch64GenAsmMatcher.inc" 5565 5566 // Define this matcher function after the auto-generated include so we 5567 // have the match class enum definitions. 5568 unsigned AArch64AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, 5569 unsigned Kind) { 5570 AArch64Operand &Op = static_cast<AArch64Operand &>(AsmOp); 5571 // If the kind is a token for a literal immediate, check if our asm 5572 // operand matches. This is for InstAliases which have a fixed-value 5573 // immediate in the syntax. 5574 int64_t ExpectedVal; 5575 switch (Kind) { 5576 default: 5577 return Match_InvalidOperand; 5578 case MCK__HASH_0: 5579 ExpectedVal = 0; 5580 break; 5581 case MCK__HASH_1: 5582 ExpectedVal = 1; 5583 break; 5584 case MCK__HASH_12: 5585 ExpectedVal = 12; 5586 break; 5587 case MCK__HASH_16: 5588 ExpectedVal = 16; 5589 break; 5590 case MCK__HASH_2: 5591 ExpectedVal = 2; 5592 break; 5593 case MCK__HASH_24: 5594 ExpectedVal = 24; 5595 break; 5596 case MCK__HASH_3: 5597 ExpectedVal = 3; 5598 break; 5599 case MCK__HASH_32: 5600 ExpectedVal = 32; 5601 break; 5602 case MCK__HASH_4: 5603 ExpectedVal = 4; 5604 break; 5605 case MCK__HASH_48: 5606 ExpectedVal = 48; 5607 break; 5608 case MCK__HASH_6: 5609 ExpectedVal = 6; 5610 break; 5611 case MCK__HASH_64: 5612 ExpectedVal = 64; 5613 break; 5614 case MCK__HASH_8: 5615 ExpectedVal = 8; 5616 break; 5617 } 5618 if (!Op.isImm()) 5619 return Match_InvalidOperand; 5620 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm()); 5621 if (!CE) 5622 return Match_InvalidOperand; 5623 if (CE->getValue() == ExpectedVal) 5624 return Match_Success; 5625 return Match_InvalidOperand; 5626 } 5627 5628 OperandMatchResultTy 5629 AArch64AsmParser::tryParseGPRSeqPair(OperandVector &Operands) { 5630 5631 SMLoc S = getLoc(); 5632 5633 if (getParser().getTok().isNot(AsmToken::Identifier)) { 5634 Error(S, "expected register"); 5635 return MatchOperand_ParseFail; 5636 } 5637 5638 unsigned FirstReg; 5639 OperandMatchResultTy Res = tryParseScalarRegister(FirstReg); 5640 if (Res != MatchOperand_Success) 5641 return MatchOperand_ParseFail; 5642 5643 const MCRegisterClass &WRegClass = 5644 AArch64MCRegisterClasses[AArch64::GPR32RegClassID]; 5645 const MCRegisterClass &XRegClass = 5646 AArch64MCRegisterClasses[AArch64::GPR64RegClassID]; 5647 5648 bool isXReg = XRegClass.contains(FirstReg), 5649 isWReg = WRegClass.contains(FirstReg); 5650 if (!isXReg && !isWReg) { 5651 Error(S, "expected first even register of a " 5652 "consecutive same-size even/odd register pair"); 5653 return MatchOperand_ParseFail; 5654 } 5655 5656 const MCRegisterInfo *RI = getContext().getRegisterInfo(); 5657 unsigned FirstEncoding = RI->getEncodingValue(FirstReg); 5658 5659 if (FirstEncoding & 0x1) { 5660 Error(S, "expected first even register of a " 5661 "consecutive same-size even/odd register pair"); 5662 return MatchOperand_ParseFail; 5663 } 5664 5665 if (getParser().getTok().isNot(AsmToken::Comma)) { 5666 Error(getLoc(), "expected comma"); 5667 return MatchOperand_ParseFail; 5668 } 5669 // Eat the comma 5670 getParser().Lex(); 5671 5672 SMLoc E = getLoc(); 5673 unsigned SecondReg; 5674 Res = tryParseScalarRegister(SecondReg); 5675 if (Res != MatchOperand_Success) 5676 return MatchOperand_ParseFail; 5677 5678 if (RI->getEncodingValue(SecondReg) != FirstEncoding + 1 || 5679 (isXReg && !XRegClass.contains(SecondReg)) || 5680 (isWReg && !WRegClass.contains(SecondReg))) { 5681 Error(E,"expected second odd register of a " 5682 "consecutive same-size even/odd register pair"); 5683 return MatchOperand_ParseFail; 5684 } 5685 5686 unsigned Pair = 0; 5687 if (isXReg) { 5688 Pair = RI->getMatchingSuperReg(FirstReg, AArch64::sube64, 5689 &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]); 5690 } else { 5691 Pair = RI->getMatchingSuperReg(FirstReg, AArch64::sube32, 5692 &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]); 5693 } 5694 5695 Operands.push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S, 5696 getLoc(), getContext())); 5697 5698 return MatchOperand_Success; 5699 } 5700 5701 template <bool ParseShiftExtend, bool ParseSuffix> 5702 OperandMatchResultTy 5703 AArch64AsmParser::tryParseSVEDataVector(OperandVector &Operands) { 5704 const SMLoc S = getLoc(); 5705 // Check for a SVE vector register specifier first. 5706 unsigned RegNum; 5707 StringRef Kind; 5708 5709 OperandMatchResultTy Res = 5710 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector); 5711 5712 if (Res != MatchOperand_Success) 5713 return Res; 5714 5715 if (ParseSuffix && Kind.empty()) 5716 return MatchOperand_NoMatch; 5717 5718 const auto &KindRes = parseVectorKind(Kind, RegKind::SVEDataVector); 5719 if (!KindRes) 5720 return MatchOperand_NoMatch; 5721 5722 unsigned ElementWidth = KindRes->second; 5723 5724 // No shift/extend is the default. 5725 if (!ParseShiftExtend || getParser().getTok().isNot(AsmToken::Comma)) { 5726 Operands.push_back(AArch64Operand::CreateVectorReg( 5727 RegNum, RegKind::SVEDataVector, ElementWidth, S, S, getContext())); 5728 5729 OperandMatchResultTy Res = tryParseVectorIndex(Operands); 5730 if (Res == MatchOperand_ParseFail) 5731 return MatchOperand_ParseFail; 5732 return MatchOperand_Success; 5733 } 5734 5735 // Eat the comma 5736 getParser().Lex(); 5737 5738 // Match the shift 5739 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> ExtOpnd; 5740 Res = tryParseOptionalShiftExtend(ExtOpnd); 5741 if (Res != MatchOperand_Success) 5742 return Res; 5743 5744 auto Ext = static_cast<AArch64Operand *>(ExtOpnd.back().get()); 5745 Operands.push_back(AArch64Operand::CreateVectorReg( 5746 RegNum, RegKind::SVEDataVector, ElementWidth, S, Ext->getEndLoc(), 5747 getContext(), Ext->getShiftExtendType(), Ext->getShiftExtendAmount(), 5748 Ext->hasShiftExtendAmount())); 5749 5750 return MatchOperand_Success; 5751 } 5752 5753 OperandMatchResultTy 5754 AArch64AsmParser::tryParseSVEPattern(OperandVector &Operands) { 5755 MCAsmParser &Parser = getParser(); 5756 5757 SMLoc SS = getLoc(); 5758 const AsmToken &TokE = Parser.getTok(); 5759 bool IsHash = TokE.is(AsmToken::Hash); 5760 5761 if (!IsHash && TokE.isNot(AsmToken::Identifier)) 5762 return MatchOperand_NoMatch; 5763 5764 int64_t Pattern; 5765 if (IsHash) { 5766 Parser.Lex(); // Eat hash 5767 5768 // Parse the immediate operand. 5769 const MCExpr *ImmVal; 5770 SS = getLoc(); 5771 if (Parser.parseExpression(ImmVal)) 5772 return MatchOperand_ParseFail; 5773 5774 auto *MCE = dyn_cast<MCConstantExpr>(ImmVal); 5775 if (!MCE) 5776 return MatchOperand_ParseFail; 5777 5778 Pattern = MCE->getValue(); 5779 } else { 5780 // Parse the pattern 5781 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.getString()); 5782 if (!Pat) 5783 return MatchOperand_NoMatch; 5784 5785 Parser.Lex(); 5786 Pattern = Pat->Encoding; 5787 assert(Pattern >= 0 && Pattern < 32); 5788 } 5789 5790 Operands.push_back( 5791 AArch64Operand::CreateImm(MCConstantExpr::create(Pattern, getContext()), 5792 SS, getLoc(), getContext())); 5793 5794 return MatchOperand_Success; 5795 } 5796