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