1 //==- AArch64AsmParser.cpp - Parse AArch64 assembly to MCInst instructions -==// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "MCTargetDesc/AArch64AddressingModes.h" 11 #include "MCTargetDesc/AArch64MCExpr.h" 12 #include "MCTargetDesc/AArch64MCTargetDesc.h" 13 #include "MCTargetDesc/AArch64TargetStreamer.h" 14 #include "Utils/AArch64BaseInfo.h" 15 #include "llvm/ADT/APFloat.h" 16 #include "llvm/ADT/APInt.h" 17 #include "llvm/ADT/ArrayRef.h" 18 #include "llvm/ADT/STLExtras.h" 19 #include "llvm/ADT/SmallVector.h" 20 #include "llvm/ADT/StringExtras.h" 21 #include "llvm/ADT/StringMap.h" 22 #include "llvm/ADT/StringRef.h" 23 #include "llvm/ADT/StringSwitch.h" 24 #include "llvm/ADT/Twine.h" 25 #include "llvm/MC/MCContext.h" 26 #include "llvm/MC/MCExpr.h" 27 #include "llvm/MC/MCInst.h" 28 #include "llvm/MC/MCLinkerOptimizationHint.h" 29 #include "llvm/MC/MCObjectFileInfo.h" 30 #include "llvm/MC/MCParser/MCAsmLexer.h" 31 #include "llvm/MC/MCParser/MCAsmParser.h" 32 #include "llvm/MC/MCParser/MCAsmParserExtension.h" 33 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 34 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 35 #include "llvm/MC/MCRegisterInfo.h" 36 #include "llvm/MC/MCStreamer.h" 37 #include "llvm/MC/MCSubtargetInfo.h" 38 #include "llvm/MC/MCSymbol.h" 39 #include "llvm/MC/MCTargetOptions.h" 40 #include "llvm/MC/SubtargetFeature.h" 41 #include "llvm/Support/Casting.h" 42 #include "llvm/Support/Compiler.h" 43 #include "llvm/Support/ErrorHandling.h" 44 #include "llvm/Support/MathExtras.h" 45 #include "llvm/Support/SMLoc.h" 46 #include "llvm/Support/TargetParser.h" 47 #include "llvm/Support/TargetRegistry.h" 48 #include "llvm/Support/raw_ostream.h" 49 #include <cassert> 50 #include <cctype> 51 #include <cstdint> 52 #include <cstdio> 53 #include <string> 54 #include <tuple> 55 #include <utility> 56 #include <vector> 57 58 using namespace llvm; 59 60 namespace { 61 62 enum class RegKind { 63 Scalar, 64 NeonVector, 65 SVEDataVector, 66 SVEPredicateVector 67 }; 68 69 class AArch64AsmParser : public MCTargetAsmParser { 70 private: 71 StringRef Mnemonic; ///< Instruction mnemonic. 72 73 // Map of register aliases registers via the .req directive. 74 StringMap<std::pair<RegKind, unsigned>> RegisterReqs; 75 76 AArch64TargetStreamer &getTargetStreamer() { 77 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); 78 return static_cast<AArch64TargetStreamer &>(TS); 79 } 80 81 SMLoc getLoc() const { return getParser().getTok().getLoc(); } 82 83 bool parseSysAlias(StringRef Name, SMLoc NameLoc, OperandVector &Operands); 84 void createSysAlias(uint16_t Encoding, OperandVector &Operands, SMLoc S); 85 AArch64CC::CondCode parseCondCodeString(StringRef Cond); 86 bool parseCondCode(OperandVector &Operands, bool invertCondCode); 87 unsigned matchRegisterNameAlias(StringRef Name, RegKind Kind); 88 int tryParseRegister(); 89 int tryMatchVectorRegister(StringRef &Kind, bool expected); 90 bool parseRegister(OperandVector &Operands); 91 bool parseSymbolicImmVal(const MCExpr *&ImmVal); 92 bool parseVectorList(OperandVector &Operands); 93 bool parseOperand(OperandVector &Operands, bool isCondCode, 94 bool invertCondCode); 95 96 bool showMatchError(SMLoc Loc, unsigned ErrCode, OperandVector &Operands); 97 98 bool parseDirectiveArch(SMLoc L); 99 bool parseDirectiveCPU(SMLoc L); 100 bool parseDirectiveWord(unsigned Size, SMLoc L); 101 bool parseDirectiveInst(SMLoc L); 102 103 bool parseDirectiveTLSDescCall(SMLoc L); 104 105 bool parseDirectiveLOH(StringRef LOH, SMLoc L); 106 bool parseDirectiveLtorg(SMLoc L); 107 108 bool parseDirectiveReq(StringRef Name, SMLoc L); 109 bool parseDirectiveUnreq(SMLoc L); 110 111 bool validateInstruction(MCInst &Inst, SmallVectorImpl<SMLoc> &Loc); 112 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 113 OperandVector &Operands, MCStreamer &Out, 114 uint64_t &ErrorInfo, 115 bool MatchingInlineAsm) override; 116 /// @name Auto-generated Match Functions 117 /// { 118 119 #define GET_ASSEMBLER_HEADER 120 #include "AArch64GenAsmMatcher.inc" 121 122 /// } 123 124 OperandMatchResultTy tryParseSVERegister(int &Reg, StringRef &Kind, 125 RegKind MatchKind); 126 OperandMatchResultTy tryParseOptionalShiftExtend(OperandVector &Operands); 127 OperandMatchResultTy tryParseBarrierOperand(OperandVector &Operands); 128 OperandMatchResultTy tryParseMRSSystemRegister(OperandVector &Operands); 129 OperandMatchResultTy tryParseSysReg(OperandVector &Operands); 130 OperandMatchResultTy tryParseSysCROperand(OperandVector &Operands); 131 OperandMatchResultTy tryParsePrefetch(OperandVector &Operands); 132 OperandMatchResultTy tryParsePSBHint(OperandVector &Operands); 133 OperandMatchResultTy tryParseAdrpLabel(OperandVector &Operands); 134 OperandMatchResultTy tryParseAdrLabel(OperandVector &Operands); 135 OperandMatchResultTy tryParseFPImm(OperandVector &Operands); 136 OperandMatchResultTy tryParseAddSubImm(OperandVector &Operands); 137 OperandMatchResultTy tryParseGPR64sp0Operand(OperandVector &Operands); 138 bool tryParseNeonVectorRegister(OperandVector &Operands); 139 OperandMatchResultTy tryParseGPRSeqPair(OperandVector &Operands); 140 template <bool ParseSuffix> 141 OperandMatchResultTy tryParseSVEDataVector(OperandVector &Operands); 142 OperandMatchResultTy tryParseSVEPredicateVector(OperandVector &Operands); 143 144 public: 145 enum AArch64MatchResultTy { 146 Match_InvalidSuffix = FIRST_TARGET_MATCH_RESULT_TY, 147 #define GET_OPERAND_DIAGNOSTIC_TYPES 148 #include "AArch64GenAsmMatcher.inc" 149 }; 150 bool IsILP32; 151 152 AArch64AsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, 153 const MCInstrInfo &MII, const MCTargetOptions &Options) 154 : MCTargetAsmParser(Options, STI, MII) { 155 IsILP32 = Options.getABIName() == "ilp32"; 156 MCAsmParserExtension::Initialize(Parser); 157 MCStreamer &S = getParser().getStreamer(); 158 if (S.getTargetStreamer() == nullptr) 159 new AArch64TargetStreamer(S); 160 161 // Initialize the set of available features. 162 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits())); 163 } 164 165 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 166 SMLoc NameLoc, OperandVector &Operands) override; 167 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 168 bool ParseDirective(AsmToken DirectiveID) override; 169 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 170 unsigned Kind) override; 171 172 static bool classifySymbolRef(const MCExpr *Expr, 173 AArch64MCExpr::VariantKind &ELFRefKind, 174 MCSymbolRefExpr::VariantKind &DarwinRefKind, 175 int64_t &Addend); 176 }; 177 178 /// AArch64Operand - Instances of this class represent a parsed AArch64 machine 179 /// instruction. 180 class AArch64Operand : public MCParsedAsmOperand { 181 private: 182 enum KindTy { 183 k_Immediate, 184 k_ShiftedImm, 185 k_CondCode, 186 k_Register, 187 k_VectorList, 188 k_VectorIndex, 189 k_Token, 190 k_SysReg, 191 k_SysCR, 192 k_Prefetch, 193 k_ShiftExtend, 194 k_FPImm, 195 k_Barrier, 196 k_PSBHint, 197 } Kind; 198 199 SMLoc StartLoc, EndLoc; 200 201 struct TokOp { 202 const char *Data; 203 unsigned Length; 204 bool IsSuffix; // Is the operand actually a suffix on the mnemonic. 205 }; 206 207 struct RegOp { 208 unsigned RegNum; 209 RegKind Kind; 210 211 int ElementWidth; 212 }; 213 214 struct VectorListOp { 215 unsigned RegNum; 216 unsigned Count; 217 unsigned NumElements; 218 unsigned ElementKind; 219 }; 220 221 struct VectorIndexOp { 222 unsigned Val; 223 }; 224 225 struct ImmOp { 226 const MCExpr *Val; 227 }; 228 229 struct ShiftedImmOp { 230 const MCExpr *Val; 231 unsigned ShiftAmount; 232 }; 233 234 struct CondCodeOp { 235 AArch64CC::CondCode Code; 236 }; 237 238 struct FPImmOp { 239 unsigned Val; // Encoded 8-bit representation. 240 }; 241 242 struct BarrierOp { 243 const char *Data; 244 unsigned Length; 245 unsigned Val; // Not the enum since not all values have names. 246 }; 247 248 struct SysRegOp { 249 const char *Data; 250 unsigned Length; 251 uint32_t MRSReg; 252 uint32_t MSRReg; 253 uint32_t PStateField; 254 }; 255 256 struct SysCRImmOp { 257 unsigned Val; 258 }; 259 260 struct PrefetchOp { 261 const char *Data; 262 unsigned Length; 263 unsigned Val; 264 }; 265 266 struct PSBHintOp { 267 const char *Data; 268 unsigned Length; 269 unsigned Val; 270 }; 271 272 struct ShiftExtendOp { 273 AArch64_AM::ShiftExtendType Type; 274 unsigned Amount; 275 bool HasExplicitAmount; 276 }; 277 278 struct ExtendOp { 279 unsigned Val; 280 }; 281 282 union { 283 struct TokOp Tok; 284 struct RegOp Reg; 285 struct VectorListOp VectorList; 286 struct VectorIndexOp VectorIndex; 287 struct ImmOp Imm; 288 struct ShiftedImmOp ShiftedImm; 289 struct CondCodeOp CondCode; 290 struct FPImmOp FPImm; 291 struct BarrierOp Barrier; 292 struct SysRegOp SysReg; 293 struct SysCRImmOp SysCRImm; 294 struct PrefetchOp Prefetch; 295 struct PSBHintOp PSBHint; 296 struct ShiftExtendOp ShiftExtend; 297 }; 298 299 // Keep the MCContext around as the MCExprs may need manipulated during 300 // the add<>Operands() calls. 301 MCContext &Ctx; 302 303 public: 304 AArch64Operand(KindTy K, MCContext &Ctx) : Kind(K), Ctx(Ctx) {} 305 306 AArch64Operand(const AArch64Operand &o) : MCParsedAsmOperand(), Ctx(o.Ctx) { 307 Kind = o.Kind; 308 StartLoc = o.StartLoc; 309 EndLoc = o.EndLoc; 310 switch (Kind) { 311 case k_Token: 312 Tok = o.Tok; 313 break; 314 case k_Immediate: 315 Imm = o.Imm; 316 break; 317 case k_ShiftedImm: 318 ShiftedImm = o.ShiftedImm; 319 break; 320 case k_CondCode: 321 CondCode = o.CondCode; 322 break; 323 case k_FPImm: 324 FPImm = o.FPImm; 325 break; 326 case k_Barrier: 327 Barrier = o.Barrier; 328 break; 329 case k_Register: 330 Reg = o.Reg; 331 break; 332 case k_VectorList: 333 VectorList = o.VectorList; 334 break; 335 case k_VectorIndex: 336 VectorIndex = o.VectorIndex; 337 break; 338 case k_SysReg: 339 SysReg = o.SysReg; 340 break; 341 case k_SysCR: 342 SysCRImm = o.SysCRImm; 343 break; 344 case k_Prefetch: 345 Prefetch = o.Prefetch; 346 break; 347 case k_PSBHint: 348 PSBHint = o.PSBHint; 349 break; 350 case k_ShiftExtend: 351 ShiftExtend = o.ShiftExtend; 352 break; 353 } 354 } 355 356 /// getStartLoc - Get the location of the first token of this operand. 357 SMLoc getStartLoc() const override { return StartLoc; } 358 /// getEndLoc - Get the location of the last token of this operand. 359 SMLoc getEndLoc() const override { return EndLoc; } 360 361 StringRef getToken() const { 362 assert(Kind == k_Token && "Invalid access!"); 363 return StringRef(Tok.Data, Tok.Length); 364 } 365 366 bool isTokenSuffix() const { 367 assert(Kind == k_Token && "Invalid access!"); 368 return Tok.IsSuffix; 369 } 370 371 const MCExpr *getImm() const { 372 assert(Kind == k_Immediate && "Invalid access!"); 373 return Imm.Val; 374 } 375 376 const MCExpr *getShiftedImmVal() const { 377 assert(Kind == k_ShiftedImm && "Invalid access!"); 378 return ShiftedImm.Val; 379 } 380 381 unsigned getShiftedImmShift() const { 382 assert(Kind == k_ShiftedImm && "Invalid access!"); 383 return ShiftedImm.ShiftAmount; 384 } 385 386 AArch64CC::CondCode getCondCode() const { 387 assert(Kind == k_CondCode && "Invalid access!"); 388 return CondCode.Code; 389 } 390 391 unsigned getFPImm() const { 392 assert(Kind == k_FPImm && "Invalid access!"); 393 return FPImm.Val; 394 } 395 396 unsigned getBarrier() const { 397 assert(Kind == k_Barrier && "Invalid access!"); 398 return Barrier.Val; 399 } 400 401 StringRef getBarrierName() const { 402 assert(Kind == k_Barrier && "Invalid access!"); 403 return StringRef(Barrier.Data, Barrier.Length); 404 } 405 406 unsigned getReg() const override { 407 assert(Kind == k_Register && "Invalid access!"); 408 return Reg.RegNum; 409 } 410 411 unsigned getVectorListStart() const { 412 assert(Kind == k_VectorList && "Invalid access!"); 413 return VectorList.RegNum; 414 } 415 416 unsigned getVectorListCount() const { 417 assert(Kind == k_VectorList && "Invalid access!"); 418 return VectorList.Count; 419 } 420 421 unsigned getVectorIndex() const { 422 assert(Kind == k_VectorIndex && "Invalid access!"); 423 return VectorIndex.Val; 424 } 425 426 StringRef getSysReg() const { 427 assert(Kind == k_SysReg && "Invalid access!"); 428 return StringRef(SysReg.Data, SysReg.Length); 429 } 430 431 unsigned getSysCR() const { 432 assert(Kind == k_SysCR && "Invalid access!"); 433 return SysCRImm.Val; 434 } 435 436 unsigned getPrefetch() const { 437 assert(Kind == k_Prefetch && "Invalid access!"); 438 return Prefetch.Val; 439 } 440 441 unsigned getPSBHint() const { 442 assert(Kind == k_PSBHint && "Invalid access!"); 443 return PSBHint.Val; 444 } 445 446 StringRef getPSBHintName() const { 447 assert(Kind == k_PSBHint && "Invalid access!"); 448 return StringRef(PSBHint.Data, PSBHint.Length); 449 } 450 451 StringRef getPrefetchName() const { 452 assert(Kind == k_Prefetch && "Invalid access!"); 453 return StringRef(Prefetch.Data, Prefetch.Length); 454 } 455 456 AArch64_AM::ShiftExtendType getShiftExtendType() const { 457 assert(Kind == k_ShiftExtend && "Invalid access!"); 458 return ShiftExtend.Type; 459 } 460 461 unsigned getShiftExtendAmount() const { 462 assert(Kind == k_ShiftExtend && "Invalid access!"); 463 return ShiftExtend.Amount; 464 } 465 466 bool hasShiftExtendAmount() const { 467 assert(Kind == k_ShiftExtend && "Invalid access!"); 468 return ShiftExtend.HasExplicitAmount; 469 } 470 471 bool isImm() const override { return Kind == k_Immediate; } 472 bool isMem() const override { return false; } 473 bool isSImm9() const { 474 if (!isImm()) 475 return false; 476 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 477 if (!MCE) 478 return false; 479 int64_t Val = MCE->getValue(); 480 return (Val >= -256 && Val < 256); 481 } 482 bool isSImm10s8() const { 483 if (!isImm()) 484 return false; 485 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 486 if (!MCE) 487 return false; 488 int64_t Val = MCE->getValue(); 489 return (Val >= -4096 && Val < 4089 && (Val & 7) == 0); 490 } 491 bool isSImm7s4() const { 492 if (!isImm()) 493 return false; 494 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 495 if (!MCE) 496 return false; 497 int64_t Val = MCE->getValue(); 498 return (Val >= -256 && Val <= 252 && (Val & 3) == 0); 499 } 500 bool isSImm7s8() const { 501 if (!isImm()) 502 return false; 503 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 504 if (!MCE) 505 return false; 506 int64_t Val = MCE->getValue(); 507 return (Val >= -512 && Val <= 504 && (Val & 7) == 0); 508 } 509 bool isSImm7s16() const { 510 if (!isImm()) 511 return false; 512 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 513 if (!MCE) 514 return false; 515 int64_t Val = MCE->getValue(); 516 return (Val >= -1024 && Val <= 1008 && (Val & 15) == 0); 517 } 518 519 bool isSymbolicUImm12Offset(const MCExpr *Expr, unsigned Scale) const { 520 AArch64MCExpr::VariantKind ELFRefKind; 521 MCSymbolRefExpr::VariantKind DarwinRefKind; 522 int64_t Addend; 523 if (!AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, 524 Addend)) { 525 // If we don't understand the expression, assume the best and 526 // let the fixup and relocation code deal with it. 527 return true; 528 } 529 530 if (DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF || 531 ELFRefKind == AArch64MCExpr::VK_LO12 || 532 ELFRefKind == AArch64MCExpr::VK_GOT_LO12 || 533 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 || 534 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC || 535 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 || 536 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC || 537 ELFRefKind == AArch64MCExpr::VK_GOTTPREL_LO12_NC || 538 ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12) { 539 // Note that we don't range-check the addend. It's adjusted modulo page 540 // size when converted, so there is no "out of range" condition when using 541 // @pageoff. 542 return Addend >= 0 && (Addend % Scale) == 0; 543 } else if (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF || 544 DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) { 545 // @gotpageoff/@tlvppageoff can only be used directly, not with an addend. 546 return Addend == 0; 547 } 548 549 return false; 550 } 551 552 template <int Scale> bool isUImm12Offset() const { 553 if (!isImm()) 554 return false; 555 556 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 557 if (!MCE) 558 return isSymbolicUImm12Offset(getImm(), Scale); 559 560 int64_t Val = MCE->getValue(); 561 return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000; 562 } 563 564 template <int N, int M> 565 bool isImmInRange() const { 566 if (!isImm()) 567 return false; 568 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 569 if (!MCE) 570 return false; 571 int64_t Val = MCE->getValue(); 572 return (Val >= N && Val <= M); 573 } 574 575 bool isLogicalImm32() const { 576 if (!isImm()) 577 return false; 578 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 579 if (!MCE) 580 return false; 581 int64_t Val = MCE->getValue(); 582 if (Val >> 32 != 0 && Val >> 32 != ~0LL) 583 return false; 584 Val &= 0xFFFFFFFF; 585 return AArch64_AM::isLogicalImmediate(Val, 32); 586 } 587 588 bool isLogicalImm64() const { 589 if (!isImm()) 590 return false; 591 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 592 if (!MCE) 593 return false; 594 return AArch64_AM::isLogicalImmediate(MCE->getValue(), 64); 595 } 596 597 bool isLogicalImm32Not() const { 598 if (!isImm()) 599 return false; 600 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 601 if (!MCE) 602 return false; 603 int64_t Val = ~MCE->getValue() & 0xFFFFFFFF; 604 return AArch64_AM::isLogicalImmediate(Val, 32); 605 } 606 607 bool isLogicalImm64Not() const { 608 if (!isImm()) 609 return false; 610 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 611 if (!MCE) 612 return false; 613 return AArch64_AM::isLogicalImmediate(~MCE->getValue(), 64); 614 } 615 616 bool isShiftedImm() const { return Kind == k_ShiftedImm; } 617 618 bool isAddSubImm() const { 619 if (!isShiftedImm() && !isImm()) 620 return false; 621 622 const MCExpr *Expr; 623 624 // An ADD/SUB shifter is either 'lsl #0' or 'lsl #12'. 625 if (isShiftedImm()) { 626 unsigned Shift = ShiftedImm.ShiftAmount; 627 Expr = ShiftedImm.Val; 628 if (Shift != 0 && Shift != 12) 629 return false; 630 } else { 631 Expr = getImm(); 632 } 633 634 AArch64MCExpr::VariantKind ELFRefKind; 635 MCSymbolRefExpr::VariantKind DarwinRefKind; 636 int64_t Addend; 637 if (AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind, 638 DarwinRefKind, Addend)) { 639 return DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF 640 || DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF 641 || (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF && Addend == 0) 642 || ELFRefKind == AArch64MCExpr::VK_LO12 643 || ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 644 || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 645 || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC 646 || ELFRefKind == AArch64MCExpr::VK_TPREL_HI12 647 || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 648 || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC 649 || ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12; 650 } 651 652 // If it's a constant, it should be a real immediate in range: 653 if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) 654 return CE->getValue() >= 0 && CE->getValue() <= 0xfff; 655 656 // If it's an expression, we hope for the best and let the fixup/relocation 657 // code deal with it. 658 return true; 659 } 660 661 bool isAddSubImmNeg() const { 662 if (!isShiftedImm() && !isImm()) 663 return false; 664 665 const MCExpr *Expr; 666 667 // An ADD/SUB shifter is either 'lsl #0' or 'lsl #12'. 668 if (isShiftedImm()) { 669 unsigned Shift = ShiftedImm.ShiftAmount; 670 Expr = ShiftedImm.Val; 671 if (Shift != 0 && Shift != 12) 672 return false; 673 } else 674 Expr = getImm(); 675 676 // Otherwise it should be a real negative immediate in range: 677 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 678 return CE != nullptr && CE->getValue() < 0 && -CE->getValue() <= 0xfff; 679 } 680 681 bool isCondCode() const { return Kind == k_CondCode; } 682 683 bool isSIMDImmType10() const { 684 if (!isImm()) 685 return false; 686 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 687 if (!MCE) 688 return false; 689 return AArch64_AM::isAdvSIMDModImmType10(MCE->getValue()); 690 } 691 692 template<int N> 693 bool isBranchTarget() const { 694 if (!isImm()) 695 return false; 696 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 697 if (!MCE) 698 return true; 699 int64_t Val = MCE->getValue(); 700 if (Val & 0x3) 701 return false; 702 assert(N > 0 && "Branch target immediate cannot be 0 bits!"); 703 return (Val >= -((1<<(N-1)) << 2) && Val <= (((1<<(N-1))-1) << 2)); 704 } 705 706 bool 707 isMovWSymbol(ArrayRef<AArch64MCExpr::VariantKind> AllowedModifiers) const { 708 if (!isImm()) 709 return false; 710 711 AArch64MCExpr::VariantKind ELFRefKind; 712 MCSymbolRefExpr::VariantKind DarwinRefKind; 713 int64_t Addend; 714 if (!AArch64AsmParser::classifySymbolRef(getImm(), ELFRefKind, 715 DarwinRefKind, Addend)) { 716 return false; 717 } 718 if (DarwinRefKind != MCSymbolRefExpr::VK_None) 719 return false; 720 721 for (unsigned i = 0; i != AllowedModifiers.size(); ++i) { 722 if (ELFRefKind == AllowedModifiers[i]) 723 return Addend == 0; 724 } 725 726 return false; 727 } 728 729 bool isMovZSymbolG3() const { 730 return isMovWSymbol(AArch64MCExpr::VK_ABS_G3); 731 } 732 733 bool isMovZSymbolG2() const { 734 return isMovWSymbol({AArch64MCExpr::VK_ABS_G2, AArch64MCExpr::VK_ABS_G2_S, 735 AArch64MCExpr::VK_TPREL_G2, 736 AArch64MCExpr::VK_DTPREL_G2}); 737 } 738 739 bool isMovZSymbolG1() const { 740 return isMovWSymbol({ 741 AArch64MCExpr::VK_ABS_G1, AArch64MCExpr::VK_ABS_G1_S, 742 AArch64MCExpr::VK_GOTTPREL_G1, AArch64MCExpr::VK_TPREL_G1, 743 AArch64MCExpr::VK_DTPREL_G1, 744 }); 745 } 746 747 bool isMovZSymbolG0() const { 748 return isMovWSymbol({AArch64MCExpr::VK_ABS_G0, AArch64MCExpr::VK_ABS_G0_S, 749 AArch64MCExpr::VK_TPREL_G0, 750 AArch64MCExpr::VK_DTPREL_G0}); 751 } 752 753 bool isMovKSymbolG3() const { 754 return isMovWSymbol(AArch64MCExpr::VK_ABS_G3); 755 } 756 757 bool isMovKSymbolG2() const { 758 return isMovWSymbol(AArch64MCExpr::VK_ABS_G2_NC); 759 } 760 761 bool isMovKSymbolG1() const { 762 return isMovWSymbol({AArch64MCExpr::VK_ABS_G1_NC, 763 AArch64MCExpr::VK_TPREL_G1_NC, 764 AArch64MCExpr::VK_DTPREL_G1_NC}); 765 } 766 767 bool isMovKSymbolG0() const { 768 return isMovWSymbol( 769 {AArch64MCExpr::VK_ABS_G0_NC, AArch64MCExpr::VK_GOTTPREL_G0_NC, 770 AArch64MCExpr::VK_TPREL_G0_NC, AArch64MCExpr::VK_DTPREL_G0_NC}); 771 } 772 773 template<int RegWidth, int Shift> 774 bool isMOVZMovAlias() const { 775 if (!isImm()) return false; 776 777 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 778 if (!CE) return false; 779 uint64_t Value = CE->getValue(); 780 781 return AArch64_AM::isMOVZMovAlias(Value, Shift, RegWidth); 782 } 783 784 template<int RegWidth, int Shift> 785 bool isMOVNMovAlias() const { 786 if (!isImm()) return false; 787 788 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 789 if (!CE) return false; 790 uint64_t Value = CE->getValue(); 791 792 return AArch64_AM::isMOVNMovAlias(Value, Shift, RegWidth); 793 } 794 795 bool isFPImm() const { return Kind == k_FPImm; } 796 bool isBarrier() const { return Kind == k_Barrier; } 797 bool isSysReg() const { return Kind == k_SysReg; } 798 799 bool isMRSSystemRegister() const { 800 if (!isSysReg()) return false; 801 802 return SysReg.MRSReg != -1U; 803 } 804 805 bool isMSRSystemRegister() const { 806 if (!isSysReg()) return false; 807 return SysReg.MSRReg != -1U; 808 } 809 810 bool isSystemPStateFieldWithImm0_1() const { 811 if (!isSysReg()) return false; 812 return (SysReg.PStateField == AArch64PState::PAN || 813 SysReg.PStateField == AArch64PState::UAO); 814 } 815 816 bool isSystemPStateFieldWithImm0_15() const { 817 if (!isSysReg() || isSystemPStateFieldWithImm0_1()) return false; 818 return SysReg.PStateField != -1U; 819 } 820 821 bool isReg() const override { 822 return Kind == k_Register && Reg.Kind == RegKind::Scalar; 823 } 824 825 bool isNeonVectorReg() const { 826 return Kind == k_Register && Reg.Kind == RegKind::NeonVector; 827 } 828 829 bool isNeonVectorRegLo() const { 830 return Kind == k_Register && Reg.Kind == RegKind::NeonVector && 831 AArch64MCRegisterClasses[AArch64::FPR128_loRegClassID].contains( 832 Reg.RegNum); 833 } 834 835 template <unsigned Class> bool isSVEVectorReg() const { 836 RegKind RK; 837 switch (Class) { 838 case AArch64::ZPRRegClassID: 839 RK = RegKind::SVEDataVector; 840 break; 841 case AArch64::PPRRegClassID: 842 RK = RegKind::SVEPredicateVector; 843 break; 844 default: 845 llvm_unreachable("Unsupport register class"); 846 } 847 848 return (Kind == k_Register && Reg.Kind == RK) && 849 AArch64MCRegisterClasses[Class].contains(getReg()); 850 } 851 852 template <int ElementWidth, unsigned Class> 853 bool isSVEVectorRegOfWidth() const { 854 return isSVEVectorReg<Class>() && 855 (ElementWidth == -1 || Reg.ElementWidth == ElementWidth); 856 } 857 858 bool isGPR32as64() const { 859 return Kind == k_Register && Reg.Kind == RegKind::Scalar && 860 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(Reg.RegNum); 861 } 862 863 bool isWSeqPair() const { 864 return Kind == k_Register && Reg.Kind == RegKind::Scalar && 865 AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID].contains( 866 Reg.RegNum); 867 } 868 869 bool isXSeqPair() const { 870 return Kind == k_Register && Reg.Kind == RegKind::Scalar && 871 AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID].contains( 872 Reg.RegNum); 873 } 874 875 bool isGPR64sp0() const { 876 return Kind == k_Register && Reg.Kind == RegKind::Scalar && 877 AArch64MCRegisterClasses[AArch64::GPR64spRegClassID].contains(Reg.RegNum); 878 } 879 880 template<int64_t Angle, int64_t Remainder> 881 bool isComplexRotation() const { 882 if (!isImm()) return false; 883 884 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 885 if (!CE) return false; 886 uint64_t Value = CE->getValue(); 887 888 return (Value % Angle == Remainder && Value <= 270); 889 } 890 891 /// Is this a vector list with the type implicit (presumably attached to the 892 /// instruction itself)? 893 template <unsigned NumRegs> bool isImplicitlyTypedVectorList() const { 894 return Kind == k_VectorList && VectorList.Count == NumRegs && 895 !VectorList.ElementKind; 896 } 897 898 template <unsigned NumRegs, unsigned NumElements, char ElementKind> 899 bool isTypedVectorList() const { 900 if (Kind != k_VectorList) 901 return false; 902 if (VectorList.Count != NumRegs) 903 return false; 904 if (VectorList.ElementKind != ElementKind) 905 return false; 906 return VectorList.NumElements == NumElements; 907 } 908 909 bool isVectorIndex1() const { 910 return Kind == k_VectorIndex && VectorIndex.Val == 1; 911 } 912 913 bool isVectorIndexB() const { 914 return Kind == k_VectorIndex && VectorIndex.Val < 16; 915 } 916 917 bool isVectorIndexH() const { 918 return Kind == k_VectorIndex && VectorIndex.Val < 8; 919 } 920 921 bool isVectorIndexS() const { 922 return Kind == k_VectorIndex && VectorIndex.Val < 4; 923 } 924 925 bool isVectorIndexD() const { 926 return Kind == k_VectorIndex && VectorIndex.Val < 2; 927 } 928 929 bool isToken() const override { return Kind == k_Token; } 930 931 bool isTokenEqual(StringRef Str) const { 932 return Kind == k_Token && getToken() == Str; 933 } 934 bool isSysCR() const { return Kind == k_SysCR; } 935 bool isPrefetch() const { return Kind == k_Prefetch; } 936 bool isPSBHint() const { return Kind == k_PSBHint; } 937 bool isShiftExtend() const { return Kind == k_ShiftExtend; } 938 bool isShifter() const { 939 if (!isShiftExtend()) 940 return false; 941 942 AArch64_AM::ShiftExtendType ST = getShiftExtendType(); 943 return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR || 944 ST == AArch64_AM::ASR || ST == AArch64_AM::ROR || 945 ST == AArch64_AM::MSL); 946 } 947 bool isExtend() const { 948 if (!isShiftExtend()) 949 return false; 950 951 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 952 return (ET == AArch64_AM::UXTB || ET == AArch64_AM::SXTB || 953 ET == AArch64_AM::UXTH || ET == AArch64_AM::SXTH || 954 ET == AArch64_AM::UXTW || ET == AArch64_AM::SXTW || 955 ET == AArch64_AM::UXTX || ET == AArch64_AM::SXTX || 956 ET == AArch64_AM::LSL) && 957 getShiftExtendAmount() <= 4; 958 } 959 960 bool isExtend64() const { 961 if (!isExtend()) 962 return false; 963 // UXTX and SXTX require a 64-bit source register (the ExtendLSL64 class). 964 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 965 return ET != AArch64_AM::UXTX && ET != AArch64_AM::SXTX; 966 } 967 968 bool isExtendLSL64() const { 969 if (!isExtend()) 970 return false; 971 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 972 return (ET == AArch64_AM::UXTX || ET == AArch64_AM::SXTX || 973 ET == AArch64_AM::LSL) && 974 getShiftExtendAmount() <= 4; 975 } 976 977 template<int Width> bool isMemXExtend() const { 978 if (!isExtend()) 979 return false; 980 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 981 return (ET == AArch64_AM::LSL || ET == AArch64_AM::SXTX) && 982 (getShiftExtendAmount() == Log2_32(Width / 8) || 983 getShiftExtendAmount() == 0); 984 } 985 986 template<int Width> bool isMemWExtend() const { 987 if (!isExtend()) 988 return false; 989 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 990 return (ET == AArch64_AM::UXTW || ET == AArch64_AM::SXTW) && 991 (getShiftExtendAmount() == Log2_32(Width / 8) || 992 getShiftExtendAmount() == 0); 993 } 994 995 template <unsigned width> 996 bool isArithmeticShifter() const { 997 if (!isShifter()) 998 return false; 999 1000 // An arithmetic shifter is LSL, LSR, or ASR. 1001 AArch64_AM::ShiftExtendType ST = getShiftExtendType(); 1002 return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR || 1003 ST == AArch64_AM::ASR) && getShiftExtendAmount() < width; 1004 } 1005 1006 template <unsigned width> 1007 bool isLogicalShifter() const { 1008 if (!isShifter()) 1009 return false; 1010 1011 // A logical shifter is LSL, LSR, ASR or ROR. 1012 AArch64_AM::ShiftExtendType ST = getShiftExtendType(); 1013 return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR || 1014 ST == AArch64_AM::ASR || ST == AArch64_AM::ROR) && 1015 getShiftExtendAmount() < width; 1016 } 1017 1018 bool isMovImm32Shifter() const { 1019 if (!isShifter()) 1020 return false; 1021 1022 // A MOVi shifter is LSL of 0, 16, 32, or 48. 1023 AArch64_AM::ShiftExtendType ST = getShiftExtendType(); 1024 if (ST != AArch64_AM::LSL) 1025 return false; 1026 uint64_t Val = getShiftExtendAmount(); 1027 return (Val == 0 || Val == 16); 1028 } 1029 1030 bool isMovImm64Shifter() const { 1031 if (!isShifter()) 1032 return false; 1033 1034 // A MOVi shifter is LSL of 0 or 16. 1035 AArch64_AM::ShiftExtendType ST = getShiftExtendType(); 1036 if (ST != AArch64_AM::LSL) 1037 return false; 1038 uint64_t Val = getShiftExtendAmount(); 1039 return (Val == 0 || Val == 16 || Val == 32 || Val == 48); 1040 } 1041 1042 bool isLogicalVecShifter() const { 1043 if (!isShifter()) 1044 return false; 1045 1046 // A logical vector shifter is a left shift by 0, 8, 16, or 24. 1047 unsigned Shift = getShiftExtendAmount(); 1048 return getShiftExtendType() == AArch64_AM::LSL && 1049 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24); 1050 } 1051 1052 bool isLogicalVecHalfWordShifter() const { 1053 if (!isLogicalVecShifter()) 1054 return false; 1055 1056 // A logical vector shifter is a left shift by 0 or 8. 1057 unsigned Shift = getShiftExtendAmount(); 1058 return getShiftExtendType() == AArch64_AM::LSL && 1059 (Shift == 0 || Shift == 8); 1060 } 1061 1062 bool isMoveVecShifter() const { 1063 if (!isShiftExtend()) 1064 return false; 1065 1066 // A logical vector shifter is a left shift by 8 or 16. 1067 unsigned Shift = getShiftExtendAmount(); 1068 return getShiftExtendType() == AArch64_AM::MSL && 1069 (Shift == 8 || Shift == 16); 1070 } 1071 1072 // Fallback unscaled operands are for aliases of LDR/STR that fall back 1073 // to LDUR/STUR when the offset is not legal for the former but is for 1074 // the latter. As such, in addition to checking for being a legal unscaled 1075 // address, also check that it is not a legal scaled address. This avoids 1076 // ambiguity in the matcher. 1077 template<int Width> 1078 bool isSImm9OffsetFB() const { 1079 return isSImm9() && !isUImm12Offset<Width / 8>(); 1080 } 1081 1082 bool isAdrpLabel() const { 1083 // Validation was handled during parsing, so we just sanity check that 1084 // something didn't go haywire. 1085 if (!isImm()) 1086 return false; 1087 1088 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) { 1089 int64_t Val = CE->getValue(); 1090 int64_t Min = - (4096 * (1LL << (21 - 1))); 1091 int64_t Max = 4096 * ((1LL << (21 - 1)) - 1); 1092 return (Val % 4096) == 0 && Val >= Min && Val <= Max; 1093 } 1094 1095 return true; 1096 } 1097 1098 bool isAdrLabel() const { 1099 // Validation was handled during parsing, so we just sanity check that 1100 // something didn't go haywire. 1101 if (!isImm()) 1102 return false; 1103 1104 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) { 1105 int64_t Val = CE->getValue(); 1106 int64_t Min = - (1LL << (21 - 1)); 1107 int64_t Max = ((1LL << (21 - 1)) - 1); 1108 return Val >= Min && Val <= Max; 1109 } 1110 1111 return true; 1112 } 1113 1114 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 1115 // Add as immediates when possible. Null MCExpr = 0. 1116 if (!Expr) 1117 Inst.addOperand(MCOperand::createImm(0)); 1118 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 1119 Inst.addOperand(MCOperand::createImm(CE->getValue())); 1120 else 1121 Inst.addOperand(MCOperand::createExpr(Expr)); 1122 } 1123 1124 void addRegOperands(MCInst &Inst, unsigned N) const { 1125 assert(N == 1 && "Invalid number of operands!"); 1126 Inst.addOperand(MCOperand::createReg(getReg())); 1127 } 1128 1129 void addGPR32as64Operands(MCInst &Inst, unsigned N) const { 1130 assert(N == 1 && "Invalid number of operands!"); 1131 assert( 1132 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(getReg())); 1133 1134 const MCRegisterInfo *RI = Ctx.getRegisterInfo(); 1135 uint32_t Reg = RI->getRegClass(AArch64::GPR32RegClassID).getRegister( 1136 RI->getEncodingValue(getReg())); 1137 1138 Inst.addOperand(MCOperand::createReg(Reg)); 1139 } 1140 1141 void addVectorReg64Operands(MCInst &Inst, unsigned N) const { 1142 assert(N == 1 && "Invalid number of operands!"); 1143 assert( 1144 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains(getReg())); 1145 Inst.addOperand(MCOperand::createReg(AArch64::D0 + getReg() - AArch64::Q0)); 1146 } 1147 1148 void addVectorReg128Operands(MCInst &Inst, unsigned N) const { 1149 assert(N == 1 && "Invalid number of operands!"); 1150 assert( 1151 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains(getReg())); 1152 Inst.addOperand(MCOperand::createReg(getReg())); 1153 } 1154 1155 void addVectorRegLoOperands(MCInst &Inst, unsigned N) const { 1156 assert(N == 1 && "Invalid number of operands!"); 1157 Inst.addOperand(MCOperand::createReg(getReg())); 1158 } 1159 1160 template <unsigned NumRegs> 1161 void addVectorList64Operands(MCInst &Inst, unsigned N) const { 1162 assert(N == 1 && "Invalid number of operands!"); 1163 static const unsigned FirstRegs[] = { AArch64::D0, 1164 AArch64::D0_D1, 1165 AArch64::D0_D1_D2, 1166 AArch64::D0_D1_D2_D3 }; 1167 unsigned FirstReg = FirstRegs[NumRegs - 1]; 1168 1169 Inst.addOperand( 1170 MCOperand::createReg(FirstReg + getVectorListStart() - AArch64::Q0)); 1171 } 1172 1173 template <unsigned NumRegs> 1174 void addVectorList128Operands(MCInst &Inst, unsigned N) const { 1175 assert(N == 1 && "Invalid number of operands!"); 1176 static const unsigned FirstRegs[] = { AArch64::Q0, 1177 AArch64::Q0_Q1, 1178 AArch64::Q0_Q1_Q2, 1179 AArch64::Q0_Q1_Q2_Q3 }; 1180 unsigned FirstReg = FirstRegs[NumRegs - 1]; 1181 1182 Inst.addOperand( 1183 MCOperand::createReg(FirstReg + getVectorListStart() - AArch64::Q0)); 1184 } 1185 1186 void addVectorIndex1Operands(MCInst &Inst, unsigned N) const { 1187 assert(N == 1 && "Invalid number of operands!"); 1188 Inst.addOperand(MCOperand::createImm(getVectorIndex())); 1189 } 1190 1191 void addVectorIndexBOperands(MCInst &Inst, unsigned N) const { 1192 assert(N == 1 && "Invalid number of operands!"); 1193 Inst.addOperand(MCOperand::createImm(getVectorIndex())); 1194 } 1195 1196 void addVectorIndexHOperands(MCInst &Inst, unsigned N) const { 1197 assert(N == 1 && "Invalid number of operands!"); 1198 Inst.addOperand(MCOperand::createImm(getVectorIndex())); 1199 } 1200 1201 void addVectorIndexSOperands(MCInst &Inst, unsigned N) const { 1202 assert(N == 1 && "Invalid number of operands!"); 1203 Inst.addOperand(MCOperand::createImm(getVectorIndex())); 1204 } 1205 1206 void addVectorIndexDOperands(MCInst &Inst, unsigned N) const { 1207 assert(N == 1 && "Invalid number of operands!"); 1208 Inst.addOperand(MCOperand::createImm(getVectorIndex())); 1209 } 1210 1211 void addImmOperands(MCInst &Inst, unsigned N) const { 1212 assert(N == 1 && "Invalid number of operands!"); 1213 // If this is a pageoff symrefexpr with an addend, adjust the addend 1214 // to be only the page-offset portion. Otherwise, just add the expr 1215 // as-is. 1216 addExpr(Inst, getImm()); 1217 } 1218 1219 void addAddSubImmOperands(MCInst &Inst, unsigned N) const { 1220 assert(N == 2 && "Invalid number of operands!"); 1221 if (isShiftedImm()) { 1222 addExpr(Inst, getShiftedImmVal()); 1223 Inst.addOperand(MCOperand::createImm(getShiftedImmShift())); 1224 } else { 1225 addExpr(Inst, getImm()); 1226 Inst.addOperand(MCOperand::createImm(0)); 1227 } 1228 } 1229 1230 void addAddSubImmNegOperands(MCInst &Inst, unsigned N) const { 1231 assert(N == 2 && "Invalid number of operands!"); 1232 1233 const MCExpr *MCE = isShiftedImm() ? getShiftedImmVal() : getImm(); 1234 const MCConstantExpr *CE = cast<MCConstantExpr>(MCE); 1235 int64_t Val = -CE->getValue(); 1236 unsigned ShiftAmt = isShiftedImm() ? ShiftedImm.ShiftAmount : 0; 1237 1238 Inst.addOperand(MCOperand::createImm(Val)); 1239 Inst.addOperand(MCOperand::createImm(ShiftAmt)); 1240 } 1241 1242 void addCondCodeOperands(MCInst &Inst, unsigned N) const { 1243 assert(N == 1 && "Invalid number of operands!"); 1244 Inst.addOperand(MCOperand::createImm(getCondCode())); 1245 } 1246 1247 void addAdrpLabelOperands(MCInst &Inst, unsigned N) const { 1248 assert(N == 1 && "Invalid number of operands!"); 1249 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 1250 if (!MCE) 1251 addExpr(Inst, getImm()); 1252 else 1253 Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 12)); 1254 } 1255 1256 void addAdrLabelOperands(MCInst &Inst, unsigned N) const { 1257 addImmOperands(Inst, N); 1258 } 1259 1260 template<int Scale> 1261 void addUImm12OffsetOperands(MCInst &Inst, unsigned N) const { 1262 assert(N == 1 && "Invalid number of operands!"); 1263 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 1264 1265 if (!MCE) { 1266 Inst.addOperand(MCOperand::createExpr(getImm())); 1267 return; 1268 } 1269 Inst.addOperand(MCOperand::createImm(MCE->getValue() / Scale)); 1270 } 1271 1272 void addSImm9Operands(MCInst &Inst, unsigned N) const { 1273 assert(N == 1 && "Invalid number of operands!"); 1274 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1275 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1276 } 1277 1278 void addSImm10s8Operands(MCInst &Inst, unsigned N) const { 1279 assert(N == 1 && "Invalid number of operands!"); 1280 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1281 Inst.addOperand(MCOperand::createImm(MCE->getValue() / 8)); 1282 } 1283 1284 void addSImm7s4Operands(MCInst &Inst, unsigned N) const { 1285 assert(N == 1 && "Invalid number of operands!"); 1286 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1287 Inst.addOperand(MCOperand::createImm(MCE->getValue() / 4)); 1288 } 1289 1290 void addSImm7s8Operands(MCInst &Inst, unsigned N) const { 1291 assert(N == 1 && "Invalid number of operands!"); 1292 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1293 Inst.addOperand(MCOperand::createImm(MCE->getValue() / 8)); 1294 } 1295 1296 void addSImm7s16Operands(MCInst &Inst, unsigned N) const { 1297 assert(N == 1 && "Invalid number of operands!"); 1298 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1299 Inst.addOperand(MCOperand::createImm(MCE->getValue() / 16)); 1300 } 1301 1302 void addImm0_1Operands(MCInst &Inst, unsigned N) const { 1303 assert(N == 1 && "Invalid number of operands!"); 1304 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1305 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1306 } 1307 1308 void addImm0_7Operands(MCInst &Inst, unsigned N) const { 1309 assert(N == 1 && "Invalid number of operands!"); 1310 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1311 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1312 } 1313 1314 void addImm1_8Operands(MCInst &Inst, unsigned N) const { 1315 assert(N == 1 && "Invalid number of operands!"); 1316 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1317 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1318 } 1319 1320 void addImm0_15Operands(MCInst &Inst, unsigned N) const { 1321 assert(N == 1 && "Invalid number of operands!"); 1322 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1323 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1324 } 1325 1326 void addImm1_16Operands(MCInst &Inst, unsigned N) const { 1327 assert(N == 1 && "Invalid number of operands!"); 1328 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1329 assert(MCE && "Invalid constant immediate operand!"); 1330 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1331 } 1332 1333 void addImm0_31Operands(MCInst &Inst, unsigned N) const { 1334 assert(N == 1 && "Invalid number of operands!"); 1335 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1336 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1337 } 1338 1339 void addImm1_31Operands(MCInst &Inst, unsigned N) const { 1340 assert(N == 1 && "Invalid number of operands!"); 1341 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1342 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1343 } 1344 1345 void addImm1_32Operands(MCInst &Inst, unsigned N) const { 1346 assert(N == 1 && "Invalid number of operands!"); 1347 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1348 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1349 } 1350 1351 void addImm0_63Operands(MCInst &Inst, unsigned N) const { 1352 assert(N == 1 && "Invalid number of operands!"); 1353 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1354 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1355 } 1356 1357 void addImm1_63Operands(MCInst &Inst, unsigned N) const { 1358 assert(N == 1 && "Invalid number of operands!"); 1359 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1360 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1361 } 1362 1363 void addImm1_64Operands(MCInst &Inst, unsigned N) const { 1364 assert(N == 1 && "Invalid number of operands!"); 1365 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1366 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1367 } 1368 1369 void addImm0_127Operands(MCInst &Inst, unsigned N) const { 1370 assert(N == 1 && "Invalid number of operands!"); 1371 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1372 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1373 } 1374 1375 void addImm0_255Operands(MCInst &Inst, unsigned N) const { 1376 assert(N == 1 && "Invalid number of operands!"); 1377 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1378 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1379 } 1380 1381 void addImm0_65535Operands(MCInst &Inst, unsigned N) const { 1382 assert(N == 1 && "Invalid number of operands!"); 1383 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1384 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1385 } 1386 1387 void addImm32_63Operands(MCInst &Inst, unsigned N) const { 1388 assert(N == 1 && "Invalid number of operands!"); 1389 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1390 Inst.addOperand(MCOperand::createImm(MCE->getValue())); 1391 } 1392 1393 void addLogicalImm32Operands(MCInst &Inst, unsigned N) const { 1394 assert(N == 1 && "Invalid number of operands!"); 1395 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1396 uint64_t encoding = 1397 AArch64_AM::encodeLogicalImmediate(MCE->getValue() & 0xFFFFFFFF, 32); 1398 Inst.addOperand(MCOperand::createImm(encoding)); 1399 } 1400 1401 void addLogicalImm64Operands(MCInst &Inst, unsigned N) const { 1402 assert(N == 1 && "Invalid number of operands!"); 1403 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1404 uint64_t encoding = AArch64_AM::encodeLogicalImmediate(MCE->getValue(), 64); 1405 Inst.addOperand(MCOperand::createImm(encoding)); 1406 } 1407 1408 void addLogicalImm32NotOperands(MCInst &Inst, unsigned N) const { 1409 assert(N == 1 && "Invalid number of operands!"); 1410 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1411 int64_t Val = ~MCE->getValue() & 0xFFFFFFFF; 1412 uint64_t encoding = AArch64_AM::encodeLogicalImmediate(Val, 32); 1413 Inst.addOperand(MCOperand::createImm(encoding)); 1414 } 1415 1416 void addLogicalImm64NotOperands(MCInst &Inst, unsigned N) const { 1417 assert(N == 1 && "Invalid number of operands!"); 1418 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1419 uint64_t encoding = 1420 AArch64_AM::encodeLogicalImmediate(~MCE->getValue(), 64); 1421 Inst.addOperand(MCOperand::createImm(encoding)); 1422 } 1423 1424 void addSIMDImmType10Operands(MCInst &Inst, unsigned N) const { 1425 assert(N == 1 && "Invalid number of operands!"); 1426 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1427 uint64_t encoding = AArch64_AM::encodeAdvSIMDModImmType10(MCE->getValue()); 1428 Inst.addOperand(MCOperand::createImm(encoding)); 1429 } 1430 1431 void addBranchTarget26Operands(MCInst &Inst, unsigned N) const { 1432 // Branch operands don't encode the low bits, so shift them off 1433 // here. If it's a label, however, just put it on directly as there's 1434 // not enough information now to do anything. 1435 assert(N == 1 && "Invalid number of operands!"); 1436 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 1437 if (!MCE) { 1438 addExpr(Inst, getImm()); 1439 return; 1440 } 1441 assert(MCE && "Invalid constant immediate operand!"); 1442 Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2)); 1443 } 1444 1445 void addPCRelLabel19Operands(MCInst &Inst, unsigned N) const { 1446 // Branch operands don't encode the low bits, so shift them off 1447 // here. If it's a label, however, just put it on directly as there's 1448 // not enough information now to do anything. 1449 assert(N == 1 && "Invalid number of operands!"); 1450 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 1451 if (!MCE) { 1452 addExpr(Inst, getImm()); 1453 return; 1454 } 1455 assert(MCE && "Invalid constant immediate operand!"); 1456 Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2)); 1457 } 1458 1459 void addBranchTarget14Operands(MCInst &Inst, unsigned N) const { 1460 // Branch operands don't encode the low bits, so shift them off 1461 // here. If it's a label, however, just put it on directly as there's 1462 // not enough information now to do anything. 1463 assert(N == 1 && "Invalid number of operands!"); 1464 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); 1465 if (!MCE) { 1466 addExpr(Inst, getImm()); 1467 return; 1468 } 1469 assert(MCE && "Invalid constant immediate operand!"); 1470 Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2)); 1471 } 1472 1473 void addFPImmOperands(MCInst &Inst, unsigned N) const { 1474 assert(N == 1 && "Invalid number of operands!"); 1475 Inst.addOperand(MCOperand::createImm(getFPImm())); 1476 } 1477 1478 void addBarrierOperands(MCInst &Inst, unsigned N) const { 1479 assert(N == 1 && "Invalid number of operands!"); 1480 Inst.addOperand(MCOperand::createImm(getBarrier())); 1481 } 1482 1483 void addMRSSystemRegisterOperands(MCInst &Inst, unsigned N) const { 1484 assert(N == 1 && "Invalid number of operands!"); 1485 1486 Inst.addOperand(MCOperand::createImm(SysReg.MRSReg)); 1487 } 1488 1489 void addMSRSystemRegisterOperands(MCInst &Inst, unsigned N) const { 1490 assert(N == 1 && "Invalid number of operands!"); 1491 1492 Inst.addOperand(MCOperand::createImm(SysReg.MSRReg)); 1493 } 1494 1495 void addSystemPStateFieldWithImm0_1Operands(MCInst &Inst, unsigned N) const { 1496 assert(N == 1 && "Invalid number of operands!"); 1497 1498 Inst.addOperand(MCOperand::createImm(SysReg.PStateField)); 1499 } 1500 1501 void addSystemPStateFieldWithImm0_15Operands(MCInst &Inst, unsigned N) const { 1502 assert(N == 1 && "Invalid number of operands!"); 1503 1504 Inst.addOperand(MCOperand::createImm(SysReg.PStateField)); 1505 } 1506 1507 void addSysCROperands(MCInst &Inst, unsigned N) const { 1508 assert(N == 1 && "Invalid number of operands!"); 1509 Inst.addOperand(MCOperand::createImm(getSysCR())); 1510 } 1511 1512 void addPrefetchOperands(MCInst &Inst, unsigned N) const { 1513 assert(N == 1 && "Invalid number of operands!"); 1514 Inst.addOperand(MCOperand::createImm(getPrefetch())); 1515 } 1516 1517 void addPSBHintOperands(MCInst &Inst, unsigned N) const { 1518 assert(N == 1 && "Invalid number of operands!"); 1519 Inst.addOperand(MCOperand::createImm(getPSBHint())); 1520 } 1521 1522 void addShifterOperands(MCInst &Inst, unsigned N) const { 1523 assert(N == 1 && "Invalid number of operands!"); 1524 unsigned Imm = 1525 AArch64_AM::getShifterImm(getShiftExtendType(), getShiftExtendAmount()); 1526 Inst.addOperand(MCOperand::createImm(Imm)); 1527 } 1528 1529 void addExtendOperands(MCInst &Inst, unsigned N) const { 1530 assert(N == 1 && "Invalid number of operands!"); 1531 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 1532 if (ET == AArch64_AM::LSL) ET = AArch64_AM::UXTW; 1533 unsigned Imm = AArch64_AM::getArithExtendImm(ET, getShiftExtendAmount()); 1534 Inst.addOperand(MCOperand::createImm(Imm)); 1535 } 1536 1537 void addExtend64Operands(MCInst &Inst, unsigned N) const { 1538 assert(N == 1 && "Invalid number of operands!"); 1539 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 1540 if (ET == AArch64_AM::LSL) ET = AArch64_AM::UXTX; 1541 unsigned Imm = AArch64_AM::getArithExtendImm(ET, getShiftExtendAmount()); 1542 Inst.addOperand(MCOperand::createImm(Imm)); 1543 } 1544 1545 void addMemExtendOperands(MCInst &Inst, unsigned N) const { 1546 assert(N == 2 && "Invalid number of operands!"); 1547 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 1548 bool IsSigned = ET == AArch64_AM::SXTW || ET == AArch64_AM::SXTX; 1549 Inst.addOperand(MCOperand::createImm(IsSigned)); 1550 Inst.addOperand(MCOperand::createImm(getShiftExtendAmount() != 0)); 1551 } 1552 1553 // For 8-bit load/store instructions with a register offset, both the 1554 // "DoShift" and "NoShift" variants have a shift of 0. Because of this, 1555 // they're disambiguated by whether the shift was explicit or implicit rather 1556 // than its size. 1557 void addMemExtend8Operands(MCInst &Inst, unsigned N) const { 1558 assert(N == 2 && "Invalid number of operands!"); 1559 AArch64_AM::ShiftExtendType ET = getShiftExtendType(); 1560 bool IsSigned = ET == AArch64_AM::SXTW || ET == AArch64_AM::SXTX; 1561 Inst.addOperand(MCOperand::createImm(IsSigned)); 1562 Inst.addOperand(MCOperand::createImm(hasShiftExtendAmount())); 1563 } 1564 1565 template<int Shift> 1566 void addMOVZMovAliasOperands(MCInst &Inst, unsigned N) const { 1567 assert(N == 1 && "Invalid number of operands!"); 1568 1569 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 1570 uint64_t Value = CE->getValue(); 1571 Inst.addOperand(MCOperand::createImm((Value >> Shift) & 0xffff)); 1572 } 1573 1574 template<int Shift> 1575 void addMOVNMovAliasOperands(MCInst &Inst, unsigned N) const { 1576 assert(N == 1 && "Invalid number of operands!"); 1577 1578 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 1579 uint64_t Value = CE->getValue(); 1580 Inst.addOperand(MCOperand::createImm((~Value >> Shift) & 0xffff)); 1581 } 1582 1583 void addComplexRotationEvenOperands(MCInst &Inst, unsigned N) const { 1584 assert(N == 1 && "Invalid number of operands!"); 1585 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1586 Inst.addOperand(MCOperand::createImm(MCE->getValue() / 90)); 1587 } 1588 1589 void addComplexRotationOddOperands(MCInst &Inst, unsigned N) const { 1590 assert(N == 1 && "Invalid number of operands!"); 1591 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); 1592 Inst.addOperand(MCOperand::createImm((MCE->getValue() - 90) / 180)); 1593 } 1594 1595 void print(raw_ostream &OS) const override; 1596 1597 static std::unique_ptr<AArch64Operand> 1598 CreateToken(StringRef Str, bool IsSuffix, SMLoc S, MCContext &Ctx) { 1599 auto Op = make_unique<AArch64Operand>(k_Token, Ctx); 1600 Op->Tok.Data = Str.data(); 1601 Op->Tok.Length = Str.size(); 1602 Op->Tok.IsSuffix = IsSuffix; 1603 Op->StartLoc = S; 1604 Op->EndLoc = S; 1605 return Op; 1606 } 1607 1608 static std::unique_ptr<AArch64Operand> 1609 CreateReg(unsigned RegNum, RegKind Kind, SMLoc S, SMLoc E, MCContext &Ctx) { 1610 auto Op = make_unique<AArch64Operand>(k_Register, Ctx); 1611 Op->Reg.RegNum = RegNum; 1612 Op->Reg.Kind = Kind; 1613 Op->StartLoc = S; 1614 Op->EndLoc = E; 1615 return Op; 1616 } 1617 1618 static std::unique_ptr<AArch64Operand> 1619 CreateReg(unsigned RegNum, RegKind Kind, unsigned ElementWidth, 1620 SMLoc S, SMLoc E, MCContext &Ctx) { 1621 auto Op = make_unique<AArch64Operand>(k_Register, Ctx); 1622 Op->Reg.RegNum = RegNum; 1623 Op->Reg.ElementWidth = ElementWidth; 1624 Op->Reg.Kind = Kind; 1625 Op->StartLoc = S; 1626 Op->EndLoc = E; 1627 return Op; 1628 } 1629 1630 static std::unique_ptr<AArch64Operand> 1631 CreateVectorList(unsigned RegNum, unsigned Count, unsigned NumElements, 1632 char ElementKind, SMLoc S, SMLoc E, MCContext &Ctx) { 1633 auto Op = make_unique<AArch64Operand>(k_VectorList, Ctx); 1634 Op->VectorList.RegNum = RegNum; 1635 Op->VectorList.Count = Count; 1636 Op->VectorList.NumElements = NumElements; 1637 Op->VectorList.ElementKind = ElementKind; 1638 Op->StartLoc = S; 1639 Op->EndLoc = E; 1640 return Op; 1641 } 1642 1643 static std::unique_ptr<AArch64Operand> 1644 CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, MCContext &Ctx) { 1645 auto Op = make_unique<AArch64Operand>(k_VectorIndex, Ctx); 1646 Op->VectorIndex.Val = Idx; 1647 Op->StartLoc = S; 1648 Op->EndLoc = E; 1649 return Op; 1650 } 1651 1652 static std::unique_ptr<AArch64Operand> CreateImm(const MCExpr *Val, SMLoc S, 1653 SMLoc E, MCContext &Ctx) { 1654 auto Op = make_unique<AArch64Operand>(k_Immediate, Ctx); 1655 Op->Imm.Val = Val; 1656 Op->StartLoc = S; 1657 Op->EndLoc = E; 1658 return Op; 1659 } 1660 1661 static std::unique_ptr<AArch64Operand> CreateShiftedImm(const MCExpr *Val, 1662 unsigned ShiftAmount, 1663 SMLoc S, SMLoc E, 1664 MCContext &Ctx) { 1665 auto Op = make_unique<AArch64Operand>(k_ShiftedImm, Ctx); 1666 Op->ShiftedImm .Val = Val; 1667 Op->ShiftedImm.ShiftAmount = ShiftAmount; 1668 Op->StartLoc = S; 1669 Op->EndLoc = E; 1670 return Op; 1671 } 1672 1673 static std::unique_ptr<AArch64Operand> 1674 CreateCondCode(AArch64CC::CondCode Code, SMLoc S, SMLoc E, MCContext &Ctx) { 1675 auto Op = make_unique<AArch64Operand>(k_CondCode, Ctx); 1676 Op->CondCode.Code = Code; 1677 Op->StartLoc = S; 1678 Op->EndLoc = E; 1679 return Op; 1680 } 1681 1682 static std::unique_ptr<AArch64Operand> CreateFPImm(unsigned Val, SMLoc S, 1683 MCContext &Ctx) { 1684 auto Op = make_unique<AArch64Operand>(k_FPImm, Ctx); 1685 Op->FPImm.Val = Val; 1686 Op->StartLoc = S; 1687 Op->EndLoc = S; 1688 return Op; 1689 } 1690 1691 static std::unique_ptr<AArch64Operand> CreateBarrier(unsigned Val, 1692 StringRef Str, 1693 SMLoc S, 1694 MCContext &Ctx) { 1695 auto Op = make_unique<AArch64Operand>(k_Barrier, Ctx); 1696 Op->Barrier.Val = Val; 1697 Op->Barrier.Data = Str.data(); 1698 Op->Barrier.Length = Str.size(); 1699 Op->StartLoc = S; 1700 Op->EndLoc = S; 1701 return Op; 1702 } 1703 1704 static std::unique_ptr<AArch64Operand> CreateSysReg(StringRef Str, SMLoc S, 1705 uint32_t MRSReg, 1706 uint32_t MSRReg, 1707 uint32_t PStateField, 1708 MCContext &Ctx) { 1709 auto Op = make_unique<AArch64Operand>(k_SysReg, Ctx); 1710 Op->SysReg.Data = Str.data(); 1711 Op->SysReg.Length = Str.size(); 1712 Op->SysReg.MRSReg = MRSReg; 1713 Op->SysReg.MSRReg = MSRReg; 1714 Op->SysReg.PStateField = PStateField; 1715 Op->StartLoc = S; 1716 Op->EndLoc = S; 1717 return Op; 1718 } 1719 1720 static std::unique_ptr<AArch64Operand> CreateSysCR(unsigned Val, SMLoc S, 1721 SMLoc E, MCContext &Ctx) { 1722 auto Op = make_unique<AArch64Operand>(k_SysCR, Ctx); 1723 Op->SysCRImm.Val = Val; 1724 Op->StartLoc = S; 1725 Op->EndLoc = E; 1726 return Op; 1727 } 1728 1729 static std::unique_ptr<AArch64Operand> CreatePrefetch(unsigned Val, 1730 StringRef Str, 1731 SMLoc S, 1732 MCContext &Ctx) { 1733 auto Op = make_unique<AArch64Operand>(k_Prefetch, Ctx); 1734 Op->Prefetch.Val = Val; 1735 Op->Barrier.Data = Str.data(); 1736 Op->Barrier.Length = Str.size(); 1737 Op->StartLoc = S; 1738 Op->EndLoc = S; 1739 return Op; 1740 } 1741 1742 static std::unique_ptr<AArch64Operand> CreatePSBHint(unsigned Val, 1743 StringRef Str, 1744 SMLoc S, 1745 MCContext &Ctx) { 1746 auto Op = make_unique<AArch64Operand>(k_PSBHint, Ctx); 1747 Op->PSBHint.Val = Val; 1748 Op->PSBHint.Data = Str.data(); 1749 Op->PSBHint.Length = Str.size(); 1750 Op->StartLoc = S; 1751 Op->EndLoc = S; 1752 return Op; 1753 } 1754 1755 static std::unique_ptr<AArch64Operand> 1756 CreateShiftExtend(AArch64_AM::ShiftExtendType ShOp, unsigned Val, 1757 bool HasExplicitAmount, SMLoc S, SMLoc E, MCContext &Ctx) { 1758 auto Op = make_unique<AArch64Operand>(k_ShiftExtend, Ctx); 1759 Op->ShiftExtend.Type = ShOp; 1760 Op->ShiftExtend.Amount = Val; 1761 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount; 1762 Op->StartLoc = S; 1763 Op->EndLoc = E; 1764 return Op; 1765 } 1766 }; 1767 1768 } // end anonymous namespace. 1769 1770 void AArch64Operand::print(raw_ostream &OS) const { 1771 switch (Kind) { 1772 case k_FPImm: 1773 OS << "<fpimm " << getFPImm() << "(" 1774 << AArch64_AM::getFPImmFloat(getFPImm()) << ") >"; 1775 break; 1776 case k_Barrier: { 1777 StringRef Name = getBarrierName(); 1778 if (!Name.empty()) 1779 OS << "<barrier " << Name << ">"; 1780 else 1781 OS << "<barrier invalid #" << getBarrier() << ">"; 1782 break; 1783 } 1784 case k_Immediate: 1785 OS << *getImm(); 1786 break; 1787 case k_ShiftedImm: { 1788 unsigned Shift = getShiftedImmShift(); 1789 OS << "<shiftedimm "; 1790 OS << *getShiftedImmVal(); 1791 OS << ", lsl #" << AArch64_AM::getShiftValue(Shift) << ">"; 1792 break; 1793 } 1794 case k_CondCode: 1795 OS << "<condcode " << getCondCode() << ">"; 1796 break; 1797 case k_Register: 1798 OS << "<register " << getReg() << ">"; 1799 break; 1800 case k_VectorList: { 1801 OS << "<vectorlist "; 1802 unsigned Reg = getVectorListStart(); 1803 for (unsigned i = 0, e = getVectorListCount(); i != e; ++i) 1804 OS << Reg + i << " "; 1805 OS << ">"; 1806 break; 1807 } 1808 case k_VectorIndex: 1809 OS << "<vectorindex " << getVectorIndex() << ">"; 1810 break; 1811 case k_SysReg: 1812 OS << "<sysreg: " << getSysReg() << '>'; 1813 break; 1814 case k_Token: 1815 OS << "'" << getToken() << "'"; 1816 break; 1817 case k_SysCR: 1818 OS << "c" << getSysCR(); 1819 break; 1820 case k_Prefetch: { 1821 StringRef Name = getPrefetchName(); 1822 if (!Name.empty()) 1823 OS << "<prfop " << Name << ">"; 1824 else 1825 OS << "<prfop invalid #" << getPrefetch() << ">"; 1826 break; 1827 } 1828 case k_PSBHint: 1829 OS << getPSBHintName(); 1830 break; 1831 case k_ShiftExtend: 1832 OS << "<" << AArch64_AM::getShiftExtendName(getShiftExtendType()) << " #" 1833 << getShiftExtendAmount(); 1834 if (!hasShiftExtendAmount()) 1835 OS << "<imp>"; 1836 OS << '>'; 1837 break; 1838 } 1839 } 1840 1841 /// @name Auto-generated Match Functions 1842 /// { 1843 1844 static unsigned MatchRegisterName(StringRef Name); 1845 1846 /// } 1847 1848 static unsigned MatchNeonVectorRegName(StringRef Name) { 1849 return StringSwitch<unsigned>(Name.lower()) 1850 .Case("v0", AArch64::Q0) 1851 .Case("v1", AArch64::Q1) 1852 .Case("v2", AArch64::Q2) 1853 .Case("v3", AArch64::Q3) 1854 .Case("v4", AArch64::Q4) 1855 .Case("v5", AArch64::Q5) 1856 .Case("v6", AArch64::Q6) 1857 .Case("v7", AArch64::Q7) 1858 .Case("v8", AArch64::Q8) 1859 .Case("v9", AArch64::Q9) 1860 .Case("v10", AArch64::Q10) 1861 .Case("v11", AArch64::Q11) 1862 .Case("v12", AArch64::Q12) 1863 .Case("v13", AArch64::Q13) 1864 .Case("v14", AArch64::Q14) 1865 .Case("v15", AArch64::Q15) 1866 .Case("v16", AArch64::Q16) 1867 .Case("v17", AArch64::Q17) 1868 .Case("v18", AArch64::Q18) 1869 .Case("v19", AArch64::Q19) 1870 .Case("v20", AArch64::Q20) 1871 .Case("v21", AArch64::Q21) 1872 .Case("v22", AArch64::Q22) 1873 .Case("v23", AArch64::Q23) 1874 .Case("v24", AArch64::Q24) 1875 .Case("v25", AArch64::Q25) 1876 .Case("v26", AArch64::Q26) 1877 .Case("v27", AArch64::Q27) 1878 .Case("v28", AArch64::Q28) 1879 .Case("v29", AArch64::Q29) 1880 .Case("v30", AArch64::Q30) 1881 .Case("v31", AArch64::Q31) 1882 .Default(0); 1883 } 1884 1885 static bool isValidVectorKind(StringRef Name) { 1886 return StringSwitch<bool>(Name.lower()) 1887 .Case(".8b", true) 1888 .Case(".16b", true) 1889 .Case(".4h", true) 1890 .Case(".8h", true) 1891 .Case(".2s", true) 1892 .Case(".4s", true) 1893 .Case(".1d", true) 1894 .Case(".2d", true) 1895 .Case(".1q", true) 1896 // Accept the width neutral ones, too, for verbose syntax. If those 1897 // aren't used in the right places, the token operand won't match so 1898 // all will work out. 1899 .Case(".b", true) 1900 .Case(".h", true) 1901 .Case(".s", true) 1902 .Case(".d", true) 1903 // Needed for fp16 scalar pairwise reductions 1904 .Case(".2h", true) 1905 // another special case for the ARMv8.2a dot product operand 1906 .Case(".4b", true) 1907 .Default(false); 1908 } 1909 1910 static unsigned matchSVEDataVectorRegName(StringRef Name) { 1911 return StringSwitch<unsigned>(Name.lower()) 1912 .Case("z0", AArch64::Z0) 1913 .Case("z1", AArch64::Z1) 1914 .Case("z2", AArch64::Z2) 1915 .Case("z3", AArch64::Z3) 1916 .Case("z4", AArch64::Z4) 1917 .Case("z5", AArch64::Z5) 1918 .Case("z6", AArch64::Z6) 1919 .Case("z7", AArch64::Z7) 1920 .Case("z8", AArch64::Z8) 1921 .Case("z9", AArch64::Z9) 1922 .Case("z10", AArch64::Z10) 1923 .Case("z11", AArch64::Z11) 1924 .Case("z12", AArch64::Z12) 1925 .Case("z13", AArch64::Z13) 1926 .Case("z14", AArch64::Z14) 1927 .Case("z15", AArch64::Z15) 1928 .Case("z16", AArch64::Z16) 1929 .Case("z17", AArch64::Z17) 1930 .Case("z18", AArch64::Z18) 1931 .Case("z19", AArch64::Z19) 1932 .Case("z20", AArch64::Z20) 1933 .Case("z21", AArch64::Z21) 1934 .Case("z22", AArch64::Z22) 1935 .Case("z23", AArch64::Z23) 1936 .Case("z24", AArch64::Z24) 1937 .Case("z25", AArch64::Z25) 1938 .Case("z26", AArch64::Z26) 1939 .Case("z27", AArch64::Z27) 1940 .Case("z28", AArch64::Z28) 1941 .Case("z29", AArch64::Z29) 1942 .Case("z30", AArch64::Z30) 1943 .Case("z31", AArch64::Z31) 1944 .Default(0); 1945 } 1946 1947 static unsigned matchSVEPredicateVectorRegName(StringRef Name) { 1948 return StringSwitch<unsigned>(Name.lower()) 1949 .Case("p0", AArch64::P0) 1950 .Case("p1", AArch64::P1) 1951 .Case("p2", AArch64::P2) 1952 .Case("p3", AArch64::P3) 1953 .Case("p4", AArch64::P4) 1954 .Case("p5", AArch64::P5) 1955 .Case("p6", AArch64::P6) 1956 .Case("p7", AArch64::P7) 1957 .Case("p8", AArch64::P8) 1958 .Case("p9", AArch64::P9) 1959 .Case("p10", AArch64::P10) 1960 .Case("p11", AArch64::P11) 1961 .Case("p12", AArch64::P12) 1962 .Case("p13", AArch64::P13) 1963 .Case("p14", AArch64::P14) 1964 .Case("p15", AArch64::P15) 1965 .Default(0); 1966 } 1967 1968 static bool isValidSVEKind(StringRef Name) { 1969 return StringSwitch<bool>(Name.lower()) 1970 .Case(".b", true) 1971 .Case(".h", true) 1972 .Case(".s", true) 1973 .Case(".d", true) 1974 .Case(".q", true) 1975 .Default(false); 1976 } 1977 1978 static bool isSVERegister(StringRef Name) { 1979 return Name[0] == 'z' || Name[0] == 'p'; 1980 } 1981 1982 static void parseValidVectorKind(StringRef Name, unsigned &NumElements, 1983 char &ElementKind) { 1984 assert(isValidVectorKind(Name)); 1985 1986 ElementKind = Name.lower()[Name.size() - 1]; 1987 NumElements = 0; 1988 1989 if (Name.size() == 2) 1990 return; 1991 1992 // Parse the lane count 1993 Name = Name.drop_front(); 1994 while (isdigit(Name.front())) { 1995 NumElements = 10 * NumElements + (Name.front() - '0'); 1996 Name = Name.drop_front(); 1997 } 1998 } 1999 2000 bool AArch64AsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 2001 SMLoc &EndLoc) { 2002 StartLoc = getLoc(); 2003 RegNo = tryParseRegister(); 2004 EndLoc = SMLoc::getFromPointer(getLoc().getPointer() - 1); 2005 return (RegNo == (unsigned)-1); 2006 } 2007 2008 // Matches a register name or register alias previously defined by '.req' 2009 unsigned AArch64AsmParser::matchRegisterNameAlias(StringRef Name, 2010 RegKind Kind) { 2011 unsigned RegNum; 2012 switch (Kind) { 2013 case RegKind::Scalar: 2014 RegNum = MatchRegisterName(Name); 2015 break; 2016 case RegKind::NeonVector: 2017 RegNum = MatchNeonVectorRegName(Name); 2018 break; 2019 case RegKind::SVEDataVector: 2020 RegNum = matchSVEDataVectorRegName(Name); 2021 break; 2022 case RegKind::SVEPredicateVector: 2023 RegNum = matchSVEPredicateVectorRegName(Name); 2024 break; 2025 } 2026 2027 if (!RegNum) { 2028 // Check for aliases registered via .req. Canonicalize to lower case. 2029 // That's more consistent since register names are case insensitive, and 2030 // it's how the original entry was passed in from MC/MCParser/AsmParser. 2031 auto Entry = RegisterReqs.find(Name.lower()); 2032 if (Entry == RegisterReqs.end()) 2033 return 0; 2034 2035 // set RegNum if the match is the right kind of register 2036 if (Kind == Entry->getValue().first) 2037 RegNum = Entry->getValue().second; 2038 } 2039 return RegNum; 2040 } 2041 2042 /// tryParseRegister - Try to parse a register name. The token must be an 2043 /// Identifier when called, and if it is a register name the token is eaten and 2044 /// the register is added to the operand list. 2045 int AArch64AsmParser::tryParseRegister() { 2046 MCAsmParser &Parser = getParser(); 2047 const AsmToken &Tok = Parser.getTok(); 2048 if (Tok.isNot(AsmToken::Identifier)) 2049 return -1; 2050 2051 std::string lowerCase = Tok.getString().lower(); 2052 if (isSVERegister(lowerCase)) 2053 return -1; 2054 2055 unsigned RegNum = matchRegisterNameAlias(lowerCase, RegKind::Scalar); 2056 // Also handle a few aliases of registers. 2057 if (RegNum == 0) 2058 RegNum = StringSwitch<unsigned>(lowerCase) 2059 .Case("fp", AArch64::FP) 2060 .Case("lr", AArch64::LR) 2061 .Case("x31", AArch64::XZR) 2062 .Case("w31", AArch64::WZR) 2063 .Default(0); 2064 2065 if (RegNum == 0) 2066 return -1; 2067 2068 Parser.Lex(); // Eat identifier token. 2069 return RegNum; 2070 } 2071 2072 /// tryMatchVectorRegister - Try to parse a vector register name with optional 2073 /// kind specifier. If it is a register specifier, eat the token and return it. 2074 int AArch64AsmParser::tryMatchVectorRegister(StringRef &Kind, bool expected) { 2075 MCAsmParser &Parser = getParser(); 2076 if (Parser.getTok().isNot(AsmToken::Identifier)) { 2077 TokError("vector register expected"); 2078 return -1; 2079 } 2080 2081 StringRef Name = Parser.getTok().getString(); 2082 // If there is a kind specifier, it's separated from the register name by 2083 // a '.'. 2084 size_t Start = 0, Next = Name.find('.'); 2085 StringRef Head = Name.slice(Start, Next); 2086 unsigned RegNum = matchRegisterNameAlias(Head, RegKind::NeonVector); 2087 2088 if (RegNum) { 2089 if (Next != StringRef::npos) { 2090 Kind = Name.slice(Next, StringRef::npos); 2091 if (!isValidVectorKind(Kind)) { 2092 TokError("invalid vector kind qualifier"); 2093 return -1; 2094 } 2095 } 2096 Parser.Lex(); // Eat the register token. 2097 return RegNum; 2098 } 2099 2100 if (expected) 2101 TokError("vector register expected"); 2102 return -1; 2103 } 2104 2105 /// tryParseSysCROperand - Try to parse a system instruction CR operand name. 2106 OperandMatchResultTy 2107 AArch64AsmParser::tryParseSysCROperand(OperandVector &Operands) { 2108 MCAsmParser &Parser = getParser(); 2109 SMLoc S = getLoc(); 2110 2111 if (Parser.getTok().isNot(AsmToken::Identifier)) { 2112 Error(S, "Expected cN operand where 0 <= N <= 15"); 2113 return MatchOperand_ParseFail; 2114 } 2115 2116 StringRef Tok = Parser.getTok().getIdentifier(); 2117 if (Tok[0] != 'c' && Tok[0] != 'C') { 2118 Error(S, "Expected cN operand where 0 <= N <= 15"); 2119 return MatchOperand_ParseFail; 2120 } 2121 2122 uint32_t CRNum; 2123 bool BadNum = Tok.drop_front().getAsInteger(10, CRNum); 2124 if (BadNum || CRNum > 15) { 2125 Error(S, "Expected cN operand where 0 <= N <= 15"); 2126 return MatchOperand_ParseFail; 2127 } 2128 2129 Parser.Lex(); // Eat identifier token. 2130 Operands.push_back( 2131 AArch64Operand::CreateSysCR(CRNum, S, getLoc(), getContext())); 2132 return MatchOperand_Success; 2133 } 2134 2135 /// tryParsePrefetch - Try to parse a prefetch operand. 2136 OperandMatchResultTy 2137 AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) { 2138 MCAsmParser &Parser = getParser(); 2139 SMLoc S = getLoc(); 2140 const AsmToken &Tok = Parser.getTok(); 2141 // Either an identifier for named values or a 5-bit immediate. 2142 // Eat optional hash. 2143 if (parseOptionalToken(AsmToken::Hash) || 2144 Tok.is(AsmToken::Integer)) { 2145 const MCExpr *ImmVal; 2146 if (getParser().parseExpression(ImmVal)) 2147 return MatchOperand_ParseFail; 2148 2149 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 2150 if (!MCE) { 2151 TokError("immediate value expected for prefetch operand"); 2152 return MatchOperand_ParseFail; 2153 } 2154 unsigned prfop = MCE->getValue(); 2155 if (prfop > 31) { 2156 TokError("prefetch operand out of range, [0,31] expected"); 2157 return MatchOperand_ParseFail; 2158 } 2159 2160 auto PRFM = AArch64PRFM::lookupPRFMByEncoding(MCE->getValue()); 2161 Operands.push_back(AArch64Operand::CreatePrefetch( 2162 prfop, PRFM ? PRFM->Name : "", S, getContext())); 2163 return MatchOperand_Success; 2164 } 2165 2166 if (Tok.isNot(AsmToken::Identifier)) { 2167 TokError("pre-fetch hint expected"); 2168 return MatchOperand_ParseFail; 2169 } 2170 2171 auto PRFM = AArch64PRFM::lookupPRFMByName(Tok.getString()); 2172 if (!PRFM) { 2173 TokError("pre-fetch hint expected"); 2174 return MatchOperand_ParseFail; 2175 } 2176 2177 Parser.Lex(); // Eat identifier token. 2178 Operands.push_back(AArch64Operand::CreatePrefetch( 2179 PRFM->Encoding, Tok.getString(), S, getContext())); 2180 return MatchOperand_Success; 2181 } 2182 2183 /// tryParsePSBHint - Try to parse a PSB operand, mapped to Hint command 2184 OperandMatchResultTy 2185 AArch64AsmParser::tryParsePSBHint(OperandVector &Operands) { 2186 MCAsmParser &Parser = getParser(); 2187 SMLoc S = getLoc(); 2188 const AsmToken &Tok = Parser.getTok(); 2189 if (Tok.isNot(AsmToken::Identifier)) { 2190 TokError("invalid operand for instruction"); 2191 return MatchOperand_ParseFail; 2192 } 2193 2194 auto PSB = AArch64PSBHint::lookupPSBByName(Tok.getString()); 2195 if (!PSB) { 2196 TokError("invalid operand for instruction"); 2197 return MatchOperand_ParseFail; 2198 } 2199 2200 Parser.Lex(); // Eat identifier token. 2201 Operands.push_back(AArch64Operand::CreatePSBHint( 2202 PSB->Encoding, Tok.getString(), S, getContext())); 2203 return MatchOperand_Success; 2204 } 2205 2206 /// tryParseAdrpLabel - Parse and validate a source label for the ADRP 2207 /// instruction. 2208 OperandMatchResultTy 2209 AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) { 2210 MCAsmParser &Parser = getParser(); 2211 SMLoc S = getLoc(); 2212 const MCExpr *Expr; 2213 2214 if (Parser.getTok().is(AsmToken::Hash)) { 2215 Parser.Lex(); // Eat hash token. 2216 } 2217 2218 if (parseSymbolicImmVal(Expr)) 2219 return MatchOperand_ParseFail; 2220 2221 AArch64MCExpr::VariantKind ELFRefKind; 2222 MCSymbolRefExpr::VariantKind DarwinRefKind; 2223 int64_t Addend; 2224 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) { 2225 if (DarwinRefKind == MCSymbolRefExpr::VK_None && 2226 ELFRefKind == AArch64MCExpr::VK_INVALID) { 2227 // No modifier was specified at all; this is the syntax for an ELF basic 2228 // ADRP relocation (unfortunately). 2229 Expr = 2230 AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS_PAGE, getContext()); 2231 } else if ((DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGE || 2232 DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGE) && 2233 Addend != 0) { 2234 Error(S, "gotpage label reference not allowed an addend"); 2235 return MatchOperand_ParseFail; 2236 } else if (DarwinRefKind != MCSymbolRefExpr::VK_PAGE && 2237 DarwinRefKind != MCSymbolRefExpr::VK_GOTPAGE && 2238 DarwinRefKind != MCSymbolRefExpr::VK_TLVPPAGE && 2239 ELFRefKind != AArch64MCExpr::VK_GOT_PAGE && 2240 ELFRefKind != AArch64MCExpr::VK_GOTTPREL_PAGE && 2241 ELFRefKind != AArch64MCExpr::VK_TLSDESC_PAGE) { 2242 // The operand must be an @page or @gotpage qualified symbolref. 2243 Error(S, "page or gotpage label reference expected"); 2244 return MatchOperand_ParseFail; 2245 } 2246 } 2247 2248 // We have either a label reference possibly with addend or an immediate. The 2249 // addend is a raw value here. The linker will adjust it to only reference the 2250 // page. 2251 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1); 2252 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext())); 2253 2254 return MatchOperand_Success; 2255 } 2256 2257 /// tryParseAdrLabel - Parse and validate a source label for the ADR 2258 /// instruction. 2259 OperandMatchResultTy 2260 AArch64AsmParser::tryParseAdrLabel(OperandVector &Operands) { 2261 SMLoc S = getLoc(); 2262 const MCExpr *Expr; 2263 2264 parseOptionalToken(AsmToken::Hash); 2265 if (getParser().parseExpression(Expr)) 2266 return MatchOperand_ParseFail; 2267 2268 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1); 2269 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext())); 2270 2271 return MatchOperand_Success; 2272 } 2273 2274 /// tryParseFPImm - A floating point immediate expression operand. 2275 OperandMatchResultTy 2276 AArch64AsmParser::tryParseFPImm(OperandVector &Operands) { 2277 MCAsmParser &Parser = getParser(); 2278 SMLoc S = getLoc(); 2279 2280 bool Hash = parseOptionalToken(AsmToken::Hash); 2281 2282 // Handle negation, as that still comes through as a separate token. 2283 bool isNegative = parseOptionalToken(AsmToken::Minus); 2284 2285 const AsmToken &Tok = Parser.getTok(); 2286 if (Tok.is(AsmToken::Real) || Tok.is(AsmToken::Integer)) { 2287 int64_t Val; 2288 if (Tok.is(AsmToken::Integer) && !isNegative && Tok.getString().startswith("0x")) { 2289 Val = Tok.getIntVal(); 2290 if (Val > 255 || Val < 0) { 2291 TokError("encoded floating point value out of range"); 2292 return MatchOperand_ParseFail; 2293 } 2294 } else { 2295 APFloat RealVal(APFloat::IEEEdouble(), Tok.getString()); 2296 if (isNegative) 2297 RealVal.changeSign(); 2298 2299 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 2300 Val = AArch64_AM::getFP64Imm(APInt(64, IntVal)); 2301 2302 // Check for out of range values. As an exception we let Zero through, 2303 // but as tokens instead of an FPImm so that it can be matched by the 2304 // appropriate alias if one exists. 2305 if (RealVal.isPosZero()) { 2306 Parser.Lex(); // Eat the token. 2307 Operands.push_back(AArch64Operand::CreateToken("#0", false, S, getContext())); 2308 Operands.push_back(AArch64Operand::CreateToken(".0", false, S, getContext())); 2309 return MatchOperand_Success; 2310 } else if (Val == -1) { 2311 TokError("expected compatible register or floating-point constant"); 2312 return MatchOperand_ParseFail; 2313 } 2314 } 2315 Parser.Lex(); // Eat the token. 2316 Operands.push_back(AArch64Operand::CreateFPImm(Val, S, getContext())); 2317 return MatchOperand_Success; 2318 } 2319 2320 if (!Hash) 2321 return MatchOperand_NoMatch; 2322 2323 TokError("invalid floating point immediate"); 2324 return MatchOperand_ParseFail; 2325 } 2326 2327 /// tryParseAddSubImm - Parse ADD/SUB shifted immediate operand 2328 OperandMatchResultTy 2329 AArch64AsmParser::tryParseAddSubImm(OperandVector &Operands) { 2330 MCAsmParser &Parser = getParser(); 2331 SMLoc S = getLoc(); 2332 2333 if (Parser.getTok().is(AsmToken::Hash)) 2334 Parser.Lex(); // Eat '#' 2335 else if (Parser.getTok().isNot(AsmToken::Integer)) 2336 // Operand should start from # or should be integer, emit error otherwise. 2337 return MatchOperand_NoMatch; 2338 2339 const MCExpr *Imm; 2340 if (parseSymbolicImmVal(Imm)) 2341 return MatchOperand_ParseFail; 2342 else if (Parser.getTok().isNot(AsmToken::Comma)) { 2343 uint64_t ShiftAmount = 0; 2344 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Imm); 2345 if (MCE) { 2346 int64_t Val = MCE->getValue(); 2347 if (Val > 0xfff && (Val & 0xfff) == 0) { 2348 Imm = MCConstantExpr::create(Val >> 12, getContext()); 2349 ShiftAmount = 12; 2350 } 2351 } 2352 SMLoc E = Parser.getTok().getLoc(); 2353 Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S, E, 2354 getContext())); 2355 return MatchOperand_Success; 2356 } 2357 2358 // Eat ',' 2359 Parser.Lex(); 2360 2361 // The optional operand must be "lsl #N" where N is non-negative. 2362 if (!Parser.getTok().is(AsmToken::Identifier) || 2363 !Parser.getTok().getIdentifier().equals_lower("lsl")) { 2364 Error(Parser.getTok().getLoc(), "only 'lsl #+N' valid after immediate"); 2365 return MatchOperand_ParseFail; 2366 } 2367 2368 // Eat 'lsl' 2369 Parser.Lex(); 2370 2371 parseOptionalToken(AsmToken::Hash); 2372 2373 if (Parser.getTok().isNot(AsmToken::Integer)) { 2374 Error(Parser.getTok().getLoc(), "only 'lsl #+N' valid after immediate"); 2375 return MatchOperand_ParseFail; 2376 } 2377 2378 int64_t ShiftAmount = Parser.getTok().getIntVal(); 2379 2380 if (ShiftAmount < 0) { 2381 Error(Parser.getTok().getLoc(), "positive shift amount required"); 2382 return MatchOperand_ParseFail; 2383 } 2384 Parser.Lex(); // Eat the number 2385 2386 SMLoc E = Parser.getTok().getLoc(); 2387 Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, 2388 S, E, getContext())); 2389 return MatchOperand_Success; 2390 } 2391 2392 /// parseCondCodeString - Parse a Condition Code string. 2393 AArch64CC::CondCode AArch64AsmParser::parseCondCodeString(StringRef Cond) { 2394 AArch64CC::CondCode CC = StringSwitch<AArch64CC::CondCode>(Cond.lower()) 2395 .Case("eq", AArch64CC::EQ) 2396 .Case("ne", AArch64CC::NE) 2397 .Case("cs", AArch64CC::HS) 2398 .Case("hs", AArch64CC::HS) 2399 .Case("cc", AArch64CC::LO) 2400 .Case("lo", AArch64CC::LO) 2401 .Case("mi", AArch64CC::MI) 2402 .Case("pl", AArch64CC::PL) 2403 .Case("vs", AArch64CC::VS) 2404 .Case("vc", AArch64CC::VC) 2405 .Case("hi", AArch64CC::HI) 2406 .Case("ls", AArch64CC::LS) 2407 .Case("ge", AArch64CC::GE) 2408 .Case("lt", AArch64CC::LT) 2409 .Case("gt", AArch64CC::GT) 2410 .Case("le", AArch64CC::LE) 2411 .Case("al", AArch64CC::AL) 2412 .Case("nv", AArch64CC::NV) 2413 .Default(AArch64CC::Invalid); 2414 return CC; 2415 } 2416 2417 /// parseCondCode - Parse a Condition Code operand. 2418 bool AArch64AsmParser::parseCondCode(OperandVector &Operands, 2419 bool invertCondCode) { 2420 MCAsmParser &Parser = getParser(); 2421 SMLoc S = getLoc(); 2422 const AsmToken &Tok = Parser.getTok(); 2423 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2424 2425 StringRef Cond = Tok.getString(); 2426 AArch64CC::CondCode CC = parseCondCodeString(Cond); 2427 if (CC == AArch64CC::Invalid) 2428 return TokError("invalid condition code"); 2429 Parser.Lex(); // Eat identifier token. 2430 2431 if (invertCondCode) { 2432 if (CC == AArch64CC::AL || CC == AArch64CC::NV) 2433 return TokError("condition codes AL and NV are invalid for this instruction"); 2434 CC = AArch64CC::getInvertedCondCode(AArch64CC::CondCode(CC)); 2435 } 2436 2437 Operands.push_back( 2438 AArch64Operand::CreateCondCode(CC, S, getLoc(), getContext())); 2439 return false; 2440 } 2441 2442 /// tryParseOptionalShift - Some operands take an optional shift argument. Parse 2443 /// them if present. 2444 OperandMatchResultTy 2445 AArch64AsmParser::tryParseOptionalShiftExtend(OperandVector &Operands) { 2446 MCAsmParser &Parser = getParser(); 2447 const AsmToken &Tok = Parser.getTok(); 2448 std::string LowerID = Tok.getString().lower(); 2449 AArch64_AM::ShiftExtendType ShOp = 2450 StringSwitch<AArch64_AM::ShiftExtendType>(LowerID) 2451 .Case("lsl", AArch64_AM::LSL) 2452 .Case("lsr", AArch64_AM::LSR) 2453 .Case("asr", AArch64_AM::ASR) 2454 .Case("ror", AArch64_AM::ROR) 2455 .Case("msl", AArch64_AM::MSL) 2456 .Case("uxtb", AArch64_AM::UXTB) 2457 .Case("uxth", AArch64_AM::UXTH) 2458 .Case("uxtw", AArch64_AM::UXTW) 2459 .Case("uxtx", AArch64_AM::UXTX) 2460 .Case("sxtb", AArch64_AM::SXTB) 2461 .Case("sxth", AArch64_AM::SXTH) 2462 .Case("sxtw", AArch64_AM::SXTW) 2463 .Case("sxtx", AArch64_AM::SXTX) 2464 .Default(AArch64_AM::InvalidShiftExtend); 2465 2466 if (ShOp == AArch64_AM::InvalidShiftExtend) 2467 return MatchOperand_NoMatch; 2468 2469 SMLoc S = Tok.getLoc(); 2470 Parser.Lex(); 2471 2472 bool Hash = parseOptionalToken(AsmToken::Hash); 2473 2474 if (!Hash && getLexer().isNot(AsmToken::Integer)) { 2475 if (ShOp == AArch64_AM::LSL || ShOp == AArch64_AM::LSR || 2476 ShOp == AArch64_AM::ASR || ShOp == AArch64_AM::ROR || 2477 ShOp == AArch64_AM::MSL) { 2478 // We expect a number here. 2479 TokError("expected #imm after shift specifier"); 2480 return MatchOperand_ParseFail; 2481 } 2482 2483 // "extend" type operations don't need an immediate, #0 is implicit. 2484 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1); 2485 Operands.push_back( 2486 AArch64Operand::CreateShiftExtend(ShOp, 0, false, S, E, getContext())); 2487 return MatchOperand_Success; 2488 } 2489 2490 // Make sure we do actually have a number, identifier or a parenthesized 2491 // expression. 2492 SMLoc E = Parser.getTok().getLoc(); 2493 if (!Parser.getTok().is(AsmToken::Integer) && 2494 !Parser.getTok().is(AsmToken::LParen) && 2495 !Parser.getTok().is(AsmToken::Identifier)) { 2496 Error(E, "expected integer shift amount"); 2497 return MatchOperand_ParseFail; 2498 } 2499 2500 const MCExpr *ImmVal; 2501 if (getParser().parseExpression(ImmVal)) 2502 return MatchOperand_ParseFail; 2503 2504 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 2505 if (!MCE) { 2506 Error(E, "expected constant '#imm' after shift specifier"); 2507 return MatchOperand_ParseFail; 2508 } 2509 2510 E = SMLoc::getFromPointer(getLoc().getPointer() - 1); 2511 Operands.push_back(AArch64Operand::CreateShiftExtend( 2512 ShOp, MCE->getValue(), true, S, E, getContext())); 2513 return MatchOperand_Success; 2514 } 2515 2516 static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str) { 2517 if (FBS[AArch64::HasV8_1aOps]) 2518 Str += "ARMv8.1a"; 2519 else if (FBS[AArch64::HasV8_2aOps]) 2520 Str += "ARMv8.2a"; 2521 else 2522 Str += "(unknown)"; 2523 } 2524 2525 void AArch64AsmParser::createSysAlias(uint16_t Encoding, OperandVector &Operands, 2526 SMLoc S) { 2527 const uint16_t Op2 = Encoding & 7; 2528 const uint16_t Cm = (Encoding & 0x78) >> 3; 2529 const uint16_t Cn = (Encoding & 0x780) >> 7; 2530 const uint16_t Op1 = (Encoding & 0x3800) >> 11; 2531 2532 const MCExpr *Expr = MCConstantExpr::create(Op1, getContext()); 2533 2534 Operands.push_back( 2535 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext())); 2536 Operands.push_back( 2537 AArch64Operand::CreateSysCR(Cn, S, getLoc(), getContext())); 2538 Operands.push_back( 2539 AArch64Operand::CreateSysCR(Cm, S, getLoc(), getContext())); 2540 Expr = MCConstantExpr::create(Op2, getContext()); 2541 Operands.push_back( 2542 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext())); 2543 } 2544 2545 /// parseSysAlias - The IC, DC, AT, and TLBI instructions are simple aliases for 2546 /// the SYS instruction. Parse them specially so that we create a SYS MCInst. 2547 bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc, 2548 OperandVector &Operands) { 2549 if (Name.find('.') != StringRef::npos) 2550 return TokError("invalid operand"); 2551 2552 Mnemonic = Name; 2553 Operands.push_back( 2554 AArch64Operand::CreateToken("sys", false, NameLoc, getContext())); 2555 2556 MCAsmParser &Parser = getParser(); 2557 const AsmToken &Tok = Parser.getTok(); 2558 StringRef Op = Tok.getString(); 2559 SMLoc S = Tok.getLoc(); 2560 2561 if (Mnemonic == "ic") { 2562 const AArch64IC::IC *IC = AArch64IC::lookupICByName(Op); 2563 if (!IC) 2564 return TokError("invalid operand for IC instruction"); 2565 else if (!IC->haveFeatures(getSTI().getFeatureBits())) { 2566 std::string Str("IC " + std::string(IC->Name) + " requires "); 2567 setRequiredFeatureString(IC->getRequiredFeatures(), Str); 2568 return TokError(Str.c_str()); 2569 } 2570 createSysAlias(IC->Encoding, Operands, S); 2571 } else if (Mnemonic == "dc") { 2572 const AArch64DC::DC *DC = AArch64DC::lookupDCByName(Op); 2573 if (!DC) 2574 return TokError("invalid operand for DC instruction"); 2575 else if (!DC->haveFeatures(getSTI().getFeatureBits())) { 2576 std::string Str("DC " + std::string(DC->Name) + " requires "); 2577 setRequiredFeatureString(DC->getRequiredFeatures(), Str); 2578 return TokError(Str.c_str()); 2579 } 2580 createSysAlias(DC->Encoding, Operands, S); 2581 } else if (Mnemonic == "at") { 2582 const AArch64AT::AT *AT = AArch64AT::lookupATByName(Op); 2583 if (!AT) 2584 return TokError("invalid operand for AT instruction"); 2585 else if (!AT->haveFeatures(getSTI().getFeatureBits())) { 2586 std::string Str("AT " + std::string(AT->Name) + " requires "); 2587 setRequiredFeatureString(AT->getRequiredFeatures(), Str); 2588 return TokError(Str.c_str()); 2589 } 2590 createSysAlias(AT->Encoding, Operands, S); 2591 } else if (Mnemonic == "tlbi") { 2592 const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByName(Op); 2593 if (!TLBI) 2594 return TokError("invalid operand for TLBI instruction"); 2595 else if (!TLBI->haveFeatures(getSTI().getFeatureBits())) { 2596 std::string Str("TLBI " + std::string(TLBI->Name) + " requires "); 2597 setRequiredFeatureString(TLBI->getRequiredFeatures(), Str); 2598 return TokError(Str.c_str()); 2599 } 2600 createSysAlias(TLBI->Encoding, Operands, S); 2601 } 2602 2603 Parser.Lex(); // Eat operand. 2604 2605 bool ExpectRegister = (Op.lower().find("all") == StringRef::npos); 2606 bool HasRegister = false; 2607 2608 // Check for the optional register operand. 2609 if (parseOptionalToken(AsmToken::Comma)) { 2610 if (Tok.isNot(AsmToken::Identifier) || parseRegister(Operands)) 2611 return TokError("expected register operand"); 2612 HasRegister = true; 2613 } 2614 2615 if (ExpectRegister && !HasRegister) 2616 return TokError("specified " + Mnemonic + " op requires a register"); 2617 else if (!ExpectRegister && HasRegister) 2618 return TokError("specified " + Mnemonic + " op does not use a register"); 2619 2620 if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list")) 2621 return true; 2622 2623 return false; 2624 } 2625 2626 OperandMatchResultTy 2627 AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) { 2628 MCAsmParser &Parser = getParser(); 2629 const AsmToken &Tok = Parser.getTok(); 2630 2631 // Can be either a #imm style literal or an option name 2632 if (parseOptionalToken(AsmToken::Hash) || 2633 Tok.is(AsmToken::Integer)) { 2634 // Immediate operand. 2635 const MCExpr *ImmVal; 2636 SMLoc ExprLoc = getLoc(); 2637 if (getParser().parseExpression(ImmVal)) 2638 return MatchOperand_ParseFail; 2639 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 2640 if (!MCE) { 2641 Error(ExprLoc, "immediate value expected for barrier operand"); 2642 return MatchOperand_ParseFail; 2643 } 2644 if (MCE->getValue() < 0 || MCE->getValue() > 15) { 2645 Error(ExprLoc, "barrier operand out of range"); 2646 return MatchOperand_ParseFail; 2647 } 2648 auto DB = AArch64DB::lookupDBByEncoding(MCE->getValue()); 2649 Operands.push_back(AArch64Operand::CreateBarrier( 2650 MCE->getValue(), DB ? DB->Name : "", ExprLoc, getContext())); 2651 return MatchOperand_Success; 2652 } 2653 2654 if (Tok.isNot(AsmToken::Identifier)) { 2655 TokError("invalid operand for instruction"); 2656 return MatchOperand_ParseFail; 2657 } 2658 2659 // The only valid named option for ISB is 'sy' 2660 auto DB = AArch64DB::lookupDBByName(Tok.getString()); 2661 if (Mnemonic == "isb" && (!DB || DB->Encoding != AArch64DB::sy)) { 2662 TokError("'sy' or #imm operand expected"); 2663 return MatchOperand_ParseFail; 2664 } else if (!DB) { 2665 TokError("invalid barrier option name"); 2666 return MatchOperand_ParseFail; 2667 } 2668 2669 Operands.push_back(AArch64Operand::CreateBarrier( 2670 DB->Encoding, Tok.getString(), getLoc(), getContext())); 2671 Parser.Lex(); // Consume the option 2672 2673 return MatchOperand_Success; 2674 } 2675 2676 OperandMatchResultTy 2677 AArch64AsmParser::tryParseSysReg(OperandVector &Operands) { 2678 MCAsmParser &Parser = getParser(); 2679 const AsmToken &Tok = Parser.getTok(); 2680 2681 if (Tok.isNot(AsmToken::Identifier)) 2682 return MatchOperand_NoMatch; 2683 2684 int MRSReg, MSRReg; 2685 auto SysReg = AArch64SysReg::lookupSysRegByName(Tok.getString()); 2686 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) { 2687 MRSReg = SysReg->Readable ? SysReg->Encoding : -1; 2688 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1; 2689 } else 2690 MRSReg = MSRReg = AArch64SysReg::parseGenericRegister(Tok.getString()); 2691 2692 auto PState = AArch64PState::lookupPStateByName(Tok.getString()); 2693 unsigned PStateImm = -1; 2694 if (PState && PState->haveFeatures(getSTI().getFeatureBits())) 2695 PStateImm = PState->Encoding; 2696 2697 Operands.push_back( 2698 AArch64Operand::CreateSysReg(Tok.getString(), getLoc(), MRSReg, MSRReg, 2699 PStateImm, getContext())); 2700 Parser.Lex(); // Eat identifier 2701 2702 return MatchOperand_Success; 2703 } 2704 2705 /// tryParseNeonVectorRegister - Parse a vector register operand. 2706 bool AArch64AsmParser::tryParseNeonVectorRegister(OperandVector &Operands) { 2707 MCAsmParser &Parser = getParser(); 2708 if (Parser.getTok().isNot(AsmToken::Identifier)) 2709 return true; 2710 2711 SMLoc S = getLoc(); 2712 // Check for a vector register specifier first. 2713 StringRef Kind; 2714 int64_t Reg = tryMatchVectorRegister(Kind, false); 2715 if (Reg == -1) 2716 return true; 2717 Operands.push_back( 2718 AArch64Operand::CreateReg(Reg, RegKind::NeonVector, S, getLoc(), 2719 getContext())); 2720 2721 // If there was an explicit qualifier, that goes on as a literal text 2722 // operand. 2723 if (!Kind.empty()) 2724 Operands.push_back( 2725 AArch64Operand::CreateToken(Kind, false, S, getContext())); 2726 2727 // If there is an index specifier following the register, parse that too. 2728 SMLoc SIdx = getLoc(); 2729 if (parseOptionalToken(AsmToken::LBrac)) { 2730 const MCExpr *ImmVal; 2731 if (getParser().parseExpression(ImmVal)) 2732 return false; 2733 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 2734 if (!MCE) { 2735 TokError("immediate value expected for vector index"); 2736 return false; 2737 } 2738 2739 SMLoc E = getLoc(); 2740 2741 if (parseToken(AsmToken::RBrac, "']' expected")) 2742 return false; 2743 2744 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx, 2745 E, getContext())); 2746 } 2747 2748 return false; 2749 } 2750 2751 // tryParseSVEDataVectorRegister - Try to parse a SVE vector register name with 2752 // optional kind specifier. If it is a register specifier, eat the token 2753 // and return it. 2754 OperandMatchResultTy 2755 AArch64AsmParser::tryParseSVERegister(int &Reg, StringRef &Kind, 2756 RegKind MatchKind) { 2757 MCAsmParser &Parser = getParser(); 2758 const AsmToken &Tok = Parser.getTok(); 2759 2760 if (Tok.isNot(AsmToken::Identifier)) 2761 return MatchOperand_NoMatch; 2762 2763 StringRef Name = Tok.getString(); 2764 // If there is a kind specifier, it's separated from the register name by 2765 // a '.'. 2766 size_t Start = 0, Next = Name.find('.'); 2767 StringRef Head = Name.slice(Start, Next); 2768 unsigned RegNum = matchRegisterNameAlias(Head, MatchKind); 2769 2770 if (RegNum) { 2771 if (Next != StringRef::npos) { 2772 Kind = Name.slice(Next, StringRef::npos); 2773 if (!isValidSVEKind(Kind)) { 2774 TokError("invalid sve vector kind qualifier"); 2775 return MatchOperand_ParseFail; 2776 } 2777 } 2778 Parser.Lex(); // Eat the register token. 2779 2780 Reg = RegNum; 2781 return MatchOperand_Success; 2782 } 2783 2784 return MatchOperand_NoMatch; 2785 } 2786 2787 /// tryParseSVEPredicateVector - Parse a SVE predicate register operand. 2788 OperandMatchResultTy 2789 AArch64AsmParser::tryParseSVEPredicateVector(OperandVector &Operands) { 2790 // Check for a SVE predicate register specifier first. 2791 const SMLoc S = getLoc(); 2792 StringRef Kind; 2793 int RegNum = -1; 2794 auto Res = tryParseSVERegister(RegNum, Kind, RegKind::SVEPredicateVector); 2795 if (Res != MatchOperand_Success) 2796 return Res; 2797 2798 unsigned ElementWidth = StringSwitch<unsigned>(Kind.lower()) 2799 .Case("", -1) 2800 .Case(".b", 8) 2801 .Case(".h", 16) 2802 .Case(".s", 32) 2803 .Case(".d", 64) 2804 .Case(".q", 128) 2805 .Default(0); 2806 2807 if (!ElementWidth) 2808 return MatchOperand_NoMatch; 2809 2810 Operands.push_back( 2811 AArch64Operand::CreateReg(RegNum, RegKind::SVEPredicateVector, 2812 ElementWidth, S, getLoc(), getContext())); 2813 2814 return MatchOperand_Success; 2815 } 2816 2817 /// parseRegister - Parse a non-vector register operand. 2818 bool AArch64AsmParser::parseRegister(OperandVector &Operands) { 2819 SMLoc S = getLoc(); 2820 // Try for a vector (neon) register. 2821 if (!tryParseNeonVectorRegister(Operands)) 2822 return false; 2823 2824 // Try for a scalar register. 2825 int64_t Reg = tryParseRegister(); 2826 if (Reg == -1) 2827 return true; 2828 Operands.push_back(AArch64Operand::CreateReg(Reg, RegKind::Scalar, S, 2829 getLoc(), getContext())); 2830 2831 return false; 2832 } 2833 2834 bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) { 2835 MCAsmParser &Parser = getParser(); 2836 bool HasELFModifier = false; 2837 AArch64MCExpr::VariantKind RefKind; 2838 2839 if (parseOptionalToken(AsmToken::Colon)) { 2840 HasELFModifier = true; 2841 2842 if (Parser.getTok().isNot(AsmToken::Identifier)) 2843 return TokError("expect relocation specifier in operand after ':'"); 2844 2845 std::string LowerCase = Parser.getTok().getIdentifier().lower(); 2846 RefKind = StringSwitch<AArch64MCExpr::VariantKind>(LowerCase) 2847 .Case("lo12", AArch64MCExpr::VK_LO12) 2848 .Case("abs_g3", AArch64MCExpr::VK_ABS_G3) 2849 .Case("abs_g2", AArch64MCExpr::VK_ABS_G2) 2850 .Case("abs_g2_s", AArch64MCExpr::VK_ABS_G2_S) 2851 .Case("abs_g2_nc", AArch64MCExpr::VK_ABS_G2_NC) 2852 .Case("abs_g1", AArch64MCExpr::VK_ABS_G1) 2853 .Case("abs_g1_s", AArch64MCExpr::VK_ABS_G1_S) 2854 .Case("abs_g1_nc", AArch64MCExpr::VK_ABS_G1_NC) 2855 .Case("abs_g0", AArch64MCExpr::VK_ABS_G0) 2856 .Case("abs_g0_s", AArch64MCExpr::VK_ABS_G0_S) 2857 .Case("abs_g0_nc", AArch64MCExpr::VK_ABS_G0_NC) 2858 .Case("dtprel_g2", AArch64MCExpr::VK_DTPREL_G2) 2859 .Case("dtprel_g1", AArch64MCExpr::VK_DTPREL_G1) 2860 .Case("dtprel_g1_nc", AArch64MCExpr::VK_DTPREL_G1_NC) 2861 .Case("dtprel_g0", AArch64MCExpr::VK_DTPREL_G0) 2862 .Case("dtprel_g0_nc", AArch64MCExpr::VK_DTPREL_G0_NC) 2863 .Case("dtprel_hi12", AArch64MCExpr::VK_DTPREL_HI12) 2864 .Case("dtprel_lo12", AArch64MCExpr::VK_DTPREL_LO12) 2865 .Case("dtprel_lo12_nc", AArch64MCExpr::VK_DTPREL_LO12_NC) 2866 .Case("tprel_g2", AArch64MCExpr::VK_TPREL_G2) 2867 .Case("tprel_g1", AArch64MCExpr::VK_TPREL_G1) 2868 .Case("tprel_g1_nc", AArch64MCExpr::VK_TPREL_G1_NC) 2869 .Case("tprel_g0", AArch64MCExpr::VK_TPREL_G0) 2870 .Case("tprel_g0_nc", AArch64MCExpr::VK_TPREL_G0_NC) 2871 .Case("tprel_hi12", AArch64MCExpr::VK_TPREL_HI12) 2872 .Case("tprel_lo12", AArch64MCExpr::VK_TPREL_LO12) 2873 .Case("tprel_lo12_nc", AArch64MCExpr::VK_TPREL_LO12_NC) 2874 .Case("tlsdesc_lo12", AArch64MCExpr::VK_TLSDESC_LO12) 2875 .Case("got", AArch64MCExpr::VK_GOT_PAGE) 2876 .Case("got_lo12", AArch64MCExpr::VK_GOT_LO12) 2877 .Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE) 2878 .Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC) 2879 .Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1) 2880 .Case("gottprel_g0_nc", AArch64MCExpr::VK_GOTTPREL_G0_NC) 2881 .Case("tlsdesc", AArch64MCExpr::VK_TLSDESC_PAGE) 2882 .Default(AArch64MCExpr::VK_INVALID); 2883 2884 if (RefKind == AArch64MCExpr::VK_INVALID) 2885 return TokError("expect relocation specifier in operand after ':'"); 2886 2887 Parser.Lex(); // Eat identifier 2888 2889 if (parseToken(AsmToken::Colon, "expect ':' after relocation specifier")) 2890 return true; 2891 } 2892 2893 if (getParser().parseExpression(ImmVal)) 2894 return true; 2895 2896 if (HasELFModifier) 2897 ImmVal = AArch64MCExpr::create(ImmVal, RefKind, getContext()); 2898 2899 return false; 2900 } 2901 2902 /// parseVectorList - Parse a vector list operand for AdvSIMD instructions. 2903 bool AArch64AsmParser::parseVectorList(OperandVector &Operands) { 2904 MCAsmParser &Parser = getParser(); 2905 assert(Parser.getTok().is(AsmToken::LCurly) && "Token is not a Left Bracket"); 2906 SMLoc S = getLoc(); 2907 Parser.Lex(); // Eat left bracket token. 2908 StringRef Kind; 2909 int64_t FirstReg = tryMatchVectorRegister(Kind, true); 2910 if (FirstReg == -1) 2911 return true; 2912 int64_t PrevReg = FirstReg; 2913 unsigned Count = 1; 2914 2915 if (parseOptionalToken(AsmToken::Minus)) { 2916 SMLoc Loc = getLoc(); 2917 StringRef NextKind; 2918 int64_t Reg = tryMatchVectorRegister(NextKind, true); 2919 if (Reg == -1) 2920 return true; 2921 // Any Kind suffices must match on all regs in the list. 2922 if (Kind != NextKind) 2923 return Error(Loc, "mismatched register size suffix"); 2924 2925 unsigned Space = (PrevReg < Reg) ? (Reg - PrevReg) : (Reg + 32 - PrevReg); 2926 2927 if (Space == 0 || Space > 3) { 2928 return Error(Loc, "invalid number of vectors"); 2929 } 2930 2931 Count += Space; 2932 } 2933 else { 2934 while (parseOptionalToken(AsmToken::Comma)) { 2935 SMLoc Loc = getLoc(); 2936 StringRef NextKind; 2937 int64_t Reg = tryMatchVectorRegister(NextKind, true); 2938 if (Reg == -1) 2939 return true; 2940 // Any Kind suffices must match on all regs in the list. 2941 if (Kind != NextKind) 2942 return Error(Loc, "mismatched register size suffix"); 2943 2944 // Registers must be incremental (with wraparound at 31) 2945 if (getContext().getRegisterInfo()->getEncodingValue(Reg) != 2946 (getContext().getRegisterInfo()->getEncodingValue(PrevReg) + 1) % 32) 2947 return Error(Loc, "registers must be sequential"); 2948 2949 PrevReg = Reg; 2950 ++Count; 2951 } 2952 } 2953 2954 if (parseToken(AsmToken::RCurly, "'}' expected")) 2955 return true; 2956 2957 if (Count > 4) 2958 return Error(S, "invalid number of vectors"); 2959 2960 unsigned NumElements = 0; 2961 char ElementKind = 0; 2962 if (!Kind.empty()) 2963 parseValidVectorKind(Kind, NumElements, ElementKind); 2964 2965 Operands.push_back(AArch64Operand::CreateVectorList( 2966 FirstReg, Count, NumElements, ElementKind, S, getLoc(), getContext())); 2967 2968 // If there is an index specifier following the list, parse that too. 2969 SMLoc SIdx = getLoc(); 2970 if (parseOptionalToken(AsmToken::LBrac)) { // Eat left bracket token. 2971 const MCExpr *ImmVal; 2972 if (getParser().parseExpression(ImmVal)) 2973 return false; 2974 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 2975 if (!MCE) { 2976 TokError("immediate value expected for vector index"); 2977 return false; 2978 } 2979 2980 SMLoc E = getLoc(); 2981 if (parseToken(AsmToken::RBrac, "']' expected")) 2982 return false; 2983 2984 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx, 2985 E, getContext())); 2986 } 2987 return false; 2988 } 2989 2990 OperandMatchResultTy 2991 AArch64AsmParser::tryParseGPR64sp0Operand(OperandVector &Operands) { 2992 MCAsmParser &Parser = getParser(); 2993 const AsmToken &Tok = Parser.getTok(); 2994 if (!Tok.is(AsmToken::Identifier)) 2995 return MatchOperand_NoMatch; 2996 2997 unsigned RegNum = matchRegisterNameAlias(Tok.getString().lower(), RegKind::Scalar); 2998 2999 MCContext &Ctx = getContext(); 3000 const MCRegisterInfo *RI = Ctx.getRegisterInfo(); 3001 if (!RI->getRegClass(AArch64::GPR64spRegClassID).contains(RegNum)) 3002 return MatchOperand_NoMatch; 3003 3004 SMLoc S = getLoc(); 3005 Parser.Lex(); // Eat register 3006 3007 if (!parseOptionalToken(AsmToken::Comma)) { 3008 Operands.push_back( 3009 AArch64Operand::CreateReg(RegNum, RegKind::Scalar, S, getLoc(), Ctx)); 3010 return MatchOperand_Success; 3011 } 3012 3013 parseOptionalToken(AsmToken::Hash); 3014 3015 if (Parser.getTok().isNot(AsmToken::Integer)) { 3016 Error(getLoc(), "index must be absent or #0"); 3017 return MatchOperand_ParseFail; 3018 } 3019 3020 const MCExpr *ImmVal; 3021 if (Parser.parseExpression(ImmVal) || !isa<MCConstantExpr>(ImmVal) || 3022 cast<MCConstantExpr>(ImmVal)->getValue() != 0) { 3023 Error(getLoc(), "index must be absent or #0"); 3024 return MatchOperand_ParseFail; 3025 } 3026 3027 Operands.push_back( 3028 AArch64Operand::CreateReg(RegNum, RegKind::Scalar, S, getLoc(), Ctx)); 3029 return MatchOperand_Success; 3030 } 3031 3032 /// parseOperand - Parse a arm instruction operand. For now this parses the 3033 /// operand regardless of the mnemonic. 3034 bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode, 3035 bool invertCondCode) { 3036 MCAsmParser &Parser = getParser(); 3037 3038 OperandMatchResultTy ResTy = 3039 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/ true); 3040 3041 // Check if the current operand has a custom associated parser, if so, try to 3042 // custom parse the operand, or fallback to the general approach. 3043 if (ResTy == MatchOperand_Success) 3044 return false; 3045 // If there wasn't a custom match, try the generic matcher below. Otherwise, 3046 // there was a match, but an error occurred, in which case, just return that 3047 // the operand parsing failed. 3048 if (ResTy == MatchOperand_ParseFail) 3049 return true; 3050 3051 // Nothing custom, so do general case parsing. 3052 SMLoc S, E; 3053 switch (getLexer().getKind()) { 3054 default: { 3055 SMLoc S = getLoc(); 3056 const MCExpr *Expr; 3057 if (parseSymbolicImmVal(Expr)) 3058 return Error(S, "invalid operand"); 3059 3060 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1); 3061 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext())); 3062 return false; 3063 } 3064 case AsmToken::LBrac: { 3065 SMLoc Loc = Parser.getTok().getLoc(); 3066 Operands.push_back(AArch64Operand::CreateToken("[", false, Loc, 3067 getContext())); 3068 Parser.Lex(); // Eat '[' 3069 3070 // There's no comma after a '[', so we can parse the next operand 3071 // immediately. 3072 return parseOperand(Operands, false, false); 3073 } 3074 case AsmToken::LCurly: 3075 return parseVectorList(Operands); 3076 case AsmToken::Identifier: { 3077 // If we're expecting a Condition Code operand, then just parse that. 3078 if (isCondCode) 3079 return parseCondCode(Operands, invertCondCode); 3080 3081 // If it's a register name, parse it. 3082 if (!parseRegister(Operands)) 3083 return false; 3084 3085 // This could be an optional "shift" or "extend" operand. 3086 OperandMatchResultTy GotShift = tryParseOptionalShiftExtend(Operands); 3087 // We can only continue if no tokens were eaten. 3088 if (GotShift != MatchOperand_NoMatch) 3089 return GotShift; 3090 3091 // This was not a register so parse other operands that start with an 3092 // identifier (like labels) as expressions and create them as immediates. 3093 const MCExpr *IdVal; 3094 S = getLoc(); 3095 if (getParser().parseExpression(IdVal)) 3096 return true; 3097 E = SMLoc::getFromPointer(getLoc().getPointer() - 1); 3098 Operands.push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext())); 3099 return false; 3100 } 3101 case AsmToken::Integer: 3102 case AsmToken::Real: 3103 case AsmToken::Hash: { 3104 // #42 -> immediate. 3105 S = getLoc(); 3106 3107 parseOptionalToken(AsmToken::Hash); 3108 3109 // Parse a negative sign 3110 bool isNegative = false; 3111 if (Parser.getTok().is(AsmToken::Minus)) { 3112 isNegative = true; 3113 // We need to consume this token only when we have a Real, otherwise 3114 // we let parseSymbolicImmVal take care of it 3115 if (Parser.getLexer().peekTok().is(AsmToken::Real)) 3116 Parser.Lex(); 3117 } 3118 3119 // The only Real that should come through here is a literal #0.0 for 3120 // the fcmp[e] r, #0.0 instructions. They expect raw token operands, 3121 // so convert the value. 3122 const AsmToken &Tok = Parser.getTok(); 3123 if (Tok.is(AsmToken::Real)) { 3124 APFloat RealVal(APFloat::IEEEdouble(), Tok.getString()); 3125 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 3126 if (Mnemonic != "fcmp" && Mnemonic != "fcmpe" && Mnemonic != "fcmeq" && 3127 Mnemonic != "fcmge" && Mnemonic != "fcmgt" && Mnemonic != "fcmle" && 3128 Mnemonic != "fcmlt") 3129 return TokError("unexpected floating point literal"); 3130 else if (IntVal != 0 || isNegative) 3131 return TokError("expected floating-point constant #0.0"); 3132 Parser.Lex(); // Eat the token. 3133 3134 Operands.push_back( 3135 AArch64Operand::CreateToken("#0", false, S, getContext())); 3136 Operands.push_back( 3137 AArch64Operand::CreateToken(".0", false, S, getContext())); 3138 return false; 3139 } 3140 3141 const MCExpr *ImmVal; 3142 if (parseSymbolicImmVal(ImmVal)) 3143 return true; 3144 3145 E = SMLoc::getFromPointer(getLoc().getPointer() - 1); 3146 Operands.push_back(AArch64Operand::CreateImm(ImmVal, S, E, getContext())); 3147 return false; 3148 } 3149 case AsmToken::Equal: { 3150 SMLoc Loc = getLoc(); 3151 if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val) 3152 return TokError("unexpected token in operand"); 3153 Parser.Lex(); // Eat '=' 3154 const MCExpr *SubExprVal; 3155 if (getParser().parseExpression(SubExprVal)) 3156 return true; 3157 3158 if (Operands.size() < 2 || 3159 !static_cast<AArch64Operand &>(*Operands[1]).isReg()) 3160 return Error(Loc, "Only valid when first operand is register"); 3161 3162 bool IsXReg = 3163 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( 3164 Operands[1]->getReg()); 3165 3166 MCContext& Ctx = getContext(); 3167 E = SMLoc::getFromPointer(Loc.getPointer() - 1); 3168 // If the op is an imm and can be fit into a mov, then replace ldr with mov. 3169 if (isa<MCConstantExpr>(SubExprVal)) { 3170 uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue(); 3171 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16; 3172 while(Imm > 0xFFFF && countTrailingZeros(Imm) >= 16) { 3173 ShiftAmt += 16; 3174 Imm >>= 16; 3175 } 3176 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) { 3177 Operands[0] = AArch64Operand::CreateToken("movz", false, Loc, Ctx); 3178 Operands.push_back(AArch64Operand::CreateImm( 3179 MCConstantExpr::create(Imm, Ctx), S, E, Ctx)); 3180 if (ShiftAmt) 3181 Operands.push_back(AArch64Operand::CreateShiftExtend(AArch64_AM::LSL, 3182 ShiftAmt, true, S, E, Ctx)); 3183 return false; 3184 } 3185 APInt Simm = APInt(64, Imm << ShiftAmt); 3186 // check if the immediate is an unsigned or signed 32-bit int for W regs 3187 if (!IsXReg && !(Simm.isIntN(32) || Simm.isSignedIntN(32))) 3188 return Error(Loc, "Immediate too large for register"); 3189 } 3190 // If it is a label or an imm that cannot fit in a movz, put it into CP. 3191 const MCExpr *CPLoc = 3192 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc); 3193 Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx)); 3194 return false; 3195 } 3196 } 3197 } 3198 3199 /// ParseInstruction - Parse an AArch64 instruction mnemonic followed by its 3200 /// operands. 3201 bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info, 3202 StringRef Name, SMLoc NameLoc, 3203 OperandVector &Operands) { 3204 MCAsmParser &Parser = getParser(); 3205 Name = StringSwitch<StringRef>(Name.lower()) 3206 .Case("beq", "b.eq") 3207 .Case("bne", "b.ne") 3208 .Case("bhs", "b.hs") 3209 .Case("bcs", "b.cs") 3210 .Case("blo", "b.lo") 3211 .Case("bcc", "b.cc") 3212 .Case("bmi", "b.mi") 3213 .Case("bpl", "b.pl") 3214 .Case("bvs", "b.vs") 3215 .Case("bvc", "b.vc") 3216 .Case("bhi", "b.hi") 3217 .Case("bls", "b.ls") 3218 .Case("bge", "b.ge") 3219 .Case("blt", "b.lt") 3220 .Case("bgt", "b.gt") 3221 .Case("ble", "b.le") 3222 .Case("bal", "b.al") 3223 .Case("bnv", "b.nv") 3224 .Default(Name); 3225 3226 // First check for the AArch64-specific .req directive. 3227 if (Parser.getTok().is(AsmToken::Identifier) && 3228 Parser.getTok().getIdentifier() == ".req") { 3229 parseDirectiveReq(Name, NameLoc); 3230 // We always return 'error' for this, as we're done with this 3231 // statement and don't need to match the 'instruction." 3232 return true; 3233 } 3234 3235 // Create the leading tokens for the mnemonic, split by '.' characters. 3236 size_t Start = 0, Next = Name.find('.'); 3237 StringRef Head = Name.slice(Start, Next); 3238 3239 // IC, DC, AT, and TLBI instructions are aliases for the SYS instruction. 3240 if (Head == "ic" || Head == "dc" || Head == "at" || Head == "tlbi") 3241 return parseSysAlias(Head, NameLoc, Operands); 3242 3243 Operands.push_back( 3244 AArch64Operand::CreateToken(Head, false, NameLoc, getContext())); 3245 Mnemonic = Head; 3246 3247 // Handle condition codes for a branch mnemonic 3248 if (Head == "b" && Next != StringRef::npos) { 3249 Start = Next; 3250 Next = Name.find('.', Start + 1); 3251 Head = Name.slice(Start + 1, Next); 3252 3253 SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() + 3254 (Head.data() - Name.data())); 3255 AArch64CC::CondCode CC = parseCondCodeString(Head); 3256 if (CC == AArch64CC::Invalid) 3257 return Error(SuffixLoc, "invalid condition code"); 3258 Operands.push_back( 3259 AArch64Operand::CreateToken(".", true, SuffixLoc, getContext())); 3260 Operands.push_back( 3261 AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc, getContext())); 3262 } 3263 3264 // Add the remaining tokens in the mnemonic. 3265 while (Next != StringRef::npos) { 3266 Start = Next; 3267 Next = Name.find('.', Start + 1); 3268 Head = Name.slice(Start, Next); 3269 SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() + 3270 (Head.data() - Name.data()) + 1); 3271 Operands.push_back( 3272 AArch64Operand::CreateToken(Head, true, SuffixLoc, getContext())); 3273 } 3274 3275 // Conditional compare instructions have a Condition Code operand, which needs 3276 // to be parsed and an immediate operand created. 3277 bool condCodeFourthOperand = 3278 (Head == "ccmp" || Head == "ccmn" || Head == "fccmp" || 3279 Head == "fccmpe" || Head == "fcsel" || Head == "csel" || 3280 Head == "csinc" || Head == "csinv" || Head == "csneg"); 3281 3282 // These instructions are aliases to some of the conditional select 3283 // instructions. However, the condition code is inverted in the aliased 3284 // instruction. 3285 // 3286 // FIXME: Is this the correct way to handle these? Or should the parser 3287 // generate the aliased instructions directly? 3288 bool condCodeSecondOperand = (Head == "cset" || Head == "csetm"); 3289 bool condCodeThirdOperand = 3290 (Head == "cinc" || Head == "cinv" || Head == "cneg"); 3291 3292 // Read the remaining operands. 3293 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3294 // Read the first operand. 3295 if (parseOperand(Operands, false, false)) { 3296 return true; 3297 } 3298 3299 unsigned N = 2; 3300 while (parseOptionalToken(AsmToken::Comma)) { 3301 // Parse and remember the operand. 3302 if (parseOperand(Operands, (N == 4 && condCodeFourthOperand) || 3303 (N == 3 && condCodeThirdOperand) || 3304 (N == 2 && condCodeSecondOperand), 3305 condCodeSecondOperand || condCodeThirdOperand)) { 3306 return true; 3307 } 3308 3309 // After successfully parsing some operands there are two special cases to 3310 // consider (i.e. notional operands not separated by commas). Both are due 3311 // to memory specifiers: 3312 // + An RBrac will end an address for load/store/prefetch 3313 // + An '!' will indicate a pre-indexed operation. 3314 // 3315 // It's someone else's responsibility to make sure these tokens are sane 3316 // in the given context! 3317 3318 SMLoc RLoc = Parser.getTok().getLoc(); 3319 if (parseOptionalToken(AsmToken::RBrac)) 3320 Operands.push_back( 3321 AArch64Operand::CreateToken("]", false, RLoc, getContext())); 3322 SMLoc ELoc = Parser.getTok().getLoc(); 3323 if (parseOptionalToken(AsmToken::Exclaim)) 3324 Operands.push_back( 3325 AArch64Operand::CreateToken("!", false, ELoc, getContext())); 3326 3327 ++N; 3328 } 3329 } 3330 3331 if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list")) 3332 return true; 3333 3334 return false; 3335 } 3336 3337 // FIXME: This entire function is a giant hack to provide us with decent 3338 // operand range validation/diagnostics until TableGen/MC can be extended 3339 // to support autogeneration of this kind of validation. 3340 bool AArch64AsmParser::validateInstruction(MCInst &Inst, 3341 SmallVectorImpl<SMLoc> &Loc) { 3342 const MCRegisterInfo *RI = getContext().getRegisterInfo(); 3343 // Check for indexed addressing modes w/ the base register being the 3344 // same as a destination/source register or pair load where 3345 // the Rt == Rt2. All of those are undefined behaviour. 3346 switch (Inst.getOpcode()) { 3347 case AArch64::LDPSWpre: 3348 case AArch64::LDPWpost: 3349 case AArch64::LDPWpre: 3350 case AArch64::LDPXpost: 3351 case AArch64::LDPXpre: { 3352 unsigned Rt = Inst.getOperand(1).getReg(); 3353 unsigned Rt2 = Inst.getOperand(2).getReg(); 3354 unsigned Rn = Inst.getOperand(3).getReg(); 3355 if (RI->isSubRegisterEq(Rn, Rt)) 3356 return Error(Loc[0], "unpredictable LDP instruction, writeback base " 3357 "is also a destination"); 3358 if (RI->isSubRegisterEq(Rn, Rt2)) 3359 return Error(Loc[1], "unpredictable LDP instruction, writeback base " 3360 "is also a destination"); 3361 LLVM_FALLTHROUGH; 3362 } 3363 case AArch64::LDPDi: 3364 case AArch64::LDPQi: 3365 case AArch64::LDPSi: 3366 case AArch64::LDPSWi: 3367 case AArch64::LDPWi: 3368 case AArch64::LDPXi: { 3369 unsigned Rt = Inst.getOperand(0).getReg(); 3370 unsigned Rt2 = Inst.getOperand(1).getReg(); 3371 if (Rt == Rt2) 3372 return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt"); 3373 break; 3374 } 3375 case AArch64::LDPDpost: 3376 case AArch64::LDPDpre: 3377 case AArch64::LDPQpost: 3378 case AArch64::LDPQpre: 3379 case AArch64::LDPSpost: 3380 case AArch64::LDPSpre: 3381 case AArch64::LDPSWpost: { 3382 unsigned Rt = Inst.getOperand(1).getReg(); 3383 unsigned Rt2 = Inst.getOperand(2).getReg(); 3384 if (Rt == Rt2) 3385 return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt"); 3386 break; 3387 } 3388 case AArch64::STPDpost: 3389 case AArch64::STPDpre: 3390 case AArch64::STPQpost: 3391 case AArch64::STPQpre: 3392 case AArch64::STPSpost: 3393 case AArch64::STPSpre: 3394 case AArch64::STPWpost: 3395 case AArch64::STPWpre: 3396 case AArch64::STPXpost: 3397 case AArch64::STPXpre: { 3398 unsigned Rt = Inst.getOperand(1).getReg(); 3399 unsigned Rt2 = Inst.getOperand(2).getReg(); 3400 unsigned Rn = Inst.getOperand(3).getReg(); 3401 if (RI->isSubRegisterEq(Rn, Rt)) 3402 return Error(Loc[0], "unpredictable STP instruction, writeback base " 3403 "is also a source"); 3404 if (RI->isSubRegisterEq(Rn, Rt2)) 3405 return Error(Loc[1], "unpredictable STP instruction, writeback base " 3406 "is also a source"); 3407 break; 3408 } 3409 case AArch64::LDRBBpre: 3410 case AArch64::LDRBpre: 3411 case AArch64::LDRHHpre: 3412 case AArch64::LDRHpre: 3413 case AArch64::LDRSBWpre: 3414 case AArch64::LDRSBXpre: 3415 case AArch64::LDRSHWpre: 3416 case AArch64::LDRSHXpre: 3417 case AArch64::LDRSWpre: 3418 case AArch64::LDRWpre: 3419 case AArch64::LDRXpre: 3420 case AArch64::LDRBBpost: 3421 case AArch64::LDRBpost: 3422 case AArch64::LDRHHpost: 3423 case AArch64::LDRHpost: 3424 case AArch64::LDRSBWpost: 3425 case AArch64::LDRSBXpost: 3426 case AArch64::LDRSHWpost: 3427 case AArch64::LDRSHXpost: 3428 case AArch64::LDRSWpost: 3429 case AArch64::LDRWpost: 3430 case AArch64::LDRXpost: { 3431 unsigned Rt = Inst.getOperand(1).getReg(); 3432 unsigned Rn = Inst.getOperand(2).getReg(); 3433 if (RI->isSubRegisterEq(Rn, Rt)) 3434 return Error(Loc[0], "unpredictable LDR instruction, writeback base " 3435 "is also a source"); 3436 break; 3437 } 3438 case AArch64::STRBBpost: 3439 case AArch64::STRBpost: 3440 case AArch64::STRHHpost: 3441 case AArch64::STRHpost: 3442 case AArch64::STRWpost: 3443 case AArch64::STRXpost: 3444 case AArch64::STRBBpre: 3445 case AArch64::STRBpre: 3446 case AArch64::STRHHpre: 3447 case AArch64::STRHpre: 3448 case AArch64::STRWpre: 3449 case AArch64::STRXpre: { 3450 unsigned Rt = Inst.getOperand(1).getReg(); 3451 unsigned Rn = Inst.getOperand(2).getReg(); 3452 if (RI->isSubRegisterEq(Rn, Rt)) 3453 return Error(Loc[0], "unpredictable STR instruction, writeback base " 3454 "is also a source"); 3455 break; 3456 } 3457 } 3458 3459 // Now check immediate ranges. Separate from the above as there is overlap 3460 // in the instructions being checked and this keeps the nested conditionals 3461 // to a minimum. 3462 switch (Inst.getOpcode()) { 3463 case AArch64::ADDSWri: 3464 case AArch64::ADDSXri: 3465 case AArch64::ADDWri: 3466 case AArch64::ADDXri: 3467 case AArch64::SUBSWri: 3468 case AArch64::SUBSXri: 3469 case AArch64::SUBWri: 3470 case AArch64::SUBXri: { 3471 // Annoyingly we can't do this in the isAddSubImm predicate, so there is 3472 // some slight duplication here. 3473 if (Inst.getOperand(2).isExpr()) { 3474 const MCExpr *Expr = Inst.getOperand(2).getExpr(); 3475 AArch64MCExpr::VariantKind ELFRefKind; 3476 MCSymbolRefExpr::VariantKind DarwinRefKind; 3477 int64_t Addend; 3478 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) { 3479 3480 // Only allow these with ADDXri. 3481 if ((DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF || 3482 DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) && 3483 Inst.getOpcode() == AArch64::ADDXri) 3484 return false; 3485 3486 // Only allow these with ADDXri/ADDWri 3487 if ((ELFRefKind == AArch64MCExpr::VK_LO12 || 3488 ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 || 3489 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 || 3490 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC || 3491 ELFRefKind == AArch64MCExpr::VK_TPREL_HI12 || 3492 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 || 3493 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC || 3494 ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12) && 3495 (Inst.getOpcode() == AArch64::ADDXri || 3496 Inst.getOpcode() == AArch64::ADDWri)) 3497 return false; 3498 3499 // Don't allow symbol refs in the immediate field otherwise 3500 // Note: Loc.back() may be Loc[1] or Loc[2] depending on the number of 3501 // operands of the original instruction (i.e. 'add w0, w1, borked' vs 3502 // 'cmp w0, 'borked') 3503 return Error(Loc.back(), "invalid immediate expression"); 3504 } 3505 // We don't validate more complex expressions here 3506 } 3507 return false; 3508 } 3509 default: 3510 return false; 3511 } 3512 } 3513 3514 static std::string AArch64MnemonicSpellCheck(StringRef S, uint64_t FBS, 3515 unsigned VariantID = 0); 3516 3517 bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode, 3518 OperandVector &Operands) { 3519 switch (ErrCode) { 3520 case Match_MissingFeature: 3521 return Error(Loc, 3522 "instruction requires a CPU feature not currently enabled"); 3523 case Match_InvalidOperand: 3524 return Error(Loc, "invalid operand for instruction"); 3525 case Match_InvalidSuffix: 3526 return Error(Loc, "invalid type suffix for instruction"); 3527 case Match_InvalidCondCode: 3528 return Error(Loc, "expected AArch64 condition code"); 3529 case Match_AddSubRegExtendSmall: 3530 return Error(Loc, 3531 "expected '[su]xt[bhw]' or 'lsl' with optional integer in range [0, 4]"); 3532 case Match_AddSubRegExtendLarge: 3533 return Error(Loc, 3534 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]"); 3535 case Match_AddSubSecondSource: 3536 return Error(Loc, 3537 "expected compatible register, symbol or integer in range [0, 4095]"); 3538 case Match_LogicalSecondSource: 3539 return Error(Loc, "expected compatible register or logical immediate"); 3540 case Match_InvalidMovImm32Shift: 3541 return Error(Loc, "expected 'lsl' with optional integer 0 or 16"); 3542 case Match_InvalidMovImm64Shift: 3543 return Error(Loc, "expected 'lsl' with optional integer 0, 16, 32 or 48"); 3544 case Match_AddSubRegShift32: 3545 return Error(Loc, 3546 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]"); 3547 case Match_AddSubRegShift64: 3548 return Error(Loc, 3549 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]"); 3550 case Match_InvalidFPImm: 3551 return Error(Loc, 3552 "expected compatible register or floating-point constant"); 3553 case Match_InvalidMemoryIndexedSImm9: 3554 return Error(Loc, "index must be an integer in range [-256, 255]."); 3555 case Match_InvalidMemoryIndexedSImm10: 3556 return Error(Loc, "index must be a multiple of 8 in range [-4096, 4088]."); 3557 case Match_InvalidMemoryIndexed4SImm7: 3558 return Error(Loc, "index must be a multiple of 4 in range [-256, 252]."); 3559 case Match_InvalidMemoryIndexed8SImm7: 3560 return Error(Loc, "index must be a multiple of 8 in range [-512, 504]."); 3561 case Match_InvalidMemoryIndexed16SImm7: 3562 return Error(Loc, "index must be a multiple of 16 in range [-1024, 1008]."); 3563 case Match_InvalidMemoryWExtend8: 3564 return Error(Loc, 3565 "expected 'uxtw' or 'sxtw' with optional shift of #0"); 3566 case Match_InvalidMemoryWExtend16: 3567 return Error(Loc, 3568 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1"); 3569 case Match_InvalidMemoryWExtend32: 3570 return Error(Loc, 3571 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2"); 3572 case Match_InvalidMemoryWExtend64: 3573 return Error(Loc, 3574 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3"); 3575 case Match_InvalidMemoryWExtend128: 3576 return Error(Loc, 3577 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4"); 3578 case Match_InvalidMemoryXExtend8: 3579 return Error(Loc, 3580 "expected 'lsl' or 'sxtx' with optional shift of #0"); 3581 case Match_InvalidMemoryXExtend16: 3582 return Error(Loc, 3583 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1"); 3584 case Match_InvalidMemoryXExtend32: 3585 return Error(Loc, 3586 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2"); 3587 case Match_InvalidMemoryXExtend64: 3588 return Error(Loc, 3589 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3"); 3590 case Match_InvalidMemoryXExtend128: 3591 return Error(Loc, 3592 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4"); 3593 case Match_InvalidMemoryIndexed1: 3594 return Error(Loc, "index must be an integer in range [0, 4095]."); 3595 case Match_InvalidMemoryIndexed2: 3596 return Error(Loc, "index must be a multiple of 2 in range [0, 8190]."); 3597 case Match_InvalidMemoryIndexed4: 3598 return Error(Loc, "index must be a multiple of 4 in range [0, 16380]."); 3599 case Match_InvalidMemoryIndexed8: 3600 return Error(Loc, "index must be a multiple of 8 in range [0, 32760]."); 3601 case Match_InvalidMemoryIndexed16: 3602 return Error(Loc, "index must be a multiple of 16 in range [0, 65520]."); 3603 case Match_InvalidImm0_1: 3604 return Error(Loc, "immediate must be an integer in range [0, 1]."); 3605 case Match_InvalidImm0_7: 3606 return Error(Loc, "immediate must be an integer in range [0, 7]."); 3607 case Match_InvalidImm0_15: 3608 return Error(Loc, "immediate must be an integer in range [0, 15]."); 3609 case Match_InvalidImm0_31: 3610 return Error(Loc, "immediate must be an integer in range [0, 31]."); 3611 case Match_InvalidImm0_63: 3612 return Error(Loc, "immediate must be an integer in range [0, 63]."); 3613 case Match_InvalidImm0_127: 3614 return Error(Loc, "immediate must be an integer in range [0, 127]."); 3615 case Match_InvalidImm0_255: 3616 return Error(Loc, "immediate must be an integer in range [0, 255]."); 3617 case Match_InvalidImm0_65535: 3618 return Error(Loc, "immediate must be an integer in range [0, 65535]."); 3619 case Match_InvalidImm1_8: 3620 return Error(Loc, "immediate must be an integer in range [1, 8]."); 3621 case Match_InvalidImm1_16: 3622 return Error(Loc, "immediate must be an integer in range [1, 16]."); 3623 case Match_InvalidImm1_32: 3624 return Error(Loc, "immediate must be an integer in range [1, 32]."); 3625 case Match_InvalidImm1_64: 3626 return Error(Loc, "immediate must be an integer in range [1, 64]."); 3627 case Match_InvalidIndex1: 3628 return Error(Loc, "expected lane specifier '[1]'"); 3629 case Match_InvalidIndexB: 3630 return Error(Loc, "vector lane must be an integer in range [0, 15]."); 3631 case Match_InvalidIndexH: 3632 return Error(Loc, "vector lane must be an integer in range [0, 7]."); 3633 case Match_InvalidIndexS: 3634 return Error(Loc, "vector lane must be an integer in range [0, 3]."); 3635 case Match_InvalidIndexD: 3636 return Error(Loc, "vector lane must be an integer in range [0, 1]."); 3637 case Match_InvalidLabel: 3638 return Error(Loc, "expected label or encodable integer pc offset"); 3639 case Match_MRS: 3640 return Error(Loc, "expected readable system register"); 3641 case Match_MSR: 3642 return Error(Loc, "expected writable system register or pstate"); 3643 case Match_InvalidComplexRotationEven: 3644 return Error(Loc, "complex rotation must be 0, 90, 180 or 270."); 3645 case Match_InvalidComplexRotationOdd: 3646 return Error(Loc, "complex rotation must be 90 or 270."); 3647 case Match_MnemonicFail: { 3648 std::string Suggestion = AArch64MnemonicSpellCheck( 3649 ((AArch64Operand &)*Operands[0]).getToken(), 3650 ComputeAvailableFeatures(STI->getFeatureBits())); 3651 return Error(Loc, "unrecognized instruction mnemonic" + Suggestion); 3652 } 3653 case Match_InvalidSVEPredicateAnyReg: 3654 case Match_InvalidSVEPredicateBReg: 3655 case Match_InvalidSVEPredicateHReg: 3656 case Match_InvalidSVEPredicateSReg: 3657 case Match_InvalidSVEPredicateDReg: 3658 return Error(Loc, "invalid predicate register."); 3659 default: 3660 llvm_unreachable("unexpected error code!"); 3661 } 3662 } 3663 3664 static const char *getSubtargetFeatureName(uint64_t Val); 3665 3666 bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 3667 OperandVector &Operands, 3668 MCStreamer &Out, 3669 uint64_t &ErrorInfo, 3670 bool MatchingInlineAsm) { 3671 assert(!Operands.empty() && "Unexpect empty operand list!"); 3672 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[0]); 3673 assert(Op.isToken() && "Leading operand should always be a mnemonic!"); 3674 3675 StringRef Tok = Op.getToken(); 3676 unsigned NumOperands = Operands.size(); 3677 3678 if (NumOperands == 4 && Tok == "lsl") { 3679 AArch64Operand &Op2 = static_cast<AArch64Operand &>(*Operands[2]); 3680 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]); 3681 if (Op2.isReg() && Op3.isImm()) { 3682 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm()); 3683 if (Op3CE) { 3684 uint64_t Op3Val = Op3CE->getValue(); 3685 uint64_t NewOp3Val = 0; 3686 uint64_t NewOp4Val = 0; 3687 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].contains( 3688 Op2.getReg())) { 3689 NewOp3Val = (32 - Op3Val) & 0x1f; 3690 NewOp4Val = 31 - Op3Val; 3691 } else { 3692 NewOp3Val = (64 - Op3Val) & 0x3f; 3693 NewOp4Val = 63 - Op3Val; 3694 } 3695 3696 const MCExpr *NewOp3 = MCConstantExpr::create(NewOp3Val, getContext()); 3697 const MCExpr *NewOp4 = MCConstantExpr::create(NewOp4Val, getContext()); 3698 3699 Operands[0] = AArch64Operand::CreateToken( 3700 "ubfm", false, Op.getStartLoc(), getContext()); 3701 Operands.push_back(AArch64Operand::CreateImm( 3702 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext())); 3703 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(), 3704 Op3.getEndLoc(), getContext()); 3705 } 3706 } 3707 } else if (NumOperands == 4 && Tok == "bfc") { 3708 // FIXME: Horrible hack to handle BFC->BFM alias. 3709 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]); 3710 AArch64Operand LSBOp = static_cast<AArch64Operand &>(*Operands[2]); 3711 AArch64Operand WidthOp = static_cast<AArch64Operand &>(*Operands[3]); 3712 3713 if (Op1.isReg() && LSBOp.isImm() && WidthOp.isImm()) { 3714 const MCConstantExpr *LSBCE = dyn_cast<MCConstantExpr>(LSBOp.getImm()); 3715 const MCConstantExpr *WidthCE = dyn_cast<MCConstantExpr>(WidthOp.getImm()); 3716 3717 if (LSBCE && WidthCE) { 3718 uint64_t LSB = LSBCE->getValue(); 3719 uint64_t Width = WidthCE->getValue(); 3720 3721 uint64_t RegWidth = 0; 3722 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( 3723 Op1.getReg())) 3724 RegWidth = 64; 3725 else 3726 RegWidth = 32; 3727 3728 if (LSB >= RegWidth) 3729 return Error(LSBOp.getStartLoc(), 3730 "expected integer in range [0, 31]"); 3731 if (Width < 1 || Width > RegWidth) 3732 return Error(WidthOp.getStartLoc(), 3733 "expected integer in range [1, 32]"); 3734 3735 uint64_t ImmR = 0; 3736 if (RegWidth == 32) 3737 ImmR = (32 - LSB) & 0x1f; 3738 else 3739 ImmR = (64 - LSB) & 0x3f; 3740 3741 uint64_t ImmS = Width - 1; 3742 3743 if (ImmR != 0 && ImmS >= ImmR) 3744 return Error(WidthOp.getStartLoc(), 3745 "requested insert overflows register"); 3746 3747 const MCExpr *ImmRExpr = MCConstantExpr::create(ImmR, getContext()); 3748 const MCExpr *ImmSExpr = MCConstantExpr::create(ImmS, getContext()); 3749 Operands[0] = AArch64Operand::CreateToken( 3750 "bfm", false, Op.getStartLoc(), getContext()); 3751 Operands[2] = AArch64Operand::CreateReg( 3752 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar, 3753 SMLoc(), SMLoc(), getContext()); 3754 Operands[3] = AArch64Operand::CreateImm( 3755 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(), getContext()); 3756 Operands.emplace_back( 3757 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(), 3758 WidthOp.getEndLoc(), getContext())); 3759 } 3760 } 3761 } else if (NumOperands == 5) { 3762 // FIXME: Horrible hack to handle the BFI -> BFM, SBFIZ->SBFM, and 3763 // UBFIZ -> UBFM aliases. 3764 if (Tok == "bfi" || Tok == "sbfiz" || Tok == "ubfiz") { 3765 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]); 3766 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]); 3767 AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]); 3768 3769 if (Op1.isReg() && Op3.isImm() && Op4.isImm()) { 3770 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm()); 3771 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm()); 3772 3773 if (Op3CE && Op4CE) { 3774 uint64_t Op3Val = Op3CE->getValue(); 3775 uint64_t Op4Val = Op4CE->getValue(); 3776 3777 uint64_t RegWidth = 0; 3778 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( 3779 Op1.getReg())) 3780 RegWidth = 64; 3781 else 3782 RegWidth = 32; 3783 3784 if (Op3Val >= RegWidth) 3785 return Error(Op3.getStartLoc(), 3786 "expected integer in range [0, 31]"); 3787 if (Op4Val < 1 || Op4Val > RegWidth) 3788 return Error(Op4.getStartLoc(), 3789 "expected integer in range [1, 32]"); 3790 3791 uint64_t NewOp3Val = 0; 3792 if (RegWidth == 32) 3793 NewOp3Val = (32 - Op3Val) & 0x1f; 3794 else 3795 NewOp3Val = (64 - Op3Val) & 0x3f; 3796 3797 uint64_t NewOp4Val = Op4Val - 1; 3798 3799 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val) 3800 return Error(Op4.getStartLoc(), 3801 "requested insert overflows register"); 3802 3803 const MCExpr *NewOp3 = 3804 MCConstantExpr::create(NewOp3Val, getContext()); 3805 const MCExpr *NewOp4 = 3806 MCConstantExpr::create(NewOp4Val, getContext()); 3807 Operands[3] = AArch64Operand::CreateImm( 3808 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext()); 3809 Operands[4] = AArch64Operand::CreateImm( 3810 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext()); 3811 if (Tok == "bfi") 3812 Operands[0] = AArch64Operand::CreateToken( 3813 "bfm", false, Op.getStartLoc(), getContext()); 3814 else if (Tok == "sbfiz") 3815 Operands[0] = AArch64Operand::CreateToken( 3816 "sbfm", false, Op.getStartLoc(), getContext()); 3817 else if (Tok == "ubfiz") 3818 Operands[0] = AArch64Operand::CreateToken( 3819 "ubfm", false, Op.getStartLoc(), getContext()); 3820 else 3821 llvm_unreachable("No valid mnemonic for alias?"); 3822 } 3823 } 3824 3825 // FIXME: Horrible hack to handle the BFXIL->BFM, SBFX->SBFM, and 3826 // UBFX -> UBFM aliases. 3827 } else if (NumOperands == 5 && 3828 (Tok == "bfxil" || Tok == "sbfx" || Tok == "ubfx")) { 3829 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]); 3830 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]); 3831 AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]); 3832 3833 if (Op1.isReg() && Op3.isImm() && Op4.isImm()) { 3834 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm()); 3835 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm()); 3836 3837 if (Op3CE && Op4CE) { 3838 uint64_t Op3Val = Op3CE->getValue(); 3839 uint64_t Op4Val = Op4CE->getValue(); 3840 3841 uint64_t RegWidth = 0; 3842 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( 3843 Op1.getReg())) 3844 RegWidth = 64; 3845 else 3846 RegWidth = 32; 3847 3848 if (Op3Val >= RegWidth) 3849 return Error(Op3.getStartLoc(), 3850 "expected integer in range [0, 31]"); 3851 if (Op4Val < 1 || Op4Val > RegWidth) 3852 return Error(Op4.getStartLoc(), 3853 "expected integer in range [1, 32]"); 3854 3855 uint64_t NewOp4Val = Op3Val + Op4Val - 1; 3856 3857 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val) 3858 return Error(Op4.getStartLoc(), 3859 "requested extract overflows register"); 3860 3861 const MCExpr *NewOp4 = 3862 MCConstantExpr::create(NewOp4Val, getContext()); 3863 Operands[4] = AArch64Operand::CreateImm( 3864 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext()); 3865 if (Tok == "bfxil") 3866 Operands[0] = AArch64Operand::CreateToken( 3867 "bfm", false, Op.getStartLoc(), getContext()); 3868 else if (Tok == "sbfx") 3869 Operands[0] = AArch64Operand::CreateToken( 3870 "sbfm", false, Op.getStartLoc(), getContext()); 3871 else if (Tok == "ubfx") 3872 Operands[0] = AArch64Operand::CreateToken( 3873 "ubfm", false, Op.getStartLoc(), getContext()); 3874 else 3875 llvm_unreachable("No valid mnemonic for alias?"); 3876 } 3877 } 3878 } 3879 } 3880 3881 // The Cyclone CPU and early successors didn't execute the zero-cycle zeroing 3882 // instruction for FP registers correctly in some rare circumstances. Convert 3883 // it to a safe instruction and warn (because silently changing someone's 3884 // assembly is rude). 3885 if (getSTI().getFeatureBits()[AArch64::FeatureZCZeroingFPWorkaround] && 3886 NumOperands == 4 && Tok == "movi") { 3887 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]); 3888 AArch64Operand &Op2 = static_cast<AArch64Operand &>(*Operands[2]); 3889 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]); 3890 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) || 3891 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) { 3892 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken(); 3893 if (Suffix.lower() == ".2d" && 3894 cast<MCConstantExpr>(Op3.getImm())->getValue() == 0) { 3895 Warning(IDLoc, "instruction movi.2d with immediate #0 may not function" 3896 " correctly on this CPU, converting to equivalent movi.16b"); 3897 // Switch the suffix to .16b. 3898 unsigned Idx = Op1.isToken() ? 1 : 2; 3899 Operands[Idx] = AArch64Operand::CreateToken(".16b", false, IDLoc, 3900 getContext()); 3901 } 3902 } 3903 } 3904 3905 // FIXME: Horrible hack for sxtw and uxtw with Wn src and Xd dst operands. 3906 // InstAlias can't quite handle this since the reg classes aren't 3907 // subclasses. 3908 if (NumOperands == 3 && (Tok == "sxtw" || Tok == "uxtw")) { 3909 // The source register can be Wn here, but the matcher expects a 3910 // GPR64. Twiddle it here if necessary. 3911 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]); 3912 if (Op.isReg()) { 3913 unsigned Reg = getXRegFromWReg(Op.getReg()); 3914 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar, 3915 Op.getStartLoc(), Op.getEndLoc(), 3916 getContext()); 3917 } 3918 } 3919 // FIXME: Likewise for sxt[bh] with a Xd dst operand 3920 else if (NumOperands == 3 && (Tok == "sxtb" || Tok == "sxth")) { 3921 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]); 3922 if (Op.isReg() && 3923 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( 3924 Op.getReg())) { 3925 // The source register can be Wn here, but the matcher expects a 3926 // GPR64. Twiddle it here if necessary. 3927 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]); 3928 if (Op.isReg()) { 3929 unsigned Reg = getXRegFromWReg(Op.getReg()); 3930 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar, 3931 Op.getStartLoc(), 3932 Op.getEndLoc(), getContext()); 3933 } 3934 } 3935 } 3936 // FIXME: Likewise for uxt[bh] with a Xd dst operand 3937 else if (NumOperands == 3 && (Tok == "uxtb" || Tok == "uxth")) { 3938 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]); 3939 if (Op.isReg() && 3940 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( 3941 Op.getReg())) { 3942 // The source register can be Wn here, but the matcher expects a 3943 // GPR32. Twiddle it here if necessary. 3944 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]); 3945 if (Op.isReg()) { 3946 unsigned Reg = getWRegFromXReg(Op.getReg()); 3947 Operands[1] = AArch64Operand::CreateReg(Reg, RegKind::Scalar, 3948 Op.getStartLoc(), 3949 Op.getEndLoc(), getContext()); 3950 } 3951 } 3952 } 3953 3954 MCInst Inst; 3955 // First try to match against the secondary set of tables containing the 3956 // short-form NEON instructions (e.g. "fadd.2s v0, v1, v2"). 3957 unsigned MatchResult = 3958 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 1); 3959 3960 // If that fails, try against the alternate table containing long-form NEON: 3961 // "fadd v0.2s, v1.2s, v2.2s" 3962 if (MatchResult != Match_Success) { 3963 // But first, save the short-form match result: we can use it in case the 3964 // long-form match also fails. 3965 auto ShortFormNEONErrorInfo = ErrorInfo; 3966 auto ShortFormNEONMatchResult = MatchResult; 3967 3968 MatchResult = 3969 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 0); 3970 3971 // Now, both matches failed, and the long-form match failed on the mnemonic 3972 // suffix token operand. The short-form match failure is probably more 3973 // relevant: use it instead. 3974 if (MatchResult == Match_InvalidOperand && ErrorInfo == 1 && 3975 Operands.size() > 1 && ((AArch64Operand &)*Operands[1]).isToken() && 3976 ((AArch64Operand &)*Operands[1]).isTokenSuffix()) { 3977 MatchResult = ShortFormNEONMatchResult; 3978 ErrorInfo = ShortFormNEONErrorInfo; 3979 } 3980 } 3981 3982 switch (MatchResult) { 3983 case Match_Success: { 3984 // Perform range checking and other semantic validations 3985 SmallVector<SMLoc, 8> OperandLocs; 3986 NumOperands = Operands.size(); 3987 for (unsigned i = 1; i < NumOperands; ++i) 3988 OperandLocs.push_back(Operands[i]->getStartLoc()); 3989 if (validateInstruction(Inst, OperandLocs)) 3990 return true; 3991 3992 Inst.setLoc(IDLoc); 3993 Out.EmitInstruction(Inst, getSTI()); 3994 return false; 3995 } 3996 case Match_MissingFeature: { 3997 assert(ErrorInfo && "Unknown missing feature!"); 3998 // Special case the error message for the very common case where only 3999 // a single subtarget feature is missing (neon, e.g.). 4000 std::string Msg = "instruction requires:"; 4001 uint64_t Mask = 1; 4002 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) { 4003 if (ErrorInfo & Mask) { 4004 Msg += " "; 4005 Msg += getSubtargetFeatureName(ErrorInfo & Mask); 4006 } 4007 Mask <<= 1; 4008 } 4009 return Error(IDLoc, Msg); 4010 } 4011 case Match_MnemonicFail: 4012 return showMatchError(IDLoc, MatchResult, Operands); 4013 case Match_InvalidOperand: { 4014 SMLoc ErrorLoc = IDLoc; 4015 4016 if (ErrorInfo != ~0ULL) { 4017 if (ErrorInfo >= Operands.size()) 4018 return Error(IDLoc, "too few operands for instruction", 4019 SMRange(IDLoc, getTok().getLoc())); 4020 4021 ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc(); 4022 if (ErrorLoc == SMLoc()) 4023 ErrorLoc = IDLoc; 4024 } 4025 // If the match failed on a suffix token operand, tweak the diagnostic 4026 // accordingly. 4027 if (((AArch64Operand &)*Operands[ErrorInfo]).isToken() && 4028 ((AArch64Operand &)*Operands[ErrorInfo]).isTokenSuffix()) 4029 MatchResult = Match_InvalidSuffix; 4030 4031 return showMatchError(ErrorLoc, MatchResult, Operands); 4032 } 4033 case Match_InvalidMemoryIndexed1: 4034 case Match_InvalidMemoryIndexed2: 4035 case Match_InvalidMemoryIndexed4: 4036 case Match_InvalidMemoryIndexed8: 4037 case Match_InvalidMemoryIndexed16: 4038 case Match_InvalidCondCode: 4039 case Match_AddSubRegExtendSmall: 4040 case Match_AddSubRegExtendLarge: 4041 case Match_AddSubSecondSource: 4042 case Match_LogicalSecondSource: 4043 case Match_AddSubRegShift32: 4044 case Match_AddSubRegShift64: 4045 case Match_InvalidMovImm32Shift: 4046 case Match_InvalidMovImm64Shift: 4047 case Match_InvalidFPImm: 4048 case Match_InvalidMemoryWExtend8: 4049 case Match_InvalidMemoryWExtend16: 4050 case Match_InvalidMemoryWExtend32: 4051 case Match_InvalidMemoryWExtend64: 4052 case Match_InvalidMemoryWExtend128: 4053 case Match_InvalidMemoryXExtend8: 4054 case Match_InvalidMemoryXExtend16: 4055 case Match_InvalidMemoryXExtend32: 4056 case Match_InvalidMemoryXExtend64: 4057 case Match_InvalidMemoryXExtend128: 4058 case Match_InvalidMemoryIndexed4SImm7: 4059 case Match_InvalidMemoryIndexed8SImm7: 4060 case Match_InvalidMemoryIndexed16SImm7: 4061 case Match_InvalidMemoryIndexedSImm9: 4062 case Match_InvalidMemoryIndexedSImm10: 4063 case Match_InvalidImm0_1: 4064 case Match_InvalidImm0_7: 4065 case Match_InvalidImm0_15: 4066 case Match_InvalidImm0_31: 4067 case Match_InvalidImm0_63: 4068 case Match_InvalidImm0_127: 4069 case Match_InvalidImm0_255: 4070 case Match_InvalidImm0_65535: 4071 case Match_InvalidImm1_8: 4072 case Match_InvalidImm1_16: 4073 case Match_InvalidImm1_32: 4074 case Match_InvalidImm1_64: 4075 case Match_InvalidIndex1: 4076 case Match_InvalidIndexB: 4077 case Match_InvalidIndexH: 4078 case Match_InvalidIndexS: 4079 case Match_InvalidIndexD: 4080 case Match_InvalidLabel: 4081 case Match_InvalidComplexRotationEven: 4082 case Match_InvalidComplexRotationOdd: 4083 case Match_InvalidSVEPredicateAnyReg: 4084 case Match_InvalidSVEPredicateBReg: 4085 case Match_InvalidSVEPredicateHReg: 4086 case Match_InvalidSVEPredicateSReg: 4087 case Match_InvalidSVEPredicateDReg: 4088 case Match_MSR: 4089 case Match_MRS: { 4090 if (ErrorInfo >= Operands.size()) 4091 return Error(IDLoc, "too few operands for instruction", SMRange(IDLoc, (*Operands.back()).getEndLoc())); 4092 // Any time we get here, there's nothing fancy to do. Just get the 4093 // operand SMLoc and display the diagnostic. 4094 SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc(); 4095 if (ErrorLoc == SMLoc()) 4096 ErrorLoc = IDLoc; 4097 return showMatchError(ErrorLoc, MatchResult, Operands); 4098 } 4099 } 4100 4101 llvm_unreachable("Implement any new match types added!"); 4102 } 4103 4104 /// ParseDirective parses the arm specific directives 4105 bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) { 4106 const MCObjectFileInfo::Environment Format = 4107 getContext().getObjectFileInfo()->getObjectFileType(); 4108 bool IsMachO = Format == MCObjectFileInfo::IsMachO; 4109 bool IsCOFF = Format == MCObjectFileInfo::IsCOFF; 4110 4111 StringRef IDVal = DirectiveID.getIdentifier(); 4112 SMLoc Loc = DirectiveID.getLoc(); 4113 if (IDVal == ".arch") 4114 parseDirectiveArch(Loc); 4115 else if (IDVal == ".cpu") 4116 parseDirectiveCPU(Loc); 4117 else if (IDVal == ".hword") 4118 parseDirectiveWord(2, Loc); 4119 else if (IDVal == ".word") 4120 parseDirectiveWord(4, Loc); 4121 else if (IDVal == ".xword") 4122 parseDirectiveWord(8, Loc); 4123 else if (IDVal == ".tlsdesccall") 4124 parseDirectiveTLSDescCall(Loc); 4125 else if (IDVal == ".ltorg" || IDVal == ".pool") 4126 parseDirectiveLtorg(Loc); 4127 else if (IDVal == ".unreq") 4128 parseDirectiveUnreq(Loc); 4129 else if (!IsMachO && !IsCOFF) { 4130 if (IDVal == ".inst") 4131 parseDirectiveInst(Loc); 4132 else 4133 return true; 4134 } else if (IDVal == MCLOHDirectiveName()) 4135 parseDirectiveLOH(IDVal, Loc); 4136 else 4137 return true; 4138 return false; 4139 } 4140 4141 static const struct { 4142 const char *Name; 4143 const FeatureBitset Features; 4144 } ExtensionMap[] = { 4145 { "crc", {AArch64::FeatureCRC} }, 4146 { "crypto", {AArch64::FeatureCrypto} }, 4147 { "fp", {AArch64::FeatureFPARMv8} }, 4148 { "simd", {AArch64::FeatureNEON} }, 4149 { "ras", {AArch64::FeatureRAS} }, 4150 { "lse", {AArch64::FeatureLSE} }, 4151 4152 // FIXME: Unsupported extensions 4153 { "pan", {} }, 4154 { "lor", {} }, 4155 { "rdma", {} }, 4156 { "profile", {} }, 4157 }; 4158 4159 /// parseDirectiveArch 4160 /// ::= .arch token 4161 bool AArch64AsmParser::parseDirectiveArch(SMLoc L) { 4162 SMLoc ArchLoc = getLoc(); 4163 4164 StringRef Arch, ExtensionString; 4165 std::tie(Arch, ExtensionString) = 4166 getParser().parseStringToEndOfStatement().trim().split('+'); 4167 4168 AArch64::ArchKind ID = AArch64::parseArch(Arch); 4169 if (ID == AArch64::ArchKind::INVALID) 4170 return Error(ArchLoc, "unknown arch name"); 4171 4172 if (parseToken(AsmToken::EndOfStatement)) 4173 return true; 4174 4175 // Get the architecture and extension features. 4176 std::vector<StringRef> AArch64Features; 4177 AArch64::getArchFeatures(ID, AArch64Features); 4178 AArch64::getExtensionFeatures(AArch64::getDefaultExtensions("generic", ID), 4179 AArch64Features); 4180 4181 MCSubtargetInfo &STI = copySTI(); 4182 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end()); 4183 STI.setDefaultFeatures("generic", join(ArchFeatures.begin(), ArchFeatures.end(), ",")); 4184 4185 SmallVector<StringRef, 4> RequestedExtensions; 4186 if (!ExtensionString.empty()) 4187 ExtensionString.split(RequestedExtensions, '+'); 4188 4189 FeatureBitset Features = STI.getFeatureBits(); 4190 for (auto Name : RequestedExtensions) { 4191 bool EnableFeature = true; 4192 4193 if (Name.startswith_lower("no")) { 4194 EnableFeature = false; 4195 Name = Name.substr(2); 4196 } 4197 4198 for (const auto &Extension : ExtensionMap) { 4199 if (Extension.Name != Name) 4200 continue; 4201 4202 if (Extension.Features.none()) 4203 report_fatal_error("unsupported architectural extension: " + Name); 4204 4205 FeatureBitset ToggleFeatures = EnableFeature 4206 ? (~Features & Extension.Features) 4207 : ( Features & Extension.Features); 4208 uint64_t Features = 4209 ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures)); 4210 setAvailableFeatures(Features); 4211 break; 4212 } 4213 } 4214 return false; 4215 } 4216 4217 static SMLoc incrementLoc(SMLoc L, int Offset) { 4218 return SMLoc::getFromPointer(L.getPointer() + Offset); 4219 } 4220 4221 /// parseDirectiveCPU 4222 /// ::= .cpu id 4223 bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) { 4224 SMLoc CurLoc = getLoc(); 4225 4226 StringRef CPU, ExtensionString; 4227 std::tie(CPU, ExtensionString) = 4228 getParser().parseStringToEndOfStatement().trim().split('+'); 4229 4230 if (parseToken(AsmToken::EndOfStatement)) 4231 return true; 4232 4233 SmallVector<StringRef, 4> RequestedExtensions; 4234 if (!ExtensionString.empty()) 4235 ExtensionString.split(RequestedExtensions, '+'); 4236 4237 // FIXME This is using tablegen data, but should be moved to ARMTargetParser 4238 // once that is tablegen'ed 4239 if (!getSTI().isCPUStringValid(CPU)) { 4240 Error(CurLoc, "unknown CPU name"); 4241 return false; 4242 } 4243 4244 MCSubtargetInfo &STI = copySTI(); 4245 STI.setDefaultFeatures(CPU, ""); 4246 CurLoc = incrementLoc(CurLoc, CPU.size()); 4247 4248 FeatureBitset Features = STI.getFeatureBits(); 4249 for (auto Name : RequestedExtensions) { 4250 // Advance source location past '+'. 4251 CurLoc = incrementLoc(CurLoc, 1); 4252 4253 bool EnableFeature = true; 4254 4255 if (Name.startswith_lower("no")) { 4256 EnableFeature = false; 4257 Name = Name.substr(2); 4258 } 4259 4260 bool FoundExtension = false; 4261 for (const auto &Extension : ExtensionMap) { 4262 if (Extension.Name != Name) 4263 continue; 4264 4265 if (Extension.Features.none()) 4266 report_fatal_error("unsupported architectural extension: " + Name); 4267 4268 FeatureBitset ToggleFeatures = EnableFeature 4269 ? (~Features & Extension.Features) 4270 : ( Features & Extension.Features); 4271 uint64_t Features = 4272 ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures)); 4273 setAvailableFeatures(Features); 4274 FoundExtension = true; 4275 4276 break; 4277 } 4278 4279 if (!FoundExtension) 4280 Error(CurLoc, "unsupported architectural extension"); 4281 4282 CurLoc = incrementLoc(CurLoc, Name.size()); 4283 } 4284 return false; 4285 } 4286 4287 /// parseDirectiveWord 4288 /// ::= .word [ expression (, expression)* ] 4289 bool AArch64AsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 4290 auto parseOp = [&]() -> bool { 4291 const MCExpr *Value; 4292 if (getParser().parseExpression(Value)) 4293 return true; 4294 getParser().getStreamer().EmitValue(Value, Size, L); 4295 return false; 4296 }; 4297 4298 if (parseMany(parseOp)) 4299 return true; 4300 return false; 4301 } 4302 4303 /// parseDirectiveInst 4304 /// ::= .inst opcode [, ...] 4305 bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) { 4306 if (getLexer().is(AsmToken::EndOfStatement)) 4307 return Error(Loc, "expected expression following '.inst' directive"); 4308 4309 auto parseOp = [&]() -> bool { 4310 SMLoc L = getLoc(); 4311 const MCExpr *Expr; 4312 if (check(getParser().parseExpression(Expr), L, "expected expression")) 4313 return true; 4314 const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr); 4315 if (check(!Value, L, "expected constant expression")) 4316 return true; 4317 getTargetStreamer().emitInst(Value->getValue()); 4318 return false; 4319 }; 4320 4321 if (parseMany(parseOp)) 4322 return addErrorSuffix(" in '.inst' directive"); 4323 return false; 4324 } 4325 4326 // parseDirectiveTLSDescCall: 4327 // ::= .tlsdesccall symbol 4328 bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) { 4329 StringRef Name; 4330 if (check(getParser().parseIdentifier(Name), L, 4331 "expected symbol after directive") || 4332 parseToken(AsmToken::EndOfStatement)) 4333 return true; 4334 4335 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 4336 const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext()); 4337 Expr = AArch64MCExpr::create(Expr, AArch64MCExpr::VK_TLSDESC, getContext()); 4338 4339 MCInst Inst; 4340 Inst.setOpcode(AArch64::TLSDESCCALL); 4341 Inst.addOperand(MCOperand::createExpr(Expr)); 4342 4343 getParser().getStreamer().EmitInstruction(Inst, getSTI()); 4344 return false; 4345 } 4346 4347 /// ::= .loh <lohName | lohId> label1, ..., labelN 4348 /// The number of arguments depends on the loh identifier. 4349 bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) { 4350 MCLOHType Kind; 4351 if (getParser().getTok().isNot(AsmToken::Identifier)) { 4352 if (getParser().getTok().isNot(AsmToken::Integer)) 4353 return TokError("expected an identifier or a number in directive"); 4354 // We successfully get a numeric value for the identifier. 4355 // Check if it is valid. 4356 int64_t Id = getParser().getTok().getIntVal(); 4357 if (Id <= -1U && !isValidMCLOHType(Id)) 4358 return TokError("invalid numeric identifier in directive"); 4359 Kind = (MCLOHType)Id; 4360 } else { 4361 StringRef Name = getTok().getIdentifier(); 4362 // We successfully parse an identifier. 4363 // Check if it is a recognized one. 4364 int Id = MCLOHNameToId(Name); 4365 4366 if (Id == -1) 4367 return TokError("invalid identifier in directive"); 4368 Kind = (MCLOHType)Id; 4369 } 4370 // Consume the identifier. 4371 Lex(); 4372 // Get the number of arguments of this LOH. 4373 int NbArgs = MCLOHIdToNbArgs(Kind); 4374 4375 assert(NbArgs != -1 && "Invalid number of arguments"); 4376 4377 SmallVector<MCSymbol *, 3> Args; 4378 for (int Idx = 0; Idx < NbArgs; ++Idx) { 4379 StringRef Name; 4380 if (getParser().parseIdentifier(Name)) 4381 return TokError("expected identifier in directive"); 4382 Args.push_back(getContext().getOrCreateSymbol(Name)); 4383 4384 if (Idx + 1 == NbArgs) 4385 break; 4386 if (parseToken(AsmToken::Comma, 4387 "unexpected token in '" + Twine(IDVal) + "' directive")) 4388 return true; 4389 } 4390 if (parseToken(AsmToken::EndOfStatement, 4391 "unexpected token in '" + Twine(IDVal) + "' directive")) 4392 return true; 4393 4394 getStreamer().EmitLOHDirective((MCLOHType)Kind, Args); 4395 return false; 4396 } 4397 4398 /// parseDirectiveLtorg 4399 /// ::= .ltorg | .pool 4400 bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) { 4401 if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive")) 4402 return true; 4403 getTargetStreamer().emitCurrentConstantPool(); 4404 return false; 4405 } 4406 4407 /// parseDirectiveReq 4408 /// ::= name .req registername 4409 bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) { 4410 MCAsmParser &Parser = getParser(); 4411 Parser.Lex(); // Eat the '.req' token. 4412 SMLoc SRegLoc = getLoc(); 4413 int RegNum = tryParseRegister(); 4414 RegKind RegisterKind = RegKind::Scalar; 4415 4416 if (RegNum == -1) { 4417 StringRef Kind; 4418 RegisterKind = RegKind::NeonVector; 4419 RegNum = tryMatchVectorRegister(Kind, false); 4420 if (!Kind.empty()) 4421 return Error(SRegLoc, "vector register without type specifier expected"); 4422 } 4423 4424 if (RegNum == -1) { 4425 StringRef Kind; 4426 RegisterKind = RegKind::SVEDataVector; 4427 OperandMatchResultTy Res = 4428 tryParseSVERegister(RegNum, Kind, RegKind::SVEDataVector); 4429 4430 if (Res == MatchOperand_ParseFail) 4431 return true; 4432 4433 if (Res == MatchOperand_Success && !Kind.empty()) 4434 return Error(SRegLoc, 4435 "sve vector register without type specifier expected"); 4436 } 4437 4438 if (RegNum == -1) { 4439 StringRef Kind; 4440 RegisterKind = RegKind::SVEPredicateVector; 4441 OperandMatchResultTy Res = 4442 tryParseSVERegister(RegNum, Kind, RegKind::SVEPredicateVector); 4443 4444 if (Res == MatchOperand_ParseFail) 4445 return true; 4446 4447 if (Res == MatchOperand_Success && !Kind.empty()) 4448 return Error(SRegLoc, 4449 "sve predicate register without type specifier expected"); 4450 } 4451 4452 if (RegNum == -1) 4453 return Error(SRegLoc, "register name or alias expected"); 4454 4455 // Shouldn't be anything else. 4456 if (parseToken(AsmToken::EndOfStatement, 4457 "unexpected input in .req directive")) 4458 return true; 4459 4460 auto pair = std::make_pair(RegisterKind, (unsigned) RegNum); 4461 if (RegisterReqs.insert(std::make_pair(Name, pair)).first->second != pair) 4462 Warning(L, "ignoring redefinition of register alias '" + Name + "'"); 4463 4464 return false; 4465 } 4466 4467 /// parseDirectiveUneq 4468 /// ::= .unreq registername 4469 bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) { 4470 MCAsmParser &Parser = getParser(); 4471 if (getTok().isNot(AsmToken::Identifier)) 4472 return TokError("unexpected input in .unreq directive."); 4473 RegisterReqs.erase(Parser.getTok().getIdentifier().lower()); 4474 Parser.Lex(); // Eat the identifier. 4475 if (parseToken(AsmToken::EndOfStatement)) 4476 return addErrorSuffix("in '.unreq' directive"); 4477 return false; 4478 } 4479 4480 bool 4481 AArch64AsmParser::classifySymbolRef(const MCExpr *Expr, 4482 AArch64MCExpr::VariantKind &ELFRefKind, 4483 MCSymbolRefExpr::VariantKind &DarwinRefKind, 4484 int64_t &Addend) { 4485 ELFRefKind = AArch64MCExpr::VK_INVALID; 4486 DarwinRefKind = MCSymbolRefExpr::VK_None; 4487 Addend = 0; 4488 4489 if (const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) { 4490 ELFRefKind = AE->getKind(); 4491 Expr = AE->getSubExpr(); 4492 } 4493 4494 const MCSymbolRefExpr *SE = dyn_cast<MCSymbolRefExpr>(Expr); 4495 if (SE) { 4496 // It's a simple symbol reference with no addend. 4497 DarwinRefKind = SE->getKind(); 4498 return true; 4499 } 4500 4501 const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr); 4502 if (!BE) 4503 return false; 4504 4505 SE = dyn_cast<MCSymbolRefExpr>(BE->getLHS()); 4506 if (!SE) 4507 return false; 4508 DarwinRefKind = SE->getKind(); 4509 4510 if (BE->getOpcode() != MCBinaryExpr::Add && 4511 BE->getOpcode() != MCBinaryExpr::Sub) 4512 return false; 4513 4514 // See if the addend is is a constant, otherwise there's more going 4515 // on here than we can deal with. 4516 auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS()); 4517 if (!AddendExpr) 4518 return false; 4519 4520 Addend = AddendExpr->getValue(); 4521 if (BE->getOpcode() == MCBinaryExpr::Sub) 4522 Addend = -Addend; 4523 4524 // It's some symbol reference + a constant addend, but really 4525 // shouldn't use both Darwin and ELF syntax. 4526 return ELFRefKind == AArch64MCExpr::VK_INVALID || 4527 DarwinRefKind == MCSymbolRefExpr::VK_None; 4528 } 4529 4530 /// Force static initialization. 4531 extern "C" void LLVMInitializeAArch64AsmParser() { 4532 RegisterMCAsmParser<AArch64AsmParser> X(getTheAArch64leTarget()); 4533 RegisterMCAsmParser<AArch64AsmParser> Y(getTheAArch64beTarget()); 4534 RegisterMCAsmParser<AArch64AsmParser> Z(getTheARM64Target()); 4535 } 4536 4537 #define GET_REGISTER_MATCHER 4538 #define GET_SUBTARGET_FEATURE_NAME 4539 #define GET_MATCHER_IMPLEMENTATION 4540 #define GET_MNEMONIC_SPELL_CHECKER 4541 #include "AArch64GenAsmMatcher.inc" 4542 4543 // Define this matcher function after the auto-generated include so we 4544 // have the match class enum definitions. 4545 unsigned AArch64AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, 4546 unsigned Kind) { 4547 AArch64Operand &Op = static_cast<AArch64Operand &>(AsmOp); 4548 // If the kind is a token for a literal immediate, check if our asm 4549 // operand matches. This is for InstAliases which have a fixed-value 4550 // immediate in the syntax. 4551 int64_t ExpectedVal; 4552 switch (Kind) { 4553 default: 4554 return Match_InvalidOperand; 4555 case MCK__35_0: 4556 ExpectedVal = 0; 4557 break; 4558 case MCK__35_1: 4559 ExpectedVal = 1; 4560 break; 4561 case MCK__35_12: 4562 ExpectedVal = 12; 4563 break; 4564 case MCK__35_16: 4565 ExpectedVal = 16; 4566 break; 4567 case MCK__35_2: 4568 ExpectedVal = 2; 4569 break; 4570 case MCK__35_24: 4571 ExpectedVal = 24; 4572 break; 4573 case MCK__35_3: 4574 ExpectedVal = 3; 4575 break; 4576 case MCK__35_32: 4577 ExpectedVal = 32; 4578 break; 4579 case MCK__35_4: 4580 ExpectedVal = 4; 4581 break; 4582 case MCK__35_48: 4583 ExpectedVal = 48; 4584 break; 4585 case MCK__35_6: 4586 ExpectedVal = 6; 4587 break; 4588 case MCK__35_64: 4589 ExpectedVal = 64; 4590 break; 4591 case MCK__35_8: 4592 ExpectedVal = 8; 4593 break; 4594 } 4595 if (!Op.isImm()) 4596 return Match_InvalidOperand; 4597 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm()); 4598 if (!CE) 4599 return Match_InvalidOperand; 4600 if (CE->getValue() == ExpectedVal) 4601 return Match_Success; 4602 return Match_InvalidOperand; 4603 } 4604 4605 OperandMatchResultTy 4606 AArch64AsmParser::tryParseGPRSeqPair(OperandVector &Operands) { 4607 4608 SMLoc S = getLoc(); 4609 4610 if (getParser().getTok().isNot(AsmToken::Identifier)) { 4611 Error(S, "expected register"); 4612 return MatchOperand_ParseFail; 4613 } 4614 4615 int FirstReg = tryParseRegister(); 4616 if (FirstReg == -1) { 4617 return MatchOperand_ParseFail; 4618 } 4619 const MCRegisterClass &WRegClass = 4620 AArch64MCRegisterClasses[AArch64::GPR32RegClassID]; 4621 const MCRegisterClass &XRegClass = 4622 AArch64MCRegisterClasses[AArch64::GPR64RegClassID]; 4623 4624 bool isXReg = XRegClass.contains(FirstReg), 4625 isWReg = WRegClass.contains(FirstReg); 4626 if (!isXReg && !isWReg) { 4627 Error(S, "expected first even register of a " 4628 "consecutive same-size even/odd register pair"); 4629 return MatchOperand_ParseFail; 4630 } 4631 4632 const MCRegisterInfo *RI = getContext().getRegisterInfo(); 4633 unsigned FirstEncoding = RI->getEncodingValue(FirstReg); 4634 4635 if (FirstEncoding & 0x1) { 4636 Error(S, "expected first even register of a " 4637 "consecutive same-size even/odd register pair"); 4638 return MatchOperand_ParseFail; 4639 } 4640 4641 SMLoc M = getLoc(); 4642 if (getParser().getTok().isNot(AsmToken::Comma)) { 4643 Error(M, "expected comma"); 4644 return MatchOperand_ParseFail; 4645 } 4646 // Eat the comma 4647 getParser().Lex(); 4648 4649 SMLoc E = getLoc(); 4650 int SecondReg = tryParseRegister(); 4651 if (SecondReg ==-1) { 4652 return MatchOperand_ParseFail; 4653 } 4654 4655 if (RI->getEncodingValue(SecondReg) != FirstEncoding + 1 || 4656 (isXReg && !XRegClass.contains(SecondReg)) || 4657 (isWReg && !WRegClass.contains(SecondReg))) { 4658 Error(E,"expected second odd register of a " 4659 "consecutive same-size even/odd register pair"); 4660 return MatchOperand_ParseFail; 4661 } 4662 4663 unsigned Pair = 0; 4664 if (isXReg) { 4665 Pair = RI->getMatchingSuperReg(FirstReg, AArch64::sube64, 4666 &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]); 4667 } else { 4668 Pair = RI->getMatchingSuperReg(FirstReg, AArch64::sube32, 4669 &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]); 4670 } 4671 4672 Operands.push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S, 4673 getLoc(), getContext())); 4674 4675 return MatchOperand_Success; 4676 } 4677 4678 template <bool ParseSuffix> 4679 OperandMatchResultTy 4680 AArch64AsmParser::tryParseSVEDataVector(OperandVector &Operands) { 4681 const SMLoc S = getLoc(); 4682 // Check for a SVE vector register specifier first. 4683 int RegNum = -1; 4684 StringRef Kind; 4685 4686 OperandMatchResultTy Res = 4687 tryParseSVERegister(RegNum, Kind, RegKind::SVEDataVector); 4688 4689 if (Res != MatchOperand_Success) 4690 return Res; 4691 4692 if (ParseSuffix && Kind.empty()) 4693 return MatchOperand_NoMatch; 4694 4695 unsigned ElementWidth = StringSwitch<unsigned>(Kind.lower()) 4696 .Case("", -1) 4697 .Case(".b", 8) 4698 .Case(".h", 16) 4699 .Case(".s", 32) 4700 .Case(".d", 64) 4701 .Case(".q", 128) 4702 .Default(0); 4703 if (!ElementWidth) 4704 return MatchOperand_NoMatch; 4705 4706 Operands.push_back( 4707 AArch64Operand::CreateReg(RegNum, RegKind::SVEDataVector, ElementWidth, 4708 S, S, getContext())); 4709 4710 return MatchOperand_Success; 4711 } 4712