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