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