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