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