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