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