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