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