AArch64AsmParser.cpp revision dfe076af9879eb68a7b8331f9c02eecf563d85be
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 11#include "MCTargetDesc/AArch64MCTargetDesc.h" 12#include "MCTargetDesc/AArch64MCExpr.h" 13#include "Utils/AArch64BaseInfo.h" 14#include "llvm/ADT/APFloat.h" 15#include "llvm/ADT/APInt.h" 16#include "llvm/ADT/StringSwitch.h" 17#include "llvm/ADT/STLExtras.h" 18#include "llvm/MC/MCContext.h" 19#include "llvm/MC/MCInst.h" 20#include "llvm/MC/MCSubtargetInfo.h" 21#include "llvm/MC/MCTargetAsmParser.h" 22#include "llvm/MC/MCExpr.h" 23#include "llvm/MC/MCRegisterInfo.h" 24#include "llvm/MC/MCStreamer.h" 25#include "llvm/MC/MCParser/MCAsmLexer.h" 26#include "llvm/MC/MCParser/MCAsmParser.h" 27#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 28#include "llvm/Support/ErrorHandling.h" 29#include "llvm/Support/raw_ostream.h" 30#include "llvm/Support/TargetRegistry.h" 31 32using namespace llvm; 33 34namespace { 35 36class AArch64Operand; 37 38class AArch64AsmParser : public MCTargetAsmParser { 39 MCSubtargetInfo &STI; 40 MCAsmParser &Parser; 41 42#define GET_ASSEMBLER_HEADER 43#include "AArch64GenAsmMatcher.inc" 44 45public: 46 AArch64AsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) 47 : MCTargetAsmParser(), STI(_STI), Parser(_Parser) { 48 MCAsmParserExtension::Initialize(_Parser); 49 50 // Initialize the set of available features. 51 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 52 } 53 54 // These are the public interface of the MCTargetAsmParser 55 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 56 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 57 SMLoc NameLoc, 58 SmallVectorImpl<MCParsedAsmOperand*> &Operands); 59 60 bool ParseDirective(AsmToken DirectiveID); 61 bool ParseDirectiveTLSDescCall(SMLoc L); 62 bool ParseDirectiveWord(unsigned Size, SMLoc L); 63 64 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 65 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 66 MCStreamer&Out, unsigned &ErrorInfo, 67 bool MatchingInlineAsm); 68 69 // The rest of the sub-parsers have more freedom over interface: they return 70 // an OperandMatchResultTy because it's less ambiguous than true/false or 71 // -1/0/1 even if it is more verbose 72 OperandMatchResultTy 73 ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 74 StringRef Mnemonic); 75 76 OperandMatchResultTy ParseImmediate(const MCExpr *&ExprVal); 77 78 OperandMatchResultTy ParseRelocPrefix(AArch64MCExpr::VariantKind &RefKind); 79 80 OperandMatchResultTy 81 ParseNEONLane(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 82 uint32_t NumLanes); 83 84 OperandMatchResultTy 85 ParseRegister(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 86 uint32_t &NumLanes); 87 88 OperandMatchResultTy 89 ParseImmWithLSLOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 90 91 OperandMatchResultTy 92 ParseCondCodeOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 93 94 OperandMatchResultTy 95 ParseCRxOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 96 97 OperandMatchResultTy 98 ParseFPImmOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 99 100 template<typename SomeNamedImmMapper> OperandMatchResultTy 101 ParseNamedImmOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 102 return ParseNamedImmOperand(SomeNamedImmMapper(), Operands); 103 } 104 105 OperandMatchResultTy 106 ParseNamedImmOperand(const NamedImmMapper &Mapper, 107 SmallVectorImpl<MCParsedAsmOperand*> &Operands); 108 109 OperandMatchResultTy 110 ParseLSXAddressOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 111 112 OperandMatchResultTy 113 ParseShiftExtend(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 114 115 OperandMatchResultTy 116 ParseSysRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 117 118 bool validateInstruction(MCInst &Inst, 119 const SmallVectorImpl<MCParsedAsmOperand*> &Operands); 120 121 /// Scan the next token (which had better be an identifier) and determine 122 /// whether it represents a general-purpose or vector register. It returns 123 /// true if an identifier was found and populates its reference arguments. It 124 /// does not consume the token. 125 bool 126 IdentifyRegister(unsigned &RegNum, SMLoc &RegEndLoc, StringRef &LayoutSpec, 127 SMLoc &LayoutLoc) const; 128 129}; 130 131} 132 133namespace { 134 135/// Instances of this class represent a parsed AArch64 machine instruction. 136class AArch64Operand : public MCParsedAsmOperand { 137private: 138 enum KindTy { 139 k_ImmWithLSL, // #uimm {, LSL #amt } 140 k_CondCode, // eq/ne/... 141 k_FPImmediate, // Limited-precision floating-point imm 142 k_Immediate, // Including expressions referencing symbols 143 k_Register, 144 k_ShiftExtend, 145 k_SysReg, // The register operand of MRS and MSR instructions 146 k_Token, // The mnemonic; other raw tokens the auto-generated 147 k_WrappedRegister // Load/store exclusive permit a wrapped register. 148 } Kind; 149 150 SMLoc StartLoc, EndLoc; 151 152 union { 153 struct { 154 const MCExpr *Val; 155 unsigned ShiftAmount; 156 bool ImplicitAmount; 157 } ImmWithLSL; 158 159 struct { 160 A64CC::CondCodes Code; 161 } CondCode; 162 163 struct { 164 double Val; 165 } FPImm; 166 167 struct { 168 const MCExpr *Val; 169 } Imm; 170 171 struct { 172 unsigned RegNum; 173 } Reg; 174 175 struct { 176 A64SE::ShiftExtSpecifiers ShiftType; 177 unsigned Amount; 178 bool ImplicitAmount; 179 } ShiftExtend; 180 181 struct { 182 const char *Data; 183 unsigned Length; 184 } SysReg; 185 186 struct { 187 const char *Data; 188 unsigned Length; 189 } Tok; 190 }; 191 192 AArch64Operand(KindTy K, SMLoc S, SMLoc E) 193 : MCParsedAsmOperand(), Kind(K), StartLoc(S), EndLoc(E) {} 194 195public: 196 AArch64Operand(const AArch64Operand &o) : MCParsedAsmOperand() { 197 } 198 199 SMLoc getStartLoc() const { return StartLoc; } 200 SMLoc getEndLoc() const { return EndLoc; } 201 void print(raw_ostream&) const; 202 void dump() const; 203 204 StringRef getToken() const { 205 assert(Kind == k_Token && "Invalid access!"); 206 return StringRef(Tok.Data, Tok.Length); 207 } 208 209 unsigned getReg() const { 210 assert((Kind == k_Register || Kind == k_WrappedRegister) 211 && "Invalid access!"); 212 return Reg.RegNum; 213 } 214 215 const MCExpr *getImm() const { 216 assert(Kind == k_Immediate && "Invalid access!"); 217 return Imm.Val; 218 } 219 220 A64CC::CondCodes getCondCode() const { 221 assert(Kind == k_CondCode && "Invalid access!"); 222 return CondCode.Code; 223 } 224 225 static bool isNonConstantExpr(const MCExpr *E, 226 AArch64MCExpr::VariantKind &Variant) { 227 if (const AArch64MCExpr *A64E = dyn_cast<AArch64MCExpr>(E)) { 228 Variant = A64E->getKind(); 229 return true; 230 } else if (!isa<MCConstantExpr>(E)) { 231 Variant = AArch64MCExpr::VK_AARCH64_None; 232 return true; 233 } 234 235 return false; 236 } 237 238 bool isCondCode() const { return Kind == k_CondCode; } 239 bool isToken() const { return Kind == k_Token; } 240 bool isReg() const { return Kind == k_Register; } 241 bool isImm() const { return Kind == k_Immediate; } 242 bool isMem() const { return false; } 243 bool isFPImm() const { return Kind == k_FPImmediate; } 244 bool isShiftOrExtend() const { return Kind == k_ShiftExtend; } 245 bool isSysReg() const { return Kind == k_SysReg; } 246 bool isImmWithLSL() const { return Kind == k_ImmWithLSL; } 247 bool isWrappedReg() const { return Kind == k_WrappedRegister; } 248 249 bool isAddSubImmLSL0() const { 250 if (!isImmWithLSL()) return false; 251 if (ImmWithLSL.ShiftAmount != 0) return false; 252 253 AArch64MCExpr::VariantKind Variant; 254 if (isNonConstantExpr(ImmWithLSL.Val, Variant)) { 255 return Variant == AArch64MCExpr::VK_AARCH64_LO12 256 || Variant == AArch64MCExpr::VK_AARCH64_DTPREL_LO12 257 || Variant == AArch64MCExpr::VK_AARCH64_DTPREL_LO12_NC 258 || Variant == AArch64MCExpr::VK_AARCH64_TPREL_LO12 259 || Variant == AArch64MCExpr::VK_AARCH64_TPREL_LO12_NC 260 || Variant == AArch64MCExpr::VK_AARCH64_TLSDESC_LO12; 261 } 262 263 // Otherwise it should be a real immediate in range: 264 const MCConstantExpr *CE = cast<MCConstantExpr>(ImmWithLSL.Val); 265 return CE->getValue() >= 0 && CE->getValue() <= 0xfff; 266 } 267 268 bool isAddSubImmLSL12() const { 269 if (!isImmWithLSL()) return false; 270 if (ImmWithLSL.ShiftAmount != 12) return false; 271 272 AArch64MCExpr::VariantKind Variant; 273 if (isNonConstantExpr(ImmWithLSL.Val, Variant)) { 274 return Variant == AArch64MCExpr::VK_AARCH64_DTPREL_HI12 275 || Variant == AArch64MCExpr::VK_AARCH64_TPREL_HI12; 276 } 277 278 // Otherwise it should be a real immediate in range: 279 const MCConstantExpr *CE = cast<MCConstantExpr>(ImmWithLSL.Val); 280 return CE->getValue() >= 0 && CE->getValue() <= 0xfff; 281 } 282 283 template<unsigned MemSize, unsigned RmSize> bool isAddrRegExtend() const { 284 if (!isShiftOrExtend()) return false; 285 286 A64SE::ShiftExtSpecifiers Ext = ShiftExtend.ShiftType; 287 if (RmSize == 32 && !(Ext == A64SE::UXTW || Ext == A64SE::SXTW)) 288 return false; 289 290 if (RmSize == 64 && !(Ext == A64SE::LSL || Ext == A64SE::SXTX)) 291 return false; 292 293 return ShiftExtend.Amount == Log2_32(MemSize) || ShiftExtend.Amount == 0; 294 } 295 296 bool isAdrpLabel() const { 297 if (!isImm()) return false; 298 299 AArch64MCExpr::VariantKind Variant; 300 if (isNonConstantExpr(getImm(), Variant)) { 301 return Variant == AArch64MCExpr::VK_AARCH64_None 302 || Variant == AArch64MCExpr::VK_AARCH64_GOT 303 || Variant == AArch64MCExpr::VK_AARCH64_GOTTPREL 304 || Variant == AArch64MCExpr::VK_AARCH64_TLSDESC; 305 } 306 307 return isLabel<21, 4096>(); 308 } 309 310 template<unsigned RegWidth> bool isBitfieldWidth() const { 311 if (!isImm()) return false; 312 313 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 314 if (!CE) return false; 315 316 return CE->getValue() >= 1 && CE->getValue() <= RegWidth; 317 } 318 319 template<int RegWidth> 320 bool isCVTFixedPos() const { 321 if (!isImm()) return false; 322 323 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 324 if (!CE) return false; 325 326 return CE->getValue() >= 1 && CE->getValue() <= RegWidth; 327 } 328 329 bool isFMOVImm() const { 330 if (!isFPImm()) return false; 331 332 APFloat RealVal(FPImm.Val); 333 uint32_t ImmVal; 334 return A64Imms::isFPImm(RealVal, ImmVal); 335 } 336 337 bool isFPZero() const { 338 if (!isFPImm()) return false; 339 340 APFloat RealVal(FPImm.Val); 341 return RealVal.isPosZero(); 342 } 343 344 template<unsigned field_width, unsigned scale> 345 bool isLabel() const { 346 if (!isImm()) return false; 347 348 if (dyn_cast<MCSymbolRefExpr>(Imm.Val)) { 349 return true; 350 } else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) { 351 int64_t Val = CE->getValue(); 352 int64_t Min = - (scale * (1LL << (field_width - 1))); 353 int64_t Max = scale * ((1LL << (field_width - 1)) - 1); 354 return (Val % scale) == 0 && Val >= Min && Val <= Max; 355 } 356 357 // N.b. this disallows explicit relocation specifications via an 358 // AArch64MCExpr. Users needing that behaviour 359 return false; 360 } 361 362 bool isLane1() const { 363 if (!isImm()) return false; 364 365 // Because it's come through custom assembly parsing, it must always be a 366 // constant expression. 367 return cast<MCConstantExpr>(getImm())->getValue() == 1; 368 } 369 370 bool isLoadLitLabel() const { 371 if (!isImm()) return false; 372 373 AArch64MCExpr::VariantKind Variant; 374 if (isNonConstantExpr(getImm(), Variant)) { 375 return Variant == AArch64MCExpr::VK_AARCH64_None 376 || Variant == AArch64MCExpr::VK_AARCH64_GOTTPREL; 377 } 378 379 return isLabel<19, 4>(); 380 } 381 382 template<unsigned RegWidth> bool isLogicalImm() const { 383 if (!isImm()) return false; 384 385 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val); 386 if (!CE) return false; 387 388 uint32_t Bits; 389 return A64Imms::isLogicalImm(RegWidth, CE->getValue(), Bits); 390 } 391 392 template<unsigned RegWidth> bool isLogicalImmMOV() const { 393 if (!isLogicalImm<RegWidth>()) return false; 394 395 const MCConstantExpr *CE = cast<MCConstantExpr>(Imm.Val); 396 397 // The move alias for ORR is only valid if the immediate cannot be 398 // represented with a move (immediate) instruction; they take priority. 399 int UImm16, Shift; 400 return !A64Imms::isMOVZImm(RegWidth, CE->getValue(), UImm16, Shift) 401 && !A64Imms::isMOVNImm(RegWidth, CE->getValue(), UImm16, Shift); 402 } 403 404 template<int MemSize> 405 bool isOffsetUImm12() const { 406 if (!isImm()) return false; 407 408 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 409 410 // Assume they know what they're doing for now if they've given us a 411 // non-constant expression. In principle we could check for ridiculous 412 // things that can't possibly work or relocations that would almost 413 // certainly break resulting code. 414 if (!CE) 415 return true; 416 417 int64_t Val = CE->getValue(); 418 419 // Must be a multiple of the access size in bytes. 420 if ((Val & (MemSize - 1)) != 0) return false; 421 422 // Must be 12-bit unsigned 423 return Val >= 0 && Val <= 0xfff * MemSize; 424 } 425 426 template<A64SE::ShiftExtSpecifiers SHKind, bool is64Bit> 427 bool isShift() const { 428 if (!isShiftOrExtend()) return false; 429 430 if (ShiftExtend.ShiftType != SHKind) 431 return false; 432 433 return is64Bit ? ShiftExtend.Amount <= 63 : ShiftExtend.Amount <= 31; 434 } 435 436 bool isMOVN32Imm() const { 437 static AArch64MCExpr::VariantKind PermittedModifiers[] = { 438 AArch64MCExpr::VK_AARCH64_SABS_G0, 439 AArch64MCExpr::VK_AARCH64_SABS_G1, 440 AArch64MCExpr::VK_AARCH64_DTPREL_G1, 441 AArch64MCExpr::VK_AARCH64_DTPREL_G0, 442 AArch64MCExpr::VK_AARCH64_GOTTPREL_G1, 443 AArch64MCExpr::VK_AARCH64_TPREL_G1, 444 AArch64MCExpr::VK_AARCH64_TPREL_G0, 445 }; 446 unsigned NumModifiers = llvm::array_lengthof(PermittedModifiers); 447 448 return isMoveWideImm(32, PermittedModifiers, NumModifiers); 449 } 450 451 bool isMOVN64Imm() const { 452 static AArch64MCExpr::VariantKind PermittedModifiers[] = { 453 AArch64MCExpr::VK_AARCH64_SABS_G0, 454 AArch64MCExpr::VK_AARCH64_SABS_G1, 455 AArch64MCExpr::VK_AARCH64_SABS_G2, 456 AArch64MCExpr::VK_AARCH64_DTPREL_G2, 457 AArch64MCExpr::VK_AARCH64_DTPREL_G1, 458 AArch64MCExpr::VK_AARCH64_DTPREL_G0, 459 AArch64MCExpr::VK_AARCH64_GOTTPREL_G1, 460 AArch64MCExpr::VK_AARCH64_TPREL_G2, 461 AArch64MCExpr::VK_AARCH64_TPREL_G1, 462 AArch64MCExpr::VK_AARCH64_TPREL_G0, 463 }; 464 unsigned NumModifiers = llvm::array_lengthof(PermittedModifiers); 465 466 return isMoveWideImm(64, PermittedModifiers, NumModifiers); 467 } 468 469 470 bool isMOVZ32Imm() const { 471 static AArch64MCExpr::VariantKind PermittedModifiers[] = { 472 AArch64MCExpr::VK_AARCH64_ABS_G0, 473 AArch64MCExpr::VK_AARCH64_ABS_G1, 474 AArch64MCExpr::VK_AARCH64_SABS_G0, 475 AArch64MCExpr::VK_AARCH64_SABS_G1, 476 AArch64MCExpr::VK_AARCH64_DTPREL_G1, 477 AArch64MCExpr::VK_AARCH64_DTPREL_G0, 478 AArch64MCExpr::VK_AARCH64_GOTTPREL_G1, 479 AArch64MCExpr::VK_AARCH64_TPREL_G1, 480 AArch64MCExpr::VK_AARCH64_TPREL_G0, 481 }; 482 unsigned NumModifiers = llvm::array_lengthof(PermittedModifiers); 483 484 return isMoveWideImm(32, PermittedModifiers, NumModifiers); 485 } 486 487 bool isMOVZ64Imm() const { 488 static AArch64MCExpr::VariantKind PermittedModifiers[] = { 489 AArch64MCExpr::VK_AARCH64_ABS_G0, 490 AArch64MCExpr::VK_AARCH64_ABS_G1, 491 AArch64MCExpr::VK_AARCH64_ABS_G2, 492 AArch64MCExpr::VK_AARCH64_ABS_G3, 493 AArch64MCExpr::VK_AARCH64_SABS_G0, 494 AArch64MCExpr::VK_AARCH64_SABS_G1, 495 AArch64MCExpr::VK_AARCH64_SABS_G2, 496 AArch64MCExpr::VK_AARCH64_DTPREL_G2, 497 AArch64MCExpr::VK_AARCH64_DTPREL_G1, 498 AArch64MCExpr::VK_AARCH64_DTPREL_G0, 499 AArch64MCExpr::VK_AARCH64_GOTTPREL_G1, 500 AArch64MCExpr::VK_AARCH64_TPREL_G2, 501 AArch64MCExpr::VK_AARCH64_TPREL_G1, 502 AArch64MCExpr::VK_AARCH64_TPREL_G0, 503 }; 504 unsigned NumModifiers = llvm::array_lengthof(PermittedModifiers); 505 506 return isMoveWideImm(64, PermittedModifiers, NumModifiers); 507 } 508 509 bool isMOVK32Imm() const { 510 static AArch64MCExpr::VariantKind PermittedModifiers[] = { 511 AArch64MCExpr::VK_AARCH64_ABS_G0_NC, 512 AArch64MCExpr::VK_AARCH64_ABS_G1_NC, 513 AArch64MCExpr::VK_AARCH64_DTPREL_G1_NC, 514 AArch64MCExpr::VK_AARCH64_DTPREL_G0_NC, 515 AArch64MCExpr::VK_AARCH64_GOTTPREL_G0_NC, 516 AArch64MCExpr::VK_AARCH64_TPREL_G1_NC, 517 AArch64MCExpr::VK_AARCH64_TPREL_G0_NC, 518 }; 519 unsigned NumModifiers = llvm::array_lengthof(PermittedModifiers); 520 521 return isMoveWideImm(32, PermittedModifiers, NumModifiers); 522 } 523 524 bool isMOVK64Imm() const { 525 static AArch64MCExpr::VariantKind PermittedModifiers[] = { 526 AArch64MCExpr::VK_AARCH64_ABS_G0_NC, 527 AArch64MCExpr::VK_AARCH64_ABS_G1_NC, 528 AArch64MCExpr::VK_AARCH64_ABS_G2_NC, 529 AArch64MCExpr::VK_AARCH64_ABS_G3, 530 AArch64MCExpr::VK_AARCH64_DTPREL_G1_NC, 531 AArch64MCExpr::VK_AARCH64_DTPREL_G0_NC, 532 AArch64MCExpr::VK_AARCH64_GOTTPREL_G0_NC, 533 AArch64MCExpr::VK_AARCH64_TPREL_G1_NC, 534 AArch64MCExpr::VK_AARCH64_TPREL_G0_NC, 535 }; 536 unsigned NumModifiers = llvm::array_lengthof(PermittedModifiers); 537 538 return isMoveWideImm(64, PermittedModifiers, NumModifiers); 539 } 540 541 bool isMoveWideImm(unsigned RegWidth, 542 AArch64MCExpr::VariantKind *PermittedModifiers, 543 unsigned NumModifiers) const { 544 if (!isImmWithLSL()) return false; 545 546 if (ImmWithLSL.ShiftAmount % 16 != 0) return false; 547 if (ImmWithLSL.ShiftAmount >= RegWidth) return false; 548 549 AArch64MCExpr::VariantKind Modifier; 550 if (isNonConstantExpr(ImmWithLSL.Val, Modifier)) { 551 // E.g. "#:abs_g0:sym, lsl #16" makes no sense. 552 if (!ImmWithLSL.ImplicitAmount) return false; 553 554 for (unsigned i = 0; i < NumModifiers; ++i) 555 if (PermittedModifiers[i] == Modifier) return true; 556 557 return false; 558 } 559 560 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmWithLSL.Val); 561 return CE && CE->getValue() >= 0 && CE->getValue() <= 0xffff; 562 } 563 564 template<int RegWidth, bool (*isValidImm)(int, uint64_t, int&, int&)> 565 bool isMoveWideMovAlias() const { 566 if (!isImm()) return false; 567 568 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 569 if (!CE) return false; 570 571 int UImm16, Shift; 572 uint64_t Value = CE->getValue(); 573 574 // If this is a 32-bit instruction then all bits above 32 should be the 575 // same: either of these is fine because signed/unsigned values should be 576 // permitted. 577 if (RegWidth == 32) { 578 if ((Value >> 32) != 0 && (Value >> 32) != 0xffffffff) 579 return false; 580 581 Value &= 0xffffffffULL; 582 } 583 584 return isValidImm(RegWidth, Value, UImm16, Shift); 585 } 586 587 bool isMSRWithReg() const { 588 if (!isSysReg()) return false; 589 590 bool IsKnownRegister; 591 StringRef Name(SysReg.Data, SysReg.Length); 592 A64SysReg::MSRMapper().fromString(Name, IsKnownRegister); 593 594 return IsKnownRegister; 595 } 596 597 bool isMSRPState() const { 598 if (!isSysReg()) return false; 599 600 bool IsKnownRegister; 601 StringRef Name(SysReg.Data, SysReg.Length); 602 A64PState::PStateMapper().fromString(Name, IsKnownRegister); 603 604 return IsKnownRegister; 605 } 606 607 bool isMRS() const { 608 if (!isSysReg()) return false; 609 610 // First check against specific MSR-only (write-only) registers 611 bool IsKnownRegister; 612 StringRef Name(SysReg.Data, SysReg.Length); 613 A64SysReg::MRSMapper().fromString(Name, IsKnownRegister); 614 615 return IsKnownRegister; 616 } 617 618 bool isPRFM() const { 619 if (!isImm()) return false; 620 621 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 622 623 if (!CE) 624 return false; 625 626 return CE->getValue() >= 0 && CE->getValue() <= 31; 627 } 628 629 template<A64SE::ShiftExtSpecifiers SHKind> bool isRegExtend() const { 630 if (!isShiftOrExtend()) return false; 631 632 if (ShiftExtend.ShiftType != SHKind) 633 return false; 634 635 return ShiftExtend.Amount <= 4; 636 } 637 638 bool isRegExtendLSL() const { 639 if (!isShiftOrExtend()) return false; 640 641 if (ShiftExtend.ShiftType != A64SE::LSL) 642 return false; 643 644 return !ShiftExtend.ImplicitAmount && ShiftExtend.Amount <= 4; 645 } 646 647 template<int MemSize> bool isSImm7Scaled() const { 648 if (!isImm()) return false; 649 650 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 651 if (!CE) return false; 652 653 int64_t Val = CE->getValue(); 654 if (Val % MemSize != 0) return false; 655 656 Val /= MemSize; 657 658 return Val >= -64 && Val < 64; 659 } 660 661 template<int BitWidth> 662 bool isSImm() const { 663 if (!isImm()) return false; 664 665 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 666 if (!CE) return false; 667 668 return CE->getValue() >= -(1LL << (BitWidth - 1)) 669 && CE->getValue() < (1LL << (BitWidth - 1)); 670 } 671 672 template<int bitWidth> 673 bool isUImm() const { 674 if (!isImm()) return false; 675 676 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 677 if (!CE) return false; 678 679 return CE->getValue() >= 0 && CE->getValue() < (1LL << bitWidth); 680 } 681 682 bool isUImm() const { 683 if (!isImm()) return false; 684 685 return isa<MCConstantExpr>(getImm()); 686 } 687 688 static AArch64Operand *CreateImmWithLSL(const MCExpr *Val, 689 unsigned ShiftAmount, 690 bool ImplicitAmount, 691 SMLoc S, SMLoc E) { 692 AArch64Operand *Op = new AArch64Operand(k_ImmWithLSL, S, E); 693 Op->ImmWithLSL.Val = Val; 694 Op->ImmWithLSL.ShiftAmount = ShiftAmount; 695 Op->ImmWithLSL.ImplicitAmount = ImplicitAmount; 696 return Op; 697 } 698 699 static AArch64Operand *CreateCondCode(A64CC::CondCodes Code, 700 SMLoc S, SMLoc E) { 701 AArch64Operand *Op = new AArch64Operand(k_CondCode, S, E); 702 Op->CondCode.Code = Code; 703 return Op; 704 } 705 706 static AArch64Operand *CreateFPImm(double Val, 707 SMLoc S, SMLoc E) { 708 AArch64Operand *Op = new AArch64Operand(k_FPImmediate, S, E); 709 Op->FPImm.Val = Val; 710 return Op; 711 } 712 713 static AArch64Operand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 714 AArch64Operand *Op = new AArch64Operand(k_Immediate, S, E); 715 Op->Imm.Val = Val; 716 return Op; 717 } 718 719 static AArch64Operand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 720 AArch64Operand *Op = new AArch64Operand(k_Register, S, E); 721 Op->Reg.RegNum = RegNum; 722 return Op; 723 } 724 725 static AArch64Operand *CreateWrappedReg(unsigned RegNum, SMLoc S, SMLoc E) { 726 AArch64Operand *Op = new AArch64Operand(k_WrappedRegister, S, E); 727 Op->Reg.RegNum = RegNum; 728 return Op; 729 } 730 731 static AArch64Operand *CreateShiftExtend(A64SE::ShiftExtSpecifiers ShiftTyp, 732 unsigned Amount, 733 bool ImplicitAmount, 734 SMLoc S, SMLoc E) { 735 AArch64Operand *Op = new AArch64Operand(k_ShiftExtend, S, E); 736 Op->ShiftExtend.ShiftType = ShiftTyp; 737 Op->ShiftExtend.Amount = Amount; 738 Op->ShiftExtend.ImplicitAmount = ImplicitAmount; 739 return Op; 740 } 741 742 static AArch64Operand *CreateSysReg(StringRef Str, SMLoc S) { 743 AArch64Operand *Op = new AArch64Operand(k_SysReg, S, S); 744 Op->Tok.Data = Str.data(); 745 Op->Tok.Length = Str.size(); 746 return Op; 747 } 748 749 static AArch64Operand *CreateToken(StringRef Str, SMLoc S) { 750 AArch64Operand *Op = new AArch64Operand(k_Token, S, S); 751 Op->Tok.Data = Str.data(); 752 Op->Tok.Length = Str.size(); 753 return Op; 754 } 755 756 757 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 758 // Add as immediates when possible. 759 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 760 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 761 else 762 Inst.addOperand(MCOperand::CreateExpr(Expr)); 763 } 764 765 template<unsigned RegWidth> 766 void addBFILSBOperands(MCInst &Inst, unsigned N) const { 767 assert(N == 1 && "Invalid number of operands!"); 768 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 769 unsigned EncodedVal = (RegWidth - CE->getValue()) % RegWidth; 770 Inst.addOperand(MCOperand::CreateImm(EncodedVal)); 771 } 772 773 void addBFIWidthOperands(MCInst &Inst, unsigned N) const { 774 assert(N == 1 && "Invalid number of operands!"); 775 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 776 Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 777 } 778 779 void addBFXWidthOperands(MCInst &Inst, unsigned N) const { 780 assert(N == 1 && "Invalid number of operands!"); 781 782 uint64_t LSB = Inst.getOperand(Inst.getNumOperands()-1).getImm(); 783 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 784 785 Inst.addOperand(MCOperand::CreateImm(LSB + CE->getValue() - 1)); 786 } 787 788 void addCondCodeOperands(MCInst &Inst, unsigned N) const { 789 assert(N == 1 && "Invalid number of operands!"); 790 Inst.addOperand(MCOperand::CreateImm(getCondCode())); 791 } 792 793 void addCVTFixedPosOperands(MCInst &Inst, unsigned N) const { 794 assert(N == 1 && "Invalid number of operands!"); 795 796 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 797 Inst.addOperand(MCOperand::CreateImm(64 - CE->getValue())); 798 } 799 800 void addFMOVImmOperands(MCInst &Inst, unsigned N) const { 801 assert(N == 1 && "Invalid number of operands!"); 802 803 APFloat RealVal(FPImm.Val); 804 uint32_t ImmVal; 805 A64Imms::isFPImm(RealVal, ImmVal); 806 807 Inst.addOperand(MCOperand::CreateImm(ImmVal)); 808 } 809 810 void addFPZeroOperands(MCInst &Inst, unsigned N) const { 811 assert(N == 1 && "Invalid number of operands"); 812 Inst.addOperand(MCOperand::CreateImm(0)); 813 } 814 815 void addInvCondCodeOperands(MCInst &Inst, unsigned N) const { 816 assert(N == 1 && "Invalid number of operands!"); 817 unsigned Encoded = A64InvertCondCode(getCondCode()); 818 Inst.addOperand(MCOperand::CreateImm(Encoded)); 819 } 820 821 void addRegOperands(MCInst &Inst, unsigned N) const { 822 assert(N == 1 && "Invalid number of operands!"); 823 Inst.addOperand(MCOperand::CreateReg(getReg())); 824 } 825 826 void addImmOperands(MCInst &Inst, unsigned N) const { 827 assert(N == 1 && "Invalid number of operands!"); 828 addExpr(Inst, getImm()); 829 } 830 831 template<int MemSize> 832 void addSImm7ScaledOperands(MCInst &Inst, unsigned N) const { 833 assert(N == 1 && "Invalid number of operands!"); 834 835 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 836 uint64_t Val = CE->getValue() / MemSize; 837 Inst.addOperand(MCOperand::CreateImm(Val & 0x7f)); 838 } 839 840 template<int BitWidth> 841 void addSImmOperands(MCInst &Inst, unsigned N) const { 842 assert(N == 1 && "Invalid number of operands!"); 843 844 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 845 uint64_t Val = CE->getValue(); 846 Inst.addOperand(MCOperand::CreateImm(Val & ((1ULL << BitWidth) - 1))); 847 } 848 849 void addImmWithLSLOperands(MCInst &Inst, unsigned N) const { 850 assert (N == 1 && "Invalid number of operands!"); 851 852 addExpr(Inst, ImmWithLSL.Val); 853 } 854 855 template<unsigned field_width, unsigned scale> 856 void addLabelOperands(MCInst &Inst, unsigned N) const { 857 assert(N == 1 && "Invalid number of operands!"); 858 859 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val); 860 861 if (!CE) { 862 addExpr(Inst, Imm.Val); 863 return; 864 } 865 866 int64_t Val = CE->getValue(); 867 assert(Val % scale == 0 && "Unaligned immediate in instruction"); 868 Val /= scale; 869 870 Inst.addOperand(MCOperand::CreateImm(Val & ((1LL << field_width) - 1))); 871 } 872 873 template<int MemSize> 874 void addOffsetUImm12Operands(MCInst &Inst, unsigned N) const { 875 assert(N == 1 && "Invalid number of operands!"); 876 877 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) { 878 Inst.addOperand(MCOperand::CreateImm(CE->getValue() / MemSize)); 879 } else { 880 Inst.addOperand(MCOperand::CreateExpr(getImm())); 881 } 882 } 883 884 template<unsigned RegWidth> 885 void addLogicalImmOperands(MCInst &Inst, unsigned N) const { 886 assert(N == 1 && "Invalid number of operands"); 887 const MCConstantExpr *CE = cast<MCConstantExpr>(Imm.Val); 888 889 uint32_t Bits; 890 A64Imms::isLogicalImm(RegWidth, CE->getValue(), Bits); 891 892 Inst.addOperand(MCOperand::CreateImm(Bits)); 893 } 894 895 void addMRSOperands(MCInst &Inst, unsigned N) const { 896 assert(N == 1 && "Invalid number of operands!"); 897 898 bool Valid; 899 StringRef Name(SysReg.Data, SysReg.Length); 900 uint32_t Bits = A64SysReg::MRSMapper().fromString(Name, Valid); 901 902 Inst.addOperand(MCOperand::CreateImm(Bits)); 903 } 904 905 void addMSRWithRegOperands(MCInst &Inst, unsigned N) const { 906 assert(N == 1 && "Invalid number of operands!"); 907 908 bool Valid; 909 StringRef Name(SysReg.Data, SysReg.Length); 910 uint32_t Bits = A64SysReg::MSRMapper().fromString(Name, Valid); 911 912 Inst.addOperand(MCOperand::CreateImm(Bits)); 913 } 914 915 void addMSRPStateOperands(MCInst &Inst, unsigned N) const { 916 assert(N == 1 && "Invalid number of operands!"); 917 918 bool Valid; 919 StringRef Name(SysReg.Data, SysReg.Length); 920 uint32_t Bits = A64PState::PStateMapper().fromString(Name, Valid); 921 922 Inst.addOperand(MCOperand::CreateImm(Bits)); 923 } 924 925 void addMoveWideImmOperands(MCInst &Inst, unsigned N) const { 926 assert(N == 2 && "Invalid number of operands!"); 927 928 addExpr(Inst, ImmWithLSL.Val); 929 930 AArch64MCExpr::VariantKind Variant; 931 if (!isNonConstantExpr(ImmWithLSL.Val, Variant)) { 932 Inst.addOperand(MCOperand::CreateImm(ImmWithLSL.ShiftAmount / 16)); 933 return; 934 } 935 936 // We know it's relocated 937 switch (Variant) { 938 case AArch64MCExpr::VK_AARCH64_ABS_G0: 939 case AArch64MCExpr::VK_AARCH64_ABS_G0_NC: 940 case AArch64MCExpr::VK_AARCH64_SABS_G0: 941 case AArch64MCExpr::VK_AARCH64_DTPREL_G0: 942 case AArch64MCExpr::VK_AARCH64_DTPREL_G0_NC: 943 case AArch64MCExpr::VK_AARCH64_GOTTPREL_G0_NC: 944 case AArch64MCExpr::VK_AARCH64_TPREL_G0: 945 case AArch64MCExpr::VK_AARCH64_TPREL_G0_NC: 946 Inst.addOperand(MCOperand::CreateImm(0)); 947 break; 948 case AArch64MCExpr::VK_AARCH64_ABS_G1: 949 case AArch64MCExpr::VK_AARCH64_ABS_G1_NC: 950 case AArch64MCExpr::VK_AARCH64_SABS_G1: 951 case AArch64MCExpr::VK_AARCH64_DTPREL_G1: 952 case AArch64MCExpr::VK_AARCH64_DTPREL_G1_NC: 953 case AArch64MCExpr::VK_AARCH64_GOTTPREL_G1: 954 case AArch64MCExpr::VK_AARCH64_TPREL_G1: 955 case AArch64MCExpr::VK_AARCH64_TPREL_G1_NC: 956 Inst.addOperand(MCOperand::CreateImm(1)); 957 break; 958 case AArch64MCExpr::VK_AARCH64_ABS_G2: 959 case AArch64MCExpr::VK_AARCH64_ABS_G2_NC: 960 case AArch64MCExpr::VK_AARCH64_SABS_G2: 961 case AArch64MCExpr::VK_AARCH64_DTPREL_G2: 962 case AArch64MCExpr::VK_AARCH64_TPREL_G2: 963 Inst.addOperand(MCOperand::CreateImm(2)); 964 break; 965 case AArch64MCExpr::VK_AARCH64_ABS_G3: 966 Inst.addOperand(MCOperand::CreateImm(3)); 967 break; 968 default: llvm_unreachable("Inappropriate move wide relocation"); 969 } 970 } 971 972 template<int RegWidth, bool isValidImm(int, uint64_t, int&, int&)> 973 void addMoveWideMovAliasOperands(MCInst &Inst, unsigned N) const { 974 assert(N == 2 && "Invalid number of operands!"); 975 int UImm16, Shift; 976 977 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 978 uint64_t Value = CE->getValue(); 979 980 if (RegWidth == 32) { 981 Value &= 0xffffffffULL; 982 } 983 984 bool Valid = isValidImm(RegWidth, Value, UImm16, Shift); 985 (void)Valid; 986 assert(Valid && "Invalid immediates should have been weeded out by now"); 987 988 Inst.addOperand(MCOperand::CreateImm(UImm16)); 989 Inst.addOperand(MCOperand::CreateImm(Shift)); 990 } 991 992 void addPRFMOperands(MCInst &Inst, unsigned N) const { 993 assert(N == 1 && "Invalid number of operands!"); 994 995 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 996 assert(CE->getValue() >= 0 && CE->getValue() <= 31 997 && "PRFM operand should be 5-bits"); 998 999 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 1000 } 1001 1002 // For Add-sub (extended register) operands. 1003 void addRegExtendOperands(MCInst &Inst, unsigned N) const { 1004 assert(N == 1 && "Invalid number of operands!"); 1005 1006 Inst.addOperand(MCOperand::CreateImm(ShiftExtend.Amount)); 1007 } 1008 1009 // For the extend in load-store (register offset) instructions. 1010 template<unsigned MemSize> 1011 void addAddrRegExtendOperands(MCInst &Inst, unsigned N) const { 1012 addAddrRegExtendOperands(Inst, N, MemSize); 1013 } 1014 1015 void addAddrRegExtendOperands(MCInst &Inst, unsigned N, 1016 unsigned MemSize) const { 1017 assert(N == 1 && "Invalid number of operands!"); 1018 1019 // First bit of Option is set in instruction classes, the high two bits are 1020 // as follows: 1021 unsigned OptionHi = 0; 1022 switch (ShiftExtend.ShiftType) { 1023 case A64SE::UXTW: 1024 case A64SE::LSL: 1025 OptionHi = 1; 1026 break; 1027 case A64SE::SXTW: 1028 case A64SE::SXTX: 1029 OptionHi = 3; 1030 break; 1031 default: 1032 llvm_unreachable("Invalid extend type for register offset"); 1033 } 1034 1035 unsigned S = 0; 1036 if (MemSize == 1 && !ShiftExtend.ImplicitAmount) 1037 S = 1; 1038 else if (MemSize != 1 && ShiftExtend.Amount != 0) 1039 S = 1; 1040 1041 Inst.addOperand(MCOperand::CreateImm((OptionHi << 1) | S)); 1042 } 1043 void addShiftOperands(MCInst &Inst, unsigned N) const { 1044 assert(N == 1 && "Invalid number of operands!"); 1045 1046 Inst.addOperand(MCOperand::CreateImm(ShiftExtend.Amount)); 1047 } 1048}; 1049 1050} // end anonymous namespace. 1051 1052AArch64AsmParser::OperandMatchResultTy 1053AArch64AsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1054 StringRef Mnemonic) { 1055 1056 // See if the operand has a custom parser 1057 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 1058 1059 // It could either succeed, fail or just not care. 1060 if (ResTy != MatchOperand_NoMatch) 1061 return ResTy; 1062 1063 switch (getLexer().getKind()) { 1064 default: 1065 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 1066 return MatchOperand_ParseFail; 1067 case AsmToken::Identifier: { 1068 // It might be in the LSL/UXTB family ... 1069 OperandMatchResultTy GotShift = ParseShiftExtend(Operands); 1070 1071 // We can only continue if no tokens were eaten. 1072 if (GotShift != MatchOperand_NoMatch) 1073 return GotShift; 1074 1075 // ... or it might be a register ... 1076 uint32_t NumLanes = 0; 1077 OperandMatchResultTy GotReg = ParseRegister(Operands, NumLanes); 1078 assert(GotReg != MatchOperand_ParseFail 1079 && "register parsing shouldn't partially succeed"); 1080 1081 if (GotReg == MatchOperand_Success) { 1082 if (Parser.getTok().is(AsmToken::LBrac)) 1083 return ParseNEONLane(Operands, NumLanes); 1084 else 1085 return MatchOperand_Success; 1086 } 1087 1088 // ... or it might be a symbolish thing 1089 } 1090 // Fall through 1091 case AsmToken::LParen: // E.g. (strcmp-4) 1092 case AsmToken::Integer: // 1f, 2b labels 1093 case AsmToken::String: // quoted labels 1094 case AsmToken::Dot: // . is Current location 1095 case AsmToken::Dollar: // $ is PC 1096 case AsmToken::Colon: { 1097 SMLoc StartLoc = Parser.getTok().getLoc(); 1098 SMLoc EndLoc; 1099 const MCExpr *ImmVal = 0; 1100 1101 if (ParseImmediate(ImmVal) != MatchOperand_Success) 1102 return MatchOperand_ParseFail; 1103 1104 EndLoc = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1105 Operands.push_back(AArch64Operand::CreateImm(ImmVal, StartLoc, EndLoc)); 1106 return MatchOperand_Success; 1107 } 1108 case AsmToken::Hash: { // Immediates 1109 SMLoc StartLoc = Parser.getTok().getLoc(); 1110 SMLoc EndLoc; 1111 const MCExpr *ImmVal = 0; 1112 Parser.Lex(); 1113 1114 if (ParseImmediate(ImmVal) != MatchOperand_Success) 1115 return MatchOperand_ParseFail; 1116 1117 EndLoc = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1118 Operands.push_back(AArch64Operand::CreateImm(ImmVal, StartLoc, EndLoc)); 1119 return MatchOperand_Success; 1120 } 1121 case AsmToken::LBrac: { 1122 SMLoc Loc = Parser.getTok().getLoc(); 1123 Operands.push_back(AArch64Operand::CreateToken("[", Loc)); 1124 Parser.Lex(); // Eat '[' 1125 1126 // There's no comma after a '[', so we can parse the next operand 1127 // immediately. 1128 return ParseOperand(Operands, Mnemonic); 1129 } 1130 // The following will likely be useful later, but not in very early cases 1131 case AsmToken::LCurly: // Weird SIMD lists 1132 llvm_unreachable("Don't know how to deal with '{' in operand"); 1133 return MatchOperand_ParseFail; 1134 } 1135} 1136 1137AArch64AsmParser::OperandMatchResultTy 1138AArch64AsmParser::ParseImmediate(const MCExpr *&ExprVal) { 1139 if (getLexer().is(AsmToken::Colon)) { 1140 AArch64MCExpr::VariantKind RefKind; 1141 1142 OperandMatchResultTy ResTy = ParseRelocPrefix(RefKind); 1143 if (ResTy != MatchOperand_Success) 1144 return ResTy; 1145 1146 const MCExpr *SubExprVal; 1147 if (getParser().ParseExpression(SubExprVal)) 1148 return MatchOperand_ParseFail; 1149 1150 ExprVal = AArch64MCExpr::Create(RefKind, SubExprVal, getContext()); 1151 return MatchOperand_Success; 1152 } 1153 1154 // No weird AArch64MCExpr prefix 1155 return getParser().ParseExpression(ExprVal) 1156 ? MatchOperand_ParseFail : MatchOperand_Success; 1157} 1158 1159// A lane attached to a NEON register. "[N]", which should yield three tokens: 1160// '[', N, ']'. A hash is not allowed to precede the immediate here. 1161AArch64AsmParser::OperandMatchResultTy 1162AArch64AsmParser::ParseNEONLane(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1163 uint32_t NumLanes) { 1164 SMLoc Loc = Parser.getTok().getLoc(); 1165 1166 assert(Parser.getTok().is(AsmToken::LBrac) && "inappropriate operand"); 1167 Operands.push_back(AArch64Operand::CreateToken("[", Loc)); 1168 Parser.Lex(); // Eat '[' 1169 1170 if (Parser.getTok().isNot(AsmToken::Integer)) { 1171 Error(Parser.getTok().getLoc(), "expected lane number"); 1172 return MatchOperand_ParseFail; 1173 } 1174 1175 if (Parser.getTok().getIntVal() >= NumLanes) { 1176 Error(Parser.getTok().getLoc(), "lane number incompatible with layout"); 1177 return MatchOperand_ParseFail; 1178 } 1179 1180 const MCExpr *Lane = MCConstantExpr::Create(Parser.getTok().getIntVal(), 1181 getContext()); 1182 SMLoc S = Parser.getTok().getLoc(); 1183 Parser.Lex(); // Eat actual lane 1184 SMLoc E = Parser.getTok().getLoc(); 1185 Operands.push_back(AArch64Operand::CreateImm(Lane, S, E)); 1186 1187 1188 if (Parser.getTok().isNot(AsmToken::RBrac)) { 1189 Error(Parser.getTok().getLoc(), "expected ']' after lane"); 1190 return MatchOperand_ParseFail; 1191 } 1192 1193 Operands.push_back(AArch64Operand::CreateToken("]", Loc)); 1194 Parser.Lex(); // Eat ']' 1195 1196 return MatchOperand_Success; 1197} 1198 1199AArch64AsmParser::OperandMatchResultTy 1200AArch64AsmParser::ParseRelocPrefix(AArch64MCExpr::VariantKind &RefKind) { 1201 assert(getLexer().is(AsmToken::Colon) && "expected a ':'"); 1202 Parser.Lex(); 1203 1204 if (getLexer().isNot(AsmToken::Identifier)) { 1205 Error(Parser.getTok().getLoc(), 1206 "expected relocation specifier in operand after ':'"); 1207 return MatchOperand_ParseFail; 1208 } 1209 1210 std::string LowerCase = Parser.getTok().getIdentifier().lower(); 1211 RefKind = StringSwitch<AArch64MCExpr::VariantKind>(LowerCase) 1212 .Case("got", AArch64MCExpr::VK_AARCH64_GOT) 1213 .Case("got_lo12", AArch64MCExpr::VK_AARCH64_GOT_LO12) 1214 .Case("lo12", AArch64MCExpr::VK_AARCH64_LO12) 1215 .Case("abs_g0", AArch64MCExpr::VK_AARCH64_ABS_G0) 1216 .Case("abs_g0_nc", AArch64MCExpr::VK_AARCH64_ABS_G0_NC) 1217 .Case("abs_g1", AArch64MCExpr::VK_AARCH64_ABS_G1) 1218 .Case("abs_g1_nc", AArch64MCExpr::VK_AARCH64_ABS_G1_NC) 1219 .Case("abs_g2", AArch64MCExpr::VK_AARCH64_ABS_G2) 1220 .Case("abs_g2_nc", AArch64MCExpr::VK_AARCH64_ABS_G2_NC) 1221 .Case("abs_g3", AArch64MCExpr::VK_AARCH64_ABS_G3) 1222 .Case("abs_g0_s", AArch64MCExpr::VK_AARCH64_SABS_G0) 1223 .Case("abs_g1_s", AArch64MCExpr::VK_AARCH64_SABS_G1) 1224 .Case("abs_g2_s", AArch64MCExpr::VK_AARCH64_SABS_G2) 1225 .Case("dtprel_g2", AArch64MCExpr::VK_AARCH64_DTPREL_G2) 1226 .Case("dtprel_g1", AArch64MCExpr::VK_AARCH64_DTPREL_G1) 1227 .Case("dtprel_g1_nc", AArch64MCExpr::VK_AARCH64_DTPREL_G1_NC) 1228 .Case("dtprel_g0", AArch64MCExpr::VK_AARCH64_DTPREL_G0) 1229 .Case("dtprel_g0_nc", AArch64MCExpr::VK_AARCH64_DTPREL_G0_NC) 1230 .Case("dtprel_hi12", AArch64MCExpr::VK_AARCH64_DTPREL_HI12) 1231 .Case("dtprel_lo12", AArch64MCExpr::VK_AARCH64_DTPREL_LO12) 1232 .Case("dtprel_lo12_nc", AArch64MCExpr::VK_AARCH64_DTPREL_LO12_NC) 1233 .Case("gottprel_g1", AArch64MCExpr::VK_AARCH64_GOTTPREL_G1) 1234 .Case("gottprel_g0_nc", AArch64MCExpr::VK_AARCH64_GOTTPREL_G0_NC) 1235 .Case("gottprel", AArch64MCExpr::VK_AARCH64_GOTTPREL) 1236 .Case("gottprel_lo12", AArch64MCExpr::VK_AARCH64_GOTTPREL_LO12) 1237 .Case("tprel_g2", AArch64MCExpr::VK_AARCH64_TPREL_G2) 1238 .Case("tprel_g1", AArch64MCExpr::VK_AARCH64_TPREL_G1) 1239 .Case("tprel_g1_nc", AArch64MCExpr::VK_AARCH64_TPREL_G1_NC) 1240 .Case("tprel_g0", AArch64MCExpr::VK_AARCH64_TPREL_G0) 1241 .Case("tprel_g0_nc", AArch64MCExpr::VK_AARCH64_TPREL_G0_NC) 1242 .Case("tprel_hi12", AArch64MCExpr::VK_AARCH64_TPREL_HI12) 1243 .Case("tprel_lo12", AArch64MCExpr::VK_AARCH64_TPREL_LO12) 1244 .Case("tprel_lo12_nc", AArch64MCExpr::VK_AARCH64_TPREL_LO12_NC) 1245 .Case("tlsdesc", AArch64MCExpr::VK_AARCH64_TLSDESC) 1246 .Case("tlsdesc_lo12", AArch64MCExpr::VK_AARCH64_TLSDESC_LO12) 1247 .Default(AArch64MCExpr::VK_AARCH64_None); 1248 1249 if (RefKind == AArch64MCExpr::VK_AARCH64_None) { 1250 Error(Parser.getTok().getLoc(), 1251 "expected relocation specifier in operand after ':'"); 1252 return MatchOperand_ParseFail; 1253 } 1254 Parser.Lex(); // Eat identifier 1255 1256 if (getLexer().isNot(AsmToken::Colon)) { 1257 Error(Parser.getTok().getLoc(), 1258 "expected ':' after relocation specifier"); 1259 return MatchOperand_ParseFail; 1260 } 1261 Parser.Lex(); 1262 return MatchOperand_Success; 1263} 1264 1265AArch64AsmParser::OperandMatchResultTy 1266AArch64AsmParser::ParseImmWithLSLOperand( 1267 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1268 // FIXME?: I want to live in a world where immediates must start with 1269 // #. Please don't dash my hopes (well, do if you have a good reason). 1270 if (Parser.getTok().isNot(AsmToken::Hash)) return MatchOperand_NoMatch; 1271 1272 SMLoc S = Parser.getTok().getLoc(); 1273 Parser.Lex(); // Eat '#' 1274 1275 const MCExpr *Imm; 1276 if (ParseImmediate(Imm) != MatchOperand_Success) 1277 return MatchOperand_ParseFail; 1278 else if (Parser.getTok().isNot(AsmToken::Comma)) { 1279 SMLoc E = Parser.getTok().getLoc(); 1280 Operands.push_back(AArch64Operand::CreateImmWithLSL(Imm, 0, true, S, E)); 1281 return MatchOperand_Success; 1282 } 1283 1284 // Eat ',' 1285 Parser.Lex(); 1286 1287 // The optional operand must be "lsl #N" where N is non-negative. 1288 if (Parser.getTok().is(AsmToken::Identifier) 1289 && Parser.getTok().getIdentifier().lower() == "lsl") { 1290 Parser.Lex(); 1291 1292 if (Parser.getTok().is(AsmToken::Hash)) { 1293 Parser.Lex(); 1294 1295 if (Parser.getTok().isNot(AsmToken::Integer)) { 1296 Error(Parser.getTok().getLoc(), "only 'lsl #+N' valid after immediate"); 1297 return MatchOperand_ParseFail; 1298 } 1299 } 1300 } 1301 1302 int64_t ShiftAmount = Parser.getTok().getIntVal(); 1303 1304 if (ShiftAmount < 0) { 1305 Error(Parser.getTok().getLoc(), "positive shift amount required"); 1306 return MatchOperand_ParseFail; 1307 } 1308 Parser.Lex(); // Eat the number 1309 1310 SMLoc E = Parser.getTok().getLoc(); 1311 Operands.push_back(AArch64Operand::CreateImmWithLSL(Imm, ShiftAmount, 1312 false, S, E)); 1313 return MatchOperand_Success; 1314} 1315 1316 1317AArch64AsmParser::OperandMatchResultTy 1318AArch64AsmParser::ParseCondCodeOperand( 1319 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1320 if (Parser.getTok().isNot(AsmToken::Identifier)) 1321 return MatchOperand_NoMatch; 1322 1323 StringRef Tok = Parser.getTok().getIdentifier(); 1324 A64CC::CondCodes CondCode = A64StringToCondCode(Tok); 1325 1326 if (CondCode == A64CC::Invalid) 1327 return MatchOperand_NoMatch; 1328 1329 SMLoc S = Parser.getTok().getLoc(); 1330 Parser.Lex(); // Eat condition code 1331 SMLoc E = Parser.getTok().getLoc(); 1332 1333 Operands.push_back(AArch64Operand::CreateCondCode(CondCode, S, E)); 1334 return MatchOperand_Success; 1335} 1336 1337AArch64AsmParser::OperandMatchResultTy 1338AArch64AsmParser::ParseCRxOperand( 1339 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1340 SMLoc S = Parser.getTok().getLoc(); 1341 if (Parser.getTok().isNot(AsmToken::Identifier)) { 1342 Error(S, "Expected cN operand where 0 <= N <= 15"); 1343 return MatchOperand_ParseFail; 1344 } 1345 1346 std::string LowerTok = Parser.getTok().getIdentifier().lower(); 1347 StringRef Tok(LowerTok); 1348 if (Tok[0] != 'c') { 1349 Error(S, "Expected cN operand where 0 <= N <= 15"); 1350 return MatchOperand_ParseFail; 1351 } 1352 1353 uint32_t CRNum; 1354 bool BadNum = Tok.drop_front().getAsInteger(10, CRNum); 1355 if (BadNum || CRNum > 15) { 1356 Error(S, "Expected cN operand where 0 <= N <= 15"); 1357 return MatchOperand_ParseFail; 1358 } 1359 1360 const MCExpr *CRImm = MCConstantExpr::Create(CRNum, getContext()); 1361 1362 Parser.Lex(); 1363 SMLoc E = Parser.getTok().getLoc(); 1364 1365 Operands.push_back(AArch64Operand::CreateImm(CRImm, S, E)); 1366 return MatchOperand_Success; 1367} 1368 1369AArch64AsmParser::OperandMatchResultTy 1370AArch64AsmParser::ParseFPImmOperand( 1371 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1372 1373 // FIXME?: I want to live in a world where immediates must start with 1374 // #. Please don't dash my hopes (well, do if you have a good reason). 1375 if (Parser.getTok().isNot(AsmToken::Hash)) return MatchOperand_NoMatch; 1376 1377 SMLoc S = Parser.getTok().getLoc(); 1378 Parser.Lex(); // Eat '#' 1379 1380 bool Negative = false; 1381 if (Parser.getTok().is(AsmToken::Minus)) { 1382 Negative = true; 1383 Parser.Lex(); // Eat '-' 1384 } else if (Parser.getTok().is(AsmToken::Plus)) { 1385 Parser.Lex(); // Eat '+' 1386 } 1387 1388 if (Parser.getTok().isNot(AsmToken::Real)) { 1389 Error(S, "Expected floating-point immediate"); 1390 return MatchOperand_ParseFail; 1391 } 1392 1393 APFloat RealVal(APFloat::IEEEdouble, Parser.getTok().getString()); 1394 if (Negative) RealVal.changeSign(); 1395 double DblVal = RealVal.convertToDouble(); 1396 1397 Parser.Lex(); // Eat real number 1398 SMLoc E = Parser.getTok().getLoc(); 1399 1400 Operands.push_back(AArch64Operand::CreateFPImm(DblVal, S, E)); 1401 return MatchOperand_Success; 1402} 1403 1404 1405// Automatically generated 1406static unsigned MatchRegisterName(StringRef Name); 1407 1408bool 1409AArch64AsmParser::IdentifyRegister(unsigned &RegNum, SMLoc &RegEndLoc, 1410 StringRef &Layout, 1411 SMLoc &LayoutLoc) const { 1412 const AsmToken &Tok = Parser.getTok(); 1413 1414 if (Tok.isNot(AsmToken::Identifier)) 1415 return false; 1416 1417 std::string LowerReg = Tok.getString().lower(); 1418 size_t DotPos = LowerReg.find('.'); 1419 1420 RegNum = MatchRegisterName(LowerReg.substr(0, DotPos)); 1421 if (RegNum == AArch64::NoRegister) { 1422 RegNum = StringSwitch<unsigned>(LowerReg.substr(0, DotPos)) 1423 .Case("ip0", AArch64::X16) 1424 .Case("ip1", AArch64::X17) 1425 .Case("fp", AArch64::X29) 1426 .Case("lr", AArch64::X30) 1427 .Default(AArch64::NoRegister); 1428 } 1429 if (RegNum == AArch64::NoRegister) 1430 return false; 1431 1432 SMLoc S = Tok.getLoc(); 1433 RegEndLoc = SMLoc::getFromPointer(S.getPointer() + DotPos); 1434 1435 if (DotPos == StringRef::npos) { 1436 Layout = StringRef(); 1437 } else { 1438 // Everything afterwards needs to be a literal token, expected to be 1439 // '.2d','.b' etc for vector registers. 1440 1441 // This StringSwitch validates the input and (perhaps more importantly) 1442 // gives us a permanent string to use in the token (a pointer into LowerReg 1443 // would go out of scope when we return). 1444 LayoutLoc = SMLoc::getFromPointer(S.getPointer() + DotPos + 1); 1445 Layout = LowerReg.substr(DotPos, StringRef::npos); 1446 Layout = StringSwitch<const char *>(Layout) 1447 .Case(".d", ".d").Case(".1d", ".1d").Case(".2d", ".2d") 1448 .Case(".s", ".s").Case(".2s", ".2s").Case(".4s", ".4s") 1449 .Case(".h", ".h").Case(".4h", ".4h").Case(".8h", ".8h") 1450 .Case(".b", ".b").Case(".8b", ".8b").Case(".16b", ".16b") 1451 .Default(""); 1452 1453 if (Layout.size() == 0) { 1454 // Malformed register 1455 return false; 1456 } 1457 } 1458 1459 return true; 1460} 1461 1462AArch64AsmParser::OperandMatchResultTy 1463AArch64AsmParser::ParseRegister(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1464 uint32_t &NumLanes) { 1465 unsigned RegNum; 1466 StringRef Layout; 1467 SMLoc RegEndLoc, LayoutLoc; 1468 SMLoc S = Parser.getTok().getLoc(); 1469 1470 if (!IdentifyRegister(RegNum, RegEndLoc, Layout, LayoutLoc)) 1471 return MatchOperand_NoMatch; 1472 1473 Operands.push_back(AArch64Operand::CreateReg(RegNum, S, RegEndLoc)); 1474 1475 if (Layout.size() != 0) { 1476 unsigned long long TmpLanes = 0; 1477 llvm::getAsUnsignedInteger(Layout.substr(1), 10, TmpLanes); 1478 if (TmpLanes != 0) { 1479 NumLanes = TmpLanes; 1480 } else { 1481 // If the number of lanes isn't specified explicitly, a valid instruction 1482 // will have an element specifier and be capable of acting on the entire 1483 // vector register. 1484 switch (Layout.back()) { 1485 default: llvm_unreachable("Invalid layout specifier"); 1486 case 'b': NumLanes = 16; break; 1487 case 'h': NumLanes = 8; break; 1488 case 's': NumLanes = 4; break; 1489 case 'd': NumLanes = 2; break; 1490 } 1491 } 1492 1493 Operands.push_back(AArch64Operand::CreateToken(Layout, LayoutLoc)); 1494 } 1495 1496 Parser.Lex(); 1497 return MatchOperand_Success; 1498} 1499 1500bool 1501AArch64AsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 1502 SMLoc &EndLoc) { 1503 // This callback is used for things like DWARF frame directives in 1504 // assembly. They don't care about things like NEON layouts or lanes, they 1505 // just want to be able to produce the DWARF register number. 1506 StringRef LayoutSpec; 1507 SMLoc RegEndLoc, LayoutLoc; 1508 StartLoc = Parser.getTok().getLoc(); 1509 1510 if (!IdentifyRegister(RegNo, RegEndLoc, LayoutSpec, LayoutLoc)) 1511 return true; 1512 1513 Parser.Lex(); 1514 EndLoc = Parser.getTok().getLoc(); 1515 1516 return false; 1517} 1518 1519AArch64AsmParser::OperandMatchResultTy 1520AArch64AsmParser::ParseNamedImmOperand(const NamedImmMapper &Mapper, 1521 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1522 // Since these operands occur in very limited circumstances, without 1523 // alternatives, we actually signal an error if there is no match. If relaxing 1524 // this, beware of unintended consequences: an immediate will be accepted 1525 // during matching, no matter how it gets into the AArch64Operand. 1526 const AsmToken &Tok = Parser.getTok(); 1527 SMLoc S = Tok.getLoc(); 1528 1529 if (Tok.is(AsmToken::Identifier)) { 1530 bool ValidName; 1531 uint32_t Code = Mapper.fromString(Tok.getString().lower(), ValidName); 1532 1533 if (!ValidName) { 1534 Error(S, "operand specifier not recognised"); 1535 return MatchOperand_ParseFail; 1536 } 1537 1538 Parser.Lex(); // We're done with the identifier. Eat it 1539 1540 SMLoc E = Parser.getTok().getLoc(); 1541 const MCExpr *Imm = MCConstantExpr::Create(Code, getContext()); 1542 Operands.push_back(AArch64Operand::CreateImm(Imm, S, E)); 1543 return MatchOperand_Success; 1544 } else if (Tok.is(AsmToken::Hash)) { 1545 Parser.Lex(); 1546 1547 const MCExpr *ImmVal; 1548 if (ParseImmediate(ImmVal) != MatchOperand_Success) 1549 return MatchOperand_ParseFail; 1550 1551 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal); 1552 if (!CE || CE->getValue() < 0 || !Mapper.validImm(CE->getValue())) { 1553 Error(S, "Invalid immediate for instruction"); 1554 return MatchOperand_ParseFail; 1555 } 1556 1557 SMLoc E = Parser.getTok().getLoc(); 1558 Operands.push_back(AArch64Operand::CreateImm(ImmVal, S, E)); 1559 return MatchOperand_Success; 1560 } 1561 1562 Error(S, "unexpected operand for instruction"); 1563 return MatchOperand_ParseFail; 1564} 1565 1566AArch64AsmParser::OperandMatchResultTy 1567AArch64AsmParser::ParseSysRegOperand( 1568 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1569 const AsmToken &Tok = Parser.getTok(); 1570 1571 // Any MSR/MRS operand will be an identifier, and we want to store it as some 1572 // kind of string: SPSel is valid for two different forms of MSR with two 1573 // different encodings. There's no collision at the moment, but the potential 1574 // is there. 1575 if (!Tok.is(AsmToken::Identifier)) { 1576 return MatchOperand_NoMatch; 1577 } 1578 1579 SMLoc S = Tok.getLoc(); 1580 Operands.push_back(AArch64Operand::CreateSysReg(Tok.getString(), S)); 1581 Parser.Lex(); // Eat identifier 1582 1583 return MatchOperand_Success; 1584} 1585 1586AArch64AsmParser::OperandMatchResultTy 1587AArch64AsmParser::ParseLSXAddressOperand( 1588 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1589 SMLoc S = Parser.getTok().getLoc(); 1590 1591 unsigned RegNum; 1592 SMLoc RegEndLoc, LayoutLoc; 1593 StringRef Layout; 1594 if(!IdentifyRegister(RegNum, RegEndLoc, Layout, LayoutLoc) 1595 || !AArch64MCRegisterClasses[AArch64::GPR64xspRegClassID].contains(RegNum) 1596 || Layout.size() != 0) { 1597 // Check Layout.size because we don't want to let "x3.4s" or similar 1598 // through. 1599 return MatchOperand_NoMatch; 1600 } 1601 Parser.Lex(); // Eat register 1602 1603 if (Parser.getTok().is(AsmToken::RBrac)) { 1604 // We're done 1605 SMLoc E = Parser.getTok().getLoc(); 1606 Operands.push_back(AArch64Operand::CreateWrappedReg(RegNum, S, E)); 1607 return MatchOperand_Success; 1608 } 1609 1610 // Otherwise, only ", #0" is valid 1611 1612 if (Parser.getTok().isNot(AsmToken::Comma)) { 1613 Error(Parser.getTok().getLoc(), "expected ',' or ']' after register"); 1614 return MatchOperand_ParseFail; 1615 } 1616 Parser.Lex(); // Eat ',' 1617 1618 if (Parser.getTok().isNot(AsmToken::Hash)) { 1619 Error(Parser.getTok().getLoc(), "expected '#0'"); 1620 return MatchOperand_ParseFail; 1621 } 1622 Parser.Lex(); // Eat '#' 1623 1624 if (Parser.getTok().isNot(AsmToken::Integer) 1625 || Parser.getTok().getIntVal() != 0 ) { 1626 Error(Parser.getTok().getLoc(), "expected '#0'"); 1627 return MatchOperand_ParseFail; 1628 } 1629 Parser.Lex(); // Eat '0' 1630 1631 SMLoc E = Parser.getTok().getLoc(); 1632 Operands.push_back(AArch64Operand::CreateWrappedReg(RegNum, S, E)); 1633 return MatchOperand_Success; 1634} 1635 1636AArch64AsmParser::OperandMatchResultTy 1637AArch64AsmParser::ParseShiftExtend( 1638 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1639 StringRef IDVal = Parser.getTok().getIdentifier(); 1640 std::string LowerID = IDVal.lower(); 1641 1642 A64SE::ShiftExtSpecifiers Spec = 1643 StringSwitch<A64SE::ShiftExtSpecifiers>(LowerID) 1644 .Case("lsl", A64SE::LSL) 1645 .Case("lsr", A64SE::LSR) 1646 .Case("asr", A64SE::ASR) 1647 .Case("ror", A64SE::ROR) 1648 .Case("uxtb", A64SE::UXTB) 1649 .Case("uxth", A64SE::UXTH) 1650 .Case("uxtw", A64SE::UXTW) 1651 .Case("uxtx", A64SE::UXTX) 1652 .Case("sxtb", A64SE::SXTB) 1653 .Case("sxth", A64SE::SXTH) 1654 .Case("sxtw", A64SE::SXTW) 1655 .Case("sxtx", A64SE::SXTX) 1656 .Default(A64SE::Invalid); 1657 1658 if (Spec == A64SE::Invalid) 1659 return MatchOperand_NoMatch; 1660 1661 // Eat the shift 1662 SMLoc S, E; 1663 S = Parser.getTok().getLoc(); 1664 Parser.Lex(); 1665 1666 if (Spec != A64SE::LSL && Spec != A64SE::LSR && 1667 Spec != A64SE::ASR && Spec != A64SE::ROR) { 1668 // The shift amount can be omitted for the extending versions, but not real 1669 // shifts: 1670 // add x0, x0, x0, uxtb 1671 // is valid, and equivalent to 1672 // add x0, x0, x0, uxtb #0 1673 1674 if (Parser.getTok().is(AsmToken::Comma) || 1675 Parser.getTok().is(AsmToken::EndOfStatement) || 1676 Parser.getTok().is(AsmToken::RBrac)) { 1677 Operands.push_back(AArch64Operand::CreateShiftExtend(Spec, 0, true, 1678 S, E)); 1679 return MatchOperand_Success; 1680 } 1681 } 1682 1683 // Eat # at beginning of immediate 1684 if (!Parser.getTok().is(AsmToken::Hash)) { 1685 Error(Parser.getTok().getLoc(), 1686 "expected #imm after shift specifier"); 1687 return MatchOperand_ParseFail; 1688 } 1689 Parser.Lex(); 1690 1691 // Make sure we do actually have a number 1692 if (!Parser.getTok().is(AsmToken::Integer)) { 1693 Error(Parser.getTok().getLoc(), 1694 "expected integer shift amount"); 1695 return MatchOperand_ParseFail; 1696 } 1697 unsigned Amount = Parser.getTok().getIntVal(); 1698 Parser.Lex(); 1699 E = Parser.getTok().getLoc(); 1700 1701 Operands.push_back(AArch64Operand::CreateShiftExtend(Spec, Amount, false, 1702 S, E)); 1703 1704 return MatchOperand_Success; 1705} 1706 1707// FIXME: We would really like to be able to tablegen'erate this. 1708bool AArch64AsmParser:: 1709validateInstruction(MCInst &Inst, 1710 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1711 switch (Inst.getOpcode()) { 1712 case AArch64::BFIwwii: 1713 case AArch64::BFIxxii: 1714 case AArch64::SBFIZwwii: 1715 case AArch64::SBFIZxxii: 1716 case AArch64::UBFIZwwii: 1717 case AArch64::UBFIZxxii: { 1718 unsigned ImmOps = Inst.getNumOperands() - 2; 1719 int64_t ImmR = Inst.getOperand(ImmOps).getImm(); 1720 int64_t ImmS = Inst.getOperand(ImmOps+1).getImm(); 1721 1722 if (ImmR == 0) { 1723 // Bitfield inserts are preferred disassembly if ImmS < ImmR. However, 1724 // there is this one case where insert is valid syntax but the bfx 1725 // disassembly should be used: e.g. "sbfiz w0, w0, #0, #1". 1726 return false; 1727 } else if (ImmS >= ImmR) { 1728 return Error(Operands[4]->getStartLoc(), 1729 "requested insert overflows register"); 1730 } 1731 return false; 1732 } 1733 case AArch64::BFXILwwii: 1734 case AArch64::BFXILxxii: 1735 case AArch64::SBFXwwii: 1736 case AArch64::SBFXxxii: 1737 case AArch64::UBFXwwii: 1738 case AArch64::UBFXxxii: { 1739 unsigned ImmOps = Inst.getNumOperands() - 2; 1740 int64_t ImmR = Inst.getOperand(ImmOps).getImm(); 1741 int64_t ImmS = Inst.getOperand(ImmOps+1).getImm(); 1742 int64_t RegWidth = 0; 1743 switch (Inst.getOpcode()) { 1744 case AArch64::SBFXxxii: case AArch64::UBFXxxii: case AArch64::BFXILxxii: 1745 RegWidth = 64; 1746 break; 1747 case AArch64::SBFXwwii: case AArch64::UBFXwwii: case AArch64::BFXILwwii: 1748 RegWidth = 32; 1749 break; 1750 } 1751 1752 if (ImmS >= RegWidth || ImmS < ImmR) { 1753 return Error(Operands[4]->getStartLoc(), 1754 "requested extract overflows register"); 1755 } 1756 return false; 1757 } 1758 case AArch64::ICix: { 1759 int64_t ImmVal = Inst.getOperand(0).getImm(); 1760 A64IC::ICValues ICOp = static_cast<A64IC::ICValues>(ImmVal); 1761 if (!A64IC::NeedsRegister(ICOp)) { 1762 return Error(Operands[1]->getStartLoc(), 1763 "specified IC op does not use a register"); 1764 } 1765 return false; 1766 } 1767 case AArch64::ICi: { 1768 int64_t ImmVal = Inst.getOperand(0).getImm(); 1769 A64IC::ICValues ICOp = static_cast<A64IC::ICValues>(ImmVal); 1770 if (A64IC::NeedsRegister(ICOp)) { 1771 return Error(Operands[1]->getStartLoc(), 1772 "specified IC op requires a register"); 1773 } 1774 return false; 1775 } 1776 case AArch64::TLBIix: { 1777 int64_t ImmVal = Inst.getOperand(0).getImm(); 1778 A64TLBI::TLBIValues TLBIOp = static_cast<A64TLBI::TLBIValues>(ImmVal); 1779 if (!A64TLBI::NeedsRegister(TLBIOp)) { 1780 return Error(Operands[1]->getStartLoc(), 1781 "specified TLBI op does not use a register"); 1782 } 1783 return false; 1784 } 1785 case AArch64::TLBIi: { 1786 int64_t ImmVal = Inst.getOperand(0).getImm(); 1787 A64TLBI::TLBIValues TLBIOp = static_cast<A64TLBI::TLBIValues>(ImmVal); 1788 if (A64TLBI::NeedsRegister(TLBIOp)) { 1789 return Error(Operands[1]->getStartLoc(), 1790 "specified TLBI op requires a register"); 1791 } 1792 return false; 1793 } 1794 } 1795 1796 return false; 1797} 1798 1799 1800// Parses the instruction *together with* all operands, appending each parsed 1801// operand to the "Operands" list 1802bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info, 1803 StringRef Name, SMLoc NameLoc, 1804 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1805 size_t CondCodePos = Name.find('.'); 1806 1807 StringRef Mnemonic = Name.substr(0, CondCodePos); 1808 Operands.push_back(AArch64Operand::CreateToken(Mnemonic, NameLoc)); 1809 1810 if (CondCodePos != StringRef::npos) { 1811 // We have a condition code 1812 SMLoc S = SMLoc::getFromPointer(NameLoc.getPointer() + CondCodePos + 1); 1813 StringRef CondStr = Name.substr(CondCodePos + 1, StringRef::npos); 1814 A64CC::CondCodes Code; 1815 1816 Code = A64StringToCondCode(CondStr); 1817 1818 if (Code == A64CC::Invalid) { 1819 Error(S, "invalid condition code"); 1820 Parser.EatToEndOfStatement(); 1821 return true; 1822 } 1823 1824 SMLoc DotL = SMLoc::getFromPointer(NameLoc.getPointer() + CondCodePos); 1825 1826 Operands.push_back(AArch64Operand::CreateToken(".", DotL)); 1827 SMLoc E = SMLoc::getFromPointer(NameLoc.getPointer() + CondCodePos + 3); 1828 Operands.push_back(AArch64Operand::CreateCondCode(Code, S, E)); 1829 } 1830 1831 // Now we parse the operands of this instruction 1832 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1833 // Read the first operand. 1834 if (ParseOperand(Operands, Mnemonic)) { 1835 Parser.EatToEndOfStatement(); 1836 return true; 1837 } 1838 1839 while (getLexer().is(AsmToken::Comma)) { 1840 Parser.Lex(); // Eat the comma. 1841 1842 // Parse and remember the operand. 1843 if (ParseOperand(Operands, Mnemonic)) { 1844 Parser.EatToEndOfStatement(); 1845 return true; 1846 } 1847 1848 1849 // After successfully parsing some operands there are two special cases to 1850 // consider (i.e. notional operands not separated by commas). Both are due 1851 // to memory specifiers: 1852 // + An RBrac will end an address for load/store/prefetch 1853 // + An '!' will indicate a pre-indexed operation. 1854 // 1855 // It's someone else's responsibility to make sure these tokens are sane 1856 // in the given context! 1857 if (Parser.getTok().is(AsmToken::RBrac)) { 1858 SMLoc Loc = Parser.getTok().getLoc(); 1859 Operands.push_back(AArch64Operand::CreateToken("]", Loc)); 1860 Parser.Lex(); 1861 } 1862 1863 if (Parser.getTok().is(AsmToken::Exclaim)) { 1864 SMLoc Loc = Parser.getTok().getLoc(); 1865 Operands.push_back(AArch64Operand::CreateToken("!", Loc)); 1866 Parser.Lex(); 1867 } 1868 } 1869 } 1870 1871 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1872 SMLoc Loc = getLexer().getLoc(); 1873 Parser.EatToEndOfStatement(); 1874 return Error(Loc, ""); 1875 } 1876 1877 // Eat the EndOfStatement 1878 Parser.Lex(); 1879 1880 return false; 1881} 1882 1883bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) { 1884 StringRef IDVal = DirectiveID.getIdentifier(); 1885 if (IDVal == ".hword") 1886 return ParseDirectiveWord(2, DirectiveID.getLoc()); 1887 else if (IDVal == ".word") 1888 return ParseDirectiveWord(4, DirectiveID.getLoc()); 1889 else if (IDVal == ".xword") 1890 return ParseDirectiveWord(8, DirectiveID.getLoc()); 1891 else if (IDVal == ".tlsdesccall") 1892 return ParseDirectiveTLSDescCall(DirectiveID.getLoc()); 1893 1894 return true; 1895} 1896 1897/// parseDirectiveWord 1898/// ::= .word [ expression (, expression)* ] 1899bool AArch64AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 1900 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1901 for (;;) { 1902 const MCExpr *Value; 1903 if (getParser().ParseExpression(Value)) 1904 return true; 1905 1906 getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 1907 1908 if (getLexer().is(AsmToken::EndOfStatement)) 1909 break; 1910 1911 // FIXME: Improve diagnostic. 1912 if (getLexer().isNot(AsmToken::Comma)) 1913 return Error(L, "unexpected token in directive"); 1914 Parser.Lex(); 1915 } 1916 } 1917 1918 Parser.Lex(); 1919 return false; 1920} 1921 1922// parseDirectiveTLSDescCall: 1923// ::= .tlsdesccall symbol 1924bool AArch64AsmParser::ParseDirectiveTLSDescCall(SMLoc L) { 1925 StringRef Name; 1926 if (getParser().ParseIdentifier(Name)) 1927 return Error(L, "expected symbol after directive"); 1928 1929 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 1930 const MCSymbolRefExpr *Expr = MCSymbolRefExpr::Create(Sym, getContext()); 1931 1932 MCInst Inst; 1933 Inst.setOpcode(AArch64::TLSDESCCALL); 1934 Inst.addOperand(MCOperand::CreateExpr(Expr)); 1935 1936 getParser().getStreamer().EmitInstruction(Inst); 1937 return false; 1938} 1939 1940 1941bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 1942 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1943 MCStreamer &Out, unsigned &ErrorInfo, 1944 bool MatchingInlineAsm) { 1945 MCInst Inst; 1946 unsigned MatchResult; 1947 MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, 1948 MatchingInlineAsm); 1949 switch (MatchResult) { 1950 default: break; 1951 case Match_Success: 1952 if (validateInstruction(Inst, Operands)) 1953 return true; 1954 1955 Out.EmitInstruction(Inst); 1956 return false; 1957 case Match_MissingFeature: 1958 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 1959 return true; 1960 case Match_InvalidOperand: { 1961 SMLoc ErrorLoc = IDLoc; 1962 if (ErrorInfo != ~0U) { 1963 if (ErrorInfo >= Operands.size()) 1964 return Error(IDLoc, "too few operands for instruction"); 1965 1966 ErrorLoc = ((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(); 1967 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 1968 } 1969 1970 return Error(ErrorLoc, "invalid operand for instruction"); 1971 } 1972 case Match_MnemonicFail: 1973 return Error(IDLoc, "invalid instruction"); 1974 } 1975 1976 llvm_unreachable("Implement any new match types added!"); 1977 return true; 1978} 1979 1980void AArch64Operand::print(raw_ostream &OS) const { 1981 switch (Kind) { 1982 case k_CondCode: 1983 OS << "<CondCode: " << CondCode.Code << ">"; 1984 break; 1985 case k_FPImmediate: 1986 OS << "<fpimm: " << FPImm.Val << ">"; 1987 break; 1988 case k_ImmWithLSL: 1989 OS << "<immwithlsl: imm=" << ImmWithLSL.Val 1990 << ", shift=" << ImmWithLSL.ShiftAmount << ">"; 1991 break; 1992 case k_Immediate: 1993 getImm()->print(OS); 1994 break; 1995 case k_Register: 1996 OS << "<register " << getReg() << '>'; 1997 break; 1998 case k_Token: 1999 OS << '\'' << getToken() << '\''; 2000 break; 2001 case k_ShiftExtend: 2002 OS << "<shift: type=" << ShiftExtend.ShiftType 2003 << ", amount=" << ShiftExtend.Amount << ">"; 2004 break; 2005 case k_SysReg: { 2006 StringRef Name(SysReg.Data, SysReg.Length); 2007 OS << "<sysreg: " << Name << '>'; 2008 break; 2009 } 2010 default: 2011 llvm_unreachable("No idea how to print this kind of operand"); 2012 break; 2013 } 2014} 2015 2016void AArch64Operand::dump() const { 2017 print(errs()); 2018} 2019 2020 2021/// Force static initialization. 2022extern "C" void LLVMInitializeAArch64AsmParser() { 2023 RegisterMCAsmParser<AArch64AsmParser> X(TheAArch64Target); 2024} 2025 2026#define GET_REGISTER_MATCHER 2027#define GET_MATCHER_IMPLEMENTATION 2028#include "AArch64GenAsmMatcher.inc" 2029