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