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