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