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